diff --git a/go/test/endtoend/vtgate/system_schema_test.go b/go/test/endtoend/vtgate/system_schema_test.go index 5954ee5af76..8e5c29f3b5f 100644 --- a/go/test/endtoend/vtgate/system_schema_test.go +++ b/go/test/endtoend/vtgate/system_schema_test.go @@ -78,6 +78,8 @@ func TestInformationSchemaQuery(t *testing.T) { assertResultIsEmpty(t, conn, "table_schema = 'PERFORMANCE_SCHEMA'") assertSingleRowIsReturned(t, conn, "table_schema = 'performance_schema' and table_name = 'users'", "performance_schema") assertResultIsEmpty(t, conn, "table_schema = 'performance_schema' and table_name = 'foo'") + assertSingleRowIsReturned(t, conn, "table_schema = 'vt_ks' and table_name = 't1'", "vt_ks") + assertSingleRowIsReturned(t, conn, "table_schema = 'ks' and table_name = 't1'", "vt_ks") } func assertResultIsEmpty(t *testing.T, conn *mysql.Conn, pre string) { @@ -187,3 +189,29 @@ func TestSystemSchemaQueryWithoutQualifier(t *testing.T) { qr3 := exec(t, conn2, queryWithoutQualifier) require.Equal(t, qr2, qr3) } + +func TestMultipleSchemaPredicates(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + query := fmt.Sprintf("select t.table_schema,t.table_name,c.column_name,c.column_type "+ + "from information_schema.tables t "+ + "join information_schema.columns c "+ + "on c.table_schema = t.table_schema and c.table_name = t.table_name "+ + "where t.table_schema = '%s' and c.table_schema = '%s' and c.table_schema = '%s' and c.table_schema = '%s'", KeyspaceName, KeyspaceName, KeyspaceName, KeyspaceName) + qr1 := exec(t, conn, query) + require.EqualValues(t, 4, len(qr1.Fields)) + + // test a query with two keyspace names + query = fmt.Sprintf("select t.table_schema,t.table_name,c.column_name,c.column_type "+ + "from information_schema.tables t "+ + "join information_schema.columns c "+ + "on c.table_schema = t.table_schema and c.table_name = t.table_name "+ + "where t.table_schema = '%s' and c.table_schema = '%s' and c.table_schema = '%s'", KeyspaceName, KeyspaceName, "a") + _, err = conn.ExecuteFetch(query, 1000, true) + require.Error(t, err) + require.Contains(t, err.Error(), "specifying two different database in the query is not supported") +} diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index 61407b556f2..598d3e3af47 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -94,8 +94,8 @@ type Route struct { ScatterErrorsAsWarnings bool // The following two fields are used when routing information_schema queries - SysTableTableSchema evalengine.Expr - SysTableTableName evalengine.Expr + SysTableTableSchema []evalengine.Expr + SysTableTableName []evalengine.Expr // Route does not take inputs noInputs @@ -408,7 +408,7 @@ func (route *Route) routeInfoSchemaQuery(vcursor VCursor, bindVars map[string]*q return destinations, vterrors.Wrapf(err, "failed to find information about keyspace `%s`", ks) } - if route.SysTableTableName == nil && route.SysTableTableSchema == nil { + if len(route.SysTableTableName) == 0 && len(route.SysTableTableSchema) == 0 { return defaultRoute() } @@ -418,22 +418,38 @@ func (route *Route) routeInfoSchemaQuery(vcursor VCursor, bindVars map[string]*q } var specifiedKS string - if route.SysTableTableSchema != nil { - result, err := route.SysTableTableSchema.Evaluate(env) + for _, tableSchema := range route.SysTableTableSchema { + result, err := tableSchema.Evaluate(env) if err != nil { return nil, err } - specifiedKS = result.Value().ToString() + ks := result.Value().ToString() + if specifiedKS == "" { + specifiedKS = ks + } + if specifiedKS != ks { + return nil, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "specifying two different database in the query is not supported") + } + } + if specifiedKS != "" { bindVars[sqltypes.BvSchemaName] = sqltypes.StringBindVariable(specifiedKS) } var tableName string - if route.SysTableTableName != nil { - val, err := route.SysTableTableName.Evaluate(env) + for _, sysTableName := range route.SysTableTableName { + val, err := sysTableName.Evaluate(env) if err != nil { return nil, err } - tableName = val.Value().ToString() + tabName := val.Value().ToString() + if tableName == "" { + tableName = tabName + } + if tableName != tabName { + return nil, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "two predicates for table_name not supported") + } + } + if tableName != "" { bindVars[BvTableName] = sqltypes.StringBindVariable(tableName) } @@ -446,6 +462,11 @@ func (route *Route) routeInfoSchemaQuery(vcursor VCursor, bindVars map[string]*q if tableName != "" { rss, err := route.paramsRoutedTable(vcursor, bindVars, specifiedKS, tableName) if err != nil { + // Only if keyspace is not found in vschema, we try with default keyspace. + // As the in the table_schema predicates for a keyspace 'ks' it can contain 'vt_ks'. + if vterrors.Code(err) == vtrpcpb.Code_NOT_FOUND { + return defaultRoute() + } return nil, err } if rss != nil { @@ -723,11 +744,27 @@ func (route *Route) description() PrimitiveDescription { if len(route.Values) > 0 { other["Values"] = route.Values } - if route.SysTableTableSchema != nil { - other["SysTableTableSchema"] = route.SysTableTableSchema.String() - } - if route.SysTableTableName != nil { - other["SysTableTableName"] = route.SysTableTableName.String() + if len(route.SysTableTableSchema) != 0 { + sysTabSchema := "[" + for idx, tableSchema := range route.SysTableTableSchema { + if idx != 0 { + sysTabSchema += ", " + } + sysTabSchema += tableSchema.String() + } + sysTabSchema += "]" + other["SysTableTableSchema"] = sysTabSchema + } + if len(route.SysTableTableName) != 0 { + sysTableName := "[" + for idx, tableName := range route.SysTableTableName { + if idx != 0 { + sysTableName += ", " + } + sysTableName += tableName.String() + } + sysTableName += "]" + other["SysTableTableName"] = sysTableName } orderBy := GenericJoin(route.OrderBy, orderByToString) if orderBy != "" { diff --git a/go/vt/vtgate/engine/route_test.go b/go/vt/vtgate/engine/route_test.go index bb8bad02339..93deb22a727 100644 --- a/go/vt/vtgate/engine/route_test.go +++ b/go/vt/vtgate/engine/route_test.go @@ -78,23 +78,24 @@ func TestSelectUnsharded(t *testing.T) { } func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) { - stringToExpr := func(in string) evalengine.Expr { - var schema evalengine.Expr - if in != "" { - schema = evalengine.NewLiteralString([]byte(in)) + stringListToExprList := func(in []string) []evalengine.Expr { + var schema []evalengine.Expr + for _, s := range in { + schema = append(schema, evalengine.NewLiteralString([]byte(s))) } return schema } type testCase struct { - tableSchema, tableName, testName string - expectedLog []string - routed bool + tableSchema, tableName []string + testName string + expectedLog []string + routed bool } tests := []testCase{{ testName: "both schema and table predicates - routed table", - tableSchema: "schema", - tableName: "table", + tableSchema: []string{"schema"}, + tableName: []string{"table"}, routed: true, expectedLog: []string{ "FindTable(`schema`.`table`)", @@ -102,8 +103,17 @@ func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) "ExecuteMultiShard routedKeyspace.1: dummy_select {__replacevtschemaname: type:INT64 value:\"1\" __vttablename: type:VARBINARY value:\"routedTable\" } false false"}, }, { testName: "both schema and table predicates - not routed", - tableSchema: "schema", - tableName: "table", + tableSchema: []string{"schema"}, + tableName: []string{"table"}, + routed: false, + expectedLog: []string{ + "FindTable(`schema`.`table`)", + "ResolveDestinations schema [] Destinations:DestinationAnyShard()", + "ExecuteMultiShard schema.1: dummy_select {__replacevtschemaname: type:INT64 value:\"1\" __vttablename: type:VARBINARY value:\"table\" } false false"}, + }, { + testName: "multiple schema and table predicates", + tableSchema: []string{"schema", "schema", "schema"}, + tableName: []string{"table", "table", "table"}, routed: false, expectedLog: []string{ "FindTable(`schema`.`table`)", @@ -111,7 +121,7 @@ func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) "ExecuteMultiShard schema.1: dummy_select {__replacevtschemaname: type:INT64 value:\"1\" __vttablename: type:VARBINARY value:\"table\" } false false"}, }, { testName: "table name predicate - routed table", - tableName: "tableName", + tableName: []string{"tableName"}, routed: true, expectedLog: []string{ "FindTable(tableName)", @@ -119,7 +129,7 @@ func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) "ExecuteMultiShard routedKeyspace.1: dummy_select {__vttablename: type:VARBINARY value:\"routedTable\" } false false"}, }, { testName: "table name predicate - not routed", - tableName: "tableName", + tableName: []string{"tableName"}, routed: false, expectedLog: []string{ "FindTable(tableName)", @@ -127,7 +137,13 @@ func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) "ExecuteMultiShard ks.1: dummy_select {__vttablename: type:VARBINARY value:\"tableName\" } false false"}, }, { testName: "schema predicate", - tableSchema: "myKeyspace", + tableSchema: []string{"myKeyspace"}, + expectedLog: []string{ + "ResolveDestinations myKeyspace [] Destinations:DestinationAnyShard()", + "ExecuteMultiShard myKeyspace.1: dummy_select {__replacevtschemaname: type:INT64 value:\"1\" } false false"}, + }, { + testName: "multiple schema predicates", + tableSchema: []string{"myKeyspace", "myKeyspace", "myKeyspace", "myKeyspace"}, expectedLog: []string{ "ResolveDestinations myKeyspace [] Destinations:DestinationAnyShard()", "ExecuteMultiShard myKeyspace.1: dummy_select {__replacevtschemaname: type:INT64 value:\"1\" } false false"}, @@ -148,8 +164,8 @@ func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) }, Query: "dummy_select", FieldQuery: "dummy_select_field", - SysTableTableSchema: stringToExpr(tc.tableSchema), - SysTableTableName: stringToExpr(tc.tableName), + SysTableTableSchema: stringListToExprList(tc.tableSchema), + SysTableTableName: stringListToExprList(tc.tableName), } vc := &loggingVCursor{ shards: []string{"1"}, diff --git a/go/vt/vtgate/evalengine/expressions.go b/go/vt/vtgate/evalengine/expressions.go index baafbe8a0c2..a32badee480 100644 --- a/go/vt/vtgate/evalengine/expressions.go +++ b/go/vt/vtgate/evalengine/expressions.go @@ -327,15 +327,3 @@ func evaluateByType(val *querypb.BindVariable) (EvalResult, error) { func (e *EvalResult) debugString() string { return fmt.Sprintf("(%s) %d %d %f %s", querypb.Type_name[int32(e.typ)], e.ival, e.uval, e.fval, string(e.bytes)) } - -// AreExprEqual checks if the provided Expr are the same or not -func AreExprEqual(expr1 Expr, expr2 Expr) bool { - // Check the types of the two expressions, if they don't match then the two are not equal - if fmt.Sprintf("%T", expr1) != fmt.Sprintf("%T", expr2) { - return false - } - if expr1.String() == expr2.String() { - return true - } - return false -} diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 7ea60e1ac2f..99cb73273f4 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -69,8 +69,8 @@ func TestSelectDBA(t *testing.T) { require.NoError(t, err) wantQueries := []*querypb.BoundQuery{{Sql: query, BindVariables: map[string]*querypb.BindVariable{}}} utils.MustMatch(t, wantQueries, sbc1.Queries) - sbc1.Queries = nil + sbc1.Queries = nil query = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'performance_schema' AND table_name = 'foo'" _, err = executor.Execute(context.Background(), "TestSelectDBA", NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}), @@ -84,6 +84,33 @@ func TestSelectDBA(t *testing.T) { }}} utils.MustMatch(t, wantQueries, sbc1.Queries) + sbc1.Queries = nil + query = "select 1 from information_schema.table_constraints where constraint_schema = 'vt_ks' and table_name = 'user'" + _, err = executor.Execute(context.Background(), "TestSelectDBA", + NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}), + query, map[string]*querypb.BindVariable{}, + ) + require.NoError(t, err) + wantQueries = []*querypb.BoundQuery{{Sql: "select 1 from information_schema.table_constraints where constraint_schema = :__vtschemaname and table_name = :__vttablename", + BindVariables: map[string]*querypb.BindVariable{ + "__vtschemaname": sqltypes.StringBindVariable("vt_ks"), + "__vttablename": sqltypes.StringBindVariable("user"), + }}} + utils.MustMatch(t, wantQueries, sbc1.Queries) + + sbc1.Queries = nil + query = "select 1 from information_schema.table_constraints where constraint_schema = 'vt_ks'" + _, err = executor.Execute(context.Background(), "TestSelectDBA", + NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}), + query, map[string]*querypb.BindVariable{}, + ) + require.NoError(t, err) + wantQueries = []*querypb.BoundQuery{{Sql: "select 1 from information_schema.table_constraints where constraint_schema = :__vtschemaname", + BindVariables: map[string]*querypb.BindVariable{ + "__vtschemaname": sqltypes.StringBindVariable("vt_ks"), + }}} + utils.MustMatch(t, wantQueries, sbc1.Queries) + } func TestUnsharded(t *testing.T) { @@ -2290,7 +2317,7 @@ func TestSelectFromInformationSchema(t *testing.T) { // check failure when trying to query two keyspaces _, err := exec(executor, session, "SELECT B.TABLE_NAME FROM INFORMATION_SCHEMA.TABLES AS A, INFORMATION_SCHEMA.COLUMNS AS B WHERE A.TABLE_SCHEMA = 'TestExecutor' AND A.TABLE_SCHEMA = 'TestXBadSharding'") require.Error(t, err) - require.Contains(t, err.Error(), "two predicates for specifying the database are not supported") + require.Contains(t, err.Error(), "specifying two different database in the query is not supported") // we pick a keyspace and query for table_schema = database(). should be routed to the picked keyspace session.TargetString = "TestExecutor" diff --git a/go/vt/vtgate/planbuilder/route.go b/go/vt/vtgate/planbuilder/route.go index ea6baaa24c7..5e921e0abec 100644 --- a/go/vt/vtgate/planbuilder/route.go +++ b/go/vt/vtgate/planbuilder/route.go @@ -392,15 +392,7 @@ func (rb *route) JoinCanMerge(pb *primitiveBuilder, rrb *route, ajoin *sqlparser if where == nil { return true } - hasRuntimeRoutingPredicates := false - sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { - col, ok := node.(*sqlparser.ColName) - if ok { - hasRuntimeRoutingPredicates = hasRuntimeRoutingPredicates || isTableNameCol(col) || isDbNameCol(col) - } - return !hasRuntimeRoutingPredicates, nil - }, where) - return !hasRuntimeRoutingPredicates + return ajoin != nil } if ajoin == nil { return false diff --git a/go/vt/vtgate/planbuilder/system_tables.go b/go/vt/vtgate/planbuilder/system_tables.go index 84ee0d323d7..3d073d63a65 100644 --- a/go/vt/vtgate/planbuilder/system_tables.go +++ b/go/vt/vtgate/planbuilder/system_tables.go @@ -18,9 +18,7 @@ package planbuilder import ( "vitess.io/vitess/go/sqltypes" - vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/evalengine" ) @@ -36,15 +34,9 @@ func (pb *primitiveBuilder) findSysInfoRoutingPredicates(expr sqlparser.Expr, ru } if isTableSchema { - if rut.eroute.SysTableTableSchema != nil && !evalengine.AreExprEqual(rut.eroute.SysTableTableSchema, out) { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "two predicates for specifying the database are not supported") - } - rut.eroute.SysTableTableSchema = out + rut.eroute.SysTableTableSchema = append(rut.eroute.SysTableTableSchema, out) } else { - if rut.eroute.SysTableTableName != nil && !evalengine.AreExprEqual(rut.eroute.SysTableTableName, out) { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "two predicates for table_name not supported") - } - rut.eroute.SysTableTableName = out + rut.eroute.SysTableTableName = append(rut.eroute.SysTableTableName, out) } return nil diff --git a/go/vt/vtgate/planbuilder/testdata/filter_cases.txt b/go/vt/vtgate/planbuilder/testdata/filter_cases.txt index a2ba4862a31..308c97f6afb 100644 --- a/go/vt/vtgate/planbuilder/testdata/filter_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/filter_cases.txt @@ -1683,7 +1683,21 @@ # query trying to query two different keyspaces at the same time "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'user' AND TABLE_SCHEMA = 'main'" -"two predicates for specifying the database are not supported" +{ + "QueryType": "SELECT", + "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'user' AND TABLE_SCHEMA = 'main'", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", + "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname and TABLE_SCHEMA = :__vtschemaname", + "SysTableTableSchema": "[VARBINARY(\"user\"), VARBINARY(\"main\")]" + } +} # information_schema query using database() func "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = database()" @@ -1716,7 +1730,7 @@ }, "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname", - "SysTableTableSchema": "VARBINARY(\"ks\")" + "SysTableTableSchema": "[VARBINARY(\"ks\")]" } } @@ -1751,8 +1765,8 @@ }, "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname and TABLE_NAME = :__vttablename", - "SysTableTableName": "VARBINARY(\"route1\")", - "SysTableTableSchema": "VARBINARY(\"ks\")" + "SysTableTableName": "[VARBINARY(\"route1\")]", + "SysTableTableSchema": "[VARBINARY(\"ks\")]" } } @@ -1770,7 +1784,7 @@ }, "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname and other_column = 42", - "SysTableTableSchema": "VARBINARY(\"ks\")" + "SysTableTableSchema": "[VARBINARY(\"ks\")]" } } diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.txt b/go/vt/vtgate/planbuilder/testdata/from_cases.txt index e918b9d902f..a50a63fcee0 100644 --- a/go/vt/vtgate/planbuilder/testdata/from_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/from_cases.txt @@ -2192,34 +2192,15 @@ "QueryType": "SELECT", "Original": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as name, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = ':vtg1' and rc.constraint_schema = database() and rc.table_name = ':vtg1'", "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "1,2,3,4,-1,-2", - "TableName": "_", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select rc.update_rule as on_update, rc.delete_rule as on_delete, rc.constraint_schema, rc.constraint_name from information_schema.referential_constraints as rc where 1 != 1", - "Query": "select rc.update_rule as on_update, rc.delete_rule as on_delete, rc.constraint_schema, rc.constraint_name from information_schema.referential_constraints as rc where rc.constraint_schema = database() and rc.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\":vtg1\")" - }, - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name` from information_schema.key_column_usage as fk where 1 != 1", - "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name` from information_schema.key_column_usage as fk where fk.constraint_schema = :rc_constraint_schema and fk.constraint_name = :rc_constraint_name and fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\":vtg1\")" - } - ] + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk on rc.constraint_schema = fk.constraint_schema and rc.constraint_name = fk.constraint_name where 1 != 1", + "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk on rc.constraint_schema = fk.constraint_schema and rc.constraint_name = fk.constraint_name where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = :__vttablename and rc.constraint_schema = database() and rc.table_name = :__vttablename", + "SysTableTableName": "[VARBINARY(\":vtg1\"), VARBINARY(\":vtg1\")]" } } @@ -2237,7 +2218,7 @@ }, "FieldQuery": "select * from information_schema.schemata where 1 != 1", "Query": "select * from information_schema.schemata where schema_name = :__vtschemaname", - "SysTableTableSchema": "VARBINARY(\"user\")" + "SysTableTableSchema": "[VARBINARY(\"user\")]" } } @@ -2255,8 +2236,8 @@ }, "FieldQuery": "select table_comment from information_schema.`tables` where 1 != 1", "Query": "select table_comment from information_schema.`tables` where table_schema = :__vtschemaname and table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"schema_name\")" + "SysTableTableName": "[VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"schema_name\")]" } } @@ -2266,36 +2247,16 @@ "QueryType": "SELECT", "Original": "SELECT fk.referenced_table_name AS 'to_table', fk.referenced_column_name AS 'primary_key',fk.column_name AS 'column',fk.constraint_name AS 'name',rc.update_rule AS 'on_update',rc.delete_rule AS 'on_delete' FROM information_schema.referential_constraints rc JOIN information_schema.key_column_usage fk USING (constraint_schema, constraint_name) WHERE fk.referenced_column_name IS NOT NULL AND fk.table_schema = 'table_schema' AND fk.table_name = 'table_name' AND rc.constraint_schema = 'table_schema' AND rc.table_name = 'table_name'", "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "1,2,3,4,-1,-2", - "TableName": "_", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select rc.update_rule as on_update, rc.delete_rule as on_delete, rc.constraint_schema, rc.constraint_name from information_schema.referential_constraints as rc where 1 != 1", - "Query": "select rc.update_rule as on_update, rc.delete_rule as on_delete, rc.constraint_schema, rc.constraint_name from information_schema.referential_constraints as rc where rc.constraint_schema = :__vtschemaname and rc.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" - }, - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name` from information_schema.key_column_usage as fk where 1 != 1", - "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name` from information_schema.key_column_usage as fk where fk.constraint_schema = :rc_constraint_schema and fk.constraint_name = :rc_constraint_name and fk.referenced_column_name is not null and fk.table_schema = :__vtschemaname and fk.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" - } - ] + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk on rc.constraint_schema = fk.constraint_schema and rc.constraint_name = fk.constraint_name where 1 != 1", + "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk on rc.constraint_schema = fk.constraint_schema and rc.constraint_name = fk.constraint_name where fk.referenced_column_name is not null and fk.table_schema = :__vtschemaname and fk.table_name = :__vttablename and rc.constraint_schema = :__vtschemaname and rc.table_name = :__vttablename", + "SysTableTableName": "[VARBINARY(\"table_name\"), VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"table_schema\"), VARBINARY(\"table_schema\")]" } } @@ -2305,35 +2266,16 @@ "QueryType": "SELECT", "Original": "SELECT cc.constraint_name AS 'name', cc.check_clause AS 'expression' FROM information_schema.check_constraints cc JOIN information_schema.table_constraints tc USING (constraint_schema, constraint_name) WHERE tc.table_schema = 'table_schema' AND tc.table_name = 'table_name' AND cc.constraint_schema = 'constraint_schema'", "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "-1,-2", - "TableName": "_", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select cc.constraint_name as `name`, cc.check_clause as expression, cc.constraint_schema from information_schema.check_constraints as cc where 1 != 1", - "Query": "select cc.constraint_name as `name`, cc.check_clause as expression, cc.constraint_schema from information_schema.check_constraints as cc where cc.constraint_schema = :__vtschemaname", - "SysTableTableSchema": "VARBINARY(\"constraint_schema\")" - }, - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from information_schema.table_constraints as tc where 1 != 1", - "Query": "select 1 from information_schema.table_constraints as tc where tc.constraint_schema = :cc_constraint_schema and tc.constraint_name = :cc_constraint_name and tc.table_schema = :__vtschemaname and tc.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" - } - ] + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select cc.constraint_name as `name`, cc.check_clause as expression from information_schema.check_constraints as cc join information_schema.table_constraints as tc on cc.constraint_schema = tc.constraint_schema and cc.constraint_name = tc.constraint_name where 1 != 1", + "Query": "select cc.constraint_name as `name`, cc.check_clause as expression from information_schema.check_constraints as cc join information_schema.table_constraints as tc on cc.constraint_schema = tc.constraint_schema and cc.constraint_name = tc.constraint_name where tc.table_schema = :__vtschemaname and tc.table_name = :__vttablename and cc.constraint_schema = :__vtschemaname", + "SysTableTableName": "[VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"table_schema\"), VARBINARY(\"constraint_schema\")]" } } @@ -2351,8 +2293,8 @@ }, "FieldQuery": "select column_name from information_schema.statistics where 1 != 1", "Query": "select column_name from information_schema.statistics where index_name = 'PRIMARY' and table_schema = :__vtschemaname and table_name = :__vttablename order by seq_in_index asc", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" + "SysTableTableName": "[VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"table_schema\")]" } } @@ -2370,8 +2312,8 @@ }, "FieldQuery": "select generation_expression from information_schema.`columns` where 1 != 1", "Query": "select generation_expression from information_schema.`columns` where table_schema = :__vtschemaname and table_name = :__vttablename and column_name = 'column_name'", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" + "SysTableTableName": "[VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"table_schema\")]" } } @@ -2406,7 +2348,7 @@ }, "FieldQuery": "select table_name from (select * from information_schema.`tables` where 1 != 1) as _subquery where 1 != 1", "Query": "select table_name from (select * from information_schema.`tables` where table_schema = :__vtschemaname) as _subquery", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" + "SysTableTableSchema": "[VARBINARY(\"table_schema\")]" } } @@ -2424,8 +2366,8 @@ }, "FieldQuery": "select table_name from (select * from information_schema.`tables` where 1 != 1) as _subquery where 1 != 1", "Query": "select table_name from (select * from information_schema.`tables` where table_schema = :__vtschemaname) as _subquery where _subquery.table_type = 'table_type' and _subquery.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" + "SysTableTableName": "[VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"table_schema\")]" } } @@ -2443,7 +2385,7 @@ }, "FieldQuery": "select cc.constraint_name as `name` from information_schema.check_constraints as cc where 1 != 1", "Query": "select cc.constraint_name as `name` from information_schema.check_constraints as cc where cc.constraint_schema = :__vtschemaname and cc.table_schema = :__vtschemaname", - "SysTableTableSchema": "VARBINARY(\"a\")" + "SysTableTableSchema": "[VARBINARY(\"a\"), VARBINARY(\"a\")]" } } @@ -2461,7 +2403,7 @@ }, "FieldQuery": "select COUNT(*) from INFORMATION_SCHEMA.`TABLES` where 1 != 1", "Query": "select COUNT(*) from INFORMATION_SCHEMA.`TABLES` where table_schema = :__vtschemaname and table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"foo\")", - "SysTableTableSchema": "VARBINARY(\"performance_schema\")" + "SysTableTableName": "[VARBINARY(\"foo\")]", + "SysTableTableSchema": "[VARBINARY(\"performance_schema\")]" } } diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.txt b/go/vt/vtgate/planbuilder/testdata/select_cases.txt index e80cb524aef..b94fd79accd 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.txt @@ -1661,3 +1661,97 @@ ] } } + +# Select from information schema query with two tables that route should be merged +"SELECT DELETE_RULE, UPDATE_RULE FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.COLUMN_NAME = 'id' AND KCU.REFERENCED_TABLE_SCHEMA = 'test' AND KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME" +{ + "QueryType": "SELECT", + "Original": "SELECT DELETE_RULE, UPDATE_RULE FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.COLUMN_NAME = 'id' AND KCU.REFERENCED_TABLE_SCHEMA = 'test' AND KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select DELETE_RULE, UPDATE_RULE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where 1 != 1", + "Query": "select DELETE_RULE, UPDATE_RULE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where KCU.TABLE_SCHEMA = :__vtschemaname and KCU.TABLE_NAME = :__vttablename and KCU.COLUMN_NAME = 'id' and KCU.REFERENCED_TABLE_SCHEMA = 'test' and KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' order by KCU.CONSTRAINT_NAME asc, KCU.COLUMN_NAME asc", + "SysTableTableName": "[VARBINARY(\"data_type_table\")]", + "SysTableTableSchema": "[VARBINARY(\"test\")]" + } +} + +# Select from information schema query with three tables such that route for 2 should be merged but not for the last. +"SELECT KCU.DELETE_RULE, S.UPDATE_RULE FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME, INFORMATION_SCHEMA.K AS S WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.TABLE_NAME = 'data_type_table' AND S.TABLE_SCHEMA = 'test' AND S.TABLE_NAME = 'sc' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME" +{ + "QueryType": "SELECT", + "Original": "SELECT KCU.DELETE_RULE, S.UPDATE_RULE FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME, INFORMATION_SCHEMA.K AS S WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.TABLE_NAME = 'data_type_table' AND S.TABLE_SCHEMA = 'test' AND S.TABLE_NAME = 'sc' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "-1,1", + "TableName": "_", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select KCU.DELETE_RULE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where 1 != 1", + "Query": "select KCU.DELETE_RULE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where KCU.TABLE_SCHEMA = :__vtschemaname and KCU.TABLE_NAME = :__vttablename and KCU.TABLE_NAME = :__vttablename order by KCU.CONSTRAINT_NAME asc, KCU.COLUMN_NAME asc", + "SysTableTableName": "[VARBINARY(\"data_type_table\"), VARBINARY(\"data_type_table\")]", + "SysTableTableSchema": "[VARBINARY(\"test\")]" + }, + { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select S.UPDATE_RULE from INFORMATION_SCHEMA.K as S where 1 != 1", + "Query": "select S.UPDATE_RULE from INFORMATION_SCHEMA.K as S where S.TABLE_SCHEMA = :__vtschemaname and S.TABLE_NAME = :__vttablename", + "SysTableTableName": "[VARBINARY(\"sc\")]", + "SysTableTableSchema": "[VARBINARY(\"test\")]" + } + ] + } +} + +#information_schema table sizes +"SELECT SUM(data_length + index_length) as size FROM information_schema.TABLES WHERE table_schema = ?" +{ + "QueryType": "SELECT", + "Original": "SELECT SUM(data_length + index_length) as size FROM information_schema.TABLES WHERE table_schema = ?", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select SUM(data_length + index_length) as size from information_schema.`TABLES` where 1 != 1", + "Query": "select SUM(data_length + index_length) as size from information_schema.`TABLES` where table_schema = :__vtschemaname", + "SysTableTableSchema": "[:v1]" + } +} + +#information_schema referential contraints +"SELECT kcu.constraint_name constraint_name, kcu.column_name column_name, kcu.referenced_table_name referenced_table_name, kcu.referenced_column_name referenced_column_name, kcu.ordinal_position ordinal_position, kcu.table_name table_name, rc.delete_rule delete_rule, rc.update_rule update_rule FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON kcu.constraint_name = rc.constraint_name WHERE kcu.table_schema = ? AND rc.constraint_schema = ? AND kcu.referenced_column_name IS NOT NULL ORDER BY ordinal_position" +{ + "QueryType": "SELECT", + "Original": "SELECT kcu.constraint_name constraint_name, kcu.column_name column_name, kcu.referenced_table_name referenced_table_name, kcu.referenced_column_name referenced_column_name, kcu.ordinal_position ordinal_position, kcu.table_name table_name, rc.delete_rule delete_rule, rc.update_rule update_rule FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON kcu.constraint_name = rc.constraint_name WHERE kcu.table_schema = ? AND rc.constraint_schema = ? AND kcu.referenced_column_name IS NOT NULL ORDER BY ordinal_position", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select kcu.constraint_name as constraint_name, kcu.column_name as column_name, kcu.referenced_table_name as referenced_table_name, kcu.referenced_column_name as referenced_column_name, kcu.ordinal_position as ordinal_position, kcu.table_name as table_name, rc.delete_rule as delete_rule, rc.update_rule as update_rule from information_schema.key_column_usage as kcu join information_schema.referential_constraints as rc on kcu.constraint_name = rc.constraint_name where 1 != 1", + "Query": "select kcu.constraint_name as constraint_name, kcu.column_name as column_name, kcu.referenced_table_name as referenced_table_name, kcu.referenced_column_name as referenced_column_name, kcu.ordinal_position as ordinal_position, kcu.table_name as table_name, rc.delete_rule as delete_rule, rc.update_rule as update_rule from information_schema.key_column_usage as kcu join information_schema.referential_constraints as rc on kcu.constraint_name = rc.constraint_name where kcu.table_schema = :__vtschemaname and rc.constraint_schema = :__vtschemaname and kcu.referenced_column_name is not null order by ordinal_position asc", + "SysTableTableSchema": "[:v1, :v2]" + } +} diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt index 4bb18995a80..99970fe9d1a 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt @@ -379,8 +379,23 @@ "unsupported: this construct is not supported on sharded keyspace" # unsupported two predicates specifying the database for the same table if they are different +# will fail on run time but will pass on the planbuilder "SELECT cc.constraint_name AS 'name' FROM information_schema.check_constraints cc WHERE cc.constraint_schema = 'constraint_schema' AND cc.table_schema = 'a'" -"two predicates for specifying the database are not supported" +{ + "QueryType": "SELECT", + "Original": "SELECT cc.constraint_name AS 'name' FROM information_schema.check_constraints cc WHERE cc.constraint_schema = 'constraint_schema' AND cc.table_schema = 'a'", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select cc.constraint_name as `name` from information_schema.check_constraints as cc where 1 != 1", + "Query": "select cc.constraint_name as `name` from information_schema.check_constraints as cc where cc.constraint_schema = :__vtschemaname and cc.table_schema = :__vtschemaname", + "SysTableTableSchema": "[VARBINARY(\"constraint_schema\"), VARBINARY(\"a\")]" + } +} # create view with Cannot auto-resolve for cross-shard joins "create view user.view_a as select col from user join user_extra" diff --git a/go/vt/vtgate/vindexes/vschema.go b/go/vt/vtgate/vindexes/vschema.go index 3054b611dde..7e5c4d70623 100644 --- a/go/vt/vtgate/vindexes/vschema.go +++ b/go/vt/vtgate/vindexes/vschema.go @@ -23,6 +23,9 @@ import ( "io/ioutil" "sort" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/json2" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/sqlparser" @@ -481,7 +484,7 @@ func (vschema *VSchema) findTable(keyspace, tablename string) (*Table, error) { } ks, ok := vschema.Keyspaces[keyspace] if !ok { - return nil, fmt.Errorf("keyspace %s not found in vschema", keyspace) + return nil, vterrors.Errorf(vtrpcpb.Code_NOT_FOUND, "keyspace %s not found in vschema", keyspace) } table := ks.Tables[tablename] if table == nil { @@ -559,7 +562,7 @@ func (vschema *VSchema) FindVindex(keyspace, name string) (Vindex, error) { } ks, ok := vschema.Keyspaces[keyspace] if !ok { - return nil, fmt.Errorf("keyspace %s not found in vschema", keyspace) + return nil, vterrors.Errorf(vtrpcpb.Code_NOT_FOUND, "keyspace %s not found in vschema", keyspace) } return ks.Vindexes[name], nil } diff --git a/go/vt/vtgate/vindexes/vschema_test.go b/go/vt/vtgate/vindexes/vschema_test.go index 823b46f4e8c..0dc1782d47b 100644 --- a/go/vt/vtgate/vindexes/vschema_test.go +++ b/go/vt/vtgate/vindexes/vschema_test.go @@ -2156,33 +2156,24 @@ func TestFindTable(t *testing.T) { } vschema, _ := BuildVSchema(&input) _, err := vschema.FindTable("", "t1") - wantErr := "ambiguous table reference: t1" - if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) - } + require.EqualError(t, err, "ambiguous table reference: t1") + _, err = vschema.FindTable("", "none") - wantErr = "table none not found" - if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) - } - got, err := vschema.FindTable("", "ta") - if err != nil { - t.Error(err) - return - } + require.EqualError(t, err, "table none not found") + ta := &Table{ Name: sqlparser.NewTableIdent("ta"), Keyspace: &Keyspace{ Name: "ksa", }, } - if !reflect.DeepEqual(got, ta) { - t.Errorf("FindTable(\"t1a\"): %+v, want %+v", got, ta) - } + got, err := vschema.FindTable("", "ta") + require.NoError(t, err) + require.Equal(t, ta, got) + got, _ = vschema.FindTable("ksa", "ta") - if !reflect.DeepEqual(got, ta) { - t.Errorf("FindTable(\"t1a\"): %+v, want %+v", got, ta) - } + require.Equal(t, ta, got) + none := &Table{ Name: sqlparser.NewTableIdent("none"), Keyspace: &Keyspace{ @@ -2190,19 +2181,13 @@ func TestFindTable(t *testing.T) { }, } got, _ = vschema.FindTable("ksa", "none") - if !reflect.DeepEqual(got, none) { - t.Errorf("FindTable(\"t1a\"): %+v, want %+v", got, none) - } + require.Equal(t, none, got) + _, err = vschema.FindTable("ksb", "none") - wantErr = "table none not found" - if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) - } + require.EqualError(t, err, "table none not found") + _, err = vschema.FindTable("none", "aa") - wantErr = "keyspace none not found in vschema" - if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) - } + require.EqualError(t, err, "keyspace none not found in vschema") } func TestFindTableOrVindex(t *testing.T) { diff --git a/go/vt/vtgate/vtgate_test.go b/go/vt/vtgate/vtgate_test.go index ff465ff4931..01ddb499c0a 100644 --- a/go/vt/vtgate/vtgate_test.go +++ b/go/vt/vtgate/vtgate_test.go @@ -21,6 +21,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "context" "github.com/golang/protobuf/proto" @@ -140,9 +142,7 @@ func TestVTGateExecuteWithKeyspaceShard(t *testing.T) { nil, ) want := "vtgate: : keyspace invalid_keyspace not found in vschema" - if err == nil || err.Error() != want { - t.Errorf("Execute: %v, want %s", err, want) - } + assert.EqualError(t, err, want) // Valid keyspace/shard. _, qr, err = rpcVTGate.Execute(