Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add lit_timestamp_nanosecond #1030

Merged
merged 4 commits into from
Sep 22, 2021
Merged

Conversation

NGA-TRAN
Copy link
Contributor

@NGA-TRAN NGA-TRAN commented Sep 20, 2021

Which issue does this PR close?

Closes #.

Rationale for this change

Add function lit_timestamp_nanosecond to create a literal timestamp expression for a number. See tests for examples

@github-actions github-actions bot added the datafusion Changes in the datafusion crate label Sep 20, 2021
unnormalize_col, unnormalize_cols, upper, when, Column, Expr, ExprRewriter,
ExpressionVisitor, Literal, Recursion, RewriteRecursion,
exprlist_to_fields, floor, in_list, initcap, left, length, lit,
lit_timestamp_nanosecond, ln, log10, log2, lower, lpad, ltrim, max, md5, min,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lit_timestamp_nanosecond is newly added

@@ -1871,6 +1920,21 @@ mod tests {
assert!(maybe_expr.is_err());
}

#[test]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are a few examples: is time column has timestamp data type, value 10 needs to also be a timestamp (in nanosecond in this case) to have the expression analysis works

@NGA-TRAN
Copy link
Contributor Author

@alamb Can you help review this?

@houqp houqp requested a review from alamb September 20, 2021 22:35
@houqp houqp added the enhancement New feature or request label Sep 20, 2021
@@ -1408,6 +1452,11 @@ pub fn lit<T: Literal>(n: T) -> Expr {
n.lit()
}

/// Create a literal timestamp expression
pub fn lit_timestamp_nanosecond<T: Literal>(n: T) -> Expr {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we consider it a user error if a non-numerical literal type is passed in here? If so, it might be better to introduce a new ns timestamp trait and only implement it for the numeric types we support so we can let rust compiler catch these issues at build time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be nice to try and parse str into timestamps, though that would require making this function fallible, which might be kind of messy. 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a new trait for appropriate numeric only is a good solution. It can be extended later to support string parsing. Let me give it a shot.


fn lit_timestamp_nanosecond(&self) -> Expr {
let scalar = ScalarValue::$SCALAR(Some(self.clone()));
scalar.lit_timestamp_nanosecond()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this seems a little bit inefficient to wrap a numeric value with ScalarValue enum, then subsequently match on that enum to unpack the value and return a different enum. Perhaps we could find a way to execute ScalarValue::TimestampNanosecond(Some(self.clone().into()) here directly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a good solution to me👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried that but not all data type works for the into


fn lit_timestamp_nanosecond(&self) -> Expr {
let scalar = ScalarValue::$SCALAR(Some(self.clone()));
scalar.lit_timestamp_nanosecond()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@@ -1408,6 +1452,11 @@ pub fn lit<T: Literal>(n: T) -> Expr {
n.lit()
}

/// Create a literal timestamp expression
pub fn lit_timestamp_nanosecond<T: Literal>(n: T) -> Expr {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be nice to try and parse str into timestamps, though that would require making this function fallible, which might be kind of messy. 🤔

@@ -1360,24 +1360,63 @@ pub fn in_list(expr: Expr, list: Vec<Expr>, negated: bool) -> Expr {
pub trait Literal {
/// convert the value to a Literal expression
fn lit(&self) -> Expr;

/// convert the number to literal expression of timestamp in nanosecond
fn lit_timestamp_nanosecond(&self) -> Expr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking perhaps calling this lit_timestamp_nano or something would be more consistent with chrono, but when I looked, chrono appears to be inconsistent on this point (uses both nano and nanosecond) https://docs.rs/chrono/0.4.19/chrono/?search=nano

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like lit_timestamp_nano better because it is shorter. Let go with it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alamb @Dandandan and @houqp I have added a new trait for it. Can you have a look?

Copy link
Member

@houqp houqp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new implementation looks much cleaner, thanks a lot @NGA-TRAN !

@houqp
Copy link
Member

houqp commented Sep 21, 2021

BTW, we have a python test that fails intermittently, I manually restarted the test.

Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good -- thanks @NGA-TRAN !

@alamb alamb merged commit 1c858ce into apache:master Sep 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
datafusion Changes in the datafusion crate enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants