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

Add Oracle SQL - Update statement #11692

Merged
merged 9 commits into from Aug 22, 2021

Conversation

ThanoshanMV
Copy link
Member

#10111

Hi @wgy8283335, I've added SQL definition for Oracle UPDATE statement. Please check it.

Changes proposed in this pull request:

  • Add Oracle DELETE statement.
  • Add test cases.
  • I commented SQL case id update_with_special_comments as it's not aligned with Oracle SQL's returningCluase:

ParsingFailsForReturningClause

  • As Oracle allows us to set a value to a list of columns, I tried to get the list of column values in the AssignmentSegment:

UpdateSetClause

@codecov-commenter
Copy link

codecov-commenter commented Aug 7, 2021

Codecov Report

Merging #11692 (7fba441) into master (0ccdc93) will increase coverage by 0.03%.
The diff coverage is 50.38%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master   #11692      +/-   ##
============================================
+ Coverage     63.11%   63.15%   +0.03%     
  Complexity     1225     1225              
============================================
  Files          2328     2329       +1     
  Lines         35177    35263      +86     
  Branches       6130     6141      +11     
============================================
+ Hits          22203    22271      +68     
- Misses        11181    11196      +15     
- Partials       1793     1796       +3     
Impacted Files Coverage Δ
...meter/impl/EncryptAssignmentParameterRewriter.java 0.00% <0.00%> (ø)
...enerator/impl/EncryptAssignmentTokenGenerator.java 0.00% <0.00%> (ø)
...ator/impl/EncryptInsertOnUpdateTokenGenerator.java 0.00% <0.00%> (ø)
...ql/parser/sql/common/extractor/TableExtractor.java 5.40% <0.00%> (ø)
...mmon/segment/dml/assignment/AssignmentSegment.java 0.00% <0.00%> (ø)
...d/asserts/segment/assignment/AssignmentAssert.java 0.00% <0.00%> (ø)
...erts/segment/assignment/AssignmentValueAssert.java 0.00% <0.00%> (ø)
...in/segment/impl/assignment/ExpectedAssignment.java 100.00% <ø> (ø)
...gment/impl/assignment/ExpectedAssignmentValue.java 100.00% <ø> (ø)
...meter/impl/ShadowUpdateValueParameterRewriter.java 33.33% <50.00%> (ø)
... and 15 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0ccdc93...7fba441. Read the comment docs.

@tristaZero tristaZero added this to the 5.0.0-RC1 milestone Aug 7, 2021
@tristaZero
Copy link
Contributor

Hi @ThanoshanMV ,

Looks our final evaluation is on the way. Let us make it all the way through and win! ;-) @ThanoshanMV @wgy8283335

@@ -36,5 +39,7 @@

private final ColumnSegment column;

private List<ColumnSegment> columns = new LinkedList<>();
Copy link
Contributor

@wgy8283335 wgy8283335 Aug 9, 2021

Choose a reason for hiding this comment

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

What about combining the column and columns?
And change the value to list.

@RequiredArgsConstructor
@Getter
public final class AssignmentSegment implements SQLSegment {
    
    private final int startIndex;
    
    private final int stopIndex;
    
    private final List<ColumnSegment> columns;
    
    private final List<ExpressionSegment> values;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

What about combining the column and columns?

We can combine columns as a list but since the AssignmentSegment is used across the ShardingSphere project, we need to make changes in all AssignmentSegment occurrences. For example in EncryptAssignmentParameterRewriter:

AssignmentSegmentUseCases

What shall we do?

Copy link
Member Author

Choose a reason for hiding this comment

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

And change the value to list

I think we don't have to create a list for value, as an assignment can have only one value:

UpdateSetClauseHasOnlyOneAssignmentValue

Please let me know what do you think.

Copy link
Contributor

Choose a reason for hiding this comment

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

Below is not reasonable:

@RequiredArgsConstructor
@Getter
public final class AssignmentSegment implements SQLSegment {
    
    private final int startIndex;
    
    private final int stopIndex;
    
