parse timestamp

main
Ziyang Hu 2 years ago
parent 12d8af24d6
commit 115873e61a

@ -627,7 +627,7 @@ Empty matches::
--------------------
Misc functions
Timestamp functions
--------------------
.. function:: now()
@ -638,4 +638,8 @@ Misc functions
Interpret ``ts`` as seconds since the epoch and format as a string according to `RFC3339 <https://www.rfc-editor.org/rfc/rfc3339>`_.
If a second string argument is provided, it is interpreted as a `timezone <https://en.wikipedia.org/wiki/Tz_database>`_ and used to format the timestamp.
If a second string argument is provided, it is interpreted as a `timezone <https://en.wikipedia.org/wiki/Tz_database>`_ and used to format the timestamp.
.. function:: parse_timestamp(str)
Parse ``str`` into seconds since the epoch according to RFC3339.

@ -336,7 +336,7 @@ impl Expr {
if target == symb {
let tar_val = match val.get_int() {
Some(i) => DataValue::from(i),
None => val.clone()
None => val.clone(),
};
return Ok(ValueRange::lower_bound(tar_val));
}
@ -347,7 +347,7 @@ impl Expr {
if target == symb {
let tar_val = match val.get_float() {
Some(i) => DataValue::from(i),
None => val.clone()
None => val.clone(),
};
return Ok(ValueRange::upper_bound(tar_val));
}
@ -361,7 +361,7 @@ impl Expr {
if target == symb {
let tar_val = match val.get_float() {
Some(i) => DataValue::from(i),
None => val.clone()
None => val.clone(),
};
return Ok(ValueRange::upper_bound(tar_val));
@ -373,7 +373,7 @@ impl Expr {
if target == symb {
let tar_val = match val.get_int() {
Some(i) => DataValue::from(i),
None => val.clone()
None => val.clone(),
};
return Ok(ValueRange::lower_bound(tar_val));
@ -653,6 +653,7 @@ pub(crate) fn get_op(name: &str) -> Option<&'static Op> {
"uuid_timestamp" => &OP_UUID_TIMESTAMP,
"now" => &OP_NOW,
"format_timestamp" => &OP_FORMAT_TIMESTAMP,
"parse_timestamp" => &OP_PARSE_TIMESTAMP,
_ => return None,
})
}

@ -3,7 +3,7 @@ use std::ops::{Div, Rem};
use std::str::FromStr;
use std::time::{SystemTime, UNIX_EPOCH};
use chrono::{TimeZone, Utc};
use chrono::{DateTime, TimeZone, Utc};
use itertools::Itertools;
use miette::{bail, ensure, miette, Result};
use num_traits::FloatConst;
@ -1417,7 +1417,8 @@ pub(crate) fn op_format_timestamp(args: &[DataValue]) -> Result<DataValue> {
let tz_s = tz_v.get_string().ok_or_else(|| {
miette!("'format_timestamp' timezone specification requires a string")
})?;
let tz = chrono_tz::Tz::from_str(tz_s).map_err(|_| miette!("bad timezone specification: {}", tz_s))?;
let tz = chrono_tz::Tz::from_str(tz_s)
.map_err(|_| miette!("bad timezone specification: {}", tz_s))?;
let dt_tz = dt.with_timezone(&tz);
let s = SmartString::from(dt_tz.to_rfc3339());
Ok(DataValue::Str(s))
@ -1429,6 +1430,18 @@ pub(crate) fn op_format_timestamp(args: &[DataValue]) -> Result<DataValue> {
}
}
define_op!(OP_PARSE_TIMESTAMP, 1, false);
pub(crate) fn op_parse_timestamp(args: &[DataValue]) -> Result<DataValue> {
let s = args[0]
.get_string()
.ok_or_else(|| miette!("'parse_timestamp' expects a string"))?;
let dt = DateTime::parse_from_rfc3339(s).map_err(|_| miette!("bad datetime: {}", s))?;
let st: SystemTime = dt.into();
Ok(DataValue::from(
st.duration_since(UNIX_EPOCH).unwrap().as_secs_f64(),
))
}
define_op!(OP_RAND_UUID_V1, 0, false);
pub(crate) fn op_rand_uuid_v1(_args: &[DataValue]) -> Result<DataValue> {
let mut rng = rand::thread_rng();

@ -1328,5 +1328,6 @@ fn test_uuid() {
fn test_now() {
let now = op_now(&[]).unwrap();
assert!(matches!(now, DataValue::Num(_)));
op_format_timestamp(&[now]).unwrap();
let s = op_format_timestamp(&[now]).unwrap();
let _dt = op_parse_timestamp(&[s]).unwrap();
}

@ -756,6 +756,7 @@ impl RelationRA {
left_to_prefix_indices.push(left_join_indices[*idx]);
}
// TODO don't build the whole thing is prefix scan suffices
let mut right_join_vals = BTreeSet::new();
for tuple in self.storage.scan_all(tx) {
let tuple = tuple?;

Loading…
Cancel
Save