-
Notifications
You must be signed in to change notification settings - Fork 2.3k
vtgate: subquery support #3923
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
Merged
Merged
vtgate: subquery support #3923
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -730,6 +730,178 @@ | |
| } | ||
| } | ||
|
|
||
| # cross-shard subquery in IN clause. | ||
| # Note the improved Underlying plan as SelectIN. | ||
| "select id from user where id in (select col from user)" | ||
| { | ||
| "Original": "select id from user where id in (select col from user)", | ||
| "Instructions": { | ||
| "Opcode": "PulloutIn", | ||
| "SubqueryResult": "__sq1", | ||
| "HasValues": "__sq_has_values1", | ||
| "Subquery": { | ||
| "Opcode": "SelectScatter", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select col from user", | ||
| "FieldQuery": "select col from user where 1 != 1" | ||
| }, | ||
| "Underlying": { | ||
| "Opcode": "SelectIN", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select id from user where :__sq_has_values1 = 1 and (id in ::__vals)", | ||
| "FieldQuery": "select id from user where 1 != 1", | ||
| "Vindex": "user_index", | ||
| "Values": [ | ||
| "::__sq1" | ||
| ] | ||
| } | ||
| } | ||
| } | ||
|
|
||
| # cross-shard subquery in NOT IN clause. | ||
| "select id from user where id not in (select col from user)" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also think it would be incredibly useful for cases like this to include vtexplain test cases for each of these as well to be able to more easily see as a reviewer (and someone getting to know Vitess) which exact queries end up running for these various patterns. |
||
| { | ||
| "Original": "select id from user where id not in (select col from user)", | ||
| "Instructions": { | ||
| "Opcode": "PulloutNotIn", | ||
| "SubqueryResult": "__sq1", | ||
| "HasValues": "__sq_has_values1", | ||
| "Subquery": { | ||
| "Opcode": "SelectScatter", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select col from user", | ||
| "FieldQuery": "select col from user where 1 != 1" | ||
| }, | ||
| "Underlying": { | ||
| "Opcode": "SelectScatter", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select id from user where (:__sq_has_values1 = 0 or (id not in ::__sq1))", | ||
| "FieldQuery": "select id from user where 1 != 1" | ||
| } | ||
| } | ||
| } | ||
|
|
||
| # cross-shard subquery in EXISTS clause. | ||
| "select id from user where exists (select col from user)" | ||
| { | ||
| "Original": "select id from user where exists (select col from user)", | ||
| "Instructions": { | ||
| "Opcode": "PulloutExists", | ||
| "SubqueryResult": "__sq1", | ||
| "HasValues": "__sq_has_values1", | ||
| "Subquery": { | ||
| "Opcode": "SelectScatter", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select col from user", | ||
| "FieldQuery": "select col from user where 1 != 1" | ||
| }, | ||
| "Underlying": { | ||
| "Opcode": "SelectScatter", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select id from user where :__sq_has_values1", | ||
| "FieldQuery": "select id from user where 1 != 1" | ||
| } | ||
| } | ||
| } | ||
|
|
||
| # cross-shard subquery as expression | ||
| "select id from user where id = (select col from user)" | ||
| { | ||
| "Original": "select id from user where id = (select col from user)", | ||
| "Instructions": { | ||
| "Opcode": "PulloutValue", | ||
| "SubqueryResult": "__sq1", | ||
| "HasValues": "__sq_has_values1", | ||
| "Subquery": { | ||
| "Opcode": "SelectScatter", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select col from user", | ||
| "FieldQuery": "select col from user where 1 != 1" | ||
| }, | ||
| "Underlying": { | ||
| "Opcode": "SelectEqualUnique", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select id from user where id = :__sq1", | ||
| "FieldQuery": "select id from user where 1 != 1", | ||
| "Vindex": "user_index", | ||
| "Values": [ | ||
| ":__sq1" | ||
| ] | ||
| } | ||
| } | ||
| } | ||
|
|
||
| # multi-level pullout | ||
| "select id1 from user where id = (select id2 from user where id2 in (select id3 from user))" | ||
| { | ||
| "Original": "select id1 from user where id = (select id2 from user where id2 in (select id3 from user))", | ||
| "Instructions": { | ||
| "Opcode": "PulloutValue", | ||
| "SubqueryResult": "__sq2", | ||
| "HasValues": "__sq_has_values2", | ||
| "Subquery": { | ||
| "Opcode": "PulloutIn", | ||
| "SubqueryResult": "__sq1", | ||
| "HasValues": "__sq_has_values1", | ||
| "Subquery": { | ||
| "Opcode": "SelectScatter", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select id3 from user", | ||
| "FieldQuery": "select id3 from user where 1 != 1" | ||
| }, | ||
| "Underlying": { | ||
| "Opcode": "SelectScatter", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select id2 from user where :__sq_has_values1 = 1 and (id2 in ::__sq1)", | ||
| "FieldQuery": "select id2 from user where 1 != 1" | ||
| } | ||
| }, | ||
| "Underlying": { | ||
| "Opcode": "SelectEqualUnique", | ||
| "Keyspace": { | ||
| "Name": "user", | ||
| "Sharded": true | ||
| }, | ||
| "Query": "select id1 from user where id = :__sq2", | ||
| "FieldQuery": "select id1 from user where 1 != 1", | ||
| "Vindex": "user_index", | ||
| "Values": [ | ||
| ":__sq2" | ||
| ] | ||
| } | ||
| } | ||
| } | ||
|
|
||
| # Case preservation test | ||
| "select user_extra.Id from user join user_extra on user.iD = user_extra.User_Id where user.Id = 5" | ||
| { | ||
|
|
@@ -766,4 +938,4 @@ | |
| # but they refer to different things. The first reference is to the outermost query, | ||
| # and the second reference is to the the innermost 'from' subquery. | ||
| "select id2 from user uu where id in (select id from user where id = uu.id and user.col in (select col from (select id from user_extra where user_id = 5) uu where uu.user_id = uu.id))" | ||
| "unsupported: UNION or subquery on different shards: vindex values are different" | ||
| "unsupported: cross-shard correlated subquery" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing that occurred to me in reading this -- can we push down a subquery to a single shard if specified in the query?
Specifically suppose two tables are both sharded by a
company_idcolumn and we ran a query like:In this case the query can be pushed down to whichever shard has both the user and user_admin.
Does the current implementation handle this efficiently?