-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Range queries in from clause #3771
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
Range queries in from clause #3771
Conversation
* Some general refactor of plan builders (move them to have their own files). * Refactor parse destination code and put it in key package. * Add general support for range queries in delete statements. Signed-off-by: Rafael Chacon <rafael@slack-corp.com>
Signed-off-by: Rafael Chacon <rafael@slack-corp.com>
Signed-off-by: Rafael Chacon <rafael@slack-corp.com>
f5769f2 to
775a2d8
Compare
go/vt/vtgate/executor.go
Outdated
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.
@sougou - this looks like the right thing here, but wanted to double check with you.
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.
This is ok for now. Ideally, we want shard targeting to be honored here also. But can be changed later.
Signed-off-by: Rafael Chacon <rafael@slack-corp.com> Delete
775a2d8 to
7ef8184
Compare
go/vt/vtgate/planbuilder/delete.go
Outdated
| return nil, err | ||
| } | ||
| edel.Table = table | ||
| if destTarget.Destination != nil { |
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.
This the only real change here.
sougou
left a comment
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.
This is my initial pass.
Got some comments.
I think I like this approach. Need to let it sink in.
go/vt/key/key.go
Outdated
| return buf | ||
| } | ||
|
|
||
| type DestinationTarget struct { |
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.
This name is confusing. How about QualifiedDestination?
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.
I'm actually wondering if we even need this type. Could we get away with always using the relevant individual fields, without the structure? One reason I'm saying that is for instance the TabletType is not useful in delete.go below, as a delete would always be on the master.
The parse method can look like:
parse(toParse string, defaultType tabletType) (keyspace string, tabletType, Destination, error)
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.
@alainjobart - I originally went down this approach but thought it was too verbose when we actually need the all the values:
keyspace, tabletType, dest, err := key.ParseDestination(targetString, defaultTabletType)
I leaned towards the struct because it was more concise.
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.
Another reason for this is we pass keysapce/tablettype + single Destination, or keyspace/tablettype + []Destination in a few methods. Like in srvtoporesolver.go:
func (r *Resolver) ResolveDestinations(ctx context.Context, keyspace string, tabletType topodatapb.TabletType, ids []*querypb.Value, destinations []key.Destination) ([]*ResolvedShard, [][]*querypb.Value, error) {
I agree it's more concise with the structure, but then we'd need another one with []Destination too, and it's starting to bloat the code...
(note I'm not opposed to thi that much, it just feels overkill)
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.
I think it's better to not have the type (for now). If the combination of vars gains widespread usage, we should look at making it a core type used everywhere.
Not having the type also avoids the argument about what to name it :).
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.
These are good points!
I updated the code to not have this data structure.
go/vt/vtgate/executor.go
Outdated
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.
This is ok for now. Ideally, we want shard targeting to be honored here also. But can be changed later.
| "vitess.io/vitess/go/sqltypes" | ||
| "vitess.io/vitess/go/vt/sqlparser" | ||
| "vitess.io/vitess/go/vt/vterrors" | ||
| "vitess.io/vitess/go/vt/vtgate/engine" |
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.
This file should be deleted, and its functions moved elsewhere right?
go/vt/vtgate/planbuilder/builder.go
Outdated
| type VSchema interface { | ||
| FindTable(tablename sqlparser.TableName) (*vindexes.Table, error) | ||
| FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, error) | ||
| FindTable(tablename sqlparser.TableName) (*vindexes.Table, key.DestinationTarget, error) |
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.
Let's rename this to VCursor, because the FindTable function signature doesn't match the one in VSchema any more.
go/vt/key/key.go
Outdated
| return buf | ||
| } | ||
|
|
||
| type DestinationTarget struct { |
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.
I'm actually wondering if we even need this type. Could we get away with always using the relevant individual fields, without the structure? One reason I'm saying that is for instance the TabletType is not useful in delete.go below, as a delete would always be on the master.
The parse method can look like:
parse(toParse string, defaultType tabletType) (keyspace string, tabletType, Destination, error)
go/vt/vtgate/executor.go
Outdated
| func (e *Executor) destinationExec(ctx context.Context, safeSession *SafeSession, sql string, bindVars map[string]*querypb.BindVariable, target querypb.Target, destination key.Destination, logStats *LogStats) (*sqltypes.Result, error) { | ||
| return e.resolver.Execute(ctx, sql, bindVars, target.Keyspace, target.TabletType, destination, safeSession.Session, false /* notInTransaction */, safeSession.Options, logStats) | ||
| func (e *Executor) destinationExec(ctx context.Context, safeSession *SafeSession, sql string, bindVars map[string]*querypb.BindVariable, destTarget key.DestinationTarget, logStats *LogStats) (*sqltypes.Result, error) { | ||
| return e.resolver.Execute(ctx, sql, bindVars, destTarget.Keyspace, destTarget.TabletType, destTarget.Destination, safeSession.Session, false /* notInTransaction */, safeSession.Options, logStats) |
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.
I feel that the previous one was wrong, it is:
target querypb.Target, destination key.Destination
should have been:
keyspace string, targetType, destination
See my previous comment, we don't really need a structure for this, do we?
go/vt/key/key.go
Outdated
| return buf | ||
| } | ||
|
|
||
| type DestinationTarget struct { |
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.
I think it's better to not have the type (for now). If the combination of vars gains widespread usage, we should look at making it a core type used everywhere.
Not having the type also avoids the argument about what to name it :).
go/vt/key/key.go
Outdated
|
|
||
| // ParseDestination parses the string representation of a Destionation | ||
| // of the form keyspace:shard@tablet_type. You can use a / instead of a :. | ||
| func ParseDestination(targetString string, defaultTabletType topodatapb.TabletType) (DestinationTarget, error) { |
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.
I feel like this function belongs inside executor's parseDestinationTarget, and we should have vcursor call that instead. It will keep this file simple. Open to counter-arguments.
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.
@sougou - I think this is in the only comment I haven't addressed. I will think a bit more about it.
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.
I thought about this. I think it makes sense. I wanted to keep the one here as a more generic version, but now I'm thinking that the slight difference in implementation could bite us in the future.
What do you think if I move this method to the executor and make it private. The reason for this is that I would like to have something hook into it easily in the context of the tests in plan_test.go that does not require a real executor.
Then in vcursor use ParseDestinationTarget.
Thoughts?
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.
Sounds good.
Signed-off-by: Rafael Chacon <rafael@slack-corp.com>
* Refactor key.topo to not have an extra data structure. This could be added in the future if we need it. For now keep it simple and avoid the overhead of adding it. Signed-off-by: Rafael Chacon <rafael@slack-corp.com>
ae1c1eb to
c29eb8e
Compare
Signed-off-by: Rafael Chacon <rafael@slack-corp.com>
e60cb70 to
416e2e7
Compare
Signed-off-by: Rafael Chacon <rafael@slack-corp.com>
alainjobart
left a comment
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.
Looks good now, mostly cosmetic comments :)
go/vt/key/key.go
Outdated
| func parseTabletType(param string) topodatapb.TabletType { | ||
| value, ok := topodatapb.TabletType_value[strings.ToUpper(param)] | ||
| if !ok { | ||
| return topodatapb.TabletType_UNKNOWN |
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.
I think this method should return an error:
func parseTabletType(param string) (topodatapb.TabletType, error) {
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.
After I moved ParseDestination out of key.go, I don't longer need this method and I'm using topoproto.ParseTabletType
go/vt/key/key_test.go
Outdated
| targetString string | ||
| dest Destination | ||
| keyspace string | ||
| tabletType topodatapb.TabletType |
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.
adding 'errorString string' and testing for error cases might be good here too.
go/vt/vtgate/engine/delete.go
Outdated
| // Keyspace specifies the keyspace to send the query to. | ||
| Keyspace *vindexes.Keyspace | ||
|
|
||
| // Keyspace specifies the keyspace to send the query to. |
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.
Update comment.
go/vt/vtgate/executor.go
Outdated
| } | ||
|
|
||
| if keyRange != nil || target.Shard != "" { | ||
| func (e *Executor) handleExec(ctx context.Context, safeSession *SafeSession, sql string, bindVars map[string]*querypb.BindVariable, dest key.Destination, destKeyspace string, destTabletType topodatapb.TabletType, logStats *LogStats) (*sqltypes.Result, error) { |
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.
Th usual ordering of the parameters is keyspace, tablet type, and then destination.
go/vt/vtgate/planbuilder/builder.go
Outdated
| FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, error) | ||
| type ContextVSchema interface { | ||
| FindTable(tablename sqlparser.TableName) (*vindexes.Table, key.Destination, string, topodatapb.TabletType, error) | ||
| FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, key.Destination, string, topodatapb.TabletType, error) |
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.
same for these two here, keyspace, tablettype,destination is the usual order.
3121589 to
2010712
Compare
|
@sougou , @alainjobart I think all comments have been addressed! This should be ready. |
* Make sure vcursor implementation uses same ParseDestination logic as executor. * Address other PR comments and refactor methods to better respect conventions within Vitess codebase. Signed-off-by: Rafael Chacon <rafael@slack-corp.com>
2010712 to
6445dd8
Compare
Description
Summary of changes
DELETEstatements.engine.goto make destination a first class citizen, instead of a shard target. I think this simplifies the code even more and expands on using destination and the refactor that started in: Enhanced shard targeting part I #3692.DeleteShardedtoDeleteScatter, that's more consistent with existent opcodes.dml.goplanbuilder intoinsert.goanddelete.go. Also, to be more consistent with all the other primitives.