зеркало из https://github.com/github/vitess-gh.git
Коммит
0698355fb7
|
@ -6,6 +6,21 @@
|
||||||
"delete from nouser"
|
"delete from nouser"
|
||||||
"table nouser not found"
|
"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 unsharded
|
||||||
"update main1 set val = 1"
|
"update main1 set val = 1"
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
# duplicate symbols
|
||||||
"select user.id from user join user"
|
"select user.id from user join user"
|
||||||
"duplicate symbol: user"
|
"duplicate symbol: user"
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
"Owner": "user"
|
"Owner": "user"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Classes": {
|
"Tables": {
|
||||||
"user": {
|
"user": {
|
||||||
"ColVindexes": [
|
"ColVindexes": [
|
||||||
{
|
{
|
||||||
|
@ -77,23 +77,14 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"Tables": {
|
|
||||||
"user": "user",
|
|
||||||
"user_extra": "user_extra",
|
|
||||||
"music": "music",
|
|
||||||
"music_extra": "music_extra"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"main": {
|
"main": {
|
||||||
"Classes": {
|
"Tables": {
|
||||||
|
"main1": {},
|
||||||
"seq": {
|
"seq": {
|
||||||
"Type": "Sequence"
|
"Type": "Sequence"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"Tables": {
|
|
||||||
"main1": "",
|
|
||||||
"seq": "seq"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,10 +146,6 @@
|
||||||
"delete from user where col = (select id from main1)"
|
"delete from user where col = (select id from main1)"
|
||||||
"unsupported: subqueries in DML"
|
"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 with no where clause
|
||||||
"update user set val = 1"
|
"update user set val = 1"
|
||||||
"unsupported: multi-shard where clause in DML"
|
"unsupported: multi-shard where clause in DML"
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
"Type": "numeric"
|
"Type": "numeric"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Classes": {
|
"Tables": {
|
||||||
"user": {
|
"user": {
|
||||||
"ColVindexes": [
|
"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": {
|
"lookup": {
|
||||||
"Sharded": false,
|
"Sharded": false,
|
||||||
"Classes": {
|
|
||||||
"seq": {
|
|
||||||
"Type": "Sequence"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Tables": {
|
"Tables": {
|
||||||
"user_seq": "seq",
|
"user_seq": {
|
||||||
"music_seq": "seq",
|
"Type": "Sequence"
|
||||||
"name_user_idx": ""
|
},
|
||||||
|
"music_seq": {
|
||||||
|
"Type": "Sequence"
|
||||||
|
},
|
||||||
|
"name_user_idx": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,11 +65,11 @@ func (c *callerIDClient) checkCallerID(ctx context.Context, received string) (bo
|
||||||
return true, fmt.Errorf("SUCCESS: callerid matches")
|
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 {
|
if ok, err := c.checkCallerID(ctx, sql); ok {
|
||||||
return nil, err
|
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) {
|
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)
|
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 {
|
if ok, err := c.checkCallerID(ctx, sql); ok {
|
||||||
return err
|
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 {
|
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 {
|
||||||
|
|
|
@ -86,18 +86,19 @@ func echoQueryResult(vals map[string]interface{}) *sqltypes.Result {
|
||||||
return qr
|
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) {
|
if strings.HasPrefix(sql, EchoPrefix) {
|
||||||
return echoQueryResult(map[string]interface{}{
|
return echoQueryResult(map[string]interface{}{
|
||||||
"callerId": callerid.EffectiveCallerIDFromContext(ctx),
|
"callerId": callerid.EffectiveCallerIDFromContext(ctx),
|
||||||
"query": sql,
|
"query": sql,
|
||||||
"bindVars": bindVariables,
|
"bindVars": bindVariables,
|
||||||
|
"keyspace": keyspace,
|
||||||
"tabletType": tabletType,
|
"tabletType": tabletType,
|
||||||
"session": session,
|
"session": session,
|
||||||
"notInTransaction": notInTransaction,
|
"notInTransaction": notInTransaction,
|
||||||
}), nil
|
}), 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) {
|
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)
|
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) {
|
if strings.HasPrefix(sql, EchoPrefix) {
|
||||||
sendReply(echoQueryResult(map[string]interface{}{
|
sendReply(echoQueryResult(map[string]interface{}{
|
||||||
"callerId": callerid.EffectiveCallerIDFromContext(ctx),
|
"callerId": callerid.EffectiveCallerIDFromContext(ctx),
|
||||||
"query": sql,
|
"query": sql,
|
||||||
"bindVars": bindVariables,
|
"bindVars": bindVariables,
|
||||||
|
"keyspace": keyspace,
|
||||||
"tabletType": tabletType,
|
"tabletType": tabletType,
|
||||||
}))
|
}))
|
||||||
return nil
|
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 {
|
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 {
|
||||||
|
|
|
@ -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 {
|
if err := requestToPartialError(sql, session); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := requestToError(sql); err != nil {
|
if err := requestToError(sql); err != nil {
|
||||||
return nil, err
|
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) {
|
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)
|
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 {
|
if err := requestToError(sql); err != nil {
|
||||||
return err
|
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 {
|
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 {
|
||||||
|
|
|
@ -27,8 +27,8 @@ func newFallbackClient(fallback vtgateservice.VTGateService) fallbackClient {
|
||||||
return fallbackClient{fallback: fallback}
|
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) {
|
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, tabletType, session, notInTransaction)
|
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) {
|
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)
|
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 {
|
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, tabletType, sendReply)
|
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 {
|
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 {
|
||||||
|
|
|
@ -29,7 +29,7 @@ func newTerminalClient() *terminalClient {
|
||||||
return &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://" {
|
if sql == "quit://" {
|
||||||
log.Fatal("Received quit:// query. Going down.")
|
log.Fatal("Received quit:// query. Going down.")
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ func (c *terminalClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries []
|
||||||
return nil, errTerminal
|
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
|
return errTerminal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"`
|
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.
|
// 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"`
|
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{} }
|
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"`
|
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.
|
// 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"`
|
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{} }
|
func (m *StreamExecuteRequest) Reset() { *m = StreamExecuteRequest{} }
|
||||||
|
@ -1376,87 +1380,88 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptor0 = []byte{
|
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,
|
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,
|
0x14, 0x97, 0xe3, 0x34, 0x69, 0x9e, 0x93, 0xb4, 0xeb, 0x6d, 0x77, 0x43, 0x58, 0xb6, 0xc5, 0x02,
|
||||||
0x5b, 0x60, 0x65, 0x69, 0xb3, 0xfc, 0x13, 0x42, 0x02, 0x1a, 0x2a, 0x14, 0x2d, 0xac, 0xca, 0xb4,
|
0x6d, 0x81, 0x95, 0xa5, 0xcd, 0xf2, 0x4f, 0x08, 0x09, 0x68, 0xa8, 0x50, 0xb4, 0xb0, 0x2a, 0xd3,
|
||||||
0x42, 0x1c, 0x40, 0x96, 0x9b, 0x8c, 0x5a, 0xd3, 0xc4, 0x0e, 0x9e, 0x71, 0xa0, 0x1c, 0xb8, 0x21,
|
0x0a, 0x71, 0x00, 0x59, 0x6e, 0x32, 0x6a, 0x4d, 0x13, 0x3b, 0x78, 0xc6, 0x81, 0x72, 0xe0, 0x86,
|
||||||
0x71, 0xdb, 0x13, 0x12, 0x42, 0x5c, 0x90, 0xf8, 0x02, 0x7c, 0x04, 0x4e, 0x1c, 0x39, 0x70, 0xe0,
|
0xc4, 0x6d, 0x0f, 0x08, 0x09, 0x21, 0x2e, 0x7c, 0x04, 0xbe, 0x01, 0x9c, 0x38, 0x72, 0xe0, 0xc0,
|
||||||
0xc6, 0x47, 0x80, 0x23, 0x17, 0x0e, 0x8c, 0x67, 0xc6, 0x7f, 0xe2, 0x36, 0x69, 0x9a, 0xb4, 0x55,
|
0x8d, 0x8f, 0x00, 0x5f, 0x80, 0x03, 0xe3, 0x99, 0xf1, 0x9f, 0xb8, 0x49, 0x9a, 0x26, 0x6d, 0x95,
|
||||||
0x7a, 0xaa, 0x67, 0xde, 0x9b, 0x79, 0xef, 0xfd, 0x7e, 0x6f, 0xde, 0xcc, 0x6b, 0xa0, 0x3c, 0xa0,
|
0x9e, 0xea, 0x99, 0xf7, 0x66, 0xde, 0x7b, 0xbf, 0xdf, 0x9b, 0x37, 0xf3, 0x1a, 0x28, 0x0f, 0xe8,
|
||||||
0x87, 0x36, 0xc5, 0x66, 0xdf, 0xf7, 0xa8, 0xa7, 0x17, 0xc4, 0xa8, 0xae, 0x7d, 0x1e, 0x60, 0xff,
|
0xa1, 0x4d, 0xb1, 0xd9, 0xf7, 0x3d, 0xea, 0xe9, 0x05, 0x31, 0xaa, 0x6b, 0x9f, 0x07, 0xd8, 0x3f,
|
||||||
0x44, 0x4c, 0xd6, 0xab, 0xd4, 0xeb, 0x7b, 0x1d, 0x9b, 0xda, 0x72, 0xac, 0x0d, 0xa8, 0xdf, 0x6f,
|
0x11, 0x93, 0xf5, 0x2a, 0xf5, 0xfa, 0x5e, 0xc7, 0xa6, 0xb6, 0x1c, 0x6b, 0x03, 0xea, 0xf7, 0xdb,
|
||||||
0x8b, 0x81, 0xf1, 0x87, 0x02, 0xc5, 0x3d, 0x4c, 0x88, 0xe3, 0xb9, 0xfa, 0xf3, 0x50, 0x75, 0x5c,
|
0x62, 0x60, 0xfc, 0xa9, 0x40, 0x71, 0x0f, 0x13, 0xe2, 0x78, 0xae, 0xfe, 0x3c, 0x54, 0x1d, 0xd7,
|
||||||
0x8b, 0xfa, 0xb6, 0x4b, 0xec, 0x36, 0x65, 0x33, 0x35, 0x65, 0x53, 0xd9, 0x5a, 0x44, 0x15, 0xc7,
|
0xa2, 0xbe, 0xed, 0x12, 0xbb, 0x4d, 0xd9, 0x4c, 0x4d, 0xd9, 0x54, 0xb6, 0x96, 0x51, 0xc5, 0x71,
|
||||||
0xdd, 0x4f, 0x26, 0xf5, 0x26, 0x54, 0xc9, 0x91, 0xed, 0x77, 0x2c, 0x22, 0xd6, 0x91, 0x5a, 0x6e,
|
0xf7, 0x93, 0x49, 0xbd, 0x09, 0x55, 0x72, 0x64, 0xfb, 0x1d, 0x8b, 0x88, 0x75, 0xa4, 0x96, 0xdb,
|
||||||
0x53, 0xdd, 0xd2, 0x1a, 0x77, 0x4c, 0xe9, 0x8b, 0xdc, 0xcf, 0xdc, 0x0b, 0xb5, 0xe4, 0x00, 0x55,
|
0x54, 0xb7, 0xb4, 0xc6, 0x1d, 0x53, 0xfa, 0x22, 0xf7, 0x33, 0xf7, 0x42, 0x2d, 0x39, 0x40, 0x15,
|
||||||
0x48, 0x6a, 0x44, 0xea, 0x9f, 0x40, 0x39, 0x2d, 0x66, 0xb6, 0x0b, 0xd4, 0xf6, 0x0f, 0x31, 0xe5,
|
0x92, 0x1a, 0x91, 0xfa, 0x27, 0x50, 0x4e, 0x8b, 0x99, 0xed, 0x02, 0xb5, 0xfd, 0x43, 0x4c, 0xb9,
|
||||||
0x36, 0xb5, 0x46, 0xc5, 0x14, 0x21, 0xec, 0xf3, 0x49, 0x24, 0x85, 0xa1, 0x8b, 0x29, 0xff, 0x2c,
|
0x4d, 0xad, 0x51, 0x31, 0x45, 0x08, 0xfb, 0x7c, 0x12, 0x49, 0x61, 0xe8, 0x62, 0xca, 0x3f, 0xcb,
|
||||||
0xa7, 0xc3, 0x6c, 0x2b, 0x5b, 0x2a, 0xaa, 0xa4, 0x66, 0x5b, 0x1d, 0xe3, 0x5f, 0x05, 0xaa, 0x3b,
|
0xe9, 0x30, 0xdb, 0xca, 0x96, 0x8a, 0x2a, 0xa9, 0xd9, 0x56, 0xc7, 0xf8, 0x2e, 0x07, 0xd5, 0x9d,
|
||||||
0x5f, 0xe2, 0x76, 0x40, 0x31, 0xc2, 0x6c, 0x23, 0x42, 0xf5, 0xfb, 0x50, 0x6a, 0xdb, 0xdd, 0x2e,
|
0x2f, 0x71, 0x3b, 0xa0, 0x18, 0x61, 0xb6, 0x11, 0xa1, 0xfa, 0x7d, 0x28, 0xb5, 0xed, 0x6e, 0x17,
|
||||||
0xf6, 0xc3, 0x45, 0xc2, 0xc6, 0x92, 0x29, 0x90, 0x68, 0xf2, 0xf9, 0xd6, 0xbb, 0x68, 0x51, 0x68,
|
0xfb, 0xe1, 0x22, 0x61, 0x63, 0xc5, 0x14, 0x48, 0x34, 0xf9, 0x7c, 0xeb, 0x5d, 0xb4, 0x2c, 0x34,
|
||||||
0xb4, 0x3a, 0xfa, 0x0b, 0x50, 0x94, 0xd1, 0x71, 0x03, 0x42, 0x37, 0x1d, 0x1c, 0x8a, 0xe4, 0xfa,
|
0x5a, 0x1d, 0xfd, 0x05, 0x28, 0xca, 0xe8, 0xb8, 0x01, 0xa1, 0x9b, 0x0e, 0x0e, 0x45, 0x72, 0xfd,
|
||||||
0x3d, 0x58, 0xe0, 0xae, 0xd6, 0x54, 0xae, 0xb8, 0x22, 0x1d, 0xdf, 0xf6, 0x02, 0xb7, 0xf3, 0x61,
|
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,
|
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,
|
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, 0x70, 0x66, 0x96, 0x99, 0xa4, 0x95, 0x26,
|
0x9b, 0x39, 0xae, 0xbb, 0x1e, 0xb5, 0x32, 0xcc, 0x2c, 0x71, 0x66, 0x56, 0x99, 0xa4, 0x35, 0x44,
|
||||||
0xc7, 0x78, 0xa2, 0xc0, 0x52, 0x1c, 0x39, 0xe9, 0x33, 0xa8, 0x31, 0x03, 0x6d, 0x01, 0xfb, 0xbe,
|
0x4e, 0x1d, 0x96, 0x8f, 0xf1, 0x09, 0xe9, 0xdb, 0x6d, 0x5c, 0x2b, 0x30, 0x9d, 0x12, 0x8a, 0xc7,
|
||||||
0xe7, 0x67, 0xc2, 0x46, 0xbb, 0xcd, 0x9d, 0x70, 0x1a, 0x09, 0xe9, 0x45, 0x62, 0x7e, 0x11, 0x0a,
|
0xc6, 0x13, 0x05, 0x56, 0x62, 0x54, 0x48, 0x9f, 0xd1, 0x80, 0x19, 0xa0, 0x4b, 0xd8, 0xf7, 0x3d,
|
||||||
0x3e, 0x26, 0x41, 0x97, 0xca, 0xa0, 0x75, 0x19, 0xb4, 0x88, 0x97, 0x4b, 0x90, 0xd4, 0x30, 0x7e,
|
0x3f, 0x03, 0x09, 0xda, 0x6d, 0xee, 0x84, 0xd3, 0x48, 0x48, 0xcf, 0x83, 0xc7, 0x8b, 0x50, 0xf0,
|
||||||
0xc9, 0xc1, 0xaa, 0xf4, 0x88, 0x33, 0x4e, 0xe6, 0x87, 0x91, 0x3a, 0x2c, 0x1e, 0xe3, 0x13, 0xd2,
|
0x31, 0x09, 0xba, 0x54, 0x02, 0xa2, 0x4b, 0x40, 0x04, 0x16, 0x5c, 0x82, 0xa4, 0x86, 0xf1, 0x4b,
|
||||||
0xb7, 0xdb, 0x82, 0x8e, 0x12, 0x8a, 0xc7, 0xfa, 0x6d, 0x28, 0xf0, 0x8c, 0x25, 0x0c, 0x6a, 0x95,
|
0x0e, 0xd6, 0xa4, 0x47, 0x3c, 0x1b, 0xc8, 0xe2, 0xb0, 0x95, 0x06, 0x32, 0x3f, 0x0c, 0xa4, 0x7e,
|
||||||
0x49, 0xe4, 0x28, 0xcb, 0x62, 0x61, 0x26, 0x16, 0x8b, 0x23, 0x58, 0xfc, 0x4e, 0x81, 0xb5, 0x0c,
|
0x0b, 0x0a, 0x3c, 0x9b, 0x09, 0xa3, 0x41, 0x65, 0x12, 0x39, 0xca, 0x32, 0x5c, 0x98, 0x8b, 0xe1,
|
||||||
0x66, 0x73, 0xc1, 0xe5, 0xaf, 0x39, 0x78, 0x4a, 0xfa, 0xf5, 0x48, 0x02, 0xd5, 0xba, 0x29, 0x84,
|
0xe2, 0x68, 0x86, 0x8d, 0xef, 0x15, 0x58, 0xcf, 0x60, 0xb6, 0x10, 0x5c, 0xfe, 0x96, 0x83, 0xa7,
|
||||||
0x3e, 0x0b, 0xe5, 0xe8, 0x9b, 0xf9, 0x27, 0x68, 0x2d, 0x23, 0xed, 0x38, 0x89, 0xe3, 0x7a, 0xb8,
|
0xa4, 0x5f, 0x8f, 0x24, 0x50, 0xad, 0xeb, 0x42, 0xe8, 0xb3, 0x50, 0x8e, 0xbe, 0x99, 0x7f, 0x82,
|
||||||
0xfd, 0x41, 0x81, 0xfa, 0x59, 0x18, 0xce, 0x05, 0xc1, 0xbf, 0xe7, 0x60, 0x3d, 0x71, 0x0e, 0xd9,
|
0xd6, 0x32, 0xd2, 0x8e, 0x93, 0x38, 0xae, 0x86, 0xdb, 0x1f, 0x15, 0xa8, 0x8f, 0xc2, 0x70, 0x21,
|
||||||
0xee, 0x21, 0xbe, 0x21, 0xf4, 0x3e, 0x00, 0x60, 0xdf, 0x96, 0xcf, 0x5d, 0xe6, 0xe4, 0x86, 0x91,
|
0x08, 0xfe, 0x23, 0x07, 0xb7, 0x13, 0xe7, 0x90, 0xed, 0x1e, 0xe2, 0x6b, 0x42, 0xef, 0x03, 0x00,
|
||||||
0xc6, 0xd4, 0x45, 0xd1, 0xa0, 0xd2, 0x71, 0x14, 0xd7, 0xf5, 0xd0, 0xfd, 0xbd, 0x02, 0xb5, 0xd3,
|
0xf6, 0x6d, 0xf9, 0xdc, 0x65, 0x4e, 0x6e, 0x18, 0x69, 0x4c, 0x5d, 0x14, 0x0d, 0x2a, 0x1d, 0x47,
|
||||||
0x88, 0xce, 0x05, 0xd9, 0xdf, 0xe6, 0x63, 0xb2, 0x77, 0x5c, 0xea, 0xd0, 0x93, 0x1b, 0x73, 0x96,
|
0x71, 0x5d, 0x0d, 0xdd, 0x3f, 0x28, 0x50, 0x3b, 0x8d, 0xe8, 0x42, 0x90, 0xfd, 0x6d, 0x3e, 0x26,
|
||||||
0x19, 0x05, 0x98, 0x7b, 0x6c, 0xb5, 0xbd, 0x6e, 0xd0, 0x73, 0x2d, 0xd7, 0xee, 0x61, 0x7e, 0x27,
|
0x7b, 0xc7, 0xa5, 0x0e, 0x3d, 0xb9, 0x36, 0x67, 0x99, 0x51, 0x80, 0xb9, 0xc7, 0x56, 0xdb, 0xeb,
|
||||||
0x96, 0xd0, 0xb2, 0x90, 0x34, 0xb9, 0xe0, 0x31, 0x9b, 0xd7, 0x3f, 0x86, 0x5b, 0x52, 0x7b, 0xa8,
|
0x06, 0x3d, 0xd7, 0x72, 0xed, 0x1e, 0xe6, 0xf7, 0x65, 0x09, 0xad, 0x0a, 0x49, 0x93, 0x0b, 0x1e,
|
||||||
0x00, 0x14, 0x78, 0x8e, 0x6c, 0x45, 0x9e, 0x8e, 0x40, 0xc2, 0x8c, 0x26, 0xd0, 0x8a, 0xd8, 0xe4,
|
0xb3, 0x79, 0xfd, 0x63, 0xb8, 0x29, 0xb5, 0x87, 0x0a, 0x40, 0x81, 0xe7, 0xc8, 0x56, 0xe4, 0xe9,
|
||||||
0xd1, 0xe8, 0x82, 0x51, 0x9c, 0x29, 0x83, 0x16, 0xcf, 0xce, 0xa0, 0xfa, 0x01, 0x2c, 0x46, 0x3e,
|
0x18, 0x24, 0xcc, 0x68, 0x02, 0xdd, 0x10, 0x9b, 0x3c, 0x1a, 0x5f, 0x30, 0x8a, 0x73, 0x65, 0xd0,
|
||||||
0xe8, 0x1b, 0x90, 0xe7, 0x96, 0x14, 0x6e, 0x49, 0x8b, 0x1e, 0x49, 0xa1, 0x01, 0x2e, 0xd0, 0x57,
|
0xf2, 0xe8, 0x0c, 0xaa, 0x1f, 0xc0, 0x72, 0xe4, 0x83, 0xbe, 0x01, 0x79, 0x6e, 0x49, 0xe1, 0x96,
|
||||||
0x61, 0x61, 0x60, 0x77, 0x03, 0xcc, 0x79, 0x28, 0x23, 0x31, 0x60, 0xcb, 0xb4, 0x54, 0xe8, 0x1c,
|
0xb4, 0xe8, 0x01, 0x15, 0x1a, 0xe0, 0x02, 0x7d, 0x0d, 0x96, 0x06, 0x76, 0x37, 0xc0, 0x9c, 0x87,
|
||||||
0xfa, 0x32, 0x82, 0xa4, 0xf4, 0xa5, 0xb3, 0x34, 0x05, 0xc0, 0x5c, 0x64, 0xa9, 0x0b, 0x4b, 0x3c,
|
0x32, 0x12, 0x03, 0xb6, 0x4c, 0x4b, 0x85, 0xce, 0xa1, 0x2f, 0x23, 0x48, 0x4a, 0x5f, 0x3a, 0x4b,
|
||||||
0x39, 0xf8, 0x45, 0xc8, 0x15, 0x92, 0x1c, 0x52, 0x2e, 0x90, 0x43, 0xb9, 0x91, 0x17, 0xbc, 0x9a,
|
0x53, 0x00, 0x2c, 0x44, 0x96, 0xba, 0xb0, 0xc2, 0x93, 0x83, 0x5f, 0x84, 0x5c, 0x21, 0xc9, 0x21,
|
||||||
0xbe, 0xe0, 0x8d, 0x6f, 0x92, 0x3b, 0x6e, 0xdb, 0xa6, 0xed, 0xa3, 0x6b, 0x7a, 0xb4, 0x3c, 0x80,
|
0xe5, 0x1c, 0x39, 0x94, 0x1b, 0x7b, 0xc1, 0xab, 0xe9, 0x0b, 0xde, 0xf8, 0x26, 0xb9, 0xe3, 0xb6,
|
||||||
0x62, 0xe8, 0xb3, 0x83, 0x85, 0x3f, 0x5a, 0x63, 0x3d, 0x52, 0xcd, 0x44, 0x8f, 0x22, 0xbd, 0x69,
|
0x6d, 0xda, 0x3e, 0xba, 0xa2, 0x47, 0xcb, 0x03, 0x28, 0x86, 0x3e, 0x3b, 0x58, 0xf8, 0xa3, 0x35,
|
||||||
0x1f, 0x94, 0xec, 0x0d, 0x6d, 0x93, 0x33, 0x1e, 0x93, 0x15, 0x9b, 0xa4, 0x0b, 0xd7, 0x8f, 0xc9,
|
0x6e, 0x47, 0xaa, 0x99, 0xe8, 0x51, 0xa4, 0x37, 0xeb, 0x63, 0x93, 0xbd, 0xaf, 0x6d, 0x32, 0xe2,
|
||||||
0x3d, 0x35, 0x84, 0xc3, 0x95, 0x25, 0xc5, 0x7d, 0x28, 0x0a, 0xca, 0x23, 0x04, 0xce, 0xca, 0x8a,
|
0xa1, 0x59, 0xb1, 0x49, 0xba, 0x70, 0xfd, 0x94, 0xdc, 0x53, 0x43, 0x38, 0x5c, 0x5a, 0x52, 0xdc,
|
||||||
0x48, 0xc5, 0xf8, 0x1a, 0x56, 0x39, 0x30, 0xc9, 0x71, 0xbc, 0xc4, 0xdc, 0xc8, 0xbe, 0x15, 0xd4,
|
0x87, 0xa2, 0xa0, 0x3c, 0x42, 0x60, 0x54, 0x56, 0x44, 0x2a, 0xc6, 0xd7, 0xb0, 0xc6, 0x81, 0x49,
|
||||||
0x53, 0x6f, 0x05, 0xe3, 0x49, 0x0e, 0xee, 0xa6, 0xe1, 0xb9, 0xce, 0xf7, 0xd0, 0xab, 0xd9, 0x5c,
|
0x8e, 0xe3, 0x05, 0xe6, 0x46, 0xf6, 0xad, 0xa0, 0x9e, 0x7a, 0x2b, 0x18, 0x4f, 0x72, 0x70, 0x37,
|
||||||
0xb9, 0x33, 0x94, 0x2b, 0x19, 0x48, 0xae, 0x2b, 0x61, 0x7e, 0x52, 0x60, 0x63, 0x24, 0x22, 0x73,
|
0x0d, 0xcf, 0x55, 0xbe, 0x87, 0x5e, 0xcd, 0xe6, 0xca, 0x9d, 0xa1, 0x5c, 0xc9, 0x40, 0x72, 0x55,
|
||||||
0x92, 0x35, 0x3f, 0x2b, 0xb0, 0xba, 0x47, 0x7d, 0x6c, 0xf7, 0x66, 0x6a, 0x0f, 0xe3, 0x24, 0xcb,
|
0x09, 0xf3, 0xb3, 0x02, 0x1b, 0x63, 0x11, 0x59, 0x90, 0xac, 0xf9, 0x55, 0x81, 0xb5, 0x3d, 0xea,
|
||||||
0x5d, 0xac, 0xe7, 0x53, 0x27, 0x43, 0xdc, 0x68, 0xc2, 0x5a, 0xc6, 0x4b, 0x89, 0x5f, 0x52, 0x38,
|
0x63, 0xbb, 0x37, 0x57, 0xeb, 0x18, 0x27, 0x59, 0xee, 0x7c, 0xfd, 0xa0, 0x3a, 0x25, 0xe2, 0x13,
|
||||||
0x95, 0x73, 0x0b, 0xe7, 0x5f, 0xec, 0x00, 0x0f, 0xed, 0x32, 0x4b, 0x25, 0x9b, 0x38, 0xe2, 0xf4,
|
0xee, 0x3e, 0xa3, 0x09, 0xeb, 0x99, 0x08, 0x24, 0xb6, 0x49, 0x51, 0x55, 0xce, 0x2c, 0xaa, 0x7f,
|
||||||
0xb1, 0x52, 0x47, 0x96, 0xdc, 0xfc, 0xb8, 0x9e, 0x6a, 0x61, 0x42, 0x94, 0x5a, 0xf0, 0xf4, 0x99,
|
0xb3, 0xc3, 0x3d, 0xb4, 0xcb, 0x3c, 0x55, 0x6e, 0x6a, 0x34, 0xd2, 0x61, 0xa9, 0x63, 0xcb, 0x71,
|
||||||
0xf1, 0x4d, 0x81, 0xd5, 0xdf, 0x2c, 0x77, 0x87, 0xf6, 0x9a, 0xf9, 0x38, 0x5f, 0x0a, 0x60, 0xd9,
|
0x7e, 0x52, 0xbf, 0xb5, 0x34, 0x1d, 0x82, 0x46, 0x0b, 0x9e, 0x1e, 0x19, 0xdf, 0x0c, 0x58, 0xfd,
|
||||||
0x3a, 0x94, 0x3f, 0xb7, 0x67, 0x99, 0x14, 0xbb, 0xc7, 0xb0, 0x39, 0x3a, 0xde, 0x29, 0x00, 0xfc,
|
0xc3, 0xf2, 0x7a, 0x68, 0xaf, 0xb9, 0x8f, 0xfa, 0x85, 0x00, 0x96, 0xad, 0x51, 0xf9, 0x33, 0xfb,
|
||||||
0x4f, 0x81, 0x67, 0xb2, 0x1b, 0xce, 0xd2, 0x3e, 0x5c, 0x0a, 0x7c, 0xc3, 0x3d, 0x41, 0x7e, 0x8a,
|
0x99, 0x69, 0xb1, 0x7b, 0x0c, 0x9b, 0xe3, 0xe3, 0x9d, 0x01, 0xc0, 0xff, 0x14, 0x78, 0x26, 0xbb,
|
||||||
0x9e, 0x60, 0x52, 0x38, 0xdf, 0x87, 0xbb, 0xa3, 0xa2, 0x9f, 0x02, 0xcc, 0x37, 0xa1, 0xbc, 0x8d,
|
0xe1, 0x3c, 0xad, 0xc5, 0x85, 0xc0, 0x37, 0xdc, 0x2f, 0xe4, 0x67, 0xe8, 0x17, 0xa6, 0x85, 0xf3,
|
||||||
0x0f, 0x1d, 0x77, 0x2a, 0xe8, 0x8c, 0x37, 0xa0, 0x22, 0x57, 0x4b, 0xd3, 0xa9, 0x6a, 0xaa, 0x8c,
|
0x7d, 0xb8, 0x3b, 0x2e, 0xfa, 0x19, 0xc0, 0x7c, 0x13, 0xca, 0xdb, 0xf8, 0xd0, 0x71, 0x67, 0x82,
|
||||||
0xaf, 0xa6, 0xc6, 0x11, 0x54, 0x9a, 0x5e, 0xaf, 0xe7, 0xd0, 0xab, 0xbe, 0xc3, 0x8c, 0x65, 0xa8,
|
0xce, 0x78, 0x03, 0x2a, 0x72, 0xb5, 0x34, 0x9d, 0xaa, 0xb4, 0xca, 0xe4, 0x4a, 0x6b, 0x1c, 0x41,
|
||||||
0x46, 0x96, 0x84, 0x9b, 0xc6, 0x67, 0xb0, 0x84, 0xbc, 0x6e, 0xf7, 0xc0, 0x6e, 0x1f, 0x5f, 0xb9,
|
0xa5, 0xe9, 0xf5, 0x7a, 0x0e, 0xbd, 0xec, 0xfb, 0xcd, 0x58, 0x85, 0x6a, 0x64, 0x49, 0xb8, 0x69,
|
||||||
0x75, 0x1d, 0x96, 0x13, 0x5b, 0xd2, 0xfe, 0x3f, 0x39, 0x58, 0xd9, 0xeb, 0x77, 0x1d, 0x2a, 0x29,
|
0x7c, 0x06, 0x2b, 0xc8, 0xeb, 0x76, 0x0f, 0xec, 0xf6, 0xf1, 0xa5, 0x5b, 0xd7, 0x61, 0x35, 0xb1,
|
||||||
0x99, 0xc6, 0x85, 0x71, 0x8f, 0x8a, 0x89, 0x3b, 0x1f, 0x76, 0xea, 0x49, 0xe8, 0x87, 0x6c, 0x6e,
|
0x25, 0xed, 0xff, 0x9b, 0x83, 0x1b, 0x7b, 0xfd, 0xae, 0x43, 0x25, 0x25, 0xb3, 0xb8, 0x30, 0xe9,
|
||||||
0x64, 0xb1, 0xd4, 0xf8, 0x9c, 0x68, 0x6b, 0xc2, 0x07, 0x7d, 0xa4, 0x12, 0xb8, 0x94, 0xa7, 0xa9,
|
0xc1, 0x31, 0x75, 0x57, 0xc4, 0x4e, 0x3d, 0x09, 0xfd, 0x90, 0x8d, 0x8f, 0x2c, 0x96, 0x1a, 0x9f,
|
||||||
0x8a, 0x40, 0x6a, 0xb0, 0x19, 0xfd, 0x65, 0x58, 0x77, 0x83, 0x9e, 0xe5, 0x7b, 0x5f, 0x10, 0xab,
|
0x13, 0x2d, 0x4f, 0xf8, 0xd8, 0x8f, 0x54, 0x02, 0x97, 0xf2, 0x34, 0x55, 0x11, 0x48, 0x0d, 0x36,
|
||||||
0xcf, 0x9c, 0xe7, 0x3b, 0x5b, 0x7d, 0xdb, 0xa7, 0xbc, 0xcf, 0x55, 0xd1, 0x2d, 0x26, 0x46, 0x4c,
|
0xa3, 0xbf, 0x0c, 0xb7, 0xdd, 0xa0, 0x67, 0xf9, 0xde, 0x17, 0xc4, 0xea, 0x33, 0xe7, 0xf9, 0xce,
|
||||||
0xba, 0x8b, 0x7d, 0x6e, 0x7c, 0x97, 0x89, 0xf4, 0xb7, 0xa1, 0x64, 0x77, 0x0f, 0x3d, 0xdf, 0xa1,
|
0x56, 0xdf, 0xf6, 0x29, 0xef, 0x81, 0x55, 0x74, 0x93, 0x89, 0x11, 0x93, 0xee, 0x62, 0x9f, 0x1b,
|
||||||
0x47, 0x3d, 0xd9, 0xcd, 0x18, 0xd2, 0xcd, 0x53, 0xc8, 0x98, 0xef, 0x44, 0x9a, 0x28, 0x59, 0xa4,
|
0xdf, 0x65, 0x22, 0xfd, 0x6d, 0x28, 0xd9, 0xdd, 0x43, 0xcf, 0x77, 0xe8, 0x51, 0x4f, 0x76, 0x3a,
|
||||||
0xbf, 0x04, 0x7a, 0x40, 0xb0, 0x25, 0x9c, 0x13, 0x46, 0x07, 0x0d, 0xd9, 0xda, 0x2c, 0x31, 0x49,
|
0x86, 0x74, 0xf3, 0x14, 0x32, 0xe6, 0x3b, 0x91, 0x26, 0x4a, 0x16, 0xe9, 0x2f, 0x81, 0x1e, 0x10,
|
||||||
0xb2, 0xcd, 0x47, 0x0d, 0xe3, 0x37, 0x15, 0xf4, 0xf4, 0xbe, 0x32, 0x5f, 0x5f, 0x63, 0xd7, 0x44,
|
0x6c, 0x09, 0xe7, 0x84, 0xd1, 0x41, 0x43, 0xb6, 0x3d, 0x2b, 0x4c, 0x92, 0x6c, 0xf3, 0x51, 0xc3,
|
||||||
0x38, 0x4b, 0x18, 0xde, 0xe1, 0x91, 0xdd, 0x88, 0x69, 0x3c, 0xa5, 0x6b, 0x86, 0x6e, 0x23, 0xa9,
|
0xf8, 0x5d, 0x05, 0x3d, 0xbd, 0xaf, 0xcc, 0xd7, 0xd7, 0xd8, 0x35, 0x11, 0xce, 0x12, 0x86, 0x77,
|
||||||
0x5e, 0xff, 0x14, 0xca, 0xd1, 0xc1, 0xe3, 0xe1, 0xa4, 0xd9, 0x50, 0xc6, 0xd6, 0x86, 0xdc, 0x04,
|
0x78, 0x64, 0x37, 0x62, 0x1a, 0x4f, 0xe9, 0x9a, 0xa1, 0xdb, 0x48, 0xaa, 0xd7, 0x3f, 0x85, 0x72,
|
||||||
0xb5, 0xa1, 0xfe, 0x16, 0x94, 0xf8, 0x15, 0x73, 0xee, 0xde, 0xc9, 0x3d, 0x97, 0x4b, 0xdf, 0x73,
|
0x74, 0xf0, 0x78, 0x38, 0x69, 0x36, 0x94, 0x89, 0xb5, 0x21, 0x37, 0x45, 0x6d, 0xa8, 0xbf, 0x05,
|
||||||
0xf5, 0x3f, 0x15, 0xc8, 0xf3, 0xc5, 0x13, 0x3f, 0x52, 0x3f, 0x80, 0x6a, 0xec, 0xa5, 0x60, 0x4f,
|
0x25, 0x7e, 0xc5, 0x9c, 0xb9, 0x77, 0x72, 0xcf, 0xe5, 0xd2, 0xf7, 0x5c, 0xfd, 0x2f, 0x05, 0xf2,
|
||||||
0x64, 0xf6, 0xbd, 0x31, 0x90, 0xa4, 0x21, 0x40, 0xe5, 0xe3, 0x34, 0x20, 0x4d, 0x00, 0xf1, 0xaf,
|
0x7c, 0xf1, 0xd4, 0x0f, 0xd8, 0x0f, 0xa0, 0x1a, 0x7b, 0x29, 0xd8, 0x13, 0x99, 0x7d, 0x6f, 0x02,
|
||||||
0x7b, 0xbe, 0x95, 0xc8, 0xc3, 0xe7, 0xc6, 0x6c, 0x15, 0x87, 0x8b, 0x4a, 0x24, 0x8e, 0x5c, 0x87,
|
0x24, 0x69, 0x08, 0x50, 0xf9, 0x38, 0x0d, 0x48, 0x13, 0x40, 0xfc, 0xcb, 0x9f, 0x6f, 0x25, 0xf2,
|
||||||
0x3c, 0x71, 0xbe, 0x12, 0xcf, 0x47, 0x15, 0xf1, 0x6f, 0xe3, 0x21, 0xac, 0xbd, 0x87, 0xe9, 0x9e,
|
0xf0, 0xb9, 0x09, 0x5b, 0xc5, 0xe1, 0xa2, 0x12, 0x89, 0x23, 0xd7, 0x21, 0x4f, 0x9c, 0xaf, 0xc4,
|
||||||
0x3f, 0x88, 0xee, 0x91, 0xe8, 0xf8, 0x8c, 0x81, 0xc9, 0x40, 0x70, 0x3b, 0xbb, 0x48, 0x66, 0xc0,
|
0xa3, 0x45, 0x45, 0xfc, 0xdb, 0x78, 0x08, 0xeb, 0xef, 0x61, 0xba, 0xe7, 0x0f, 0xa2, 0x7b, 0x24,
|
||||||
0xeb, 0xec, 0x04, 0xf8, 0x03, 0x6b, 0x68, 0xa5, 0xd6, 0x58, 0x4b, 0xe8, 0x49, 0x2f, 0xd2, 0x48,
|
0x3a, 0x3e, 0x13, 0x60, 0x32, 0x10, 0xdc, 0xca, 0x2e, 0x92, 0x19, 0xf0, 0x3a, 0x3b, 0x01, 0xfe,
|
||||||
0x32, 0xd8, 0xae, 0x43, 0xad, 0xed, 0xf5, 0xcc, 0x13, 0x2f, 0xa0, 0xc1, 0x01, 0x36, 0x07, 0x0e,
|
0xc0, 0x1a, 0x5a, 0xa9, 0x35, 0xd6, 0x13, 0x7a, 0xd2, 0x8b, 0x34, 0x92, 0x0c, 0xb6, 0xeb, 0x50,
|
||||||
0x65, 0x27, 0x5e, 0xfc, 0xd6, 0x71, 0x50, 0xe0, 0x7f, 0x1e, 0xfe, 0x1f, 0x00, 0x00, 0xff, 0xff,
|
0x6b, 0x7b, 0x3d, 0xf3, 0xc4, 0x0b, 0x68, 0x70, 0x80, 0xcd, 0x81, 0x43, 0xd9, 0x89, 0x17, 0xbf,
|
||||||
0xad, 0x6e, 0xed, 0xad, 0x34, 0x19, 0x00, 0x00,
|
0x91, 0x1c, 0x14, 0xf8, 0x9f, 0x87, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0x12, 0x77, 0x8b, 0xc2,
|
||||||
|
0x6c, 0x19, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ type fakeVTGateService struct {
|
||||||
type queryExecute struct {
|
type queryExecute struct {
|
||||||
SQL string
|
SQL string
|
||||||
BindVariables map[string]interface{}
|
BindVariables map[string]interface{}
|
||||||
|
Keyspace string
|
||||||
TabletType topodatapb.TabletType
|
TabletType topodatapb.TabletType
|
||||||
Session *vtgatepb.Session
|
Session *vtgatepb.Session
|
||||||
NotInTransaction bool
|
NotInTransaction bool
|
||||||
|
@ -36,7 +37,7 @@ type queryExecuteSpecificShard struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute is part of the VTGateService interface
|
// 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]
|
execCase, ok := execMap[sql]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("no match for: %s", sql)
|
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{
|
query := &queryExecute{
|
||||||
SQL: sql,
|
SQL: sql,
|
||||||
BindVariables: bindVariables,
|
BindVariables: bindVariables,
|
||||||
|
Keyspace: keyspace,
|
||||||
TabletType: tabletType,
|
TabletType: tabletType,
|
||||||
Session: session,
|
Session: session,
|
||||||
NotInTransaction: notInTransaction,
|
NotInTransaction: notInTransaction,
|
||||||
|
@ -109,7 +111,7 @@ func (f *fakeVTGateService) ExecuteBatchKeyspaceIds(ctx context.Context, queries
|
||||||
}
|
}
|
||||||
|
|
||||||
// StreamExecute is part of the VTGateService interface
|
// 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]
|
execCase, ok := execMap[sql]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("no match for: %s", sql)
|
return fmt.Errorf("no match for: %s", sql)
|
||||||
|
@ -117,6 +119,7 @@ func (f *fakeVTGateService) StreamExecute(ctx context.Context, sql string, bindV
|
||||||
query := &queryExecute{
|
query := &queryExecute{
|
||||||
SQL: sql,
|
SQL: sql,
|
||||||
BindVariables: bindVariables,
|
BindVariables: bindVariables,
|
||||||
|
Keyspace: keyspace,
|
||||||
TabletType: tabletType,
|
TabletType: tabletType,
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(query, execCase.execQuery) {
|
if !reflect.DeepEqual(query, execCase.execQuery) {
|
||||||
|
|
|
@ -37,7 +37,7 @@ func (vtg *VTGate) Execute(ctx context.Context, request *vtgatepb.ExecuteRequest
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, vterrors.ToGRPCError(err)
|
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{
|
return &vtgatepb.ExecuteResponse{
|
||||||
Result: sqltypes.ResultToProto3(result),
|
Result: sqltypes.ResultToProto3(result),
|
||||||
Session: request.Session,
|
Session: request.Session,
|
||||||
|
@ -196,6 +196,7 @@ func (vtg *VTGate) StreamExecute(request *vtgatepb.StreamExecuteRequest, stream
|
||||||
vtgErr := vtg.server.StreamExecute(ctx,
|
vtgErr := vtg.server.StreamExecute(ctx,
|
||||||
string(request.Query.Sql),
|
string(request.Query.Sql),
|
||||||
bv,
|
bv,
|
||||||
|
request.Keyspace,
|
||||||
request.TabletType,
|
request.TabletType,
|
||||||
func(value *sqltypes.Result) error {
|
func(value *sqltypes.Result) error {
|
||||||
return stream.Send(&vtgatepb.StreamExecuteResponse{
|
return stream.Send(&vtgatepb.StreamExecuteResponse{
|
||||||
|
|
|
@ -68,9 +68,15 @@ type builder interface {
|
||||||
SupplyCol(ref colref) int
|
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.
|
// Build builds a plan for a query based on the specified vschema.
|
||||||
// It's the main entry point for this package.
|
// 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)
|
statement, err := sqlparser.Parse(query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -14,15 +14,23 @@ import (
|
||||||
"github.com/youtube/vitess/go/vt/vtgate/vindexes"
|
"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.
|
// 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{
|
route := &engine.Route{
|
||||||
Query: generateQuery(upd),
|
Query: generateQuery(upd),
|
||||||
}
|
}
|
||||||
// We allow only one table in an update.
|
|
||||||
tablename := sqlparser.GetTableName(upd.Table)
|
|
||||||
var err error
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -47,7 +55,7 @@ func buildUpdatePlan(upd *sqlparser.Update, vschema *vindexes.VSchema) (*engine.
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateQuery(statement sqlparser.Statement) string {
|
func generateQuery(statement sqlparser.Statement) string {
|
||||||
buf := sqlparser.NewTrackedBuffer(nil)
|
buf := sqlparser.NewTrackedBuffer(dmlFormatter)
|
||||||
statement.Format(buf)
|
statement.Format(buf)
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
@ -68,14 +76,12 @@ func isIndexChanging(setClauses sqlparser.UpdateExprs, colVindexes []*vindexes.C
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildUpdatePlan builds the instructions for a DELETE statement.
|
// 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{
|
route := &engine.Route{
|
||||||
Query: generateQuery(del),
|
Query: generateQuery(del),
|
||||||
}
|
}
|
||||||
// We allow only one table in a delete.
|
|
||||||
tablename := sqlparser.GetTableName(del.Table)
|
|
||||||
var err error
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,11 @@ import (
|
||||||
"github.com/youtube/vitess/go/vt/vtgate/vindexes"
|
"github.com/youtube/vitess/go/vt/vtgate/vindexes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This file has functions to analyze the FROM clause
|
// This file has functions to analyze the FROM clause.
|
||||||
// for select statements.
|
|
||||||
|
|
||||||
// processTableExprs analyzes the FROM clause. It produces a builder
|
// processTableExprs analyzes the FROM clause. It produces a builder
|
||||||
// with all the routes identified.
|
// 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 {
|
if len(tableExprs) != 1 {
|
||||||
return nil, errors.New("unsupported: ',' join operator")
|
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.
|
// 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) {
|
switch tableExpr := tableExpr.(type) {
|
||||||
case *sqlparser.AliasedTableExpr:
|
case *sqlparser.AliasedTableExpr:
|
||||||
return processAliasedTable(tableExpr, vschema)
|
return processAliasedTable(tableExpr, vschema)
|
||||||
|
@ -55,7 +54,7 @@ func processTableExpr(tableExpr sqlparser.TableExpr, vschema *vindexes.VSchema)
|
||||||
// vindex columns will be added to the tabsym.
|
// vindex columns will be added to the tabsym.
|
||||||
// A symtab symbol can only point to a route. This means that we canoot
|
// A symtab symbol can only point to a route. This means that we canoot
|
||||||
// support complex joins in subqueries yet.
|
// 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) {
|
switch expr := tableExpr.Expr.(type) {
|
||||||
case *sqlparser.TableName:
|
case *sqlparser.TableName:
|
||||||
eroute, table, err := getTablePlan(expr, vschema)
|
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.
|
// getTablePlan produces the initial engine.Route for the specified TableName.
|
||||||
// It also returns the associated vschema info (*Table) so that
|
// It also returns the associated vschema info (*Table) so that
|
||||||
// it can be used to create the symbol table entry.
|
// it can be used to create the symbol table entry.
|
||||||
func getTablePlan(tableName *sqlparser.TableName, vschema *vindexes.VSchema) (*engine.Route, *vindexes.Table, error) {
|
func getTablePlan(tableName *sqlparser.TableName, vschema VSchema) (*engine.Route, *vindexes.Table, error) {
|
||||||
table, err := vschema.FindTable(string(tableName.Name))
|
table, err := vschema.Find(string(tableName.Qualifier), string(tableName.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
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.
|
// processJoin produces a builder subtree for the given Join.
|
||||||
// If the left and right nodes can be part of the same route,
|
// If the left and right nodes can be part of the same route,
|
||||||
// then it's a route. Otherwise, it's a join.
|
// 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 {
|
switch ajoin.Join {
|
||||||
case sqlparser.JoinStr, sqlparser.StraightJoinStr, sqlparser.LeftJoinStr:
|
case sqlparser.JoinStr, sqlparser.StraightJoinStr, sqlparser.LeftJoinStr:
|
||||||
case sqlparser.RightJoinStr:
|
case sqlparser.RightJoinStr:
|
||||||
|
|
|
@ -14,13 +14,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// buildInsertPlan builds the route for an INSERT statement.
|
// 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{
|
route := &engine.Route{
|
||||||
Query: generateQuery(ins),
|
Query: generateQuery(ins),
|
||||||
}
|
}
|
||||||
tablename := sqlparser.GetTableName(ins.Table)
|
|
||||||
var err error
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ type route struct {
|
||||||
ERoute *engine.Route
|
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:
|
// We have some circular pointer references here:
|
||||||
// The route points to the symtab idicating
|
// The route points to the symtab idicating
|
||||||
// the symtab that should be used to resolve symbols
|
// the symtab that should be used to resolve symbols
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// buildSelectPlan is the new function to build a Select plan.
|
// 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)
|
bindvars := getBindvars(sel)
|
||||||
builder, err := processSelect(sel, vschema, nil)
|
builder, err := processSelect(sel, vschema, nil)
|
||||||
if err != 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.
|
// 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)
|
bldr, err := processTableExprs(sel.From, vschema)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -50,12 +50,12 @@ type symtab struct {
|
||||||
Colsyms []*colsym
|
Colsyms []*colsym
|
||||||
Externs []*sqlparser.ColName
|
Externs []*sqlparser.ColName
|
||||||
Outer *symtab
|
Outer *symtab
|
||||||
VSchema *vindexes.VSchema
|
VSchema VSchema
|
||||||
}
|
}
|
||||||
|
|
||||||
// newSymtab creates a new symtab initialized
|
// newSymtab creates a new symtab initialized
|
||||||
// to contain the provided table alias.
|
// to contain the provided table alias.
|
||||||
func newSymtab(vschema *vindexes.VSchema) *symtab {
|
func newSymtab(vschema VSchema) *symtab {
|
||||||
return &symtab{
|
return &symtab{
|
||||||
VSchema: vschema,
|
VSchema: vschema,
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,14 +45,21 @@ func NewPlanner(vschema *vindexes.VSchema, cacheSize int) *Planner {
|
||||||
|
|
||||||
// GetPlan computes the plan for the given query. If one is in
|
// GetPlan computes the plan for the given query. If one is in
|
||||||
// the cache, it reuses it.
|
// 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 {
|
if plr.vschema == nil {
|
||||||
return nil, errors.New("vschema not initialized")
|
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
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -95,3 +102,15 @@ func (plr *Planner) ServeHTTP(response http.ResponseWriter, request *http.Reques
|
||||||
response.WriteHeader(http.StatusNotFound)
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -17,17 +17,19 @@ type requestContext struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
sql string
|
sql string
|
||||||
bindVars map[string]interface{}
|
bindVars map[string]interface{}
|
||||||
|
keyspace string
|
||||||
tabletType topodatapb.TabletType
|
tabletType topodatapb.TabletType
|
||||||
session *vtgatepb.Session
|
session *vtgatepb.Session
|
||||||
notInTransaction bool
|
notInTransaction bool
|
||||||
router *Router
|
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{
|
return &requestContext{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
sql: sql,
|
sql: sql,
|
||||||
bindVars: bindVars,
|
bindVars: bindVars,
|
||||||
|
keyspace: keyspace,
|
||||||
tabletType: tabletType,
|
tabletType: tabletType,
|
||||||
session: session,
|
session: session,
|
||||||
notInTransaction: notInTransaction,
|
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) {
|
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) {
|
func (vc *requestContext) ExecuteRoute(route *engine.Route, joinvars map[string]interface{}) (*sqltypes.Result, error) {
|
||||||
|
|
|
@ -59,12 +59,12 @@ func NewRouter(serv topo.SrvTopoServer, cell string, vschema *vindexes.VSchema,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute routes a non-streaming query.
|
// 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 {
|
if bindVars == nil {
|
||||||
bindVars = make(map[string]interface{})
|
bindVars = make(map[string]interface{})
|
||||||
}
|
}
|
||||||
vcursor := newRequestContext(ctx, sql, bindVars, tabletType, session, notInTransaction, rtr)
|
vcursor := newRequestContext(ctx, sql, bindVars, keyspace, tabletType, session, notInTransaction, rtr)
|
||||||
plan, err := rtr.planner.GetPlan(sql)
|
plan, err := rtr.planner.GetPlan(sql, keyspace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -72,12 +72,12 @@ func (rtr *Router) Execute(ctx context.Context, sql string, bindVars map[string]
|
||||||
}
|
}
|
||||||
|
|
||||||
// StreamExecute executes a streaming query.
|
// 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 {
|
if bindVars == nil {
|
||||||
bindVars = make(map[string]interface{})
|
bindVars = make(map[string]interface{})
|
||||||
}
|
}
|
||||||
vcursor := newRequestContext(ctx, sql, bindVars, tabletType, nil, false, rtr)
|
vcursor := newRequestContext(ctx, sql, bindVars, keyspace, tabletType, nil, false, rtr)
|
||||||
plan, err := rtr.planner.GetPlan(sql)
|
plan, err := rtr.planner.GetPlan(sql, keyspace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ var routerVSchema = createTestVSchema(`
|
||||||
"Type": "numeric"
|
"Type": "numeric"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Classes": {
|
"Tables": {
|
||||||
"user": {
|
"user": {
|
||||||
"ColVindexes": [
|
"ColVindexes": [
|
||||||
{
|
{
|
||||||
|
@ -67,10 +67,10 @@ var routerVSchema = createTestVSchema(`
|
||||||
"Name": "name_user_map"
|
"Name": "name_user_map"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Autoinc" : {
|
"Autoinc" : {
|
||||||
"Col": "id",
|
"Col": "id",
|
||||||
"Sequence": "user_seq"
|
"Sequence": "user_seq"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"user_extra": {
|
"user_extra": {
|
||||||
"ColVindexes": [
|
"ColVindexes": [
|
||||||
|
@ -91,10 +91,10 @@ var routerVSchema = createTestVSchema(`
|
||||||
"Name": "music_user_map"
|
"Name": "music_user_map"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Autoinc" : {
|
"Autoinc" : {
|
||||||
"Col": "id",
|
"Col": "id",
|
||||||
"Sequence": "user_seq"
|
"Sequence": "user_seq"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"music_extra": {
|
"music_extra": {
|
||||||
"ColVindexes": [
|
"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": {
|
"TestBadSharding": {
|
||||||
"Sharded": false,
|
"Sharded": false,
|
||||||
"Tables": {
|
"Tables": {
|
||||||
"sharded_table": ""
|
"sharded_table": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"TestUnsharded": {
|
"TestUnsharded": {
|
||||||
"Sharded": false,
|
"Sharded": false,
|
||||||
"Classes": {
|
|
||||||
"seq": {
|
|
||||||
"Type": "Sequence"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Tables": {
|
"Tables": {
|
||||||
"user_seq": "seq",
|
"user_seq": {
|
||||||
"music_user_map": "",
|
"Type": "Sequence"
|
||||||
"name_user_map": ""
|
},
|
||||||
|
"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(),
|
return router.Execute(context.Background(),
|
||||||
sql,
|
sql,
|
||||||
bv,
|
bv,
|
||||||
|
"",
|
||||||
topodatapb.TabletType_MASTER,
|
topodatapb.TabletType_MASTER,
|
||||||
nil,
|
nil,
|
||||||
false)
|
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) {
|
func routerStream(router *Router, sql string) (qr *sqltypes.Result, err error) {
|
||||||
results := make(chan *sqltypes.Result, 10)
|
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
|
results <- qr
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
|
@ -6,7 +6,6 @@ package vindexes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -48,8 +47,8 @@ type ColVindex struct {
|
||||||
|
|
||||||
// KeyspaceSchema contains the schema(table) for a keyspace.
|
// KeyspaceSchema contains the schema(table) for a keyspace.
|
||||||
type KeyspaceSchema struct {
|
type KeyspaceSchema struct {
|
||||||
Sharded bool
|
Keyspace *Keyspace
|
||||||
Tables map[string]*Table
|
Tables map[string]*Table
|
||||||
}
|
}
|
||||||
|
|
||||||
// Autoinc contains the auto-inc information for a 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),
|
tables: make(map[string]*Table),
|
||||||
Keyspaces: make(map[string]*KeyspaceSchema),
|
Keyspaces: make(map[string]*KeyspaceSchema),
|
||||||
}
|
}
|
||||||
keyspaces := buildKeyspaces(source, vschema)
|
buildKeyspaces(source, vschema)
|
||||||
// We have to build the sequences first to avoid
|
// We have to build the sequences first to avoid
|
||||||
// forward reference errors.
|
// forward reference errors.
|
||||||
err = buildSequences(source, vschema, keyspaces)
|
err = buildSequences(source, vschema)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = buildTables(source, vschema, keyspaces)
|
err = buildTables(source, vschema)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return vschema, nil
|
return vschema, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildKeyspaces(source *VSchemaFormal, vschema *VSchema) map[string]*Keyspace {
|
func buildKeyspaces(source *VSchemaFormal, vschema *VSchema) {
|
||||||
k := make(map[string]*Keyspace)
|
|
||||||
for ksname, ks := range source.Keyspaces {
|
for ksname, ks := range source.Keyspaces {
|
||||||
k[ksname] = &Keyspace{
|
|
||||||
Name: ksname,
|
|
||||||
Sharded: ks.Sharded,
|
|
||||||
}
|
|
||||||
vschema.Keyspaces[ksname] = &KeyspaceSchema{
|
vschema.Keyspaces[ksname] = &KeyspaceSchema{
|
||||||
Sharded: ks.Sharded,
|
Keyspace: &Keyspace{
|
||||||
Tables: make(map[string]*Table),
|
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 {
|
for ksname, ks := range source.Keyspaces {
|
||||||
keyspace := keyspaces[ksname]
|
keyspace := vschema.Keyspaces[ksname].Keyspace
|
||||||
for tname, cname := range ks.Tables {
|
for tname, table := range ks.Tables {
|
||||||
if cname == "" {
|
if table.Type != "Sequence" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
class, ok := ks.Classes[cname]
|
t := &Table{
|
||||||
if !ok {
|
Name: tname,
|
||||||
return fmt.Errorf("class %s not found for table %s", cname, tname)
|
Keyspace: keyspace,
|
||||||
|
IsSequence: true,
|
||||||
}
|
}
|
||||||
if class.Type == "Sequence" {
|
if _, ok := vschema.tables[tname]; ok {
|
||||||
t := &Table{
|
vschema.tables[tname] = nil
|
||||||
Name: tname,
|
} else {
|
||||||
Keyspace: keyspace,
|
vschema.tables[tname] = t
|
||||||
IsSequence: true,
|
|
||||||
}
|
|
||||||
if _, ok := vschema.tables[tname]; ok {
|
|
||||||
vschema.tables[tname] = nil
|
|
||||||
} else {
|
|
||||||
vschema.tables[tname] = t
|
|
||||||
}
|
|
||||||
vschema.Keyspaces[ksname].Tables[tname] = t
|
|
||||||
}
|
}
|
||||||
|
vschema.Keyspaces[ksname].Tables[tname] = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
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 {
|
for ksname, ks := range source.Keyspaces {
|
||||||
keyspace := keyspaces[ksname]
|
keyspace := vschema.Keyspaces[ksname].Keyspace
|
||||||
vindexes := make(map[string]Vindex)
|
vindexes := make(map[string]Vindex)
|
||||||
for vname, vindexInfo := range ks.Vindexes {
|
for vname, vindexInfo := range ks.Vindexes {
|
||||||
vindex, err := CreateVindex(vindexInfo.Type, vname, vindexInfo.Params)
|
vindex, err := CreateVindex(vindexInfo.Type, vname, vindexInfo.Params)
|
||||||
|
@ -142,12 +132,8 @@ func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]*
|
||||||
}
|
}
|
||||||
vindexes[vname] = vindex
|
vindexes[vname] = vindex
|
||||||
}
|
}
|
||||||
for tname, cname := range ks.Tables {
|
for tname, table := range ks.Tables {
|
||||||
class, ok := ks.Classes[cname]
|
if table.Type == "Sequence" {
|
||||||
if !ok && cname != "" {
|
|
||||||
return fmt.Errorf("class %s not found for table %s", cname, tname)
|
|
||||||
}
|
|
||||||
if class.Type == "Sequence" {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
t := &Table{
|
t := &Table{
|
||||||
|
@ -163,10 +149,10 @@ func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]*
|
||||||
if !keyspace.Sharded {
|
if !keyspace.Sharded {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for i, ind := range class.ColVindexes {
|
for i, ind := range table.ColVindexes {
|
||||||
vindexInfo, ok := ks.Vindexes[ind.Name]
|
vindexInfo, ok := ks.Vindexes[ind.Name]
|
||||||
if !ok {
|
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]
|
vindex := vindexes[ind.Name]
|
||||||
owned := false
|
owned := false
|
||||||
|
@ -183,10 +169,10 @@ func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]*
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
// Perform Primary vindex check.
|
// Perform Primary vindex check.
|
||||||
if _, ok := columnVindex.Vindex.(Unique); !ok {
|
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 {
|
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)
|
t.ColVindexes = append(t.ColVindexes, columnVindex)
|
||||||
|
@ -195,11 +181,11 @@ func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Ordered = colVindexSorted(t.ColVindexes)
|
t.Ordered = colVindexSorted(t.ColVindexes)
|
||||||
if class.Autoinc != nil {
|
if table.Autoinc != nil {
|
||||||
t.Autoinc = &Autoinc{Col: class.Autoinc.Col, ColVindexNum: -1}
|
t.Autoinc = &Autoinc{Col: table.Autoinc.Col, ColVindexNum: -1}
|
||||||
seq, ok := vschema.tables[class.Autoinc.Sequence]
|
seq, ok := vschema.tables[table.Autoinc.Sequence]
|
||||||
if !ok {
|
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
|
t.Autoinc.Sequence = seq
|
||||||
for i, cv := range t.ColVindexes {
|
for i, cv := range t.ColVindexes {
|
||||||
|
@ -214,18 +200,43 @@ func buildTables(source *VSchemaFormal, vschema *VSchema, keyspaces map[string]*
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindTable returns a pointer to the Table if found.
|
// Find returns a pointer to the Table. If a keyspace is specified, only tables
|
||||||
// Otherwise, it returns a reason, which is equivalent to an error.
|
// from that keyspace are searched. If the specified keyspace is unsharded
|
||||||
func (vschema *VSchema) FindTable(tablename string) (table *Table, err error) {
|
// and no tables matched, it's considered valid: Find will construct a table
|
||||||
if tablename == "" {
|
// of that name and return it. If no kesypace is specified, then a table is returned
|
||||||
return nil, errors.New("unsupported: compex table expression in DML")
|
// 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
|
||||||
table, ok := vschema.tables[tablename]
|
// valid and belonging to that keyspace.
|
||||||
if table == nil {
|
func (vschema *VSchema) Find(keyspace, tablename string) (table *Table, err error) {
|
||||||
if ok {
|
if keyspace == "" {
|
||||||
return nil, fmt.Errorf("ambiguous table reference: %s", tablename)
|
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
|
return table, nil
|
||||||
}
|
}
|
||||||
|
@ -257,8 +268,7 @@ type VSchemaFormal struct {
|
||||||
type KeyspaceFormal struct {
|
type KeyspaceFormal struct {
|
||||||
Sharded bool
|
Sharded bool
|
||||||
Vindexes map[string]VindexFormal
|
Vindexes map[string]VindexFormal
|
||||||
Classes map[string]ClassFormal
|
Tables map[string]TableFormal
|
||||||
Tables map[string]string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VindexFormal is the info for each index as loaded from
|
// VindexFormal is the info for each index as loaded from
|
||||||
|
@ -269,9 +279,9 @@ type VindexFormal struct {
|
||||||
Owner string
|
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.
|
// the source.
|
||||||
type ClassFormal struct {
|
type TableFormal struct {
|
||||||
Type string
|
Type string
|
||||||
ColVindexes []ColVindexFormal
|
ColVindexes []ColVindexFormal
|
||||||
Autoinc *AutoincFormal
|
Autoinc *AutoincFormal
|
||||||
|
|
|
@ -85,8 +85,8 @@ func TestUnshardedVSchema(t *testing.T) {
|
||||||
good := VSchemaFormal{
|
good := VSchemaFormal{
|
||||||
Keyspaces: map[string]KeyspaceFormal{
|
Keyspaces: map[string]KeyspaceFormal{
|
||||||
"unsharded": {
|
"unsharded": {
|
||||||
Tables: map[string]string{
|
Tables: map[string]TableFormal{
|
||||||
"t1": "",
|
"t1": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -95,11 +95,12 @@ func TestUnshardedVSchema(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
ks := &Keyspace{
|
||||||
|
Name: "unsharded",
|
||||||
|
}
|
||||||
t1 := &Table{
|
t1 := &Table{
|
||||||
Name: "t1",
|
Name: "t1",
|
||||||
Keyspace: &Keyspace{
|
Keyspace: ks,
|
||||||
Name: "unsharded",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
want := &VSchema{
|
want := &VSchema{
|
||||||
tables: map[string]*Table{
|
tables: map[string]*Table{
|
||||||
|
@ -107,6 +108,7 @@ func TestUnshardedVSchema(t *testing.T) {
|
||||||
},
|
},
|
||||||
Keyspaces: map[string]*KeyspaceSchema{
|
Keyspaces: map[string]*KeyspaceSchema{
|
||||||
"unsharded": {
|
"unsharded": {
|
||||||
|
Keyspace: ks,
|
||||||
Tables: map[string]*Table{
|
Tables: map[string]*Table{
|
||||||
"t1": t1,
|
"t1": t1,
|
||||||
},
|
},
|
||||||
|
@ -136,7 +138,7 @@ func TestShardedVSchemaOwned(t *testing.T) {
|
||||||
Owner: "t1",
|
Owner: "t1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"t1": {
|
"t1": {
|
||||||
ColVindexes: []ColVindexFormal{
|
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 {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
ks := &Keyspace{
|
||||||
|
Name: "sharded",
|
||||||
|
Sharded: true,
|
||||||
|
}
|
||||||
t1 := &Table{
|
t1 := &Table{
|
||||||
Name: "t1",
|
Name: "t1",
|
||||||
Keyspace: &Keyspace{
|
Keyspace: ks,
|
||||||
Name: "sharded",
|
|
||||||
Sharded: true,
|
|
||||||
},
|
|
||||||
ColVindexes: []*ColVindex{
|
ColVindexes: []*ColVindex{
|
||||||
{
|
{
|
||||||
Col: "c1",
|
Col: "c1",
|
||||||
|
@ -197,7 +197,7 @@ func TestShardedVSchemaOwned(t *testing.T) {
|
||||||
},
|
},
|
||||||
Keyspaces: map[string]*KeyspaceSchema{
|
Keyspaces: map[string]*KeyspaceSchema{
|
||||||
"sharded": {
|
"sharded": {
|
||||||
Sharded: true,
|
Keyspace: ks,
|
||||||
Tables: map[string]*Table{
|
Tables: map[string]*Table{
|
||||||
"t1": t1,
|
"t1": t1,
|
||||||
},
|
},
|
||||||
|
@ -226,7 +226,7 @@ func TestShardedVSchemaNotOwned(t *testing.T) {
|
||||||
Owner: "",
|
Owner: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"t1": {
|
"t1": {
|
||||||
ColVindexes: []ColVindexFormal{
|
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 {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
ks := &Keyspace{
|
||||||
|
Name: "sharded",
|
||||||
|
Sharded: true,
|
||||||
|
}
|
||||||
t1 := &Table{
|
t1 := &Table{
|
||||||
Name: "t1",
|
Name: "t1",
|
||||||
Keyspace: &Keyspace{
|
Keyspace: ks,
|
||||||
Name: "sharded",
|
|
||||||
Sharded: true,
|
|
||||||
},
|
|
||||||
ColVindexes: []*ColVindex{
|
ColVindexes: []*ColVindex{
|
||||||
{
|
{
|
||||||
Col: "c1",
|
Col: "c1",
|
||||||
|
@ -282,7 +280,7 @@ func TestShardedVSchemaNotOwned(t *testing.T) {
|
||||||
},
|
},
|
||||||
Keyspaces: map[string]*KeyspaceSchema{
|
Keyspaces: map[string]*KeyspaceSchema{
|
||||||
"sharded": {
|
"sharded": {
|
||||||
Sharded: true,
|
Keyspace: ks,
|
||||||
Tables: map[string]*Table{
|
Tables: map[string]*Table{
|
||||||
"t1": t1,
|
"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) {
|
func TestBuildVSchemaVindexNotFoundFail(t *testing.T) {
|
||||||
bad := VSchemaFormal{
|
bad := VSchemaFormal{
|
||||||
Keyspaces: map[string]KeyspaceFormal{
|
Keyspaces: map[string]KeyspaceFormal{
|
||||||
|
@ -351,7 +316,7 @@ func TestBuildVSchemaVindexNotFoundFail(t *testing.T) {
|
||||||
Type: "noexist",
|
Type: "noexist",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"t1": {
|
"t1": {
|
||||||
ColVindexes: []ColVindexFormal{
|
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",
|
Type: "stf",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"t1": {
|
"t1": {
|
||||||
ColVindexes: []ColVindexFormal{
|
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{
|
good := VSchemaFormal{
|
||||||
Keyspaces: map[string]KeyspaceFormal{
|
Keyspaces: map[string]KeyspaceFormal{
|
||||||
"ksa": {
|
"ksa": {
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"seq": {
|
"t1": {
|
||||||
Type: "Sequence",
|
Type: "Sequence",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Tables: map[string]string{
|
|
||||||
"t1": "seq",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"ksb": {
|
"ksb": {
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"seq": {
|
"t1": {
|
||||||
Type: "Sequence",
|
Type: "Sequence",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Tables: map[string]string{
|
|
||||||
"t1": "seq",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
ksa := &Keyspace{
|
||||||
|
Name: "ksa",
|
||||||
|
}
|
||||||
|
ksb := &Keyspace{
|
||||||
|
Name: "ksb",
|
||||||
|
}
|
||||||
got, _ := BuildVSchema(&good)
|
got, _ := BuildVSchema(&good)
|
||||||
t1a := &Table{
|
t1a := &Table{
|
||||||
Name: "t1",
|
Name: "t1",
|
||||||
Keyspace: &Keyspace{
|
Keyspace: ksa,
|
||||||
Name: "ksa",
|
|
||||||
},
|
|
||||||
IsSequence: true,
|
IsSequence: true,
|
||||||
}
|
}
|
||||||
t1b := &Table{
|
t1b := &Table{
|
||||||
Name: "t1",
|
Name: "t1",
|
||||||
Keyspace: &Keyspace{
|
Keyspace: ksb,
|
||||||
Name: "ksb",
|
|
||||||
},
|
|
||||||
IsSequence: true,
|
IsSequence: true,
|
||||||
}
|
}
|
||||||
want := &VSchema{
|
want := &VSchema{
|
||||||
|
@ -453,11 +408,13 @@ func TestBuildVSchemaDupSeq(t *testing.T) {
|
||||||
},
|
},
|
||||||
Keyspaces: map[string]*KeyspaceSchema{
|
Keyspaces: map[string]*KeyspaceSchema{
|
||||||
"ksa": {
|
"ksa": {
|
||||||
|
Keyspace: ksa,
|
||||||
Tables: map[string]*Table{
|
Tables: map[string]*Table{
|
||||||
"t1": t1a,
|
"t1": t1a,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ksb": {
|
"ksb": {
|
||||||
|
Keyspace: ksb,
|
||||||
Tables: map[string]*Table{
|
Tables: map[string]*Table{
|
||||||
"t1": t1b,
|
"t1": t1b,
|
||||||
},
|
},
|
||||||
|
@ -475,29 +432,31 @@ func TestBuildVSchemaDupTable(t *testing.T) {
|
||||||
good := VSchemaFormal{
|
good := VSchemaFormal{
|
||||||
Keyspaces: map[string]KeyspaceFormal{
|
Keyspaces: map[string]KeyspaceFormal{
|
||||||
"ksa": {
|
"ksa": {
|
||||||
Tables: map[string]string{
|
Tables: map[string]TableFormal{
|
||||||
"t1": "",
|
"t1": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ksb": {
|
"ksb": {
|
||||||
Tables: map[string]string{
|
Tables: map[string]TableFormal{
|
||||||
"t1": "",
|
"t1": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
got, _ := BuildVSchema(&good)
|
got, _ := BuildVSchema(&good)
|
||||||
|
ksa := &Keyspace{
|
||||||
|
Name: "ksa",
|
||||||
|
}
|
||||||
t1a := &Table{
|
t1a := &Table{
|
||||||
Name: "t1",
|
Name: "t1",
|
||||||
Keyspace: &Keyspace{
|
Keyspace: ksa,
|
||||||
Name: "ksa",
|
}
|
||||||
},
|
ksb := &Keyspace{
|
||||||
|
Name: "ksb",
|
||||||
}
|
}
|
||||||
t1b := &Table{
|
t1b := &Table{
|
||||||
Name: "t1",
|
Name: "t1",
|
||||||
Keyspace: &Keyspace{
|
Keyspace: ksb,
|
||||||
Name: "ksb",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
want := &VSchema{
|
want := &VSchema{
|
||||||
tables: map[string]*Table{
|
tables: map[string]*Table{
|
||||||
|
@ -505,11 +464,13 @@ func TestBuildVSchemaDupTable(t *testing.T) {
|
||||||
},
|
},
|
||||||
Keyspaces: map[string]*KeyspaceSchema{
|
Keyspaces: map[string]*KeyspaceSchema{
|
||||||
"ksa": {
|
"ksa": {
|
||||||
|
Keyspace: ksa,
|
||||||
Tables: map[string]*Table{
|
Tables: map[string]*Table{
|
||||||
"t1": t1a,
|
"t1": t1a,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ksb": {
|
"ksb": {
|
||||||
|
Keyspace: ksb,
|
||||||
Tables: map[string]*Table{
|
Tables: map[string]*Table{
|
||||||
"t1": t1b,
|
"t1": t1b,
|
||||||
},
|
},
|
||||||
|
@ -533,7 +494,7 @@ func TestBuildVSchemaNoindexFail(t *testing.T) {
|
||||||
Type: "stfu",
|
Type: "stfu",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"t1": {
|
"t1": {
|
||||||
ColVindexes: []ColVindexFormal{
|
ColVindexes: []ColVindexFormal{
|
||||||
{
|
{
|
||||||
|
@ -543,14 +504,11 @@ func TestBuildVSchemaNoindexFail(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Tables: map[string]string{
|
|
||||||
"t1": "t1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, err := BuildVSchema(&bad)
|
_, 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 {
|
if err == nil || err.Error() != want {
|
||||||
t.Errorf("BuildVSchema: %v, want %v", err, want)
|
t.Errorf("BuildVSchema: %v, want %v", err, want)
|
||||||
}
|
}
|
||||||
|
@ -566,7 +524,7 @@ func TestBuildVSchemaNotUniqueFail(t *testing.T) {
|
||||||
Type: "stln",
|
Type: "stln",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"t1": {
|
"t1": {
|
||||||
ColVindexes: []ColVindexFormal{
|
ColVindexes: []ColVindexFormal{
|
||||||
{
|
{
|
||||||
|
@ -576,14 +534,11 @@ func TestBuildVSchemaNotUniqueFail(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Tables: map[string]string{
|
|
||||||
"t1": "t1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, err := BuildVSchema(&bad)
|
_, 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 {
|
if err == nil || err.Error() != want {
|
||||||
t.Errorf("BuildVSchema: %v, want %v", err, want)
|
t.Errorf("BuildVSchema: %v, want %v", err, want)
|
||||||
}
|
}
|
||||||
|
@ -600,7 +555,7 @@ func TestBuildVSchemaPrimaryNonFunctionalFail(t *testing.T) {
|
||||||
Owner: "t1",
|
Owner: "t1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"t1": {
|
"t1": {
|
||||||
ColVindexes: []ColVindexFormal{
|
ColVindexes: []ColVindexFormal{
|
||||||
{
|
{
|
||||||
|
@ -610,14 +565,11 @@ func TestBuildVSchemaPrimaryNonFunctionalFail(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Tables: map[string]string{
|
|
||||||
"t1": "t1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, err := BuildVSchema(&bad)
|
_, 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 {
|
if err == nil || err.Error() != want {
|
||||||
t.Errorf("BuildVSchema: %v, want %v", err, want)
|
t.Errorf("BuildVSchema: %v, want %v", err, want)
|
||||||
}
|
}
|
||||||
|
@ -627,14 +579,11 @@ func TestSequence(t *testing.T) {
|
||||||
good := VSchemaFormal{
|
good := VSchemaFormal{
|
||||||
Keyspaces: map[string]KeyspaceFormal{
|
Keyspaces: map[string]KeyspaceFormal{
|
||||||
"unsharded": {
|
"unsharded": {
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"seq": {
|
"seq": {
|
||||||
Type: "Sequence",
|
Type: "Sequence",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Tables: map[string]string{
|
|
||||||
"seq": "seq",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"sharded": {
|
"sharded": {
|
||||||
Sharded: true,
|
Sharded: true,
|
||||||
|
@ -646,7 +595,7 @@ func TestSequence(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"t1": {
|
"t1": {
|
||||||
ColVindexes: []ColVindexFormal{
|
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 {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
ksu := &Keyspace{
|
||||||
|
Name: "unsharded",
|
||||||
|
}
|
||||||
|
kss := &Keyspace{
|
||||||
|
Name: "sharded",
|
||||||
|
Sharded: true,
|
||||||
|
}
|
||||||
seq := &Table{
|
seq := &Table{
|
||||||
Name: "seq",
|
Name: "seq",
|
||||||
Keyspace: &Keyspace{
|
Keyspace: ksu,
|
||||||
Name: "unsharded",
|
|
||||||
},
|
|
||||||
IsSequence: true,
|
IsSequence: true,
|
||||||
}
|
}
|
||||||
t1 := &Table{
|
t1 := &Table{
|
||||||
Name: "t1",
|
Name: "t1",
|
||||||
Keyspace: &Keyspace{
|
Keyspace: kss,
|
||||||
Name: "sharded",
|
|
||||||
Sharded: true,
|
|
||||||
},
|
|
||||||
ColVindexes: []*ColVindex{
|
ColVindexes: []*ColVindex{
|
||||||
{
|
{
|
||||||
Col: "c1",
|
Col: "c1",
|
||||||
|
@ -711,12 +659,13 @@ func TestSequence(t *testing.T) {
|
||||||
},
|
},
|
||||||
Keyspaces: map[string]*KeyspaceSchema{
|
Keyspaces: map[string]*KeyspaceSchema{
|
||||||
"unsharded": {
|
"unsharded": {
|
||||||
|
Keyspace: ksu,
|
||||||
Tables: map[string]*Table{
|
Tables: map[string]*Table{
|
||||||
"seq": seq,
|
"seq": seq,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sharded": {
|
"sharded": {
|
||||||
Sharded: true,
|
Keyspace: kss,
|
||||||
Tables: map[string]*Table{
|
Tables: map[string]*Table{
|
||||||
"t1": t1,
|
"t1": t1,
|
||||||
},
|
},
|
||||||
|
@ -735,7 +684,7 @@ func TestBadSequence(t *testing.T) {
|
||||||
Keyspaces: map[string]KeyspaceFormal{
|
Keyspaces: map[string]KeyspaceFormal{
|
||||||
"sharded": {
|
"sharded": {
|
||||||
Sharded: true,
|
Sharded: true,
|
||||||
Classes: map[string]ClassFormal{
|
Tables: map[string]TableFormal{
|
||||||
"t1": {
|
"t1": {
|
||||||
Autoinc: &AutoincFormal{
|
Autoinc: &AutoincFormal{
|
||||||
Col: "c1",
|
Col: "c1",
|
||||||
|
@ -743,14 +692,11 @@ func TestBadSequence(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Tables: map[string]string{
|
|
||||||
"t1": "t1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, err := BuildVSchema(&bad)
|
_, 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 {
|
if err == nil || err.Error() != want {
|
||||||
t.Errorf("BuildVSchema: %v, want %v", err, want)
|
t.Errorf("BuildVSchema: %v, want %v", err, want)
|
||||||
}
|
}
|
||||||
|
@ -760,47 +706,108 @@ func TestFind(t *testing.T) {
|
||||||
input := VSchemaFormal{
|
input := VSchemaFormal{
|
||||||
Keyspaces: map[string]KeyspaceFormal{
|
Keyspaces: map[string]KeyspaceFormal{
|
||||||
"ksa": {
|
"ksa": {
|
||||||
Tables: map[string]string{
|
Tables: map[string]TableFormal{
|
||||||
"ta": "",
|
"ta": {},
|
||||||
"t1": "",
|
"t1": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ksb": {
|
"ksb": {
|
||||||
Tables: map[string]string{
|
Sharded: true,
|
||||||
"tb": "",
|
Tables: map[string]TableFormal{
|
||||||
"t1": "",
|
"tb": {},
|
||||||
|
"t1": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
vschema, _ := BuildVSchema(&input)
|
vschema, _ := BuildVSchema(&input)
|
||||||
_, err := vschema.FindTable("")
|
_, err := vschema.Find("", "t1")
|
||||||
wantErr := "unsupported: compex table expression in DML"
|
wantErr := "ambiguous table reference: t1"
|
||||||
if err == nil || err.Error() != wantErr {
|
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")
|
_, err = vschema.Find("", "none")
|
||||||
wantErr = "ambiguous table reference: t1"
|
|
||||||
if err == nil || err.Error() != wantErr {
|
|
||||||
t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr)
|
|
||||||
}
|
|
||||||
_, err = vschema.FindTable("none")
|
|
||||||
wantErr = "table none not found"
|
wantErr = "table none not found"
|
||||||
if err == nil || err.Error() != wantErr {
|
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 {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
want := &Table{
|
ta := &Table{
|
||||||
Name: "ta",
|
Name: "ta",
|
||||||
Keyspace: &Keyspace{
|
Keyspace: &Keyspace{
|
||||||
Name: "ksa",
|
Name: "ksa",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(got, want) {
|
if !reflect.DeepEqual(got, ta) {
|
||||||
t.Errorf("FindTable(\"t1a\"): %+v, want %+v", got, want)
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
// 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()
|
startTime := time.Now()
|
||||||
statsKey := []string{"Execute", "Any", strings.ToLower(tabletType.String())}
|
statsKey := []string{"Execute", "Any", strings.ToLower(tabletType.String())}
|
||||||
defer vtg.timings.Record(statsKey, startTime)
|
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
|
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 {
|
if err == nil {
|
||||||
vtg.rowsReturned.Add(statsKey, int64(len(qr.Rows)))
|
vtg.rowsReturned.Add(statsKey, int64(len(qr.Rows)))
|
||||||
return qr, nil
|
return qr, nil
|
||||||
|
@ -177,6 +177,7 @@ func (vtg *VTGate) Execute(ctx context.Context, sql string, bindVariables map[st
|
||||||
query := map[string]interface{}{
|
query := map[string]interface{}{
|
||||||
"Sql": sql,
|
"Sql": sql,
|
||||||
"BindVariables": bindVariables,
|
"BindVariables": bindVariables,
|
||||||
|
"Keyspace": keyspace,
|
||||||
"TabletType": strings.ToLower(tabletType.String()),
|
"TabletType": strings.ToLower(tabletType.String()),
|
||||||
"Session": session,
|
"Session": session,
|
||||||
"NotInTransaction": notInTransaction,
|
"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.
|
// 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()
|
startTime := time.Now()
|
||||||
statsKey := []string{"StreamExecute", "Any", strings.ToLower(tabletType.String())}
|
statsKey := []string{"StreamExecute", "Any", strings.ToLower(tabletType.String())}
|
||||||
defer vtg.timings.Record(statsKey, startTime)
|
defer vtg.timings.Record(statsKey, startTime)
|
||||||
|
@ -426,6 +427,7 @@ func (vtg *VTGate) StreamExecute(ctx context.Context, sql string, bindVariables
|
||||||
ctx,
|
ctx,
|
||||||
sql,
|
sql,
|
||||||
bindVariables,
|
bindVariables,
|
||||||
|
keyspace,
|
||||||
tabletType,
|
tabletType,
|
||||||
func(reply *sqltypes.Result) error {
|
func(reply *sqltypes.Result) error {
|
||||||
rowCount += int64(len(reply.Rows))
|
rowCount += int64(len(reply.Rows))
|
||||||
|
@ -438,6 +440,7 @@ func (vtg *VTGate) StreamExecute(ctx context.Context, sql string, bindVariables
|
||||||
query := map[string]interface{}{
|
query := map[string]interface{}{
|
||||||
"Sql": sql,
|
"Sql": sql,
|
||||||
"BindVariables": bindVariables,
|
"BindVariables": bindVariables,
|
||||||
|
"Keyspace": keyspace,
|
||||||
"TabletType": strings.ToLower(tabletType.String()),
|
"TabletType": strings.ToLower(tabletType.String()),
|
||||||
}
|
}
|
||||||
logError(err, query, vtg.logStreamExecute)
|
logError(err, query, vtg.logStreamExecute)
|
||||||
|
|
|
@ -35,7 +35,7 @@ func init() {
|
||||||
"TestUnsharded": {
|
"TestUnsharded": {
|
||||||
"Sharded": false,
|
"Sharded": false,
|
||||||
"Tables": {
|
"Tables": {
|
||||||
"t1": ""
|
"t1": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ func TestVTGateExecute(t *testing.T) {
|
||||||
qr, err := rpcVTGate.Execute(context.Background(),
|
qr, err := rpcVTGate.Execute(context.Background(),
|
||||||
"select id from t1",
|
"select id from t1",
|
||||||
nil,
|
nil,
|
||||||
|
"",
|
||||||
topodatapb.TabletType_MASTER,
|
topodatapb.TabletType_MASTER,
|
||||||
nil,
|
nil,
|
||||||
false)
|
false)
|
||||||
|
@ -68,6 +69,7 @@ func TestVTGateExecute(t *testing.T) {
|
||||||
rpcVTGate.Execute(context.Background(),
|
rpcVTGate.Execute(context.Background(),
|
||||||
"select id from t1",
|
"select id from t1",
|
||||||
nil,
|
nil,
|
||||||
|
"",
|
||||||
topodatapb.TabletType_MASTER,
|
topodatapb.TabletType_MASTER,
|
||||||
session,
|
session,
|
||||||
false)
|
false)
|
||||||
|
@ -95,12 +97,43 @@ func TestVTGateExecute(t *testing.T) {
|
||||||
rpcVTGate.Execute(context.Background(),
|
rpcVTGate.Execute(context.Background(),
|
||||||
"select id from t1",
|
"select id from t1",
|
||||||
nil,
|
nil,
|
||||||
|
"",
|
||||||
topodatapb.TabletType_MASTER,
|
topodatapb.TabletType_MASTER,
|
||||||
session,
|
session,
|
||||||
false)
|
false)
|
||||||
rpcVTGate.Rollback(context.Background(), session)
|
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) {
|
func TestVTGateExecuteShards(t *testing.T) {
|
||||||
sandbox := createSandbox("TestVTGateExecuteShards")
|
sandbox := createSandbox("TestVTGateExecuteShards")
|
||||||
sbc := &sandboxConn{}
|
sbc := &sandboxConn{}
|
||||||
|
@ -532,6 +565,7 @@ func TestVTGateStreamExecute(t *testing.T) {
|
||||||
err := rpcVTGate.StreamExecute(context.Background(),
|
err := rpcVTGate.StreamExecute(context.Background(),
|
||||||
"select id from t1",
|
"select id from t1",
|
||||||
nil,
|
nil,
|
||||||
|
"",
|
||||||
topodatapb.TabletType_MASTER,
|
topodatapb.TabletType_MASTER,
|
||||||
func(r *sqltypes.Result) error {
|
func(r *sqltypes.Result) error {
|
||||||
qrs = append(qrs, r)
|
qrs = append(qrs, r)
|
||||||
|
|
|
@ -74,13 +74,14 @@ func (f *fakeVTGateService) checkCallerID(ctx context.Context, name string) {
|
||||||
type queryExecute struct {
|
type queryExecute struct {
|
||||||
SQL string
|
SQL string
|
||||||
BindVariables map[string]interface{}
|
BindVariables map[string]interface{}
|
||||||
|
Keyspace string
|
||||||
TabletType topodatapb.TabletType
|
TabletType topodatapb.TabletType
|
||||||
Session *vtgatepb.Session
|
Session *vtgatepb.Session
|
||||||
NotInTransaction bool
|
NotInTransaction bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute is part of the VTGateService interface
|
// 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 {
|
if f.hasError {
|
||||||
return nil, errTestVtGateError
|
return nil, errTestVtGateError
|
||||||
}
|
}
|
||||||
|
@ -95,6 +96,7 @@ func (f *fakeVTGateService) Execute(ctx context.Context, sql string, bindVariabl
|
||||||
query := &queryExecute{
|
query := &queryExecute{
|
||||||
SQL: sql,
|
SQL: sql,
|
||||||
BindVariables: bindVariables,
|
BindVariables: bindVariables,
|
||||||
|
Keyspace: keyspace,
|
||||||
TabletType: tabletType,
|
TabletType: tabletType,
|
||||||
Session: session,
|
Session: session,
|
||||||
NotInTransaction: notInTransaction,
|
NotInTransaction: notInTransaction,
|
||||||
|
@ -370,7 +372,7 @@ func (f *fakeVTGateService) ExecuteBatchKeyspaceIds(ctx context.Context, queries
|
||||||
}
|
}
|
||||||
|
|
||||||
// StreamExecute is part of the VTGateService interface
|
// 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 {
|
if f.panics {
|
||||||
panic(fmt.Errorf("test forced panic"))
|
panic(fmt.Errorf("test forced panic"))
|
||||||
}
|
}
|
||||||
|
@ -382,6 +384,7 @@ func (f *fakeVTGateService) StreamExecute(ctx context.Context, sql string, bindV
|
||||||
query := &queryExecute{
|
query := &queryExecute{
|
||||||
SQL: sql,
|
SQL: sql,
|
||||||
BindVariables: bindVariables,
|
BindVariables: bindVariables,
|
||||||
|
Keyspace: keyspace,
|
||||||
TabletType: tabletType,
|
TabletType: tabletType,
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(query, execCase.execQuery) {
|
if !reflect.DeepEqual(query, execCase.execQuery) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
type VTGateService interface {
|
type VTGateService interface {
|
||||||
// Regular query execution.
|
// Regular query execution.
|
||||||
// All these methods can change the provided session.
|
// 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)
|
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)
|
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)
|
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)
|
ExecuteBatchKeyspaceIds(ctx context.Context, queries []*vtgatepb.BoundKeyspaceIdQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session) ([]sqltypes.Result, error)
|
||||||
|
|
||||||
// Streaming queries
|
// 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
|
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
|
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
|
StreamExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]interface{}, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, sendReply func(*sqltypes.Result) error) error
|
||||||
|
|
|
@ -33,15 +33,15 @@ func (_m *MockVTGateService) EXPECT() *_MockVTGateServiceRecorder {
|
||||||
return _m.recorder
|
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) {
|
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, tabletType, session, notInTransaction)
|
ret := _m.ctrl.Call(_m, "Execute", ctx, sql, bindVariables, keyspace, tabletType, session, notInTransaction)
|
||||||
ret0, _ := ret[0].(*sqltypes.Result)
|
ret0, _ := ret[0].(*sqltypes.Result)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_mr *_MockVTGateServiceRecorder) Execute(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
|
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)
|
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) {
|
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)
|
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 {
|
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, tabletType, sendReply)
|
ret := _m.ctrl.Call(_m, "StreamExecute", ctx, sql, bindVariables, keyspace, tabletType, sendReply)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_mr *_MockVTGateServiceRecorder) StreamExecute(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
|
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)
|
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 {
|
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 {
|
||||||
|
|
|
@ -41,6 +41,9 @@ message ExecuteRequest {
|
||||||
|
|
||||||
// not_in_transaction is deprecated and should not be used.
|
// not_in_transaction is deprecated and should not be used.
|
||||||
bool not_in_transaction = 5;
|
bool not_in_transaction = 5;
|
||||||
|
|
||||||
|
// keyspace to target the query to.
|
||||||
|
string keyspace = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecuteResponse is the returned value from Execute.
|
// 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.
|
// tablet_type is the type of tablets that this query is targeted to.
|
||||||
topodata.TabletType tablet_type = 3;
|
topodata.TabletType tablet_type = 3;
|
||||||
|
|
||||||
|
// keyspace to target the query to.
|
||||||
|
string keyspace = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// StreamExecuteResponse is the returned value from StreamExecute.
|
// StreamExecuteResponse is the returned value from StreamExecute.
|
||||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -126,7 +126,7 @@ vschema = '''{
|
||||||
"Owner": "vt_music"
|
"Owner": "vt_music"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Classes": {
|
"Tables": {
|
||||||
"vt_user": {
|
"vt_user": {
|
||||||
"ColVindexes": [
|
"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": {
|
"lookup": {
|
||||||
"Sharded": false,
|
"Sharded": false,
|
||||||
"Classes" : {
|
|
||||||
"seq": {
|
|
||||||
"Type": "Sequence"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Tables": {
|
"Tables": {
|
||||||
"vt_user_seq": "seq",
|
"vt_user_seq": {
|
||||||
"vt_music_seq": "seq",
|
"Type": "Sequence"
|
||||||
"music_user_map": "",
|
},
|
||||||
"name_user2_map": ""
|
"vt_music_seq": {
|
||||||
|
"Type": "Sequence"
|
||||||
|
},
|
||||||
|
"music_user_map": {},
|
||||||
|
"name_user2_map": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче