diff --git a/data/test/vtgate/dml_cases.txt b/data/test/vtgate/dml_cases.txt index fb00bb7497..2b929b7150 100644 --- a/data/test/vtgate/dml_cases.txt +++ b/data/test/vtgate/dml_cases.txt @@ -6,6 +6,21 @@ "delete from nouser" "table nouser not found" +# explicit keyspace reference +"update main.m1 set val = 1" +{ + "Original": "update main.m1 set val = 1", + "Instructions": { + "Opcode": "UpdateUnsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "Query": "update m1 set val = 1", + "Table": "m1" + } +} + # update unsharded "update main1 set val = 1" { diff --git a/data/test/vtgate/from_cases.txt b/data/test/vtgate/from_cases.txt index d374902cae..8a56108221 100644 --- a/data/test/vtgate/from_cases.txt +++ b/data/test/vtgate/from_cases.txt @@ -790,6 +790,25 @@ } } +# implicit table reference for unsharded keyspace +"select main.foo.col from main.foo" +{ + "Original": "select main.foo.col from main.foo", + "Instructions": { + "Opcode": "SelectUnsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "Query": "select foo.col from foo", + "FieldQuery": "select foo.col from foo where 1 != 1" + } +} + +# implicit table reference for sharded keyspace +"select user.foo.col from user.foo" +"table foo not found" + # duplicate symbols "select user.id from user join user" "duplicate symbol: user" diff --git a/data/test/vtgate/schema_test.json b/data/test/vtgate/schema_test.json index 335b502b23..65d2c7c8e4 100644 --- a/data/test/vtgate/schema_test.json +++ b/data/test/vtgate/schema_test.json @@ -20,7 +20,7 @@ "Owner": "user" } }, - "Classes": { + "Tables": { "user": { "ColVindexes": [ { @@ -77,23 +77,14 @@ } ] } - }, - "Tables": { - "user": "user", - "user_extra": "user_extra", - "music": "music", - "music_extra": "music_extra" } }, "main": { - "Classes": { + "Tables": { + "main1": {}, "seq": { "Type": "Sequence" } - }, - "Tables": { - "main1": "", - "seq": "seq" } } } diff --git a/data/test/vtgate/unsupported_cases.txt b/data/test/vtgate/unsupported_cases.txt index dfe7ef691d..53e1de7893 100644 --- a/data/test/vtgate/unsupported_cases.txt +++ b/data/test/vtgate/unsupported_cases.txt @@ -146,10 +146,6 @@ "delete from user where col = (select id from main1)" "unsupported: subqueries in DML" -# qualified table name in DMLs -"update u.user set id = 1" -"unsupported: compex table expression in DML" - # update with no where clause "update user set val = 1" "unsupported: multi-shard where clause in DML" diff --git a/examples/demo/schema/vschema.json b/examples/demo/schema/vschema.json index 06fecbb964..57664187c9 100644 --- a/examples/demo/schema/vschema.json +++ b/examples/demo/schema/vschema.json @@ -28,7 +28,7 @@ "Type": "numeric" } }, - "Classes": { + "Tables": { "user": { "ColVindexes": [ { @@ -89,26 +89,18 @@ } ] } - }, - "Tables": { - "user": "user", - "user_extra": "user_extra", - "music": "music", - "music_extra": "music_extra", - "music_user_idx": "music_user_idx" } }, "lookup": { "Sharded": false, - "Classes": { - "seq": { - "Type": "Sequence" - } - }, "Tables": { - "user_seq": "seq", - "music_seq": "seq", - "name_user_idx": "" + "user_seq": { + "Type": "Sequence" + }, + "music_seq": { + "Type": "Sequence" + }, + "name_user_idx": {} } } } diff --git a/go/cmd/vtgateclienttest/services/callerid.go b/go/cmd/vtgateclienttest/services/callerid.go index 3788d9beed..a52ff84338 100644 --- a/go/cmd/vtgateclienttest/services/callerid.go +++ b/go/cmd/vtgateclienttest/services/callerid.go @@ -65,11 +65,11 @@ func (c *callerIDClient) checkCallerID(ctx context.Context, received string) (bo return true, fmt.Errorf("SUCCESS: callerid matches") } -func (c *callerIDClient) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { +func (c *callerIDClient) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { if ok, err := c.checkCallerID(ctx, sql); ok { return nil, err } - return c.fallbackClient.Execute(ctx, sql, bindVariables, tabletType, session, notInTransaction) + return c.fallbackClient.Execute(ctx, sql, bindVariables, keyspace, tabletType, session, notInTransaction) } func (c *callerIDClient) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { @@ -118,11 +118,11 @@ func (c *callerIDClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries [] return c.fallbackClient.ExecuteBatchKeyspaceIds(ctx, queries, tabletType, asTransaction, session) } -func (c *callerIDClient) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { +func (c *callerIDClient) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { if ok, err := c.checkCallerID(ctx, sql); ok { return err } - return c.fallbackClient.StreamExecute(ctx, sql, bindVariables, tabletType, sendReply) + return c.fallbackClient.StreamExecute(ctx, sql, bindVariables, keyspace, tabletType, sendReply) } func (c *callerIDClient) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { diff --git a/go/cmd/vtgateclienttest/services/echo.go b/go/cmd/vtgateclienttest/services/echo.go index 175cfdc390..24c88bf630 100644 --- a/go/cmd/vtgateclienttest/services/echo.go +++ b/go/cmd/vtgateclienttest/services/echo.go @@ -86,18 +86,19 @@ func echoQueryResult(vals map[string]interface{}) *sqltypes.Result { return qr } -func (c *echoClient) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { +func (c *echoClient) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { if strings.HasPrefix(sql, EchoPrefix) { return echoQueryResult(map[string]interface{}{ "callerId": callerid.EffectiveCallerIDFromContext(ctx), "query": sql, "bindVars": bindVariables, + "keyspace": keyspace, "tabletType": tabletType, "session": session, "notInTransaction": notInTransaction, }), nil } - return c.fallbackClient.Execute(ctx, sql, bindVariables, tabletType, session, notInTransaction) + return c.fallbackClient.Execute(ctx, sql, bindVariables, keyspace, tabletType, session, notInTransaction) } func (c *echoClient) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { @@ -205,17 +206,18 @@ func (c *echoClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries []*vtg return c.fallbackClient.ExecuteBatchKeyspaceIds(ctx, queries, tabletType, asTransaction, session) } -func (c *echoClient) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { +func (c *echoClient) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { if strings.HasPrefix(sql, EchoPrefix) { sendReply(echoQueryResult(map[string]interface{}{ "callerId": callerid.EffectiveCallerIDFromContext(ctx), "query": sql, "bindVars": bindVariables, + "keyspace": keyspace, "tabletType": tabletType, })) return nil } - return c.fallbackClient.StreamExecute(ctx, sql, bindVariables, tabletType, sendReply) + return c.fallbackClient.StreamExecute(ctx, sql, bindVariables, keyspace, tabletType, sendReply) } func (c *echoClient) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { diff --git a/go/cmd/vtgateclienttest/services/errors.go b/go/cmd/vtgateclienttest/services/errors.go index 17342aad40..7fd7e8f5cf 100644 --- a/go/cmd/vtgateclienttest/services/errors.go +++ b/go/cmd/vtgateclienttest/services/errors.go @@ -118,14 +118,14 @@ func trimmedRequestToError(received string) error { } } -func (c *errorClient) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { +func (c *errorClient) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { if err := requestToPartialError(sql, session); err != nil { return nil, err } if err := requestToError(sql); err != nil { return nil, err } - return c.fallbackClient.Execute(ctx, sql, bindVariables, tabletType, session, notInTransaction) + return c.fallbackClient.Execute(ctx, sql, bindVariables, keyspace, tabletType, session, notInTransaction) } func (c *errorClient) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { @@ -192,11 +192,11 @@ func (c *errorClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries []*vt return c.fallbackClient.ExecuteBatchKeyspaceIds(ctx, queries, tabletType, asTransaction, session) } -func (c *errorClient) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { +func (c *errorClient) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { if err := requestToError(sql); err != nil { return err } - return c.fallbackClient.StreamExecute(ctx, sql, bindVariables, tabletType, sendReply) + return c.fallbackClient.StreamExecute(ctx, sql, bindVariables, keyspace, tabletType, sendReply) } func (c *errorClient) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { diff --git a/go/cmd/vtgateclienttest/services/fallback.go b/go/cmd/vtgateclienttest/services/fallback.go index 19f312975d..626699a81e 100644 --- a/go/cmd/vtgateclienttest/services/fallback.go +++ b/go/cmd/vtgateclienttest/services/fallback.go @@ -27,8 +27,8 @@ func newFallbackClient(fallback vtgateservice.VTGateService) fallbackClient { return fallbackClient{fallback: fallback} } -func (c fallbackClient) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { - return c.fallback.Execute(ctx, sql, bindVariables, tabletType, session, notInTransaction) +func (c fallbackClient) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { + return c.fallback.Execute(ctx, sql, bindVariables, keyspace, tabletType, session, notInTransaction) } func (c fallbackClient) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { @@ -55,8 +55,8 @@ func (c fallbackClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries []* return c.fallback.ExecuteBatchKeyspaceIds(ctx, queries, tabletType, asTransaction, session) } -func (c fallbackClient) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { - return c.fallback.StreamExecute(ctx, sql, bindVariables, tabletType, sendReply) +func (c fallbackClient) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { + return c.fallback.StreamExecute(ctx, sql, bindVariables, keyspace, tabletType, sendReply) } func (c fallbackClient) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { diff --git a/go/cmd/vtgateclienttest/services/terminal.go b/go/cmd/vtgateclienttest/services/terminal.go index b7f4817f53..7e1fd7fe89 100644 --- a/go/cmd/vtgateclienttest/services/terminal.go +++ b/go/cmd/vtgateclienttest/services/terminal.go @@ -29,7 +29,7 @@ func newTerminalClient() *terminalClient { return &terminalClient{} } -func (c *terminalClient) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { +func (c *terminalClient) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { if sql == "quit://" { log.Fatal("Received quit:// query. Going down.") } @@ -60,7 +60,7 @@ func (c *terminalClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries [] return nil, errTerminal } -func (c *terminalClient) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { +func (c *terminalClient) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { return errTerminal } diff --git a/go/vt/proto/vtgate/vtgate.pb.go b/go/vt/proto/vtgate/vtgate.pb.go index fd10756614..e8b6d06430 100644 --- a/go/vt/proto/vtgate/vtgate.pb.go +++ b/go/vt/proto/vtgate/vtgate.pb.go @@ -114,6 +114,8 @@ type ExecuteRequest struct { TabletType topodata.TabletType `protobuf:"varint,4,opt,name=tablet_type,json=tabletType,enum=topodata.TabletType" json:"tablet_type,omitempty"` // not_in_transaction is deprecated and should not be used. NotInTransaction bool `protobuf:"varint,5,opt,name=not_in_transaction,json=notInTransaction" json:"not_in_transaction,omitempty"` + // keyspace to target the query to. + Keyspace string `protobuf:"bytes,6,opt,name=keyspace" json:"keyspace,omitempty"` } func (m *ExecuteRequest) Reset() { *m = ExecuteRequest{} } @@ -774,6 +776,8 @@ type StreamExecuteRequest struct { Query *query.BoundQuery `protobuf:"bytes,2,opt,name=query" json:"query,omitempty"` // tablet_type is the type of tablets that this query is targeted to. TabletType topodata.TabletType `protobuf:"varint,3,opt,name=tablet_type,json=tabletType,enum=topodata.TabletType" json:"tablet_type,omitempty"` + // keyspace to target the query to. + Keyspace string `protobuf:"bytes,4,opt,name=keyspace" json:"keyspace,omitempty"` } func (m *StreamExecuteRequest) Reset() { *m = StreamExecuteRequest{} } @@ -1376,87 +1380,88 @@ func init() { } var fileDescriptor0 = []byte{ - // 1304 bytes of a gzipped FileDescriptorProto + // 1316 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xd4, 0x59, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0x97, 0xe3, 0x34, 0x69, 0x9e, 0x93, 0xb4, 0xf5, 0xb6, 0xdb, 0x10, 0x96, 0x6d, 0xb1, 0x40, - 0x5b, 0x60, 0x65, 0x69, 0xb3, 0xfc, 0x13, 0x42, 0x02, 0x1a, 0x2a, 0x14, 0x2d, 0xac, 0xca, 0xb4, - 0x42, 0x1c, 0x40, 0x96, 0x9b, 0x8c, 0x5a, 0xd3, 0xc4, 0x0e, 0x9e, 0x71, 0xa0, 0x1c, 0xb8, 0x21, - 0x71, 0xdb, 0x13, 0x12, 0x42, 0x5c, 0x90, 0xf8, 0x02, 0x7c, 0x04, 0x4e, 0x1c, 0x39, 0x70, 0xe0, - 0xc6, 0x47, 0x80, 0x23, 0x17, 0x0e, 0x8c, 0x67, 0xc6, 0x7f, 0xe2, 0x36, 0x69, 0x9a, 0xb4, 0x55, - 0x7a, 0xaa, 0x67, 0xde, 0x9b, 0x79, 0xef, 0xfd, 0x7e, 0x6f, 0xde, 0xcc, 0x6b, 0xa0, 0x3c, 0xa0, - 0x87, 0x36, 0xc5, 0x66, 0xdf, 0xf7, 0xa8, 0xa7, 0x17, 0xc4, 0xa8, 0xae, 0x7d, 0x1e, 0x60, 0xff, - 0x44, 0x4c, 0xd6, 0xab, 0xd4, 0xeb, 0x7b, 0x1d, 0x9b, 0xda, 0x72, 0xac, 0x0d, 0xa8, 0xdf, 0x6f, - 0x8b, 0x81, 0xf1, 0x87, 0x02, 0xc5, 0x3d, 0x4c, 0x88, 0xe3, 0xb9, 0xfa, 0xf3, 0x50, 0x75, 0x5c, - 0x8b, 0xfa, 0xb6, 0x4b, 0xec, 0x36, 0x65, 0x33, 0x35, 0x65, 0x53, 0xd9, 0x5a, 0x44, 0x15, 0xc7, - 0xdd, 0x4f, 0x26, 0xf5, 0x26, 0x54, 0xc9, 0x91, 0xed, 0x77, 0x2c, 0x22, 0xd6, 0x91, 0x5a, 0x6e, - 0x53, 0xdd, 0xd2, 0x1a, 0x77, 0x4c, 0xe9, 0x8b, 0xdc, 0xcf, 0xdc, 0x0b, 0xb5, 0xe4, 0x00, 0x55, - 0x48, 0x6a, 0x44, 0xea, 0x9f, 0x40, 0x39, 0x2d, 0x66, 0xb6, 0x0b, 0xd4, 0xf6, 0x0f, 0x31, 0xe5, - 0x36, 0xb5, 0x46, 0xc5, 0x14, 0x21, 0xec, 0xf3, 0x49, 0x24, 0x85, 0xa1, 0x8b, 0x29, 0xff, 0x2c, - 0xa7, 0xc3, 0x6c, 0x2b, 0x5b, 0x2a, 0xaa, 0xa4, 0x66, 0x5b, 0x1d, 0xe3, 0x5f, 0x05, 0xaa, 0x3b, - 0x5f, 0xe2, 0x76, 0x40, 0x31, 0xc2, 0x6c, 0x23, 0x42, 0xf5, 0xfb, 0x50, 0x6a, 0xdb, 0xdd, 0x2e, - 0xf6, 0xc3, 0x45, 0xc2, 0xc6, 0x92, 0x29, 0x90, 0x68, 0xf2, 0xf9, 0xd6, 0xbb, 0x68, 0x51, 0x68, - 0xb4, 0x3a, 0xfa, 0x0b, 0x50, 0x94, 0xd1, 0x71, 0x03, 0x42, 0x37, 0x1d, 0x1c, 0x8a, 0xe4, 0xfa, - 0x3d, 0x58, 0xe0, 0xae, 0xd6, 0x54, 0xae, 0xb8, 0x22, 0x1d, 0xdf, 0xf6, 0x02, 0xb7, 0xf3, 0x61, + 0x14, 0x97, 0xe3, 0x34, 0x69, 0x9e, 0x93, 0xb4, 0xeb, 0x6d, 0x77, 0x43, 0x58, 0xb6, 0xc5, 0x02, + 0x6d, 0x81, 0x95, 0xa5, 0xcd, 0xf2, 0x4f, 0x08, 0x09, 0x68, 0xa8, 0x50, 0xb4, 0xb0, 0x2a, 0xd3, + 0x0a, 0x71, 0x00, 0x59, 0x6e, 0x32, 0x6a, 0x4d, 0x13, 0x3b, 0x78, 0xc6, 0x81, 0x72, 0xe0, 0x86, + 0xc4, 0x6d, 0x0f, 0x08, 0x09, 0x21, 0x2e, 0x7c, 0x04, 0xbe, 0x01, 0x9c, 0x38, 0x72, 0xe0, 0xc0, + 0x8d, 0x8f, 0x00, 0x5f, 0x80, 0x03, 0xe3, 0x99, 0xf1, 0x9f, 0xb8, 0x49, 0x9a, 0x26, 0x6d, 0x95, + 0x9e, 0xea, 0x99, 0xf7, 0x66, 0xde, 0x7b, 0xbf, 0xdf, 0x9b, 0x37, 0xf3, 0x1a, 0x28, 0x0f, 0xe8, + 0xa1, 0x4d, 0xb1, 0xd9, 0xf7, 0x3d, 0xea, 0xe9, 0x05, 0x31, 0xaa, 0x6b, 0x9f, 0x07, 0xd8, 0x3f, + 0x11, 0x93, 0xf5, 0x2a, 0xf5, 0xfa, 0x5e, 0xc7, 0xa6, 0xb6, 0x1c, 0x6b, 0x03, 0xea, 0xf7, 0xdb, + 0x62, 0x60, 0xfc, 0xa9, 0x40, 0x71, 0x0f, 0x13, 0xe2, 0x78, 0xae, 0xfe, 0x3c, 0x54, 0x1d, 0xd7, + 0xa2, 0xbe, 0xed, 0x12, 0xbb, 0x4d, 0xd9, 0x4c, 0x4d, 0xd9, 0x54, 0xb6, 0x96, 0x51, 0xc5, 0x71, + 0xf7, 0x93, 0x49, 0xbd, 0x09, 0x55, 0x72, 0x64, 0xfb, 0x1d, 0x8b, 0x88, 0x75, 0xa4, 0x96, 0xdb, + 0x54, 0xb7, 0xb4, 0xc6, 0x1d, 0x53, 0xfa, 0x22, 0xf7, 0x33, 0xf7, 0x42, 0x2d, 0x39, 0x40, 0x15, + 0x92, 0x1a, 0x91, 0xfa, 0x27, 0x50, 0x4e, 0x8b, 0x99, 0xed, 0x02, 0xb5, 0xfd, 0x43, 0x4c, 0xb9, + 0x4d, 0xad, 0x51, 0x31, 0x45, 0x08, 0xfb, 0x7c, 0x12, 0x49, 0x61, 0xe8, 0x62, 0xca, 0x3f, 0xcb, + 0xe9, 0x30, 0xdb, 0xca, 0x96, 0x8a, 0x2a, 0xa9, 0xd9, 0x56, 0xc7, 0xf8, 0x2e, 0x07, 0xd5, 0x9d, + 0x2f, 0x71, 0x3b, 0xa0, 0x18, 0x61, 0xb6, 0x11, 0xa1, 0xfa, 0x7d, 0x28, 0xb5, 0xed, 0x6e, 0x17, + 0xfb, 0xe1, 0x22, 0x61, 0x63, 0xc5, 0x14, 0x48, 0x34, 0xf9, 0x7c, 0xeb, 0x5d, 0xb4, 0x2c, 0x34, + 0x5a, 0x1d, 0xfd, 0x05, 0x28, 0xca, 0xe8, 0xb8, 0x01, 0xa1, 0x9b, 0x0e, 0x0e, 0x45, 0x72, 0xfd, + 0x1e, 0x2c, 0x71, 0x57, 0x6b, 0x2a, 0x57, 0xbc, 0x21, 0x1d, 0xdf, 0xf6, 0x02, 0xb7, 0xf3, 0x61, 0xf8, 0x89, 0x84, 0x5c, 0x7f, 0x05, 0x34, 0x6a, 0x1f, 0x74, 0x31, 0xb5, 0xe8, 0x49, 0x1f, 0xd7, - 0xf2, 0x4c, 0xbd, 0xda, 0x58, 0x35, 0x63, 0x76, 0xf6, 0xb9, 0x70, 0x9f, 0xc9, 0x10, 0xd0, 0xf8, - 0x9b, 0x39, 0xae, 0xbb, 0x1e, 0xb5, 0x32, 0xcc, 0x2c, 0x70, 0x66, 0x96, 0x99, 0xa4, 0x95, 0x26, - 0xc7, 0x78, 0xa2, 0xc0, 0x52, 0x1c, 0x39, 0xe9, 0x33, 0xa8, 0x31, 0x03, 0x6d, 0x01, 0xfb, 0xbe, - 0xe7, 0x67, 0xc2, 0x46, 0xbb, 0xcd, 0x9d, 0x70, 0x1a, 0x09, 0xe9, 0x45, 0x62, 0x7e, 0x11, 0x0a, - 0x3e, 0x26, 0x41, 0x97, 0xca, 0xa0, 0x75, 0x19, 0xb4, 0x88, 0x97, 0x4b, 0x90, 0xd4, 0x30, 0x7e, - 0xc9, 0xc1, 0xaa, 0xf4, 0x88, 0x33, 0x4e, 0xe6, 0x87, 0x91, 0x3a, 0x2c, 0x1e, 0xe3, 0x13, 0xd2, - 0xb7, 0xdb, 0x82, 0x8e, 0x12, 0x8a, 0xc7, 0xfa, 0x6d, 0x28, 0xf0, 0x8c, 0x25, 0x0c, 0x6a, 0x95, - 0x49, 0xe4, 0x28, 0xcb, 0x62, 0x61, 0x26, 0x16, 0x8b, 0x23, 0x58, 0xfc, 0x4e, 0x81, 0xb5, 0x0c, - 0x66, 0x73, 0xc1, 0xe5, 0xaf, 0x39, 0x78, 0x4a, 0xfa, 0xf5, 0x48, 0x02, 0xd5, 0xba, 0x29, 0x84, - 0x3e, 0x0b, 0xe5, 0xe8, 0x9b, 0xf9, 0x27, 0x68, 0x2d, 0x23, 0xed, 0x38, 0x89, 0xe3, 0x7a, 0xb8, - 0xfd, 0x41, 0x81, 0xfa, 0x59, 0x18, 0xce, 0x05, 0xc1, 0xbf, 0xe7, 0x60, 0x3d, 0x71, 0x0e, 0xd9, - 0xee, 0x21, 0xbe, 0x21, 0xf4, 0x3e, 0x00, 0x60, 0xdf, 0x96, 0xcf, 0x5d, 0xe6, 0xe4, 0x86, 0x91, - 0xc6, 0xd4, 0x45, 0xd1, 0xa0, 0xd2, 0x71, 0x14, 0xd7, 0xf5, 0xd0, 0xfd, 0xbd, 0x02, 0xb5, 0xd3, - 0x88, 0xce, 0x05, 0xd9, 0xdf, 0xe6, 0x63, 0xb2, 0x77, 0x5c, 0xea, 0xd0, 0x93, 0x1b, 0x73, 0x96, - 0x19, 0x05, 0x98, 0x7b, 0x6c, 0xb5, 0xbd, 0x6e, 0xd0, 0x73, 0x2d, 0xd7, 0xee, 0x61, 0x7e, 0x27, - 0x96, 0xd0, 0xb2, 0x90, 0x34, 0xb9, 0xe0, 0x31, 0x9b, 0xd7, 0x3f, 0x86, 0x5b, 0x52, 0x7b, 0xa8, - 0x00, 0x14, 0x78, 0x8e, 0x6c, 0x45, 0x9e, 0x8e, 0x40, 0xc2, 0x8c, 0x26, 0xd0, 0x8a, 0xd8, 0xe4, - 0xd1, 0xe8, 0x82, 0x51, 0x9c, 0x29, 0x83, 0x16, 0xcf, 0xce, 0xa0, 0xfa, 0x01, 0x2c, 0x46, 0x3e, - 0xe8, 0x1b, 0x90, 0xe7, 0x96, 0x14, 0x6e, 0x49, 0x8b, 0x1e, 0x49, 0xa1, 0x01, 0x2e, 0xd0, 0x57, - 0x61, 0x61, 0x60, 0x77, 0x03, 0xcc, 0x79, 0x28, 0x23, 0x31, 0x60, 0xcb, 0xb4, 0x54, 0xe8, 0x1c, - 0xfa, 0x32, 0x82, 0xa4, 0xf4, 0xa5, 0xb3, 0x34, 0x05, 0xc0, 0x5c, 0x64, 0xa9, 0x0b, 0x4b, 0x3c, - 0x39, 0xf8, 0x45, 0xc8, 0x15, 0x92, 0x1c, 0x52, 0x2e, 0x90, 0x43, 0xb9, 0x91, 0x17, 0xbc, 0x9a, - 0xbe, 0xe0, 0x8d, 0x6f, 0x92, 0x3b, 0x6e, 0xdb, 0xa6, 0xed, 0xa3, 0x6b, 0x7a, 0xb4, 0x3c, 0x80, - 0x62, 0xe8, 0xb3, 0x83, 0x85, 0x3f, 0x5a, 0x63, 0x3d, 0x52, 0xcd, 0x44, 0x8f, 0x22, 0xbd, 0x69, - 0x1f, 0x94, 0xec, 0x0d, 0x6d, 0x93, 0x33, 0x1e, 0x93, 0x15, 0x9b, 0xa4, 0x0b, 0xd7, 0x8f, 0xc9, - 0x3d, 0x35, 0x84, 0xc3, 0x95, 0x25, 0xc5, 0x7d, 0x28, 0x0a, 0xca, 0x23, 0x04, 0xce, 0xca, 0x8a, - 0x48, 0xc5, 0xf8, 0x1a, 0x56, 0x39, 0x30, 0xc9, 0x71, 0xbc, 0xc4, 0xdc, 0xc8, 0xbe, 0x15, 0xd4, - 0x53, 0x6f, 0x05, 0xe3, 0x49, 0x0e, 0xee, 0xa6, 0xe1, 0xb9, 0xce, 0xf7, 0xd0, 0xab, 0xd9, 0x5c, - 0xb9, 0x33, 0x94, 0x2b, 0x19, 0x48, 0xae, 0x2b, 0x61, 0x7e, 0x52, 0x60, 0x63, 0x24, 0x22, 0x73, - 0x92, 0x35, 0x3f, 0x2b, 0xb0, 0xba, 0x47, 0x7d, 0x6c, 0xf7, 0x66, 0x6a, 0x0f, 0xe3, 0x24, 0xcb, - 0x5d, 0xac, 0xe7, 0x53, 0x27, 0x43, 0xdc, 0x68, 0xc2, 0x5a, 0xc6, 0x4b, 0x89, 0x5f, 0x52, 0x38, - 0x95, 0x73, 0x0b, 0xe7, 0x5f, 0xec, 0x00, 0x0f, 0xed, 0x32, 0x4b, 0x25, 0x9b, 0x38, 0xe2, 0xf4, - 0xb1, 0x52, 0x47, 0x96, 0xdc, 0xfc, 0xb8, 0x9e, 0x6a, 0x61, 0x42, 0x94, 0x5a, 0xf0, 0xf4, 0x99, - 0xf1, 0x4d, 0x81, 0xd5, 0xdf, 0x2c, 0x77, 0x87, 0xf6, 0x9a, 0xf9, 0x38, 0x5f, 0x0a, 0x60, 0xd9, - 0x3a, 0x94, 0x3f, 0xb7, 0x67, 0x99, 0x14, 0xbb, 0xc7, 0xb0, 0x39, 0x3a, 0xde, 0x29, 0x00, 0xfc, - 0x4f, 0x81, 0x67, 0xb2, 0x1b, 0xce, 0xd2, 0x3e, 0x5c, 0x0a, 0x7c, 0xc3, 0x3d, 0x41, 0x7e, 0x8a, - 0x9e, 0x60, 0x52, 0x38, 0xdf, 0x87, 0xbb, 0xa3, 0xa2, 0x9f, 0x02, 0xcc, 0x37, 0xa1, 0xbc, 0x8d, - 0x0f, 0x1d, 0x77, 0x2a, 0xe8, 0x8c, 0x37, 0xa0, 0x22, 0x57, 0x4b, 0xd3, 0xa9, 0x6a, 0xaa, 0x8c, - 0xaf, 0xa6, 0xc6, 0x11, 0x54, 0x9a, 0x5e, 0xaf, 0xe7, 0xd0, 0xab, 0xbe, 0xc3, 0x8c, 0x65, 0xa8, - 0x46, 0x96, 0x84, 0x9b, 0xc6, 0x67, 0xb0, 0x84, 0xbc, 0x6e, 0xf7, 0xc0, 0x6e, 0x1f, 0x5f, 0xb9, - 0x75, 0x1d, 0x96, 0x13, 0x5b, 0xd2, 0xfe, 0x3f, 0x39, 0x58, 0xd9, 0xeb, 0x77, 0x1d, 0x2a, 0x29, - 0x99, 0xc6, 0x85, 0x71, 0x8f, 0x8a, 0x89, 0x3b, 0x1f, 0x76, 0xea, 0x49, 0xe8, 0x87, 0x6c, 0x6e, - 0x64, 0xb1, 0xd4, 0xf8, 0x9c, 0x68, 0x6b, 0xc2, 0x07, 0x7d, 0xa4, 0x12, 0xb8, 0x94, 0xa7, 0xa9, - 0x8a, 0x40, 0x6a, 0xb0, 0x19, 0xfd, 0x65, 0x58, 0x77, 0x83, 0x9e, 0xe5, 0x7b, 0x5f, 0x10, 0xab, - 0xcf, 0x9c, 0xe7, 0x3b, 0x5b, 0x7d, 0xdb, 0xa7, 0xbc, 0xcf, 0x55, 0xd1, 0x2d, 0x26, 0x46, 0x4c, - 0xba, 0x8b, 0x7d, 0x6e, 0x7c, 0x97, 0x89, 0xf4, 0xb7, 0xa1, 0x64, 0x77, 0x0f, 0x3d, 0xdf, 0xa1, - 0x47, 0x3d, 0xd9, 0xcd, 0x18, 0xd2, 0xcd, 0x53, 0xc8, 0x98, 0xef, 0x44, 0x9a, 0x28, 0x59, 0xa4, - 0xbf, 0x04, 0x7a, 0x40, 0xb0, 0x25, 0x9c, 0x13, 0x46, 0x07, 0x0d, 0xd9, 0xda, 0x2c, 0x31, 0x49, - 0xb2, 0xcd, 0x47, 0x0d, 0xe3, 0x37, 0x15, 0xf4, 0xf4, 0xbe, 0x32, 0x5f, 0x5f, 0x63, 0xd7, 0x44, - 0x38, 0x4b, 0x18, 0xde, 0xe1, 0x91, 0xdd, 0x88, 0x69, 0x3c, 0xa5, 0x6b, 0x86, 0x6e, 0x23, 0xa9, - 0x5e, 0xff, 0x14, 0xca, 0xd1, 0xc1, 0xe3, 0xe1, 0xa4, 0xd9, 0x50, 0xc6, 0xd6, 0x86, 0xdc, 0x04, - 0xb5, 0xa1, 0xfe, 0x16, 0x94, 0xf8, 0x15, 0x73, 0xee, 0xde, 0xc9, 0x3d, 0x97, 0x4b, 0xdf, 0x73, - 0xf5, 0x3f, 0x15, 0xc8, 0xf3, 0xc5, 0x13, 0x3f, 0x52, 0x3f, 0x80, 0x6a, 0xec, 0xa5, 0x60, 0x4f, - 0x64, 0xf6, 0xbd, 0x31, 0x90, 0xa4, 0x21, 0x40, 0xe5, 0xe3, 0x34, 0x20, 0x4d, 0x00, 0xf1, 0xaf, - 0x7b, 0xbe, 0x95, 0xc8, 0xc3, 0xe7, 0xc6, 0x6c, 0x15, 0x87, 0x8b, 0x4a, 0x24, 0x8e, 0x5c, 0x87, - 0x3c, 0x71, 0xbe, 0x12, 0xcf, 0x47, 0x15, 0xf1, 0x6f, 0xe3, 0x21, 0xac, 0xbd, 0x87, 0xe9, 0x9e, - 0x3f, 0x88, 0xee, 0x91, 0xe8, 0xf8, 0x8c, 0x81, 0xc9, 0x40, 0x70, 0x3b, 0xbb, 0x48, 0x66, 0xc0, - 0xeb, 0xec, 0x04, 0xf8, 0x03, 0x6b, 0x68, 0xa5, 0xd6, 0x58, 0x4b, 0xe8, 0x49, 0x2f, 0xd2, 0x48, - 0x32, 0xd8, 0xae, 0x43, 0xad, 0xed, 0xf5, 0xcc, 0x13, 0x2f, 0xa0, 0xc1, 0x01, 0x36, 0x07, 0x0e, - 0x65, 0x27, 0x5e, 0xfc, 0xd6, 0x71, 0x50, 0xe0, 0x7f, 0x1e, 0xfe, 0x1f, 0x00, 0x00, 0xff, 0xff, - 0xad, 0x6e, 0xed, 0xad, 0x34, 0x19, 0x00, 0x00, + 0xf2, 0x4c, 0xbd, 0xda, 0x58, 0x33, 0x63, 0x76, 0xf6, 0xb9, 0x70, 0x9f, 0xc9, 0x10, 0xd0, 0xf8, + 0x9b, 0x39, 0xae, 0xbb, 0x1e, 0xb5, 0x32, 0xcc, 0x2c, 0x71, 0x66, 0x56, 0x99, 0xa4, 0x35, 0x44, + 0x4e, 0x1d, 0x96, 0x8f, 0xf1, 0x09, 0xe9, 0xdb, 0x6d, 0x5c, 0x2b, 0x30, 0x9d, 0x12, 0x8a, 0xc7, + 0xc6, 0x13, 0x05, 0x56, 0x62, 0x54, 0x48, 0x9f, 0xd1, 0x80, 0x19, 0xa0, 0x4b, 0xd8, 0xf7, 0x3d, + 0x3f, 0x03, 0x09, 0xda, 0x6d, 0xee, 0x84, 0xd3, 0x48, 0x48, 0xcf, 0x83, 0xc7, 0x8b, 0x50, 0xf0, + 0x31, 0x09, 0xba, 0x54, 0x02, 0xa2, 0x4b, 0x40, 0x04, 0x16, 0x5c, 0x82, 0xa4, 0x86, 0xf1, 0x4b, + 0x0e, 0xd6, 0xa4, 0x47, 0x3c, 0x1b, 0xc8, 0xe2, 0xb0, 0x95, 0x06, 0x32, 0x3f, 0x0c, 0xa4, 0x7e, + 0x0b, 0x0a, 0x3c, 0x9b, 0x09, 0xa3, 0x41, 0x65, 0x12, 0x39, 0xca, 0x32, 0x5c, 0x98, 0x8b, 0xe1, + 0xe2, 0x68, 0x86, 0x8d, 0xef, 0x15, 0x58, 0xcf, 0x60, 0xb6, 0x10, 0x5c, 0xfe, 0x96, 0x83, 0xa7, + 0xa4, 0x5f, 0x8f, 0x24, 0x50, 0xad, 0xeb, 0x42, 0xe8, 0xb3, 0x50, 0x8e, 0xbe, 0x99, 0x7f, 0x82, + 0xd6, 0x32, 0xd2, 0x8e, 0x93, 0x38, 0xae, 0x86, 0xdb, 0x1f, 0x15, 0xa8, 0x8f, 0xc2, 0x70, 0x21, + 0x08, 0xfe, 0x23, 0x07, 0xb7, 0x13, 0xe7, 0x90, 0xed, 0x1e, 0xe2, 0x6b, 0x42, 0xef, 0x03, 0x00, + 0xf6, 0x6d, 0xf9, 0xdc, 0x65, 0x4e, 0x6e, 0x18, 0x69, 0x4c, 0x5d, 0x14, 0x0d, 0x2a, 0x1d, 0x47, + 0x71, 0x5d, 0x0d, 0xdd, 0x3f, 0x28, 0x50, 0x3b, 0x8d, 0xe8, 0x42, 0x90, 0xfd, 0x6d, 0x3e, 0x26, + 0x7b, 0xc7, 0xa5, 0x0e, 0x3d, 0xb9, 0x36, 0x67, 0x99, 0x51, 0x80, 0xb9, 0xc7, 0x56, 0xdb, 0xeb, + 0x06, 0x3d, 0xd7, 0x72, 0xed, 0x1e, 0xe6, 0xf7, 0x65, 0x09, 0xad, 0x0a, 0x49, 0x93, 0x0b, 0x1e, + 0xb3, 0x79, 0xfd, 0x63, 0xb8, 0x29, 0xb5, 0x87, 0x0a, 0x40, 0x81, 0xe7, 0xc8, 0x56, 0xe4, 0xe9, + 0x18, 0x24, 0xcc, 0x68, 0x02, 0xdd, 0x10, 0x9b, 0x3c, 0x1a, 0x5f, 0x30, 0x8a, 0x73, 0x65, 0xd0, + 0xf2, 0xe8, 0x0c, 0xaa, 0x1f, 0xc0, 0x72, 0xe4, 0x83, 0xbe, 0x01, 0x79, 0x6e, 0x49, 0xe1, 0x96, + 0xb4, 0xe8, 0x01, 0x15, 0x1a, 0xe0, 0x02, 0x7d, 0x0d, 0x96, 0x06, 0x76, 0x37, 0xc0, 0x9c, 0x87, + 0x32, 0x12, 0x03, 0xb6, 0x4c, 0x4b, 0x85, 0xce, 0xa1, 0x2f, 0x23, 0x48, 0x4a, 0x5f, 0x3a, 0x4b, + 0x53, 0x00, 0x2c, 0x44, 0x96, 0xba, 0xb0, 0xc2, 0x93, 0x83, 0x5f, 0x84, 0x5c, 0x21, 0xc9, 0x21, + 0xe5, 0x1c, 0x39, 0x94, 0x1b, 0x7b, 0xc1, 0xab, 0xe9, 0x0b, 0xde, 0xf8, 0x26, 0xb9, 0xe3, 0xb6, + 0x6d, 0xda, 0x3e, 0xba, 0xa2, 0x47, 0xcb, 0x03, 0x28, 0x86, 0x3e, 0x3b, 0x58, 0xf8, 0xa3, 0x35, + 0x6e, 0x47, 0xaa, 0x99, 0xe8, 0x51, 0xa4, 0x37, 0xeb, 0x63, 0x93, 0xbd, 0xaf, 0x6d, 0x32, 0xe2, + 0xa1, 0x59, 0xb1, 0x49, 0xba, 0x70, 0xfd, 0x94, 0xdc, 0x53, 0x43, 0x38, 0x5c, 0x5a, 0x52, 0xdc, + 0x87, 0xa2, 0xa0, 0x3c, 0x42, 0x60, 0x54, 0x56, 0x44, 0x2a, 0xc6, 0xd7, 0xb0, 0xc6, 0x81, 0x49, + 0x8e, 0xe3, 0x05, 0xe6, 0x46, 0xf6, 0xad, 0xa0, 0x9e, 0x7a, 0x2b, 0x18, 0x4f, 0x72, 0x70, 0x37, + 0x0d, 0xcf, 0x55, 0xbe, 0x87, 0x5e, 0xcd, 0xe6, 0xca, 0x9d, 0xa1, 0x5c, 0xc9, 0x40, 0x72, 0x55, + 0x09, 0xf3, 0xb3, 0x02, 0x1b, 0x63, 0x11, 0x59, 0x90, 0xac, 0xf9, 0x55, 0x81, 0xb5, 0x3d, 0xea, + 0x63, 0xbb, 0x37, 0x57, 0xeb, 0x18, 0x27, 0x59, 0xee, 0x7c, 0xfd, 0xa0, 0x3a, 0x25, 0xe2, 0x13, + 0xee, 0x3e, 0xa3, 0x09, 0xeb, 0x99, 0x08, 0x24, 0xb6, 0x49, 0x51, 0x55, 0xce, 0x2c, 0xaa, 0x7f, + 0xb3, 0xc3, 0x3d, 0xb4, 0xcb, 0x3c, 0x55, 0x6e, 0x6a, 0x34, 0xd2, 0x61, 0xa9, 0x63, 0xcb, 0x71, + 0x7e, 0x52, 0xbf, 0xb5, 0x34, 0x1d, 0x82, 0x46, 0x0b, 0x9e, 0x1e, 0x19, 0xdf, 0x0c, 0x58, 0xfd, + 0xc3, 0xf2, 0x7a, 0x68, 0xaf, 0xb9, 0x8f, 0xfa, 0x85, 0x00, 0x96, 0xad, 0x51, 0xf9, 0x33, 0xfb, + 0x99, 0x69, 0xb1, 0x7b, 0x0c, 0x9b, 0xe3, 0xe3, 0x9d, 0x01, 0xc0, 0xff, 0x14, 0x78, 0x26, 0xbb, + 0xe1, 0x3c, 0xad, 0xc5, 0x85, 0xc0, 0x37, 0xdc, 0x2f, 0xe4, 0x67, 0xe8, 0x17, 0xa6, 0x85, 0xf3, + 0x7d, 0xb8, 0x3b, 0x2e, 0xfa, 0x19, 0xc0, 0x7c, 0x13, 0xca, 0xdb, 0xf8, 0xd0, 0x71, 0x67, 0x82, + 0xce, 0x78, 0x03, 0x2a, 0x72, 0xb5, 0x34, 0x9d, 0xaa, 0xb4, 0xca, 0xe4, 0x4a, 0x6b, 0x1c, 0x41, + 0xa5, 0xe9, 0xf5, 0x7a, 0x0e, 0xbd, 0xec, 0xfb, 0xcd, 0x58, 0x85, 0x6a, 0x64, 0x49, 0xb8, 0x69, + 0x7c, 0x06, 0x2b, 0xc8, 0xeb, 0x76, 0x0f, 0xec, 0xf6, 0xf1, 0xa5, 0x5b, 0xd7, 0x61, 0x35, 0xb1, + 0x25, 0xed, 0xff, 0x9b, 0x83, 0x1b, 0x7b, 0xfd, 0xae, 0x43, 0x25, 0x25, 0xb3, 0xb8, 0x30, 0xe9, + 0xc1, 0x31, 0x75, 0x57, 0xc4, 0x4e, 0x3d, 0x09, 0xfd, 0x90, 0x8d, 0x8f, 0x2c, 0x96, 0x1a, 0x9f, + 0x13, 0x2d, 0x4f, 0xf8, 0xd8, 0x8f, 0x54, 0x02, 0x97, 0xf2, 0x34, 0x55, 0x11, 0x48, 0x0d, 0x36, + 0xa3, 0xbf, 0x0c, 0xb7, 0xdd, 0xa0, 0x67, 0xf9, 0xde, 0x17, 0xc4, 0xea, 0x33, 0xe7, 0xf9, 0xce, + 0x56, 0xdf, 0xf6, 0x29, 0xef, 0x81, 0x55, 0x74, 0x93, 0x89, 0x11, 0x93, 0xee, 0x62, 0x9f, 0x1b, + 0xdf, 0x65, 0x22, 0xfd, 0x6d, 0x28, 0xd9, 0xdd, 0x43, 0xcf, 0x77, 0xe8, 0x51, 0x4f, 0x76, 0x3a, + 0x86, 0x74, 0xf3, 0x14, 0x32, 0xe6, 0x3b, 0x91, 0x26, 0x4a, 0x16, 0xe9, 0x2f, 0x81, 0x1e, 0x10, + 0x6c, 0x09, 0xe7, 0x84, 0xd1, 0x41, 0x43, 0xb6, 0x3d, 0x2b, 0x4c, 0x92, 0x6c, 0xf3, 0x51, 0xc3, + 0xf8, 0x5d, 0x05, 0x3d, 0xbd, 0xaf, 0xcc, 0xd7, 0xd7, 0xd8, 0x35, 0x11, 0xce, 0x12, 0x86, 0x77, + 0x78, 0x64, 0x37, 0x62, 0x1a, 0x4f, 0xe9, 0x9a, 0xa1, 0xdb, 0x48, 0xaa, 0xd7, 0x3f, 0x85, 0x72, + 0x74, 0xf0, 0x78, 0x38, 0x69, 0x36, 0x94, 0x89, 0xb5, 0x21, 0x37, 0x45, 0x6d, 0xa8, 0xbf, 0x05, + 0x25, 0x7e, 0xc5, 0x9c, 0xb9, 0x77, 0x72, 0xcf, 0xe5, 0xd2, 0xf7, 0x5c, 0xfd, 0x2f, 0x05, 0xf2, + 0x7c, 0xf1, 0xd4, 0x0f, 0xd8, 0x0f, 0xa0, 0x1a, 0x7b, 0x29, 0xd8, 0x13, 0x99, 0x7d, 0x6f, 0x02, + 0x24, 0x69, 0x08, 0x50, 0xf9, 0x38, 0x0d, 0x48, 0x13, 0x40, 0xfc, 0xcb, 0x9f, 0x6f, 0x25, 0xf2, + 0xf0, 0xb9, 0x09, 0x5b, 0xc5, 0xe1, 0xa2, 0x12, 0x89, 0x23, 0xd7, 0x21, 0x4f, 0x9c, 0xaf, 0xc4, + 0xa3, 0x45, 0x45, 0xfc, 0xdb, 0x78, 0x08, 0xeb, 0xef, 0x61, 0xba, 0xe7, 0x0f, 0xa2, 0x7b, 0x24, + 0x3a, 0x3e, 0x13, 0x60, 0x32, 0x10, 0xdc, 0xca, 0x2e, 0x92, 0x19, 0xf0, 0x3a, 0x3b, 0x01, 0xfe, + 0xc0, 0x1a, 0x5a, 0xa9, 0x35, 0xd6, 0x13, 0x7a, 0xd2, 0x8b, 0x34, 0x92, 0x0c, 0xb6, 0xeb, 0x50, + 0x6b, 0x7b, 0x3d, 0xf3, 0xc4, 0x0b, 0x68, 0x70, 0x80, 0xcd, 0x81, 0x43, 0xd9, 0x89, 0x17, 0xbf, + 0x91, 0x1c, 0x14, 0xf8, 0x9f, 0x87, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0x12, 0x77, 0x8b, 0xc2, + 0x6c, 0x19, 0x00, 0x00, } diff --git a/go/vt/vitessdriver/fakeserver_test.go b/go/vt/vitessdriver/fakeserver_test.go index c92d0a21e0..631386b292 100644 --- a/go/vt/vitessdriver/fakeserver_test.go +++ b/go/vt/vitessdriver/fakeserver_test.go @@ -22,6 +22,7 @@ type fakeVTGateService struct { type queryExecute struct { SQL string BindVariables map[string]interface{} + Keyspace string TabletType topodatapb.TabletType Session *vtgatepb.Session NotInTransaction bool @@ -36,7 +37,7 @@ type queryExecuteSpecificShard struct { } // Execute is part of the VTGateService interface -func (f *fakeVTGateService) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { +func (f *fakeVTGateService) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { execCase, ok := execMap[sql] if !ok { return nil, fmt.Errorf("no match for: %s", sql) @@ -44,6 +45,7 @@ func (f *fakeVTGateService) Execute(ctx context.Context, sql string, bindVariabl query := &queryExecute{ SQL: sql, BindVariables: bindVariables, + Keyspace: keyspace, TabletType: tabletType, Session: session, NotInTransaction: notInTransaction, @@ -109,7 +111,7 @@ func (f *fakeVTGateService) ExecuteBatchKeyspaceIds(ctx context.Context, queries } // StreamExecute is part of the VTGateService interface -func (f *fakeVTGateService) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { +func (f *fakeVTGateService) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { execCase, ok := execMap[sql] if !ok { return fmt.Errorf("no match for: %s", sql) @@ -117,6 +119,7 @@ func (f *fakeVTGateService) StreamExecute(ctx context.Context, sql string, bindV query := &queryExecute{ SQL: sql, BindVariables: bindVariables, + Keyspace: keyspace, TabletType: tabletType, } if !reflect.DeepEqual(query, execCase.execQuery) { diff --git a/go/vt/vtgate/grpcvtgateservice/server.go b/go/vt/vtgate/grpcvtgateservice/server.go index 7cf2b2d77e..d4b95e0e6a 100644 --- a/go/vt/vtgate/grpcvtgateservice/server.go +++ b/go/vt/vtgate/grpcvtgateservice/server.go @@ -37,7 +37,7 @@ func (vtg *VTGate) Execute(ctx context.Context, request *vtgatepb.ExecuteRequest if err != nil { return nil, vterrors.ToGRPCError(err) } - result, err := vtg.server.Execute(ctx, string(request.Query.Sql), bv, request.TabletType, request.Session, request.NotInTransaction) + result, err := vtg.server.Execute(ctx, string(request.Query.Sql), bv, request.Keyspace, request.TabletType, request.Session, request.NotInTransaction) return &vtgatepb.ExecuteResponse{ Result: sqltypes.ResultToProto3(result), Session: request.Session, @@ -196,6 +196,7 @@ func (vtg *VTGate) StreamExecute(request *vtgatepb.StreamExecuteRequest, stream vtgErr := vtg.server.StreamExecute(ctx, string(request.Query.Sql), bv, + request.Keyspace, request.TabletType, func(value *sqltypes.Result) error { return stream.Send(&vtgatepb.StreamExecuteResponse{ diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 1eb3a35544..8583200a1a 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -68,9 +68,15 @@ type builder interface { SupplyCol(ref colref) int } +// VSchema defines the interface for this package to fetch +// info about tables. +type VSchema interface { + Find(keyspace, tablename string) (table *vindexes.Table, err error) +} + // Build builds a plan for a query based on the specified vschema. // It's the main entry point for this package. -func Build(query string, vschema *vindexes.VSchema) (*engine.Plan, error) { +func Build(query string, vschema VSchema) (*engine.Plan, error) { statement, err := sqlparser.Parse(query) if err != nil { return nil, err diff --git a/go/vt/vtgate/planbuilder/dml.go b/go/vt/vtgate/planbuilder/dml.go index 227d4d6bf1..a7d597ccc4 100644 --- a/go/vt/vtgate/planbuilder/dml.go +++ b/go/vt/vtgate/planbuilder/dml.go @@ -14,15 +14,23 @@ import ( "github.com/youtube/vitess/go/vt/vtgate/vindexes" ) +// dmlFormatter strips out keyspace name from dmls. +func dmlFormatter(buf *sqlparser.TrackedBuffer, node sqlparser.SQLNode) { + switch node := node.(type) { + case *sqlparser.TableName: + node.Name.Format(buf) + return + } + node.Format(buf) +} + // buildUpdatePlan builds the instructions for an UPDATE statement. -func buildUpdatePlan(upd *sqlparser.Update, vschema *vindexes.VSchema) (*engine.Route, error) { +func buildUpdatePlan(upd *sqlparser.Update, vschema VSchema) (*engine.Route, error) { route := &engine.Route{ Query: generateQuery(upd), } - // We allow only one table in an update. - tablename := sqlparser.GetTableName(upd.Table) var err error - route.Table, err = vschema.FindTable(tablename) + route.Table, err = vschema.Find(string(upd.Table.Qualifier), string(upd.Table.Name)) if err != nil { return nil, err } @@ -47,7 +55,7 @@ func buildUpdatePlan(upd *sqlparser.Update, vschema *vindexes.VSchema) (*engine. } func generateQuery(statement sqlparser.Statement) string { - buf := sqlparser.NewTrackedBuffer(nil) + buf := sqlparser.NewTrackedBuffer(dmlFormatter) statement.Format(buf) return buf.String() } @@ -68,14 +76,12 @@ func isIndexChanging(setClauses sqlparser.UpdateExprs, colVindexes []*vindexes.C } // buildUpdatePlan builds the instructions for a DELETE statement. -func buildDeletePlan(del *sqlparser.Delete, vschema *vindexes.VSchema) (*engine.Route, error) { +func buildDeletePlan(del *sqlparser.Delete, vschema VSchema) (*engine.Route, error) { route := &engine.Route{ Query: generateQuery(del), } - // We allow only one table in a delete. - tablename := sqlparser.GetTableName(del.Table) var err error - route.Table, err = vschema.FindTable(tablename) + route.Table, err = vschema.Find(string(del.Table.Qualifier), string(del.Table.Name)) if err != nil { return nil, err } diff --git a/go/vt/vtgate/planbuilder/from.go b/go/vt/vtgate/planbuilder/from.go index 095ecb2e2e..e3b9dacb6a 100644 --- a/go/vt/vtgate/planbuilder/from.go +++ b/go/vt/vtgate/planbuilder/from.go @@ -13,12 +13,11 @@ import ( "github.com/youtube/vitess/go/vt/vtgate/vindexes" ) -// This file has functions to analyze the FROM clause -// for select statements. +// This file has functions to analyze the FROM clause. // processTableExprs analyzes the FROM clause. It produces a builder // with all the routes identified. -func processTableExprs(tableExprs sqlparser.TableExprs, vschema *vindexes.VSchema) (builder, error) { +func processTableExprs(tableExprs sqlparser.TableExprs, vschema VSchema) (builder, error) { if len(tableExprs) != 1 { return nil, errors.New("unsupported: ',' join operator") } @@ -26,7 +25,7 @@ func processTableExprs(tableExprs sqlparser.TableExprs, vschema *vindexes.VSchem } // processTableExpr produces a builder subtree for the given TableExpr. -func processTableExpr(tableExpr sqlparser.TableExpr, vschema *vindexes.VSchema) (builder, error) { +func processTableExpr(tableExpr sqlparser.TableExpr, vschema VSchema) (builder, error) { switch tableExpr := tableExpr.(type) { case *sqlparser.AliasedTableExpr: return processAliasedTable(tableExpr, vschema) @@ -55,7 +54,7 @@ func processTableExpr(tableExpr sqlparser.TableExpr, vschema *vindexes.VSchema) // vindex columns will be added to the tabsym. // A symtab symbol can only point to a route. This means that we canoot // support complex joins in subqueries yet. -func processAliasedTable(tableExpr *sqlparser.AliasedTableExpr, vschema *vindexes.VSchema) (builder, error) { +func processAliasedTable(tableExpr *sqlparser.AliasedTableExpr, vschema VSchema) (builder, error) { switch expr := tableExpr.Expr.(type) { case *sqlparser.TableName: eroute, table, err := getTablePlan(expr, vschema) @@ -118,8 +117,8 @@ func processAliasedTable(tableExpr *sqlparser.AliasedTableExpr, vschema *vindexe // getTablePlan produces the initial engine.Route for the specified TableName. // It also returns the associated vschema info (*Table) so that // it can be used to create the symbol table entry. -func getTablePlan(tableName *sqlparser.TableName, vschema *vindexes.VSchema) (*engine.Route, *vindexes.Table, error) { - table, err := vschema.FindTable(string(tableName.Name)) +func getTablePlan(tableName *sqlparser.TableName, vschema VSchema) (*engine.Route, *vindexes.Table, error) { + table, err := vschema.Find(string(tableName.Qualifier), string(tableName.Name)) if err != nil { return nil, nil, err } @@ -140,7 +139,7 @@ func getTablePlan(tableName *sqlparser.TableName, vschema *vindexes.VSchema) (*e // processJoin produces a builder subtree for the given Join. // If the left and right nodes can be part of the same route, // then it's a route. Otherwise, it's a join. -func processJoin(ajoin *sqlparser.JoinTableExpr, vschema *vindexes.VSchema) (builder, error) { +func processJoin(ajoin *sqlparser.JoinTableExpr, vschema VSchema) (builder, error) { switch ajoin.Join { case sqlparser.JoinStr, sqlparser.StraightJoinStr, sqlparser.LeftJoinStr: case sqlparser.RightJoinStr: diff --git a/go/vt/vtgate/planbuilder/insert.go b/go/vt/vtgate/planbuilder/insert.go index 86b8433c2a..00d9407f96 100644 --- a/go/vt/vtgate/planbuilder/insert.go +++ b/go/vt/vtgate/planbuilder/insert.go @@ -14,13 +14,12 @@ import ( ) // buildInsertPlan builds the route for an INSERT statement. -func buildInsertPlan(ins *sqlparser.Insert, vschema *vindexes.VSchema) (*engine.Route, error) { +func buildInsertPlan(ins *sqlparser.Insert, vschema VSchema) (*engine.Route, error) { route := &engine.Route{ Query: generateQuery(ins), } - tablename := sqlparser.GetTableName(ins.Table) var err error - route.Table, err = vschema.FindTable(tablename) + route.Table, err = vschema.Find(string(ins.Table.Qualifier), string(ins.Table.Name)) if err != nil { return nil, err } diff --git a/go/vt/vtgate/planbuilder/route.go b/go/vt/vtgate/planbuilder/route.go index 0aac7b1ca4..371425e2ea 100644 --- a/go/vt/vtgate/planbuilder/route.go +++ b/go/vt/vtgate/planbuilder/route.go @@ -36,7 +36,7 @@ type route struct { ERoute *engine.Route } -func newRoute(from sqlparser.TableExprs, eroute *engine.Route, table *vindexes.Table, vschema *vindexes.VSchema, alias, astName sqlparser.SQLName) *route { +func newRoute(from sqlparser.TableExprs, eroute *engine.Route, table *vindexes.Table, vschema VSchema, alias, astName sqlparser.SQLName) *route { // We have some circular pointer references here: // The route points to the symtab idicating // the symtab that should be used to resolve symbols diff --git a/go/vt/vtgate/planbuilder/select.go b/go/vt/vtgate/planbuilder/select.go index 68deb06e09..e668ca7a9d 100644 --- a/go/vt/vtgate/planbuilder/select.go +++ b/go/vt/vtgate/planbuilder/select.go @@ -13,7 +13,7 @@ import ( ) // buildSelectPlan is the new function to build a Select plan. -func buildSelectPlan(sel *sqlparser.Select, vschema *vindexes.VSchema) (primitive engine.Primitive, err error) { +func buildSelectPlan(sel *sqlparser.Select, vschema VSchema) (primitive engine.Primitive, err error) { bindvars := getBindvars(sel) builder, err := processSelect(sel, vschema, nil) if err != nil { @@ -43,7 +43,7 @@ func getBindvars(node sqlparser.SQLNode) map[string]struct{} { } // processSelect builds a primitive tree for the given query or subquery. -func processSelect(sel *sqlparser.Select, vschema *vindexes.VSchema, outer builder) (builder, error) { +func processSelect(sel *sqlparser.Select, vschema VSchema, outer builder) (builder, error) { bldr, err := processTableExprs(sel.From, vschema) if err != nil { return nil, err diff --git a/go/vt/vtgate/planbuilder/symtab.go b/go/vt/vtgate/planbuilder/symtab.go index a895c0f1e9..d17d640735 100644 --- a/go/vt/vtgate/planbuilder/symtab.go +++ b/go/vt/vtgate/planbuilder/symtab.go @@ -50,12 +50,12 @@ type symtab struct { Colsyms []*colsym Externs []*sqlparser.ColName Outer *symtab - VSchema *vindexes.VSchema + VSchema VSchema } // newSymtab creates a new symtab initialized // to contain the provided table alias. -func newSymtab(vschema *vindexes.VSchema) *symtab { +func newSymtab(vschema VSchema) *symtab { return &symtab{ VSchema: vschema, } diff --git a/go/vt/vtgate/planner.go b/go/vt/vtgate/planner.go index 721ef77cb0..61bd3a4c5b 100644 --- a/go/vt/vtgate/planner.go +++ b/go/vt/vtgate/planner.go @@ -45,14 +45,21 @@ func NewPlanner(vschema *vindexes.VSchema, cacheSize int) *Planner { // GetPlan computes the plan for the given query. If one is in // the cache, it reuses it. -func (plr *Planner) GetPlan(sql string) (*engine.Plan, error) { +func (plr *Planner) GetPlan(sql, keyspace string) (*engine.Plan, error) { if plr.vschema == nil { return nil, errors.New("vschema not initialized") } - if result, ok := plr.plans.Get(sql); ok { + key := sql + if keyspace != "" { + key = keyspace + ":" + sql + } + if result, ok := plr.plans.Get(key); ok { return result.(*engine.Plan), nil } - plan, err := planbuilder.Build(sql, plr.vschema) + plan, err := planbuilder.Build(sql, &wrappedVSchema{ + vschema: plr.vschema, + keyspace: keyspace, + }) if err != nil { return nil, err } @@ -95,3 +102,15 @@ func (plr *Planner) ServeHTTP(response http.ResponseWriter, request *http.Reques response.WriteHeader(http.StatusNotFound) } } + +type wrappedVSchema struct { + vschema *vindexes.VSchema + keyspace string +} + +func (vs *wrappedVSchema) Find(keyspace, tablename string) (table *vindexes.Table, err error) { + if keyspace == "" { + keyspace = vs.keyspace + } + return vs.vschema.Find(keyspace, tablename) +} diff --git a/go/vt/vtgate/request_context.go b/go/vt/vtgate/request_context.go index 76e69ccb54..363745f189 100644 --- a/go/vt/vtgate/request_context.go +++ b/go/vt/vtgate/request_context.go @@ -17,17 +17,19 @@ type requestContext struct { ctx context.Context sql string bindVars map[string]interface{} + keyspace string tabletType topodatapb.TabletType session *vtgatepb.Session notInTransaction bool router *Router } -func newRequestContext(ctx context.Context, sql string, bindVars map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, router *Router) *requestContext { +func newRequestContext(ctx context.Context, sql string, bindVars map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, router *Router) *requestContext { return &requestContext{ ctx: ctx, sql: sql, bindVars: bindVars, + keyspace: keyspace, tabletType: tabletType, session: session, notInTransaction: notInTransaction, @@ -36,7 +38,9 @@ func newRequestContext(ctx context.Context, sql string, bindVars map[string]inte } func (vc *requestContext) Execute(query string, bindvars map[string]interface{}) (*sqltypes.Result, error) { - return vc.router.Execute(vc.ctx, query, bindvars, vc.tabletType, vc.session, false) + // We have to use an empty keyspace here, becasue vindexes that call back can reference + // any table. + return vc.router.Execute(vc.ctx, query, bindvars, "", vc.tabletType, vc.session, false) } func (vc *requestContext) ExecuteRoute(route *engine.Route, joinvars map[string]interface{}) (*sqltypes.Result, error) { diff --git a/go/vt/vtgate/router.go b/go/vt/vtgate/router.go index 0e7be92535..e15a2acdac 100644 --- a/go/vt/vtgate/router.go +++ b/go/vt/vtgate/router.go @@ -59,12 +59,12 @@ func NewRouter(serv topo.SrvTopoServer, cell string, vschema *vindexes.VSchema, } // Execute routes a non-streaming query. -func (rtr *Router) Execute(ctx context.Context, sql string, bindVars map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { +func (rtr *Router) Execute(ctx context.Context, sql string, bindVars map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { if bindVars == nil { bindVars = make(map[string]interface{}) } - vcursor := newRequestContext(ctx, sql, bindVars, tabletType, session, notInTransaction, rtr) - plan, err := rtr.planner.GetPlan(sql) + vcursor := newRequestContext(ctx, sql, bindVars, keyspace, tabletType, session, notInTransaction, rtr) + plan, err := rtr.planner.GetPlan(sql, keyspace) if err != nil { return nil, err } @@ -72,12 +72,12 @@ func (rtr *Router) Execute(ctx context.Context, sql string, bindVars map[string] } // StreamExecute executes a streaming query. -func (rtr *Router) StreamExecute(ctx context.Context, sql string, bindVars map[string]interface{}, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { +func (rtr *Router) StreamExecute(ctx context.Context, sql string, bindVars map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { if bindVars == nil { bindVars = make(map[string]interface{}) } - vcursor := newRequestContext(ctx, sql, bindVars, tabletType, nil, false, rtr) - plan, err := rtr.planner.GetPlan(sql) + vcursor := newRequestContext(ctx, sql, bindVars, keyspace, tabletType, nil, false, rtr) + plan, err := rtr.planner.GetPlan(sql, keyspace) if err != nil { return err } diff --git a/go/vt/vtgate/router_framework_test.go b/go/vt/vtgate/router_framework_test.go index db80b407c1..e109b1d6a3 100644 --- a/go/vt/vtgate/router_framework_test.go +++ b/go/vt/vtgate/router_framework_test.go @@ -55,7 +55,7 @@ var routerVSchema = createTestVSchema(` "Type": "numeric" } }, - "Classes": { + "Tables": { "user": { "ColVindexes": [ { @@ -67,10 +67,10 @@ var routerVSchema = createTestVSchema(` "Name": "name_user_map" } ], - "Autoinc" : { - "Col": "id", - "Sequence": "user_seq" - } + "Autoinc" : { + "Col": "id", + "Sequence": "user_seq" + } }, "user_extra": { "ColVindexes": [ @@ -91,10 +91,10 @@ var routerVSchema = createTestVSchema(` "Name": "music_user_map" } ], - "Autoinc" : { - "Col": "id", - "Sequence": "user_seq" - } + "Autoinc" : { + "Col": "id", + "Sequence": "user_seq" + } }, "music_extra": { "ColVindexes": [ @@ -136,34 +136,22 @@ var routerVSchema = createTestVSchema(` } ] } - }, - "Tables": { - "user": "user", - "user_extra": "user_extra", - "music": "music", - "music_extra": "music_extra", - "music_extra_reversed": "music_extra_reversed", - "noauto_table": "noauto_table", - "ksid_table": "ksid_table" } }, "TestBadSharding": { "Sharded": false, "Tables": { - "sharded_table": "" + "sharded_table": {} } }, "TestUnsharded": { "Sharded": false, - "Classes": { - "seq": { - "Type": "Sequence" - } - }, "Tables": { - "user_seq": "seq", - "music_user_map": "", - "name_user_map": "" + "user_seq": { + "Type": "Sequence" + }, + "music_user_map": {}, + "name_user_map": {} } } } @@ -215,6 +203,7 @@ func routerExec(router *Router, sql string, bv map[string]interface{}) (*sqltype return router.Execute(context.Background(), sql, bv, + "", topodatapb.TabletType_MASTER, nil, false) @@ -222,7 +211,7 @@ func routerExec(router *Router, sql string, bv map[string]interface{}) (*sqltype func routerStream(router *Router, sql string) (qr *sqltypes.Result, err error) { results := make(chan *sqltypes.Result, 10) - err = router.StreamExecute(context.Background(), sql, nil, topodatapb.TabletType_MASTER, func(qr *sqltypes.Result) error { + err = router.StreamExecute(context.Background(), sql, nil, "", topodatapb.TabletType_MASTER, func(qr *sqltypes.Result) error { results <- qr return nil }) diff --git a/go/vt/vtgate/vindexes/vschema.go b/go/vt/vtgate/vindexes/vschema.go index df4612c9dd..5bdcd2cb79 100644 --- a/go/vt/vtgate/vindexes/vschema.go +++ b/go/vt/vtgate/vindexes/vschema.go @@ -6,7 +6,6 @@ package vindexes import ( "encoding/json" - "errors" "fmt" "io/ioutil" "sort" @@ -48,8 +47,8 @@ type ColVindex struct { // KeyspaceSchema contains the schema(table) for a keyspace. type KeyspaceSchema struct { - Sharded bool - Tables map[string]*Table + Keyspace *Keyspace + Tables map[string]*Table } // Autoinc contains the auto-inc information for a table. @@ -67,67 +66,58 @@ func BuildVSchema(source *VSchemaFormal) (vschema *VSchema, err error) { tables: make(map[string]*Table), Keyspaces: make(map[string]*KeyspaceSchema), } - keyspaces := buildKeyspaces(source, vschema) + buildKeyspaces(source, vschema) // We have to build the sequences first to avoid // forward reference errors. - err = buildSequences(source, vschema, keyspaces) + err = buildSequences(source, vschema) if err != nil { return nil, err } - err = buildTables(source, vschema, keyspaces) + err = buildTables(source, vschema) if err != nil { return nil, err } return vschema, nil } -func buildKeyspaces(source *VSchemaFormal, vschema *VSchema) map[string]*Keyspace { - k := make(map[string]*Keyspace) +func buildKeyspaces(source *VSchemaFormal, vschema *VSchema) { for ksname, ks := range source.Keyspaces { - k[ksname] = &Keyspace{ - Name: ksname, - Sharded: ks.Sharded, - } vschema.Keyspaces[ksname] = &KeyspaceSchema{ - Sharded: ks.Sharded, - Tables: make(map[string]*Table), + Keyspace: &Keyspace{ + Name: ksname, + Sharded: ks.Sharded, + }, + Tables: make(map[string]*Table), } } - return k } -func buildSequences(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]*Keyspace) error { +func buildSequences(source *VSchemaFormal, vschema *VSchema) error { for ksname, ks := range source.Keyspaces { - keyspace := keyspaces[ksname] - for tname, cname := range ks.Tables { - if cname == "" { + keyspace := vschema.Keyspaces[ksname].Keyspace + for tname, table := range ks.Tables { + if table.Type != "Sequence" { continue } - class, ok := ks.Classes[cname] - if !ok { - return fmt.Errorf("class %s not found for table %s", cname, tname) + t := &Table{ + Name: tname, + Keyspace: keyspace, + IsSequence: true, } - if class.Type == "Sequence" { - t := &Table{ - Name: tname, - Keyspace: keyspace, - IsSequence: true, - } - if _, ok := vschema.tables[tname]; ok { - vschema.tables[tname] = nil - } else { - vschema.tables[tname] = t - } - vschema.Keyspaces[ksname].Tables[tname] = t + if _, ok := vschema.tables[tname]; ok { + vschema.tables[tname] = nil + } else { + vschema.tables[tname] = t } + vschema.Keyspaces[ksname].Tables[tname] = t } } return nil } -func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]*Keyspace) error { +func buildTables(source *VSchemaFormal, vschema *VSchema) error { for ksname, ks := range source.Keyspaces { - keyspace := keyspaces[ksname] + keyspace := vschema.Keyspaces[ksname].Keyspace vindexes := make(map[string]Vindex) for vname, vindexInfo := range ks.Vindexes { vindex, err := CreateVindex(vindexInfo.Type, vname, vindexInfo.Params) @@ -142,12 +132,8 @@ func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]* } vindexes[vname] = vindex } - for tname, cname := range ks.Tables { - class, ok := ks.Classes[cname] - if !ok && cname != "" { - return fmt.Errorf("class %s not found for table %s", cname, tname) - } - if class.Type == "Sequence" { + for tname, table := range ks.Tables { + if table.Type == "Sequence" { continue } t := &Table{ @@ -163,10 +149,10 @@ func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]* if !keyspace.Sharded { continue } - for i, ind := range class.ColVindexes { + for i, ind := range table.ColVindexes { vindexInfo, ok := ks.Vindexes[ind.Name] if !ok { - return fmt.Errorf("vindex %s not found for class %s", ind.Name, cname) + return fmt.Errorf("vindex %s not found for table %s", ind.Name, tname) } vindex := vindexes[ind.Name] owned := false @@ -183,10 +169,10 @@ func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]* if i == 0 { // Perform Primary vindex check. if _, ok := columnVindex.Vindex.(Unique); !ok { - return fmt.Errorf("primary vindex %s is not Unique for class %s", ind.Name, cname) + return fmt.Errorf("primary vindex %s is not Unique for table %s", ind.Name, tname) } if owned { - return fmt.Errorf("primary vindex %s cannot be owned for class %s", ind.Name, cname) + return fmt.Errorf("primary vindex %s cannot be owned for table %s", ind.Name, tname) } } t.ColVindexes = append(t.ColVindexes, columnVindex) @@ -195,11 +181,11 @@ func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]* } } t.Ordered = colVindexSorted(t.ColVindexes) - if class.Autoinc != nil { - t.Autoinc = &Autoinc{Col: class.Autoinc.Col, ColVindexNum: -1} - seq, ok := vschema.tables[class.Autoinc.Sequence] + if table.Autoinc != nil { + t.Autoinc = &Autoinc{Col: table.Autoinc.Col, ColVindexNum: -1} + seq, ok := vschema.tables[table.Autoinc.Sequence] if !ok { - return fmt.Errorf("sequence %s not found for class %s", class.Autoinc.Sequence, cname) + return fmt.Errorf("sequence %s not found for table %s", table.Autoinc.Sequence, tname) } t.Autoinc.Sequence = seq for i, cv := range t.ColVindexes { @@ -214,18 +200,43 @@ func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]* return nil } -// FindTable returns a pointer to the Table if found. -// Otherwise, it returns a reason, which is equivalent to an error. -func (vschema *VSchema) FindTable(tablename string) (table *Table, err error) { - if tablename == "" { - return nil, errors.New("unsupported: compex table expression in DML") - } - table, ok := vschema.tables[tablename] - if table == nil { - if ok { - return nil, fmt.Errorf("ambiguous table reference: %s", tablename) +// Find returns a pointer to the Table. If a keyspace is specified, only tables +// from that keyspace are searched. If the specified keyspace is unsharded +// and no tables matched, it's considered valid: Find will construct a table +// of that name and return it. If no kesypace is specified, then a table is returned +// only if its name is unique across all keyspaces. If there is only one +// keyspace in the vschema, and it's unsharded, then all table requests are considered +// valid and belonging to that keyspace. +func (vschema *VSchema) Find(keyspace, tablename string) (table *Table, err error) { + if keyspace == "" { + table, ok := vschema.tables[tablename] + if table == nil { + if ok { + return nil, fmt.Errorf("ambiguous table reference: %s", tablename) + } + if len(vschema.Keyspaces) != 1 { + return nil, fmt.Errorf("table %s not found", tablename) + } + // Loop happens only once. + for _, ks := range vschema.Keyspaces { + if ks.Keyspace.Sharded { + return nil, fmt.Errorf("table %s not found", tablename) + } + return &Table{Name: tablename, Keyspace: ks.Keyspace}, nil + } } - return nil, fmt.Errorf("table %s not found", tablename) + return table, nil + } + ks, ok := vschema.Keyspaces[keyspace] + if !ok { + return nil, fmt.Errorf("keyspace %s not found in vschema", keyspace) + } + table = ks.Tables[tablename] + if table == nil { + if ks.Keyspace.Sharded { + return nil, fmt.Errorf("table %s not found", tablename) + } + return &Table{Name: tablename, Keyspace: ks.Keyspace}, nil } return table, nil } @@ -257,8 +268,7 @@ type VSchemaFormal struct { type KeyspaceFormal struct { Sharded bool Vindexes map[string]VindexFormal - Classes map[string]ClassFormal - Tables map[string]string + Tables map[string]TableFormal } // VindexFormal is the info for each index as loaded from @@ -269,9 +279,9 @@ type VindexFormal struct { Owner string } -// ClassFormal is the info for each table class as loaded from +// TableFormal is the info for each table as loaded from // the source. -type ClassFormal struct { +type TableFormal struct { Type string ColVindexes []ColVindexFormal Autoinc *AutoincFormal diff --git a/go/vt/vtgate/vindexes/vschema_test.go b/go/vt/vtgate/vindexes/vschema_test.go index 13dc22d261..38a697cd5d 100644 --- a/go/vt/vtgate/vindexes/vschema_test.go +++ b/go/vt/vtgate/vindexes/vschema_test.go @@ -85,8 +85,8 @@ func TestUnshardedVSchema(t *testing.T) { good := VSchemaFormal{ Keyspaces: map[string]KeyspaceFormal{ "unsharded": { - Tables: map[string]string{ - "t1": "", + Tables: map[string]TableFormal{ + "t1": {}, }, }, }, @@ -95,11 +95,12 @@ func TestUnshardedVSchema(t *testing.T) { if err != nil { t.Error(err) } + ks := &Keyspace{ + Name: "unsharded", + } t1 := &Table{ - Name: "t1", - Keyspace: &Keyspace{ - Name: "unsharded", - }, + Name: "t1", + Keyspace: ks, } want := &VSchema{ tables: map[string]*Table{ @@ -107,6 +108,7 @@ func TestUnshardedVSchema(t *testing.T) { }, Keyspaces: map[string]*KeyspaceSchema{ "unsharded": { + Keyspace: ks, Tables: map[string]*Table{ "t1": t1, }, @@ -136,7 +138,7 @@ func TestShardedVSchemaOwned(t *testing.T) { Owner: "t1", }, }, - Classes: map[string]ClassFormal{ + Tables: map[string]TableFormal{ "t1": { ColVindexes: []ColVindexFormal{ { @@ -149,9 +151,6 @@ func TestShardedVSchemaOwned(t *testing.T) { }, }, }, - Tables: map[string]string{ - "t1": "t1", - }, }, }, } @@ -159,12 +158,13 @@ func TestShardedVSchemaOwned(t *testing.T) { if err != nil { t.Error(err) } + ks := &Keyspace{ + Name: "sharded", + Sharded: true, + } t1 := &Table{ - Name: "t1", - Keyspace: &Keyspace{ - Name: "sharded", - Sharded: true, - }, + Name: "t1", + Keyspace: ks, ColVindexes: []*ColVindex{ { Col: "c1", @@ -197,7 +197,7 @@ func TestShardedVSchemaOwned(t *testing.T) { }, Keyspaces: map[string]*KeyspaceSchema{ "sharded": { - Sharded: true, + Keyspace: ks, Tables: map[string]*Table{ "t1": t1, }, @@ -226,7 +226,7 @@ func TestShardedVSchemaNotOwned(t *testing.T) { Owner: "", }, }, - Classes: map[string]ClassFormal{ + Tables: map[string]TableFormal{ "t1": { ColVindexes: []ColVindexFormal{ { @@ -239,9 +239,6 @@ func TestShardedVSchemaNotOwned(t *testing.T) { }, }, }, - Tables: map[string]string{ - "t1": "t1", - }, }, }, } @@ -249,12 +246,13 @@ func TestShardedVSchemaNotOwned(t *testing.T) { if err != nil { t.Error(err) } + ks := &Keyspace{ + Name: "sharded", + Sharded: true, + } t1 := &Table{ - Name: "t1", - Keyspace: &Keyspace{ - Name: "sharded", - Sharded: true, - }, + Name: "t1", + Keyspace: ks, ColVindexes: []*ColVindex{ { Col: "c1", @@ -282,7 +280,7 @@ func TestShardedVSchemaNotOwned(t *testing.T) { }, Keyspaces: map[string]*KeyspaceSchema{ "sharded": { - Sharded: true, + Keyspace: ks, Tables: map[string]*Table{ "t1": t1, }, @@ -308,39 +306,6 @@ func TestLoadVSchemaFail(t *testing.T) { } } -func TestBuildVSchemaClassNotFoundFail(t *testing.T) { - bad := VSchemaFormal{ - Keyspaces: map[string]KeyspaceFormal{ - "sharded": { - Sharded: true, - Vindexes: map[string]VindexFormal{ - "stfu": { - Type: "stfu", - }, - }, - Classes: map[string]ClassFormal{ - "notexist": { - ColVindexes: []ColVindexFormal{ - { - Col: "c1", - Name: "noexist", - }, - }, - }, - }, - Tables: map[string]string{ - "t1": "t1", - }, - }, - }, - } - _, err := BuildVSchema(&bad) - want := "class t1 not found for table t1" - if err == nil || err.Error() != want { - t.Errorf("BuildVSchema: %v, want %v", err, want) - } -} - func TestBuildVSchemaVindexNotFoundFail(t *testing.T) { bad := VSchemaFormal{ Keyspaces: map[string]KeyspaceFormal{ @@ -351,7 +316,7 @@ func TestBuildVSchemaVindexNotFoundFail(t *testing.T) { Type: "noexist", }, }, - Classes: map[string]ClassFormal{ + Tables: map[string]TableFormal{ "t1": { ColVindexes: []ColVindexFormal{ { @@ -361,9 +326,6 @@ func TestBuildVSchemaVindexNotFoundFail(t *testing.T) { }, }, }, - Tables: map[string]string{ - "t1": "t1", - }, }, }, } @@ -384,7 +346,7 @@ func TestBuildVSchemaInvalidVindexFail(t *testing.T) { Type: "stf", }, }, - Classes: map[string]ClassFormal{ + Tables: map[string]TableFormal{ "t1": { ColVindexes: []ColVindexFormal{ { @@ -394,9 +356,6 @@ func TestBuildVSchemaInvalidVindexFail(t *testing.T) { }, }, }, - Tables: map[string]string{ - "t1": "t1", - }, }, }, } @@ -411,40 +370,36 @@ func TestBuildVSchemaDupSeq(t *testing.T) { good := VSchemaFormal{ Keyspaces: map[string]KeyspaceFormal{ "ksa": { - Classes: map[string]ClassFormal{ - "seq": { + Tables: map[string]TableFormal{ + "t1": { Type: "Sequence", }, }, - Tables: map[string]string{ - "t1": "seq", - }, }, "ksb": { - Classes: map[string]ClassFormal{ - "seq": { + Tables: map[string]TableFormal{ + "t1": { Type: "Sequence", }, }, - Tables: map[string]string{ - "t1": "seq", - }, }, }, } + ksa := &Keyspace{ + Name: "ksa", + } + ksb := &Keyspace{ + Name: "ksb", + } got, _ := BuildVSchema(&good) t1a := &Table{ - Name: "t1", - Keyspace: &Keyspace{ - Name: "ksa", - }, + Name: "t1", + Keyspace: ksa, IsSequence: true, } t1b := &Table{ - Name: "t1", - Keyspace: &Keyspace{ - Name: "ksb", - }, + Name: "t1", + Keyspace: ksb, IsSequence: true, } want := &VSchema{ @@ -453,11 +408,13 @@ func TestBuildVSchemaDupSeq(t *testing.T) { }, Keyspaces: map[string]*KeyspaceSchema{ "ksa": { + Keyspace: ksa, Tables: map[string]*Table{ "t1": t1a, }, }, "ksb": { + Keyspace: ksb, Tables: map[string]*Table{ "t1": t1b, }, @@ -475,29 +432,31 @@ func TestBuildVSchemaDupTable(t *testing.T) { good := VSchemaFormal{ Keyspaces: map[string]KeyspaceFormal{ "ksa": { - Tables: map[string]string{ - "t1": "", + Tables: map[string]TableFormal{ + "t1": {}, }, }, "ksb": { - Tables: map[string]string{ - "t1": "", + Tables: map[string]TableFormal{ + "t1": {}, }, }, }, } got, _ := BuildVSchema(&good) + ksa := &Keyspace{ + Name: "ksa", + } t1a := &Table{ - Name: "t1", - Keyspace: &Keyspace{ - Name: "ksa", - }, + Name: "t1", + Keyspace: ksa, + } + ksb := &Keyspace{ + Name: "ksb", } t1b := &Table{ - Name: "t1", - Keyspace: &Keyspace{ - Name: "ksb", - }, + Name: "t1", + Keyspace: ksb, } want := &VSchema{ tables: map[string]*Table{ @@ -505,11 +464,13 @@ func TestBuildVSchemaDupTable(t *testing.T) { }, Keyspaces: map[string]*KeyspaceSchema{ "ksa": { + Keyspace: ksa, Tables: map[string]*Table{ "t1": t1a, }, }, "ksb": { + Keyspace: ksb, Tables: map[string]*Table{ "t1": t1b, }, @@ -533,7 +494,7 @@ func TestBuildVSchemaNoindexFail(t *testing.T) { Type: "stfu", }, }, - Classes: map[string]ClassFormal{ + Tables: map[string]TableFormal{ "t1": { ColVindexes: []ColVindexFormal{ { @@ -543,14 +504,11 @@ func TestBuildVSchemaNoindexFail(t *testing.T) { }, }, }, - Tables: map[string]string{ - "t1": "t1", - }, }, }, } _, err := BuildVSchema(&bad) - want := "vindex notexist not found for class t1" + want := "vindex notexist not found for table t1" if err == nil || err.Error() != want { t.Errorf("BuildVSchema: %v, want %v", err, want) } @@ -566,7 +524,7 @@ func TestBuildVSchemaNotUniqueFail(t *testing.T) { Type: "stln", }, }, - Classes: map[string]ClassFormal{ + Tables: map[string]TableFormal{ "t1": { ColVindexes: []ColVindexFormal{ { @@ -576,14 +534,11 @@ func TestBuildVSchemaNotUniqueFail(t *testing.T) { }, }, }, - Tables: map[string]string{ - "t1": "t1", - }, }, }, } _, err := BuildVSchema(&bad) - want := "primary vindex stln is not Unique for class t1" + want := "primary vindex stln is not Unique for table t1" if err == nil || err.Error() != want { t.Errorf("BuildVSchema: %v, want %v", err, want) } @@ -600,7 +555,7 @@ func TestBuildVSchemaPrimaryNonFunctionalFail(t *testing.T) { Owner: "t1", }, }, - Classes: map[string]ClassFormal{ + Tables: map[string]TableFormal{ "t1": { ColVindexes: []ColVindexFormal{ { @@ -610,14 +565,11 @@ func TestBuildVSchemaPrimaryNonFunctionalFail(t *testing.T) { }, }, }, - Tables: map[string]string{ - "t1": "t1", - }, }, }, } _, err := BuildVSchema(&bad) - want := "primary vindex stlu cannot be owned for class t1" + want := "primary vindex stlu cannot be owned for table t1" if err == nil || err.Error() != want { t.Errorf("BuildVSchema: %v, want %v", err, want) } @@ -627,14 +579,11 @@ func TestSequence(t *testing.T) { good := VSchemaFormal{ Keyspaces: map[string]KeyspaceFormal{ "unsharded": { - Classes: map[string]ClassFormal{ + Tables: map[string]TableFormal{ "seq": { Type: "Sequence", }, }, - Tables: map[string]string{ - "seq": "seq", - }, }, "sharded": { Sharded: true, @@ -646,7 +595,7 @@ func TestSequence(t *testing.T) { }, }, }, - Classes: map[string]ClassFormal{ + Tables: map[string]TableFormal{ "t1": { ColVindexes: []ColVindexFormal{ { @@ -660,9 +609,6 @@ func TestSequence(t *testing.T) { }, }, }, - Tables: map[string]string{ - "t1": "t1", - }, }, }, } @@ -670,19 +616,21 @@ func TestSequence(t *testing.T) { if err != nil { t.Error(err) } + ksu := &Keyspace{ + Name: "unsharded", + } + kss := &Keyspace{ + Name: "sharded", + Sharded: true, + } seq := &Table{ - Name: "seq", - Keyspace: &Keyspace{ - Name: "unsharded", - }, + Name: "seq", + Keyspace: ksu, IsSequence: true, } t1 := &Table{ - Name: "t1", - Keyspace: &Keyspace{ - Name: "sharded", - Sharded: true, - }, + Name: "t1", + Keyspace: kss, ColVindexes: []*ColVindex{ { Col: "c1", @@ -711,12 +659,13 @@ func TestSequence(t *testing.T) { }, Keyspaces: map[string]*KeyspaceSchema{ "unsharded": { + Keyspace: ksu, Tables: map[string]*Table{ "seq": seq, }, }, "sharded": { - Sharded: true, + Keyspace: kss, Tables: map[string]*Table{ "t1": t1, }, @@ -735,7 +684,7 @@ func TestBadSequence(t *testing.T) { Keyspaces: map[string]KeyspaceFormal{ "sharded": { Sharded: true, - Classes: map[string]ClassFormal{ + Tables: map[string]TableFormal{ "t1": { Autoinc: &AutoincFormal{ Col: "c1", @@ -743,14 +692,11 @@ func TestBadSequence(t *testing.T) { }, }, }, - Tables: map[string]string{ - "t1": "t1", - }, }, }, } _, err := BuildVSchema(&bad) - want := "sequence seq not found for class t1" + want := "sequence seq not found for table t1" if err == nil || err.Error() != want { t.Errorf("BuildVSchema: %v, want %v", err, want) } @@ -760,47 +706,108 @@ func TestFind(t *testing.T) { input := VSchemaFormal{ Keyspaces: map[string]KeyspaceFormal{ "ksa": { - Tables: map[string]string{ - "ta": "", - "t1": "", + Tables: map[string]TableFormal{ + "ta": {}, + "t1": {}, }, }, "ksb": { - Tables: map[string]string{ - "tb": "", - "t1": "", + Sharded: true, + Tables: map[string]TableFormal{ + "tb": {}, + "t1": {}, }, }, }, } vschema, _ := BuildVSchema(&input) - _, err := vschema.FindTable("") - wantErr := "unsupported: compex table expression in DML" + _, err := vschema.Find("", "t1") + wantErr := "ambiguous table reference: t1" if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) + t.Errorf("Find(\"\"): %v, want %s", err, wantErr) } - _, err = vschema.FindTable("t1") - wantErr = "ambiguous table reference: t1" - if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) - } - _, err = vschema.FindTable("none") + _, err = vschema.Find("", "none") wantErr = "table none not found" if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) + t.Errorf("Find(\"\"): %v, want %s", err, wantErr) } - got, err := vschema.FindTable("ta") + got, err := vschema.Find("", "ta") if err != nil { t.Error(err) return } - want := &Table{ + ta := &Table{ Name: "ta", Keyspace: &Keyspace{ Name: "ksa", }, } - if !reflect.DeepEqual(got, want) { - t.Errorf("FindTable(\"t1a\"): %+v, want %+v", got, want) + if !reflect.DeepEqual(got, ta) { + t.Errorf("Find(\"t1a\"): %+v, want %+v", got, ta) + } + got, err = vschema.Find("ksa", "ta") + if !reflect.DeepEqual(got, ta) { + t.Errorf("Find(\"t1a\"): %+v, want %+v", got, ta) + } + none := &Table{ + Name: "none", + Keyspace: &Keyspace{ + Name: "ksa", + }, + } + got, err = vschema.Find("ksa", "none") + if !reflect.DeepEqual(got, none) { + t.Errorf("Find(\"t1a\"): %+v, want %+v", got, none) + } + _, err = vschema.Find("ksb", "none") + wantErr = "table none not found" + if err == nil || err.Error() != wantErr { + t.Errorf("Find(\"\"): %v, want %s", err, wantErr) + } + _, err = vschema.Find("none", "aa") + wantErr = "keyspace none not found in vschema" + if err == nil || err.Error() != wantErr { + t.Errorf("Find(\"\"): %v, want %s", err, wantErr) + } +} + +func TestFindSingleKeyspace(t *testing.T) { + input := VSchemaFormal{ + Keyspaces: map[string]KeyspaceFormal{ + "ksa": { + Tables: map[string]TableFormal{ + "ta": {}, + "t1": {}, + }, + }, + }, + } + vschema, _ := BuildVSchema(&input) + none := &Table{ + Name: "none", + Keyspace: &Keyspace{ + Name: "ksa", + }, + } + got, _ := vschema.Find("", "none") + if !reflect.DeepEqual(got, none) { + t.Errorf("Find(\"t1a\"): %+v, want %+v", got, none) + } + input = VSchemaFormal{ + Keyspaces: map[string]KeyspaceFormal{ + "ksb": { + Sharded: true, + Tables: map[string]TableFormal{ + "tb": {}, + "t1": {}, + }, + }, + }, + } + vschema, _ = BuildVSchema(&input) + _, err := vschema.Find("", "none") + wantErr := "table none not found" + if err == nil || err.Error() != wantErr { + t.Errorf("Find(\"\"): %v, want %s", err, wantErr) } } diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index 040112bde7..d0af2bc631 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -157,7 +157,7 @@ func (vtg *VTGate) InitializeConnections(ctx context.Context) (err error) { } // Execute executes a non-streaming query by routing based on the values in the query. -func (vtg *VTGate) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { +func (vtg *VTGate) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { startTime := time.Now() statsKey := []string{"Execute", "Any", strings.ToLower(tabletType.String())} defer vtg.timings.Record(statsKey, startTime) @@ -168,7 +168,7 @@ func (vtg *VTGate) Execute(ctx context.Context, sql string, bindVariables map[st return nil, errTooManyInFlight } - qr, err := vtg.router.Execute(ctx, sql, bindVariables, tabletType, session, notInTransaction) + qr, err := vtg.router.Execute(ctx, sql, bindVariables, keyspace, tabletType, session, notInTransaction) if err == nil { vtg.rowsReturned.Add(statsKey, int64(len(qr.Rows))) return qr, nil @@ -177,6 +177,7 @@ func (vtg *VTGate) Execute(ctx context.Context, sql string, bindVariables map[st query := map[string]interface{}{ "Sql": sql, "BindVariables": bindVariables, + "Keyspace": keyspace, "TabletType": strings.ToLower(tabletType.String()), "Session": session, "NotInTransaction": notInTransaction, @@ -410,7 +411,7 @@ func (vtg *VTGate) ExecuteBatchKeyspaceIds(ctx context.Context, queries []*vtgat } // StreamExecute executes a streaming query by routing based on the values in the query. -func (vtg *VTGate) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { +func (vtg *VTGate) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { startTime := time.Now() statsKey := []string{"StreamExecute", "Any", strings.ToLower(tabletType.String())} defer vtg.timings.Record(statsKey, startTime) @@ -426,6 +427,7 @@ func (vtg *VTGate) StreamExecute(ctx context.Context, sql string, bindVariables ctx, sql, bindVariables, + keyspace, tabletType, func(reply *sqltypes.Result) error { rowCount += int64(len(reply.Rows)) @@ -438,6 +440,7 @@ func (vtg *VTGate) StreamExecute(ctx context.Context, sql string, bindVariables query := map[string]interface{}{ "Sql": sql, "BindVariables": bindVariables, + "Keyspace": keyspace, "TabletType": strings.ToLower(tabletType.String()), } logError(err, query, vtg.logStreamExecute) diff --git a/go/vt/vtgate/vtgate_test.go b/go/vt/vtgate/vtgate_test.go index 15fe2afe76..27b55225c6 100644 --- a/go/vt/vtgate/vtgate_test.go +++ b/go/vt/vtgate/vtgate_test.go @@ -35,7 +35,7 @@ func init() { "TestUnsharded": { "Sharded": false, "Tables": { - "t1": "" + "t1": {} } } } @@ -51,6 +51,7 @@ func TestVTGateExecute(t *testing.T) { qr, err := rpcVTGate.Execute(context.Background(), "select id from t1", nil, + "", topodatapb.TabletType_MASTER, nil, false) @@ -68,6 +69,7 @@ func TestVTGateExecute(t *testing.T) { rpcVTGate.Execute(context.Background(), "select id from t1", nil, + "", topodatapb.TabletType_MASTER, session, false) @@ -95,12 +97,43 @@ func TestVTGateExecute(t *testing.T) { rpcVTGate.Execute(context.Background(), "select id from t1", nil, + "", topodatapb.TabletType_MASTER, session, false) rpcVTGate.Rollback(context.Background(), session) } +func TestVTGateExecuteWithKeyspace(t *testing.T) { + sandbox := createSandbox(KsTestUnsharded) + sbc := &sandboxConn{} + sandbox.MapTestConn("0", sbc) + qr, err := rpcVTGate.Execute(context.Background(), + "select id from none", + nil, + KsTestUnsharded, + topodatapb.TabletType_MASTER, + nil, + false) + if err != nil { + t.Errorf("want nil, got %v", err) + } + if !reflect.DeepEqual(singleRowResult, qr) { + t.Errorf("want \n%+v, got \n%+v", singleRowResult, qr) + } + _, err = rpcVTGate.Execute(context.Background(), + "select id from none", + nil, + "aa", + topodatapb.TabletType_MASTER, + nil, + false) + want := "keyspace aa not found in vschema" + if err == nil || err.Error() != want { + t.Errorf("Execute: %v, want %s", err, want) + } +} + func TestVTGateExecuteShards(t *testing.T) { sandbox := createSandbox("TestVTGateExecuteShards") sbc := &sandboxConn{} @@ -532,6 +565,7 @@ func TestVTGateStreamExecute(t *testing.T) { err := rpcVTGate.StreamExecute(context.Background(), "select id from t1", nil, + "", topodatapb.TabletType_MASTER, func(r *sqltypes.Result) error { qrs = append(qrs, r) diff --git a/go/vt/vtgate/vtgateconntest/client.go b/go/vt/vtgate/vtgateconntest/client.go index 918a881d06..5a4d59e38c 100644 --- a/go/vt/vtgate/vtgateconntest/client.go +++ b/go/vt/vtgate/vtgateconntest/client.go @@ -74,13 +74,14 @@ func (f *fakeVTGateService) checkCallerID(ctx context.Context, name string) { type queryExecute struct { SQL string BindVariables map[string]interface{} + Keyspace string TabletType topodatapb.TabletType Session *vtgatepb.Session NotInTransaction bool } // Execute is part of the VTGateService interface -func (f *fakeVTGateService) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { +func (f *fakeVTGateService) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) { if f.hasError { return nil, errTestVtGateError } @@ -95,6 +96,7 @@ func (f *fakeVTGateService) Execute(ctx context.Context, sql string, bindVariabl query := &queryExecute{ SQL: sql, BindVariables: bindVariables, + Keyspace: keyspace, TabletType: tabletType, Session: session, NotInTransaction: notInTransaction, @@ -370,7 +372,7 @@ func (f *fakeVTGateService) ExecuteBatchKeyspaceIds(ctx context.Context, queries } // StreamExecute is part of the VTGateService interface -func (f *fakeVTGateService) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { +func (f *fakeVTGateService) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error { if f.panics { panic(fmt.Errorf("test forced panic")) } @@ -382,6 +384,7 @@ func (f *fakeVTGateService) StreamExecute(ctx context.Context, sql string, bindV query := &queryExecute{ SQL: sql, BindVariables: bindVariables, + Keyspace: keyspace, TabletType: tabletType, } if !reflect.DeepEqual(query, execCase.execQuery) { diff --git a/go/vt/vtgate/vtgateservice/interface.go b/go/vt/vtgate/vtgateservice/interface.go index 73e8a1e3a4..f6cd9550e9 100644 --- a/go/vt/vtgate/vtgateservice/interface.go +++ b/go/vt/vtgate/vtgateservice/interface.go @@ -20,7 +20,7 @@ import ( type VTGateService interface { // Regular query execution. // All these methods can change the provided session. - Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) + Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) ExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) ExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool) (*sqltypes.Result, error) @@ -29,7 +29,7 @@ type VTGateService interface { ExecuteBatchKeyspaceIds(ctx context.Context, queries []*vtgatepb.BoundKeyspaceIdQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session) ([]sqltypes.Result, error) // Streaming queries - StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error + StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error StreamExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error StreamExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error diff --git a/go/vt/vtgate/vtgateservice/vtgateservice_testing/mock_vtgateservice.go b/go/vt/vtgate/vtgateservice/vtgateservice_testing/mock_vtgateservice.go index adf1a08bf3..45923a853b 100644 --- a/go/vt/vtgate/vtgateservice/vtgateservice_testing/mock_vtgateservice.go +++ b/go/vt/vtgate/vtgateservice/vtgateservice_testing/mock_vtgateservice.go @@ -33,15 +33,15 @@ func (_m *MockVTGateService) EXPECT() *_MockVTGateServiceRecorder { return _m.recorder } -func (_m *MockVTGateService) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodata.TabletType, session *vtgate.Session, notInTransaction bool) (*sqltypes.Result, error) { - ret := _m.ctrl.Call(_m, "Execute", ctx, sql, bindVariables, tabletType, session, notInTransaction) +func (_m *MockVTGateService) Execute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodata.TabletType, session *vtgate.Session, notInTransaction bool) (*sqltypes.Result, error) { + ret := _m.ctrl.Call(_m, "Execute", ctx, sql, bindVariables, keyspace, tabletType, session, notInTransaction) ret0, _ := ret[0].(*sqltypes.Result) ret1, _ := ret[1].(error) return ret0, ret1 } -func (_mr *_MockVTGateServiceRecorder) Execute(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { - return _mr.mock.ctrl.RecordCall(_mr.mock, "Execute", arg0, arg1, arg2, arg3, arg4, arg5) +func (_mr *_MockVTGateServiceRecorder) Execute(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCall(_mr.mock, "Execute", arg0, arg1, arg2, arg3, arg4, arg5, arg6) } func (_m *MockVTGateService) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodata.TabletType, session *vtgate.Session, notInTransaction bool) (*sqltypes.Result, error) { @@ -110,14 +110,14 @@ func (_mr *_MockVTGateServiceRecorder) ExecuteBatchKeyspaceIds(arg0, arg1, arg2, return _mr.mock.ctrl.RecordCall(_mr.mock, "ExecuteBatchKeyspaceIds", arg0, arg1, arg2, arg3, arg4) } -func (_m *MockVTGateService) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, tabletType topodata.TabletType, sendReply func(*sqltypes.Result) error) error { - ret := _m.ctrl.Call(_m, "StreamExecute", ctx, sql, bindVariables, tabletType, sendReply) +func (_m *MockVTGateService) StreamExecute(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, tabletType topodata.TabletType, sendReply func(*sqltypes.Result) error) error { + ret := _m.ctrl.Call(_m, "StreamExecute", ctx, sql, bindVariables, keyspace, tabletType, sendReply) ret0, _ := ret[0].(error) return ret0 } -func (_mr *_MockVTGateServiceRecorder) StreamExecute(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - return _mr.mock.ctrl.RecordCall(_mr.mock, "StreamExecute", arg0, arg1, arg2, arg3, arg4) +func (_mr *_MockVTGateServiceRecorder) StreamExecute(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCall(_mr.mock, "StreamExecute", arg0, arg1, arg2, arg3, arg4, arg5) } func (_m *MockVTGateService) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, shards []string, tabletType topodata.TabletType, sendReply func(*sqltypes.Result) error) error { diff --git a/proto/vtgate.proto b/proto/vtgate.proto index 17ccdfd9ee..5c479dbb71 100644 --- a/proto/vtgate.proto +++ b/proto/vtgate.proto @@ -41,6 +41,9 @@ message ExecuteRequest { // not_in_transaction is deprecated and should not be used. bool not_in_transaction = 5; + + // keyspace to target the query to. + string keyspace = 6; } // ExecuteResponse is the returned value from Execute. @@ -345,6 +348,9 @@ message StreamExecuteRequest { // tablet_type is the type of tablets that this query is targeted to. topodata.TabletType tablet_type = 3; + + // keyspace to target the query to. + string keyspace = 4; } // StreamExecuteResponse is the returned value from StreamExecute. diff --git a/py/vtproto/vtgate_pb2.py b/py/vtproto/vtgate_pb2.py index 9879d6b3c4..93073b11bf 100644 --- a/py/vtproto/vtgate_pb2.py +++ b/py/vtproto/vtgate_pb2.py @@ -22,7 +22,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( name='vtgate.proto', package='vtgate', syntax='proto3', - serialized_pb=_b('\n\x0cvtgate.proto\x12\x06vtgate\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x0bvtrpc.proto\"\x9e\x01\n\x07Session\x12\x16\n\x0ein_transaction\x18\x01 \x01(\x08\x12\x34\n\x0eshard_sessions\x18\x02 \x03(\x0b\x32\x1c.vtgate.Session.ShardSession\x1a\x45\n\x0cShardSession\x12\x1d\n\x06target\x18\x01 \x01(\x0b\x32\r.query.Target\x12\x16\n\x0etransaction_id\x18\x02 \x01(\x03\"\xbf\x01\n\x0e\x45xecuteRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12)\n\x0btablet_type\x18\x04 \x01(\x0e\x32\x14.topodata.TabletType\x12\x1a\n\x12not_in_transaction\x18\x05 \x01(\x08\"w\n\x0f\x45xecuteResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12\"\n\x06result\x18\x03 \x01(\x0b\x32\x12.query.QueryResult\"\xe7\x01\n\x14\x45xecuteShardsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x04 \x01(\t\x12\x0e\n\x06shards\x18\x05 \x03(\t\x12)\n\x0btablet_type\x18\x06 \x01(\x0e\x32\x14.topodata.TabletType\x12\x1a\n\x12not_in_transaction\x18\x07 \x01(\x08\"}\n\x15\x45xecuteShardsResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12\"\n\x06result\x18\x03 \x01(\x0b\x32\x12.query.QueryResult\"\xf2\x01\n\x19\x45xecuteKeyspaceIdsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x04 \x01(\t\x12\x14\n\x0ckeyspace_ids\x18\x05 \x03(\x0c\x12)\n\x0btablet_type\x18\x06 \x01(\x0e\x32\x14.topodata.TabletType\x12\x1a\n\x12not_in_transaction\x18\x07 \x01(\x08\"\x82\x01\n\x1a\x45xecuteKeyspaceIdsResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12\"\n\x06result\x18\x03 \x01(\x0b\x32\x12.query.QueryResult\"\x82\x02\n\x17\x45xecuteKeyRangesRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x04 \x01(\t\x12&\n\nkey_ranges\x18\x05 \x03(\x0b\x32\x12.topodata.KeyRange\x12)\n\x0btablet_type\x18\x06 \x01(\x0e\x32\x14.topodata.TabletType\x12\x1a\n\x12not_in_transaction\x18\x07 \x01(\x08\"\x80\x01\n\x18\x45xecuteKeyRangesResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12\"\n\x06result\x18\x03 \x01(\x0b\x32\x12.query.QueryResult\"\x88\x03\n\x17\x45xecuteEntityIdsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x04 \x01(\t\x12\x1a\n\x12\x65ntity_column_name\x18\x05 \x01(\t\x12\x45\n\x13\x65ntity_keyspace_ids\x18\x06 \x03(\x0b\x32(.vtgate.ExecuteEntityIdsRequest.EntityId\x12)\n\x0btablet_type\x18\x07 \x01(\x0e\x32\x14.topodata.TabletType\x12\x1a\n\x12not_in_transaction\x18\x08 \x01(\x08\x1aI\n\x08\x45ntityId\x12\x19\n\x04type\x18\x01 \x01(\x0e\x32\x0b.query.Type\x12\r\n\x05value\x18\x02 \x01(\x0c\x12\x13\n\x0bkeyspace_id\x18\x03 \x01(\x0c\"\x80\x01\n\x18\x45xecuteEntityIdsResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12\"\n\x06result\x18\x03 \x01(\x0b\x32\x12.query.QueryResult\"U\n\x0f\x42oundShardQuery\x12 \n\x05query\x18\x01 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x02 \x01(\t\x12\x0e\n\x06shards\x18\x03 \x03(\t\"\xce\x01\n\x19\x45xecuteBatchShardsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12(\n\x07queries\x18\x03 \x03(\x0b\x32\x17.vtgate.BoundShardQuery\x12)\n\x0btablet_type\x18\x04 \x01(\x0e\x32\x14.topodata.TabletType\x12\x16\n\x0e\x61s_transaction\x18\x05 \x01(\x08\"\x83\x01\n\x1a\x45xecuteBatchShardsResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12#\n\x07results\x18\x03 \x03(\x0b\x32\x12.query.QueryResult\"`\n\x14\x42oundKeyspaceIdQuery\x12 \n\x05query\x18\x01 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x02 \x01(\t\x12\x14\n\x0ckeyspace_ids\x18\x03 \x03(\x0c\"\xd8\x01\n\x1e\x45xecuteBatchKeyspaceIdsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12-\n\x07queries\x18\x03 \x03(\x0b\x32\x1c.vtgate.BoundKeyspaceIdQuery\x12)\n\x0btablet_type\x18\x04 \x01(\x0e\x32\x14.topodata.TabletType\x12\x16\n\x0e\x61s_transaction\x18\x05 \x01(\x08\"\x88\x01\n\x1f\x45xecuteBatchKeyspaceIdsResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12#\n\x07results\x18\x03 \x03(\x0b\x32\x12.query.QueryResult\"\x87\x01\n\x14StreamExecuteRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x05query\x18\x02 \x01(\x0b\x32\x11.query.BoundQuery\x12)\n\x0btablet_type\x18\x03 \x01(\x0e\x32\x14.topodata.TabletType\";\n\x15StreamExecuteResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xaf\x01\n\x1aStreamExecuteShardsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x05query\x18\x02 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x03 \x01(\t\x12\x0e\n\x06shards\x18\x04 \x03(\t\x12)\n\x0btablet_type\x18\x05 \x01(\x0e\x32\x14.topodata.TabletType\"A\n\x1bStreamExecuteShardsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xba\x01\n\x1fStreamExecuteKeyspaceIdsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x05query\x18\x02 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x03 \x01(\t\x12\x14\n\x0ckeyspace_ids\x18\x04 \x03(\x0c\x12)\n\x0btablet_type\x18\x05 \x01(\x0e\x32\x14.topodata.TabletType\"F\n StreamExecuteKeyspaceIdsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xca\x01\n\x1dStreamExecuteKeyRangesRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x05query\x18\x02 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x03 \x01(\t\x12&\n\nkey_ranges\x18\x04 \x03(\x0b\x32\x12.topodata.KeyRange\x12)\n\x0btablet_type\x18\x05 \x01(\x0e\x32\x14.topodata.TabletType\"D\n\x1eStreamExecuteKeyRangesResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"2\n\x0c\x42\x65ginRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\"1\n\rBeginResponse\x12 \n\x07session\x18\x01 \x01(\x0b\x32\x0f.vtgate.Session\"U\n\rCommitRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\"\x10\n\x0e\x43ommitResponse\"W\n\x0fRollbackRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\"\x12\n\x10RollbackResponse\"\x8a\x02\n\x11SplitQueryRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x10\n\x08keyspace\x18\x02 \x01(\t\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12\x14\n\x0csplit_column\x18\x04 \x03(\t\x12\x13\n\x0bsplit_count\x18\x05 \x01(\x03\x12\x1f\n\x17num_rows_per_query_part\x18\x06 \x01(\x03\x12\x35\n\talgorithm\x18\x07 \x01(\x0e\x32\".query.SplitQueryRequest.Algorithm\x12\x1a\n\x12use_split_query_v2\x18\x08 \x01(\x08\"\xf2\x02\n\x12SplitQueryResponse\x12/\n\x06splits\x18\x01 \x03(\x0b\x32\x1f.vtgate.SplitQueryResponse.Part\x1aH\n\x0cKeyRangePart\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12&\n\nkey_ranges\x18\x02 \x03(\x0b\x32\x12.topodata.KeyRange\x1a-\n\tShardPart\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0e\n\x06shards\x18\x02 \x03(\t\x1a\xb1\x01\n\x04Part\x12 \n\x05query\x18\x01 \x01(\x0b\x32\x11.query.BoundQuery\x12?\n\x0ekey_range_part\x18\x02 \x01(\x0b\x32\'.vtgate.SplitQueryResponse.KeyRangePart\x12\x38\n\nshard_part\x18\x03 \x01(\x0b\x32$.vtgate.SplitQueryResponse.ShardPart\x12\x0c\n\x04size\x18\x04 \x01(\x03\")\n\x15GetSrvKeyspaceRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\"E\n\x16GetSrvKeyspaceResponse\x12+\n\x0csrv_keyspace\x18\x01 \x01(\x0b\x32\x15.topodata.SrvKeyspaceB\x1a\n\x18\x63om.youtube.vitess.protob\x06proto3') + serialized_pb=_b('\n\x0cvtgate.proto\x12\x06vtgate\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x0bvtrpc.proto\"\x9e\x01\n\x07Session\x12\x16\n\x0ein_transaction\x18\x01 \x01(\x08\x12\x34\n\x0eshard_sessions\x18\x02 \x03(\x0b\x32\x1c.vtgate.Session.ShardSession\x1a\x45\n\x0cShardSession\x12\x1d\n\x06target\x18\x01 \x01(\x0b\x32\r.query.Target\x12\x16\n\x0etransaction_id\x18\x02 \x01(\x03\"\xd1\x01\n\x0e\x45xecuteRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12)\n\x0btablet_type\x18\x04 \x01(\x0e\x32\x14.topodata.TabletType\x12\x1a\n\x12not_in_transaction\x18\x05 \x01(\x08\x12\x10\n\x08keyspace\x18\x06 \x01(\t\"w\n\x0f\x45xecuteResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12\"\n\x06result\x18\x03 \x01(\x0b\x32\x12.query.QueryResult\"\xe7\x01\n\x14\x45xecuteShardsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x04 \x01(\t\x12\x0e\n\x06shards\x18\x05 \x03(\t\x12)\n\x0btablet_type\x18\x06 \x01(\x0e\x32\x14.topodata.TabletType\x12\x1a\n\x12not_in_transaction\x18\x07 \x01(\x08\"}\n\x15\x45xecuteShardsResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12\"\n\x06result\x18\x03 \x01(\x0b\x32\x12.query.QueryResult\"\xf2\x01\n\x19\x45xecuteKeyspaceIdsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x04 \x01(\t\x12\x14\n\x0ckeyspace_ids\x18\x05 \x03(\x0c\x12)\n\x0btablet_type\x18\x06 \x01(\x0e\x32\x14.topodata.TabletType\x12\x1a\n\x12not_in_transaction\x18\x07 \x01(\x08\"\x82\x01\n\x1a\x45xecuteKeyspaceIdsResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12\"\n\x06result\x18\x03 \x01(\x0b\x32\x12.query.QueryResult\"\x82\x02\n\x17\x45xecuteKeyRangesRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x04 \x01(\t\x12&\n\nkey_ranges\x18\x05 \x03(\x0b\x32\x12.topodata.KeyRange\x12)\n\x0btablet_type\x18\x06 \x01(\x0e\x32\x14.topodata.TabletType\x12\x1a\n\x12not_in_transaction\x18\x07 \x01(\x08\"\x80\x01\n\x18\x45xecuteKeyRangesResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12\"\n\x06result\x18\x03 \x01(\x0b\x32\x12.query.QueryResult\"\x88\x03\n\x17\x45xecuteEntityIdsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x04 \x01(\t\x12\x1a\n\x12\x65ntity_column_name\x18\x05 \x01(\t\x12\x45\n\x13\x65ntity_keyspace_ids\x18\x06 \x03(\x0b\x32(.vtgate.ExecuteEntityIdsRequest.EntityId\x12)\n\x0btablet_type\x18\x07 \x01(\x0e\x32\x14.topodata.TabletType\x12\x1a\n\x12not_in_transaction\x18\x08 \x01(\x08\x1aI\n\x08\x45ntityId\x12\x19\n\x04type\x18\x01 \x01(\x0e\x32\x0b.query.Type\x12\r\n\x05value\x18\x02 \x01(\x0c\x12\x13\n\x0bkeyspace_id\x18\x03 \x01(\x0c\"\x80\x01\n\x18\x45xecuteEntityIdsResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12\"\n\x06result\x18\x03 \x01(\x0b\x32\x12.query.QueryResult\"U\n\x0f\x42oundShardQuery\x12 \n\x05query\x18\x01 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x02 \x01(\t\x12\x0e\n\x06shards\x18\x03 \x03(\t\"\xce\x01\n\x19\x45xecuteBatchShardsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12(\n\x07queries\x18\x03 \x03(\x0b\x32\x17.vtgate.BoundShardQuery\x12)\n\x0btablet_type\x18\x04 \x01(\x0e\x32\x14.topodata.TabletType\x12\x16\n\x0e\x61s_transaction\x18\x05 \x01(\x08\"\x83\x01\n\x1a\x45xecuteBatchShardsResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12#\n\x07results\x18\x03 \x03(\x0b\x32\x12.query.QueryResult\"`\n\x14\x42oundKeyspaceIdQuery\x12 \n\x05query\x18\x01 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x02 \x01(\t\x12\x14\n\x0ckeyspace_ids\x18\x03 \x03(\x0c\"\xd8\x01\n\x1e\x45xecuteBatchKeyspaceIdsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12-\n\x07queries\x18\x03 \x03(\x0b\x32\x1c.vtgate.BoundKeyspaceIdQuery\x12)\n\x0btablet_type\x18\x04 \x01(\x0e\x32\x14.topodata.TabletType\x12\x16\n\x0e\x61s_transaction\x18\x05 \x01(\x08\"\x88\x01\n\x1f\x45xecuteBatchKeyspaceIdsResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\x12#\n\x07results\x18\x03 \x03(\x0b\x32\x12.query.QueryResult\"\x99\x01\n\x14StreamExecuteRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x05query\x18\x02 \x01(\x0b\x32\x11.query.BoundQuery\x12)\n\x0btablet_type\x18\x03 \x01(\x0e\x32\x14.topodata.TabletType\x12\x10\n\x08keyspace\x18\x04 \x01(\t\";\n\x15StreamExecuteResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xaf\x01\n\x1aStreamExecuteShardsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x05query\x18\x02 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x03 \x01(\t\x12\x0e\n\x06shards\x18\x04 \x03(\t\x12)\n\x0btablet_type\x18\x05 \x01(\x0e\x32\x14.topodata.TabletType\"A\n\x1bStreamExecuteShardsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xba\x01\n\x1fStreamExecuteKeyspaceIdsRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x05query\x18\x02 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x03 \x01(\t\x12\x14\n\x0ckeyspace_ids\x18\x04 \x03(\x0c\x12)\n\x0btablet_type\x18\x05 \x01(\x0e\x32\x14.topodata.TabletType\"F\n StreamExecuteKeyspaceIdsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xca\x01\n\x1dStreamExecuteKeyRangesRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x05query\x18\x02 \x01(\x0b\x32\x11.query.BoundQuery\x12\x10\n\x08keyspace\x18\x03 \x01(\t\x12&\n\nkey_ranges\x18\x04 \x03(\x0b\x32\x12.topodata.KeyRange\x12)\n\x0btablet_type\x18\x05 \x01(\x0e\x32\x14.topodata.TabletType\"D\n\x1eStreamExecuteKeyRangesResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"2\n\x0c\x42\x65ginRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\"1\n\rBeginResponse\x12 \n\x07session\x18\x01 \x01(\x0b\x32\x0f.vtgate.Session\"U\n\rCommitRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\"\x10\n\x0e\x43ommitResponse\"W\n\x0fRollbackRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12 \n\x07session\x18\x02 \x01(\x0b\x32\x0f.vtgate.Session\"\x12\n\x10RollbackResponse\"\x8a\x02\n\x11SplitQueryRequest\x12\"\n\tcaller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x10\n\x08keyspace\x18\x02 \x01(\t\x12 \n\x05query\x18\x03 \x01(\x0b\x32\x11.query.BoundQuery\x12\x14\n\x0csplit_column\x18\x04 \x03(\t\x12\x13\n\x0bsplit_count\x18\x05 \x01(\x03\x12\x1f\n\x17num_rows_per_query_part\x18\x06 \x01(\x03\x12\x35\n\talgorithm\x18\x07 \x01(\x0e\x32\".query.SplitQueryRequest.Algorithm\x12\x1a\n\x12use_split_query_v2\x18\x08 \x01(\x08\"\xf2\x02\n\x12SplitQueryResponse\x12/\n\x06splits\x18\x01 \x03(\x0b\x32\x1f.vtgate.SplitQueryResponse.Part\x1aH\n\x0cKeyRangePart\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12&\n\nkey_ranges\x18\x02 \x03(\x0b\x32\x12.topodata.KeyRange\x1a-\n\tShardPart\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0e\n\x06shards\x18\x02 \x03(\t\x1a\xb1\x01\n\x04Part\x12 \n\x05query\x18\x01 \x01(\x0b\x32\x11.query.BoundQuery\x12?\n\x0ekey_range_part\x18\x02 \x01(\x0b\x32\'.vtgate.SplitQueryResponse.KeyRangePart\x12\x38\n\nshard_part\x18\x03 \x01(\x0b\x32$.vtgate.SplitQueryResponse.ShardPart\x12\x0c\n\x04size\x18\x04 \x01(\x03\")\n\x15GetSrvKeyspaceRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\"E\n\x16GetSrvKeyspaceResponse\x12+\n\x0csrv_keyspace\x18\x01 \x01(\x0b\x32\x15.topodata.SrvKeyspaceB\x1a\n\x18\x63om.youtube.vitess.protob\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,vtrpc__pb2.DESCRIPTOR,]) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -147,6 +147,13 @@ _EXECUTEREQUEST = _descriptor.Descriptor( message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), + _descriptor.FieldDescriptor( + name='keyspace', full_name='vtgate.ExecuteRequest.keyspace', index=5, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), ], extensions=[ ], @@ -160,7 +167,7 @@ _EXECUTEREQUEST = _descriptor.Descriptor( oneofs=[ ], serialized_start=228, - serialized_end=419, + serialized_end=437, ) @@ -204,8 +211,8 @@ _EXECUTERESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=421, - serialized_end=540, + serialized_start=439, + serialized_end=558, ) @@ -277,8 +284,8 @@ _EXECUTESHARDSREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=543, - serialized_end=774, + serialized_start=561, + serialized_end=792, ) @@ -322,8 +329,8 @@ _EXECUTESHARDSRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=776, - serialized_end=901, + serialized_start=794, + serialized_end=919, ) @@ -395,8 +402,8 @@ _EXECUTEKEYSPACEIDSREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=904, - serialized_end=1146, + serialized_start=922, + serialized_end=1164, ) @@ -440,8 +447,8 @@ _EXECUTEKEYSPACEIDSRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1149, - serialized_end=1279, + serialized_start=1167, + serialized_end=1297, ) @@ -513,8 +520,8 @@ _EXECUTEKEYRANGESREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1282, - serialized_end=1540, + serialized_start=1300, + serialized_end=1558, ) @@ -558,8 +565,8 @@ _EXECUTEKEYRANGESRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1543, - serialized_end=1671, + serialized_start=1561, + serialized_end=1689, ) @@ -603,8 +610,8 @@ _EXECUTEENTITYIDSREQUEST_ENTITYID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1993, - serialized_end=2066, + serialized_start=2011, + serialized_end=2084, ) _EXECUTEENTITYIDSREQUEST = _descriptor.Descriptor( @@ -682,8 +689,8 @@ _EXECUTEENTITYIDSREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1674, - serialized_end=2066, + serialized_start=1692, + serialized_end=2084, ) @@ -727,8 +734,8 @@ _EXECUTEENTITYIDSRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2069, - serialized_end=2197, + serialized_start=2087, + serialized_end=2215, ) @@ -772,8 +779,8 @@ _BOUNDSHARDQUERY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2199, - serialized_end=2284, + serialized_start=2217, + serialized_end=2302, ) @@ -831,8 +838,8 @@ _EXECUTEBATCHSHARDSREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2287, - serialized_end=2493, + serialized_start=2305, + serialized_end=2511, ) @@ -876,8 +883,8 @@ _EXECUTEBATCHSHARDSRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2496, - serialized_end=2627, + serialized_start=2514, + serialized_end=2645, ) @@ -921,8 +928,8 @@ _BOUNDKEYSPACEIDQUERY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2629, - serialized_end=2725, + serialized_start=2647, + serialized_end=2743, ) @@ -980,8 +987,8 @@ _EXECUTEBATCHKEYSPACEIDSREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2728, - serialized_end=2944, + serialized_start=2746, + serialized_end=2962, ) @@ -1025,8 +1032,8 @@ _EXECUTEBATCHKEYSPACEIDSRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2947, - serialized_end=3083, + serialized_start=2965, + serialized_end=3101, ) @@ -1058,6 +1065,13 @@ _STREAMEXECUTEREQUEST = _descriptor.Descriptor( message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), + _descriptor.FieldDescriptor( + name='keyspace', full_name='vtgate.StreamExecuteRequest.keyspace', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), ], extensions=[ ], @@ -1070,8 +1084,8 @@ _STREAMEXECUTEREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3086, - serialized_end=3221, + serialized_start=3104, + serialized_end=3257, ) @@ -1101,8 +1115,8 @@ _STREAMEXECUTERESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3223, - serialized_end=3282, + serialized_start=3259, + serialized_end=3318, ) @@ -1160,8 +1174,8 @@ _STREAMEXECUTESHARDSREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3285, - serialized_end=3460, + serialized_start=3321, + serialized_end=3496, ) @@ -1191,8 +1205,8 @@ _STREAMEXECUTESHARDSRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3462, - serialized_end=3527, + serialized_start=3498, + serialized_end=3563, ) @@ -1250,8 +1264,8 @@ _STREAMEXECUTEKEYSPACEIDSREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3530, - serialized_end=3716, + serialized_start=3566, + serialized_end=3752, ) @@ -1281,8 +1295,8 @@ _STREAMEXECUTEKEYSPACEIDSRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3718, - serialized_end=3788, + serialized_start=3754, + serialized_end=3824, ) @@ -1340,8 +1354,8 @@ _STREAMEXECUTEKEYRANGESREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3791, - serialized_end=3993, + serialized_start=3827, + serialized_end=4029, ) @@ -1371,8 +1385,8 @@ _STREAMEXECUTEKEYRANGESRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3995, - serialized_end=4063, + serialized_start=4031, + serialized_end=4099, ) @@ -1402,8 +1416,8 @@ _BEGINREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4065, - serialized_end=4115, + serialized_start=4101, + serialized_end=4151, ) @@ -1433,8 +1447,8 @@ _BEGINRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4117, - serialized_end=4166, + serialized_start=4153, + serialized_end=4202, ) @@ -1471,8 +1485,8 @@ _COMMITREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4168, - serialized_end=4253, + serialized_start=4204, + serialized_end=4289, ) @@ -1495,8 +1509,8 @@ _COMMITRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4255, - serialized_end=4271, + serialized_start=4291, + serialized_end=4307, ) @@ -1533,8 +1547,8 @@ _ROLLBACKREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4273, - serialized_end=4360, + serialized_start=4309, + serialized_end=4396, ) @@ -1557,8 +1571,8 @@ _ROLLBACKRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4362, - serialized_end=4380, + serialized_start=4398, + serialized_end=4416, ) @@ -1637,8 +1651,8 @@ _SPLITQUERYREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4383, - serialized_end=4649, + serialized_start=4419, + serialized_end=4685, ) @@ -1675,8 +1689,8 @@ _SPLITQUERYRESPONSE_KEYRANGEPART = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4723, - serialized_end=4795, + serialized_start=4759, + serialized_end=4831, ) _SPLITQUERYRESPONSE_SHARDPART = _descriptor.Descriptor( @@ -1712,8 +1726,8 @@ _SPLITQUERYRESPONSE_SHARDPART = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4797, - serialized_end=4842, + serialized_start=4833, + serialized_end=4878, ) _SPLITQUERYRESPONSE_PART = _descriptor.Descriptor( @@ -1763,8 +1777,8 @@ _SPLITQUERYRESPONSE_PART = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4845, - serialized_end=5022, + serialized_start=4881, + serialized_end=5058, ) _SPLITQUERYRESPONSE = _descriptor.Descriptor( @@ -1793,8 +1807,8 @@ _SPLITQUERYRESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=4652, - serialized_end=5022, + serialized_start=4688, + serialized_end=5058, ) @@ -1824,8 +1838,8 @@ _GETSRVKEYSPACEREQUEST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=5024, - serialized_end=5065, + serialized_start=5060, + serialized_end=5101, ) @@ -1855,8 +1869,8 @@ _GETSRVKEYSPACERESPONSE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=5067, - serialized_end=5136, + serialized_start=5103, + serialized_end=5172, ) _SESSION_SHARDSESSION.fields_by_name['target'].message_type = query__pb2._TARGET diff --git a/test/vtgatev3_test.py b/test/vtgatev3_test.py index 0b9be504a0..a028bd4283 100755 --- a/test/vtgatev3_test.py +++ b/test/vtgatev3_test.py @@ -126,7 +126,7 @@ vschema = '''{ "Owner": "vt_music" } }, - "Classes": { + "Tables": { "vt_user": { "ColVindexes": [ { @@ -203,29 +203,19 @@ vschema = '''{ } ] } - }, - "Tables": { - "vt_user": "vt_user", - "vt_user2": "vt_user2", - "vt_user_extra": "vt_user_extra", - "vt_music": "vt_music", - "vt_music_extra": "vt_music_extra", - "join_user": "join_user", - "join_user_extra": "join_user_extra" } }, "lookup": { "Sharded": false, - "Classes" : { - "seq": { - "Type": "Sequence" - } - }, "Tables": { - "vt_user_seq": "seq", - "vt_music_seq": "seq", - "music_user_map": "", - "name_user2_map": "" + "vt_user_seq": { + "Type": "Sequence" + }, + "vt_music_seq": { + "Type": "Sequence" + }, + "music_user_map": {}, + "name_user2_map": {} } } }