    private final ColumnSegment column;

    private List<ColumnSegment> columns = new LinkedList<>();
    
    private final ExpressionSegment value;
}

But what shall we do in this situation? @jingshanglu @tristaZero

UPDATE employees a SET department_id = (SELECT department_id FROM departments WHERE location_id = '2100'), (salary, commission_pct) = (SELECT 1.1*AVG(salary), 1.5*AVG(commission_pct) FROM employees b WHERE a.department_id = b.department_id);

Copy link
Contributor

Choose a reason for hiding this comment

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

@wgy8283335 @ThanoshanMV Maybe we can extract abstract class and combine these two idea.

public abstract class AssignmentSegment implements SQLSegment {
    
   List<ColumnSegment> getColumns();
   ExpressionSegment getValue();
}

@RequiredArgsConstructor
@Getter
public final class OracleAssignmentSegment extends AssignmentSegment {
    
   private final int startIndex;
    
    private final int stopIndex;

    private List<ColumnSegment> columns = new LinkedList<>();
    
    private final ExpressionSegment value;
}
SET department_id = (SELECT department_id FROM departments WHERE location_id = '2100')
expressed as
OracleAssignmentSegment{columns=[department_id],value=subquery}

(salary, commission_pct) = (SELECT 1.1*AVG(salary), 1.5*AVG(commission_pct) FROM employees b WHERE a.department_id = b.department_id)
expressed as 
OracleAssignmentSegment{columns=[salary, commission_pct],value=subquery}

Maybe it has better decoupling and scalability, but we need to make changes in all AssignmentSegment occurrences.

Copy link
Member Author

Choose a reason for hiding this comment

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

@jingshanglu do you mean like this:

AssignmentSegment:

AssignmentSegment

OracleAssignmentSegment:

OracleAssignmentSegment

Copy link
Member Author

Choose a reason for hiding this comment

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

Shall we create similar child classes for other SQL dialects, for example, PostgreSQLAssignmentSegment or shall we rename OracleAssignmentSegment to a generic one?

Currently, whenever we need to create an instance of AssignmentSegment, we have to utilize OracleAssignmentSegment. In the below image, the method visitSetClause is in PostgreSQLStatementSQLVisitor which returns an instance of AssignmentSegment:

PostgreSQLIssue

Copy link
Contributor

Choose a reason for hiding this comment

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

Shall we create similar child classes for other SQL dialects, for example, PostgreSQLAssignmentSegment or shall we rename OracleAssignmentSegment to a generic one?

Currently, whenever we need to create an instance of AssignmentSegment, we have to utilize OracleAssignmentSegment. In the below image, the method visitSetClause is in PostgreSQLStatementSQLVisitor which returns an instance of AssignmentSegment:

PostgreSQLIssue

@ThanoshanMV Yes, maybe it is better to rename OracleAssignmentSegment to a genneric one, define new subclasses when we need to expand.


private final int stopIndex;

private List<ColumnSegment> columns = new LinkedList<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it need to be initialized with LinkedList, as ColumnAssignmentSegment has @RequiredArgsConstructor?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll change as private final List<ColumnSegment> columns, remove the initialization and make other changes accordingly.

@wgy8283335
Copy link
Contributor

There are many changes in this pr, and it's better to make all of the ci checks pass.

@tristaZero
Copy link
Contributor

Hi @wgy8283335 Thanks for your tips, all the CI tests passed, do you think this one is ready to merge?

@wgy8283335
Copy link
Contributor

@ThanoshanMV, have you finished your modification?

@ThanoshanMV
Copy link
Member Author

@ThanoshanMV, have you finished your modification?

Yes @wgy8283335. I changed as private final List<ColumnSegment> columns and removed commented SQL case id update_with_special_comments as it's not aligned with Oracle SQL's returningCluase.

@tristaZero tristaZero merged commit 3c51144 into apache:master Aug 22, 2021
@menghaoranss menghaoranss modified the milestones: 5.0.0-RC1, 5.0.0 Oct 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants