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

delete with multi columns IN Predicate #1001

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

aman-db
Copy link
Contributor

@aman-db aman-db commented Oct 14, 2024

closes #953
Grammar changes required to handle queries like

DELETE FROM test_tbl
WHERE (version, type) IN (
    SELECT DISTINCT version, type
     FROM test_tbl_stg
);

Implemented a new visitor method - visitPredExprListIn
Added code to change the Optimized Plan for Delete with Exists

Copy link

github-actions bot commented Oct 14, 2024

Coverage tests results

454 tests  +6   419 ✅ +5   4s ⏱️ ±0s
  6 suites ±0    35 💤 +1 
  6 files   ±0     0 ❌ ±0 

Results for commit 2e50a96. ± Comparison against base commit 50771bf.

♻️ This comment has been updated with latest results.

@aman-db aman-db force-pushed the feature/multi_column_delete_to_exist branch from cc8fe09 to 057e3f9 Compare October 15, 2024 12:17
@aman-db aman-db changed the title initial commit for delete with multi columns delete with multi columns IN Predicate Oct 16, 2024
Copy link
Contributor

@jimidle jimidle left a comment

Choose a reason for hiding this comment

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

It is on the right track, assuming we wish to change ir.IN() like this. If we are chaing that, then make sure that TSQL changes if it needs to.

@@ -3557,7 +3557,7 @@ predicate
| expression comparisonOperator expression # predBinop
| expression comparisonOperator (ALL | SOME | ANY) L_PAREN subquery R_PAREN # predASA
| expression IS NOT? NULL # predIsNull
| expression NOT? IN L_PAREN (subquery | exprList) R_PAREN # predIn
| (L_PAREN exprList R_PAREN | expression) NOT? IN L_PAREN (subquery | exprList) R_PAREN # predIn
Copy link
Contributor

Choose a reason for hiding this comment

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

| expression NOT? IN L_PAREN (subquery | exprList) R_PAREN                     # predIn
| L_PAREN exprList R_PAREN  NOT? IN L_PAREN (subquery | exprList) R_PAREN      # predExprListIn

keep these separate with a separate visitor then there is no need to do complex logic to see whether there is an exprList or an expression. visitpredExprListIn will autmatically know that it is two expression lists.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

}
left.size match {
case 1 =>
val in = ir.In(left.head, right) // If there's only one expression on the left side
Copy link
Contributor

@jimidle jimidle Oct 16, 2024

Choose a reason for hiding this comment

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

Revert to the existing code for visitPredIn and implement visitPredExprListIn if there is overlap then share the overlap with a buildXXX def to handle the common features so that the visitors are actually quite simple

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

print(s"subquery: $subquery")
val newSubquery = transformSubquery(target, subquery)
delete.copy(where = Some(Exists(newSubquery)))
// delete.copy(where = newSubquery)
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove commented out code.

Copy link
Contributor

Choose a reason for hiding this comment

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

This commented out code is still there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Comment on lines 627 to 769
override def visitPredExprListIn(ctx: PredExprListInContext): ir.Expression = {
// left side of In can be a list of expressions
val leftExprList = ctx.exprList(0).expr().asScala.map(_.accept(this))
Copy link
Contributor

Choose a reason for hiding this comment

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

// LHS is a list of expressions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@aman-db aman-db force-pushed the feature/multi_column_delete_to_exist branch from c94d95c to c518114 Compare October 25, 2024 19:42
Copy link
Contributor

@jimidle jimidle left a comment

Choose a reason for hiding this comment

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

We need to reinstate the errorCheck(ctx) match { staements

@@ -3558,6 +3558,7 @@ predicate
| expression comparisonOperator (ALL | SOME | ANY) L_PAREN subquery R_PAREN # predASA
| expression IS NOT? NULL # predIsNull
| expression NOT? IN L_PAREN (subquery | exprList) R_PAREN # predIn
| L_PAREN exprList R_PAREN NOT? IN L_PAREN (subquery | exprList) R_PAREN # predExprListIn
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like the ANTLR formatter has been disabled. Extra space crept in there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Comment on lines 756 to 750
override def visitPredIn(ctx: PredInContext): ir.Expression = errorCheck(ctx) match {
case Some(errorResult) => errorResult
case None =>
val in = if (ctx.subquery() != null) {
// In the result of a sub query
ir.In(ctx.expression().accept(this), Seq(ir.ScalarSubquery(ctx.subquery().accept(vc.relationBuilder))))
} else {
// In a list of expressions
ir.In(ctx.expression().accept(this), ctx.exprList().expr().asScala.map(_.accept(this)))
Copy link
Contributor

Choose a reason for hiding this comment

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

You have deleted the error checking match. That needs to go back in so that errorNodes are generated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Comment on lines 767 to 770
override def visitPredExprListIn(ctx: PredExprListInContext): ir.Expression = {
// left side of In is a list of expressions
val leftExprList = ctx.exprList(0).expr().asScala.map(_.accept(this))

Copy link
Contributor

Choose a reason for hiding this comment

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

Error handling needs to go back in

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

-- snowflake sql:
DELETE FROM test_tbl
WHERE (version, type) NOT IN (
SELECT version1 , type2
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add more test case to check the behaviour., when select column names are expressions.

@aman-db aman-db marked this pull request as ready for review November 5, 2024 11:06
@@ -34,7 +34,9 @@ class SnowflakeAcceptanceSuite
"test_command/test_command_3.sql",
"test_skip_unsupported_operations/test_skip_unsupported_operations_7.sql",
"test_skip_unsupported_operations/test_skip_unsupported_operations_9.sql",
"test_skip_unsupported_operations/test_skip_unsupported_operations_10.sql"),
"test_skip_unsupported_operations/test_skip_unsupported_operations_10.sql",
"core_engine/delete/test_delete_with_not_in.sql",
Copy link
Contributor

Choose a reason for hiding this comment

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

why are these added in ignored 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.

done

@aman-db aman-db marked this pull request as draft November 6, 2024 09:54
@aman-db aman-db marked this pull request as ready for review November 6, 2024 11:03
@aman-db aman-db marked this pull request as draft November 11, 2024 14:59
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.

[FEATURE]: Multi column in predicate delete statements to be converted to exist statements
3 participants