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

fix: support unary operator in default value, partition rule and prepare statement #4301

Merged
merged 10 commits into from
Jul 9, 2024

Conversation

waynexia
Copy link
Member

@waynexia waynexia commented Jul 5, 2024

I hereby agree to the terms of the GreptimeDB CLA.

Refer to a related PR or issue link (optional)

Closes #4247

What's changed and what's your intention?

Make the unary operator an optional parameter of sql_value_to_value and handle it in several places stated in title.

Checklist

  • I have written the necessary rustdoc comments.
  • I have added the necessary unit tests and integration tests.
  • This PR requires documentation updates.

Summary by CodeRabbit

  • New Features

    • Enhanced error handling for unsupported unary operations in SQL statements.
    • Improved control flow in SQL value processing to account for unary operations.
  • Bug Fixes

    • Corrected handling of unary operations to ensure accurate error reporting and processing.
  • Refactor

    • Streamlined error types to provide clearer feedback on invalid and unsupported unary operations.

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
@waynexia waynexia requested a review from a team as a code owner July 5, 2024 09:45
@github-actions github-actions bot added the docs-not-required This change does not impact docs. label Jul 5, 2024
Copy link

codecov bot commented Jul 5, 2024

Codecov Report

Attention: Patch coverage is 56.30631% with 97 lines in your changes missing coverage. Please review.

Project coverage is 84.87%. Comparing base (1a9314a) to head (6779ea2).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4301      +/-   ##
==========================================
- Coverage   85.18%   84.87%   -0.32%     
==========================================
  Files        1061     1061              
  Lines      188392   188586     +194     
==========================================
- Hits       160485   160065     -420     
- Misses      27907    28521     +614     

src/sql/src/error.rs Outdated Show resolved Hide resolved
src/sql/src/statements.rs Outdated Show resolved Hide resolved
src/sql/src/statements.rs Show resolved Hide resolved
src/sql/src/statements.rs Show resolved Hide resolved
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Copy link
Contributor

coderabbitai bot commented Jul 8, 2024

Walkthrough

The recent changes enhance error handling and control flow in SQL-related functions, primarily involving unary operators. These improvements introduce specific error types for unary operations, modify function signatures for greater flexibility, and update existing logic to support unary operator handling. The goal is to address partition rule expressions and other scenarios where unary operations are involved.

Changes

File Change Summary
src/sql/src/statements.rs Enhanced sql_value_to_value function for unary operations; added new error types.
src/operator/src/req_convert/…/stmt_to_region.rs Modified sql_value_to_grpc_value call to include None argument.
src/sql/src/error.rs Added new error variants for unary operators and updated error handling.
src/sql/src/parsers/create_parser.rs Added handling of Expr::UnaryOp in ensure_one_expr function.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Function
    participant ErrorHandler
    User->>Function: Call sql_value_to_value with unary_op
    Function->>+Logic: Process value with unary_op
    Logic-)Function: Return result or error
    Function->>+ErrorHandler: Handle InvalidUnaryOp or UnsupportedUnaryOp
    ErrorHandler->>User: Return detailed error message
Loading

Assessment against linked issues

Objective Addressed Explanation
Handle unary operators in SQL error management (#4247)
Ensure sql_value_to_value properly processes unary operation expressions (#4247)
Modify function signature to accommodate additional unary operation parameter (#4247)
Recursive handling of unary operations for expression parsing in create_parser (#4247)

Poem

In code we trust, our logic aligned,
Unary operations no longer confined.
Errors will falter, precise and clear,
With each new function, it’s innovation we steer. 🐰✨
Through SQL pathways, our solutions now shine,
GreptimeDB's strength, a testament in time.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@waynexia waynexia requested a review from killme2008 July 8, 2024 07:43
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between b1219fa and 513082e.

Files selected for processing (21)
  • src/common/decimal/src/decimal128.rs (1 hunks)
  • src/common/time/src/date.rs (1 hunks)
  • src/common/time/src/datetime.rs (1 hunks)
  • src/common/time/src/duration.rs (1 hunks)
  • src/common/time/src/interval.rs (1 hunks)
  • src/common/time/src/time.rs (1 hunks)
  • src/common/time/src/timestamp.rs (1 hunks)
  • src/datatypes/src/value.rs (1 hunks)
  • src/operator/src/lib.rs (1 hunks)
  • src/operator/src/req_convert/insert/stmt_to_region.rs (1 hunks)
  • src/operator/src/statement/ddl.rs (3 hunks)
  • src/servers/src/lib.rs (1 hunks)
  • src/servers/src/mysql/helper.rs (1 hunks)
  • src/sql/src/error.rs (3 hunks)
  • src/sql/src/parsers/create_parser.rs (1 hunks)
  • src/sql/src/statements.rs (12 hunks)
  • tests-integration/tests/sql.rs (1 hunks)
  • tests/cases/standalone/common/insert/insert_default.result (1 hunks)
  • tests/cases/standalone/common/insert/insert_default.sql (1 hunks)
  • tests/cases/standalone/common/partition.result (1 hunks)
  • tests/cases/standalone/common/partition.sql (1 hunks)
Files skipped from review due to trivial changes (3)
  • src/operator/src/lib.rs
  • src/servers/src/lib.rs
  • tests/cases/standalone/common/insert/insert_default.sql
Additional comments not posted (26)
tests/cases/standalone/common/insert/insert_default.result (1)

67-91: LGTM: Added tests for negative default values

The changes introduce tests for default negative values in table creation and insertion. The test cases appear to be correctly verifying the new functionality.

tests/cases/standalone/common/partition.sql (1)

88-110: LGTM: Added tests for partition rules with unary operators

The changes introduce tests for partition rules with unary operators. The test cases appear to be correctly verifying the new functionality.

tests/cases/standalone/common/partition.result (1)

188-224: LGTM: Expected results for partition rules with unary operators

The changes introduce the expected results for partition rules with unary operators. The results appear to be correctly reflecting the new functionality.

src/operator/src/req_convert/insert/stmt_to_region.rs (1)

203-203: LGTM: Modified function to handle unary operators

The changes modify the sql_value_to_grpc_value function to handle unary operators. The implementation appears to be correct.

However, ensure that all function calls to sql_value_to_grpc_value match the new signature.

Verification successful

Let's examine the function call to sql_value_to_grpc_value in src/operator/src/req_convert/insert/stmt_to_region.rs to ensure it aligns with the new signature.


Verified: Function call matches the new signature

The function sql_value_to_grpc_value is correctly called with the new signature that includes the optional timezone parameter.

  • src/operator/src/req_convert/insert/stmt_to_region.rs: Line 123
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `sql_value_to_grpc_value` match the new signature.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type rust $'sql_value_to_grpc_value'

Length of output: 229


Script:

#!/bin/bash
# Description: Display the function call to `sql_value_to_grpc_value` to verify it matches the new signature.

# Extract the relevant lines around the function call for context
rg --type rust --context 5 --line-number 'sql_value_to_grpc_value' src/operator/src/req_convert/insert/stmt_to_region.rs

Length of output: 875

src/common/time/src/date.rs (1)

163-165: LGTM! Verify the function usage in the codebase.

The negative method correctly negates the internal value of the Date struct.

However, ensure that all function calls to negative are correctly handled.

src/sql/src/error.rs (2)

165-171: LGTM!

The InvalidUnaryOp error variant correctly captures the unary operator and value information.


173-178: LGTM!

The UnsupportedUnaryOp error variant correctly captures the unary operator information.

src/common/time/src/datetime.rs (1)

196-198: LGTM! Verify the function usage in the codebase.

The negative method correctly negates the internal value of the DateTime struct.

However, ensure that all function calls to negative are correctly handled.

Verification successful

Verify the negative method usage in DateTime struct.

The negative method in the DateTime struct is used correctly in src/datatypes/src/value.rs. It is part of a match arm that handles various types, including DateTime, to negate their values.

  • src/datatypes/src/value.rs: Value::DateTime(x) => Some(Value::DateTime(x.negative())),
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `negative` for `DateTime` struct.

# Test: Search for the function usage. Expect: Only occurances of the new function.
rg --type rust 'negative()'

Length of output: 4369


Script:

#!/bin/bash
# Description: Verify all function calls to `negative` for `DateTime` struct specifically.

# Test: Search for the `DateTime` struct definition to ensure we're targeting the correct usages.
rg --type rust 'struct DateTime'

# Test: Search for the `negative` method calls specifically related to `DateTime`.
rg --type rust 'DateTime(.+)?\.negative\(\)'

Length of output: 303


Script:

#!/bin/bash
# Description: Inspect the context around the `negative` method call in `src/datatypes/src/value.rs`.

# Test: Display the lines around the `negative` method call to understand its context.
rg --type rust --context 10 'DateTime(.+)?\.negative\(\)' src/datatypes/src/value.rs

Length of output: 1061

src/common/time/src/time.rs (1)

149-152: LGTM! Verify the function usage in the codebase.

The negative method correctly negates the internal value of the Time struct.

However, ensure that all function calls to negative are correctly handled.

Verification successful

Verify the consistency of negative method usage across the codebase.

The negative method is defined in multiple files and used in value.rs. Ensure that each usage corresponds to the appropriate struct and method signature.


Ensure that the negative method signatures match their usages in value.rs.

The negative method signatures vary between mut self and &self. Verify that the structs used in value.rs match the correct method signatures.


Verify the negative method definitions in the relevant files to ensure they match the usages in value.rs.

The value.rs file contains structs like Date, DateTime, Time, Timestamp, Interval, Duration, and Decimal128. Ensure that each struct's negative method matches the usages in value.rs.


The negative method usages in value.rs are consistent with their definitions.

The method signatures match the respective struct definitions, ensuring proper implementation.

  • Decimal128(x.negative()): matches decimal128.rs
  • Date(x.negative()): matches date.rs
  • DateTime(x.negative()): matches datetime.rs
  • Timestamp(x.negative()): matches timestamp.rs
  • Time(x.negative()): matches time.rs
  • Duration(x.negative()): matches duration.rs
  • Interval(x.negative()): matches interval.rs
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `negative` for `Time` struct.

# Test: Search for the function usage. Expect: Only occurances of the new function.
rg --type rust 'negative()'

Length of output: 4369


Script:

#!/bin/bash
# Description: Verify the consistency of `negative` method usage across the codebase.

# Extract the definitions of `negative` from relevant files.
echo "Definitions of 'negative' methods:"
rg --type rust 'pub fn negative'

# Extract the usages of `negative` in `value.rs`.
echo "Usages of 'negative' in value.rs:"
rg --type rust 'negative()' src/datatypes/src/value.rs

Length of output: 1288


Script:

#!/bin/bash
# Description: Verify the struct definitions in value.rs to ensure they match the negative method signatures.

# Extract the struct definitions in value.rs.
echo "Struct definitions in value.rs:"
rg --type rust 'struct' src/datatypes/src/value.rs

Length of output: 1872


Script:

#!/bin/bash
# Description: Verify the `negative` method definitions for relevant structs to ensure they match the usages in value.rs.

# Extract the `negative` method definitions for relevant structs.
echo "Definitions of 'negative' methods for relevant structs:"
rg --type rust 'pub fn negative' src/common/time/src/date.rs \
                                src/common/time/src/datetime.rs \
                                src/common/time/src/time.rs \
                                src/common/time/src/timestamp.rs \
                                src/common/time/src/interval.rs \
                                src/common/time/src/duration.rs \
                                src/common/decimal/src/decimal128.rs

Length of output: 876

src/common/time/src/duration.rs (1)

96-99: Addition of negative method looks good.

The negative method correctly negates the value field of the Duration struct.

src/servers/src/mysql/helper.rs (1)

208-218: Ensure proper handling of unary operators.

The changes to handle unary operators in convert_expr_to_scalar_value look good. The new logic correctly processes unary operators and converts values accordingly.

src/common/decimal/src/decimal128.rs (1)

125-128: Addition of negative method looks good.

The negative method correctly negates the value field of the Decimal128 struct.

src/common/time/src/interval.rs (1)

285-292: Addition of negative method looks good.

The negative method correctly negates the months, days, and nsecs fields of the Interval struct while keeping the unit unchanged.

tests-integration/tests/sql.rs (2)

243-247: LGTM! Consider adding comments for clarity.

The changes correctly handle inserting negative values and validating them. Adding comments can improve readability.

+    // Insert a negative value
    sqlx::query("insert into demo(i) values(?)")
        .bind(-99)
        .execute(&pool)
        .await
        .unwrap();

252-259: LGTM! Consider adding comments for clarity.

The assertion checks for the absolute value of i to be 99, ensuring the correct handling of negative values. Adding comments can improve readability.

+    // Verify the inserted values, checking the absolute value of `i`
    assert_eq!(rows.len(), 2);

    for row in rows {
        let i: i64 = row.get("i");
        let ts: DateTime<Utc> = row.get("ts");
        let now = common_time::util::current_time_millis();
        assert!(now - ts.timestamp_millis() < 1000);
        assert_eq!(i.abs(), 99);
    }
src/sql/src/statements.rs (4)

230-230: The function signature has been updated to include unary_op.

The function signature now includes an optional unary_op parameter to handle unary operators.


262-273: LGTM! Consider adding comments for clarity.

The logic for handling different unary operators is correctly added. Adding comments can improve readability.

+    // Handle unary operators if provided
    if let Some(unary_op) = unary_op {
        match unary_op {
            UnaryOperator::Plus | UnaryOperator::Minus | UnaryOperator::Not => {}
            UnaryOperator::PGBitwiseNot
            | UnaryOperator::PGSquareRoot
            | UnaryOperator::PGCubeRoot
            | UnaryOperator::PGPostfixFactorial
            | UnaryOperator::PGPrefixFactorial
            | UnaryOperator::PGAbs => {
                return UnsupportedUnaryOpSnafu { unary_op }.fail();
            }
        }
    }

276-313: LGTM! Consider adding comments for clarity.

The logic for applying unary operators to different value types is correctly added. Adding comments can improve readability.

+        // Apply unary operator to the value
        match value {
            Value::Null => {}
            Value::Boolean(bool) => match unary_op {
                UnaryOperator::Not => value = Value::Boolean(!bool),
                _ => {
                    return InvalidUnaryOpSnafu { unary_op, value }.fail();
                }
            },
            Value::UInt8(_)
            | Value::UInt16(_)
            | Value::UInt32(_)
            | Value::UInt64(_)
            | Value::Int8(_)
            | Value::Int16(_)
            | Value::Int32(_)
            | Value::Int64(_)
            | Value::Float32(_)
            | Value::Float64(_)
            | Value::Decimal128(_)
            | Value::Date(_)
            | Value::DateTime(_)
            | Value::Timestamp(_)
            | Value::Time(_)
            | Value::Duration(_)
            | Value::Interval(_) => match unary_op {
                UnaryOperator::Plus => {}
                UnaryOperator::Minus => {
                    value = value
                        .try_negative()
                        .with_context(|| InvalidUnaryOpSnafu { unary_op, value })?;
                }
                _ => return InvalidUnaryOpSnafu { unary_op, value }.fail(),
            },

            Value::String(_) | Value::Binary(_) | Value::List(_) => {
                return InvalidUnaryOpSnafu { unary_op, value }.fail()
            }
        }
    }

Line range hint 361-376: LGTM! Consider adding tests for unary operators in default constraints.

The changes correctly handle unary operators in default constraints. Ensure that tests cover these scenarios.

+            ColumnOption::Default(Expr::UnaryOp { op, expr }) => {
+                if let Expr::Value(v) = &**expr {
+                    let value = sql_value_to_value(column_name, data_type, v, timezone, Some(*op))?;
+                    ColumnDefaultConstraint::Value(value)
+                } else {
+                    return UnsupportedDefaultValueSnafu {
+                        column_name,
+                        expr: *expr.clone(),
+                    }
+                    .fail();
+                }
+            }
src/operator/src/statement/ddl.rs (3)

59-59: Import statement for UnaryOperator looks good.

The import is necessary for handling unary operators in expressions.


1338-1344: Handling unary operators in partition expressions looks good.

The function correctly identifies and converts unary operators in partition expressions.


1391-1394: Handling unary operators in value conversion looks good.

The function now accepts an optional unary_op parameter to handle unary operators when converting SQL values to internal values.

src/sql/src/parsers/create_parser.rs (1)

871-873: LGTM! Ensure test coverage for unary operators in partition rules.

The changes correctly add support for unary operators in partition rule expressions.

Ensure that the test cases cover unary operators in partition rules.

src/datatypes/src/value.rs (3)

371-419: Ensure consistent handling of unsigned integer types.

The try_negative method correctly handles unsigned integer types by returning None for non-zero values. This is consistent with the fact that negation is not defined for unsigned types.


403-415: Correct negation handling for numeric types.

The method correctly handles negation for signed integers, floating-point numbers, and other numeric types by returning their negated values.


417-418: Handling non-numeric types.

The method appropriately returns None for non-numeric types like Binary, String, Boolean, and List, where negation is not applicable.

src/common/time/src/timestamp.rs Show resolved Hide resolved
src/servers/src/mysql/helper.rs Show resolved Hide resolved
Copy link
Contributor

@killme2008 killme2008 left a comment

Choose a reason for hiding this comment

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

LGTM

@killme2008 killme2008 enabled auto-merge July 8, 2024 16:32
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 513082e and b73b0ce.

Files selected for processing (1)
  • src/sql/src/statements.rs (13 hunks)
Files skipped from review as they are similar to previous changes (1)
  • src/sql/src/statements.rs

@killme2008
Copy link
Contributor

@waynexia After rebasing, there is a compile error that needs to be fixed.

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between b73b0ce and c87fb3a.

Files selected for processing (4)
  • src/operator/src/req_convert/insert/stmt_to_region.rs (1 hunks)
  • src/sql/src/error.rs (3 hunks)
  • src/sql/src/parsers/create_parser.rs (1 hunks)
  • src/sql/src/statements.rs (12 hunks)
Files skipped from review as they are similar to previous changes (4)
  • src/operator/src/req_convert/insert/stmt_to_region.rs
  • src/sql/src/error.rs
  • src/sql/src/parsers/create_parser.rs
  • src/sql/src/statements.rs

Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between c87fb3a and 6779ea2.

Files selected for processing (1)
  • src/sql/src/statements.rs (12 hunks)
Files skipped from review as they are similar to previous changes (1)
  • src/sql/src/statements.rs

@killme2008 killme2008 added this pull request to the merge queue Jul 9, 2024
Merged via the queue into GreptimeTeam:main with commit 185953e Jul 9, 2024
55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs-not-required This change does not impact docs.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Partition rule expr UnaryOp is not a binary expression
3 participants