diff --git a/go/mysql/schema.go b/go/mysql/schema.go index 3a59c771f6e..c67517c08ce 100644 --- a/go/mysql/schema.go +++ b/go/mysql/schema.go @@ -98,43 +98,6 @@ order by table_name, ordinal_position` // GetColumnNamesQueryPatternForTable is used for mocking queries in unit tests GetColumnNamesQueryPatternForTable = `SELECT COLUMN_NAME.*TABLE_NAME.*%s.*` - - // DetectViewChange query detects if there is any view change from previous copy. - DetectViewChange = ` -SELECT distinct table_name -FROM ( - SELECT table_name, view_definition - FROM information_schema.views - WHERE table_schema = database() - - UNION ALL - - SELECT table_name, view_definition - FROM %s.views - WHERE table_schema = database() -) _inner -GROUP BY table_name, view_definition -HAVING COUNT(*) = 1 -` - // FetchViewDefinition retrieves view definition from information_schema.views table. - FetchViewDefinition = `select table_name, view_definition from information_schema.views -where table_schema = database() and table_name in ::tableNames` - - // FetchCreateStatement retrieves create statement. - FetchCreateStatement = `show create table %s` - - // DeleteFromViewsTable removes the views from the table. - DeleteFromViewsTable = `delete from %s.views where table_schema = database() and table_name in ::tableNames` - - // InsertIntoViewsTable using information_schema.views. - InsertIntoViewsTable = `insert %s.views(table_schema, table_name, create_statement, view_definition) -values (database(), :table_name, :create_statement, :view_definition)` - - // FetchUpdatedViews queries fetches information about updated views - FetchUpdatedViews = `select table_name, create_statement from %s.views where table_schema = database() and table_name in ::viewnames` - - // FetchViews queries fetches all views - FetchViews = `select table_name, create_statement from %s.views where table_schema = database()` ) // BaseShowTablesFields contains the fields returned by a BaseShowTables or a BaseShowTablesForTable command. diff --git a/go/test/endtoend/vreplication/sidecardb_test.go b/go/test/endtoend/vreplication/sidecardb_test.go index 3b796da908c..ef05e051be2 100644 --- a/go/test/endtoend/vreplication/sidecardb_test.go +++ b/go/test/endtoend/vreplication/sidecardb_test.go @@ -38,7 +38,7 @@ var ddls1, ddls2 []string func init() { sidecarDBTables = []string{"copy_state", "dt_participant", "dt_state", "heartbeat", "post_copy_action", "redo_state", - "redo_statement", "reparent_journal", "resharding_journal", "schema_engine_tables", "schema_engine_views", "schema_migrations", "schema_version", "schemacopy", + "redo_statement", "reparent_journal", "resharding_journal", "schema_migrations", "schema_version", "schemacopy", "tables", "vdiff", "vdiff_log", "vdiff_table", "views", "vreplication", "vreplication_log"} numSidecarDBTables = len(sidecarDBTables) ddls1 = []string{ diff --git a/go/vt/sidecardb/schema/schemaengine/schema_engine_views.sql b/go/vt/sidecardb/schema/schemaengine/schema_engine_views.sql deleted file mode 100644 index 43e0fe2f247..00000000000 --- a/go/vt/sidecardb/schema/schemaengine/schema_engine_views.sql +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright 2023 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -CREATE TABLE IF NOT EXISTS schema_engine_views -( - TABLE_SCHEMA varchar(64) NOT NULL, - TABLE_NAME varchar(64) NOT NULL, - CREATE_STATEMENT longtext, - VIEW_DEFINITION longtext NOT NULL, - PRIMARY KEY (TABLE_SCHEMA, TABLE_NAME) -) engine = InnoDB diff --git a/go/vt/sidecardb/schema/schemaengine/schema_engine_tables.sql b/go/vt/sidecardb/schema/schemaengine/tables.sql similarity index 94% rename from go/vt/sidecardb/schema/schemaengine/schema_engine_tables.sql rename to go/vt/sidecardb/schema/schemaengine/tables.sql index 5c5869c850b..00fd0194d67 100644 --- a/go/vt/sidecardb/schema/schemaengine/schema_engine_tables.sql +++ b/go/vt/sidecardb/schema/schemaengine/tables.sql @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -CREATE TABLE IF NOT EXISTS schema_engine_tables +CREATE TABLE IF NOT EXISTS tables ( TABLE_SCHEMA varchar(64) NOT NULL, TABLE_NAME varchar(64) NOT NULL, diff --git a/go/vt/sidecardb/schema/misc/views.sql b/go/vt/sidecardb/schema/schemaengine/views.sql similarity index 90% rename from go/vt/sidecardb/schema/misc/views.sql rename to go/vt/sidecardb/schema/schemaengine/views.sql index 36123fb0d85..1fee077202f 100644 --- a/go/vt/sidecardb/schema/misc/views.sql +++ b/go/vt/sidecardb/schema/schemaengine/views.sql @@ -20,6 +20,5 @@ CREATE TABLE IF NOT EXISTS views TABLE_NAME varchar(64) NOT NULL, CREATE_STATEMENT longtext, VIEW_DEFINITION longtext NOT NULL, - UPDATED_AT TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (TABLE_SCHEMA, TABLE_NAME) ) engine = InnoDB diff --git a/go/vt/sidecardb/sidecardb.go b/go/vt/sidecardb/sidecardb.go index e916f9982fd..e03dd76fe0b 100644 --- a/go/vt/sidecardb/sidecardb.go +++ b/go/vt/sidecardb/sidecardb.go @@ -368,7 +368,7 @@ func (si *schemaInit) setCurrentDatabase(dbName string) error { func (si *schemaInit) getCurrentSchema(tableName string) (string, error) { var currentTableSchema string - rs, err := si.exec(si.ctx, sqlparser.BuildParsedQuery(showCreateTableQuery, GetIdentifier(), tableName).Query, 1, false) + rs, err := si.exec(si.ctx, sqlparser.BuildParsedQuery(showCreateTableQuery, GetIdentifier(), sqlparser.String(sqlparser.NewIdentifierCS(tableName))).Query, 1, false) if err != nil { if sqlErr, ok := err.(*mysql.SQLError); ok && sqlErr.Number() == mysql.ERNoSuchTable { // table does not exist in the sidecar database diff --git a/go/vt/vttablet/endtoend/framework/client.go b/go/vt/vttablet/endtoend/framework/client.go index b06c78645e8..9d3abdbbf26 100644 --- a/go/vt/vttablet/endtoend/framework/client.go +++ b/go/vt/vttablet/endtoend/framework/client.go @@ -415,9 +415,11 @@ func (client *QueryClient) UpdateContext(ctx context.Context) { } func (client *QueryClient) GetSchema(tableType querypb.SchemaTableType, tableNames ...string) (map[string]string, error) { - schemaDef := map[string]string{} + schemaDef := make(map[string]string) err := client.server.GetSchema(client.ctx, client.target, tableType, tableNames, func(schemaRes *querypb.GetSchemaResponse) error { - schemaDef = schemaRes.TableDefinition + for tableName, schemaDefinition := range schemaRes.TableDefinition { + schemaDef[tableName] = schemaDefinition + } return nil }) if err != nil { diff --git a/go/vt/vttablet/endtoend/main_test.go b/go/vt/vttablet/endtoend/main_test.go index a809e7e42ae..d4a6bd70899 100644 --- a/go/vt/vttablet/endtoend/main_test.go +++ b/go/vt/vttablet/endtoend/main_test.go @@ -208,7 +208,7 @@ var tableACLConfig = `{ }, { "name": "vitess", - "table_names_or_prefixes": ["vitess_a", "vitess_b", "vitess_c", "dual", "vitess_d", "vitess_temp", "vitess_e", "vitess_f", "vitess_mixed_case", "upsert_test", "vitess_strings", "vitess_fracts", "vitess_ints", "vitess_misc", "vitess_bit_default", "vitess_big", "vitess_stress", "vitess_view", "vitess_json", "vitess_bool", "vitess_autoinc_seq"], + "table_names_or_prefixes": ["vitess_a", "vitess_b", "vitess_c", "dual", "vitess_d", "vitess_temp", "vitess_temp1", "vitess_temp2", "vitess_temp3", "vitess_e", "vitess_f", "vitess_mixed_case", "upsert_test", "vitess_strings", "vitess_fracts", "vitess_ints", "vitess_misc", "vitess_bit_default", "vitess_big", "vitess_stress", "vitess_view", "vitess_json", "vitess_bool", "vitess_autoinc_seq"], "readers": ["dev"], "writers": ["dev"], "admins": ["dev"] diff --git a/go/vt/vttablet/endtoend/rpc_test.go b/go/vt/vttablet/endtoend/rpc_test.go new file mode 100644 index 00000000000..a186d444f8d --- /dev/null +++ b/go/vt/vttablet/endtoend/rpc_test.go @@ -0,0 +1,218 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package endtoend + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/vt/callerid" + querypb "vitess.io/vitess/go/vt/proto/query" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vttablet/endtoend/framework" +) + +// TestGetSchemaRPC will validate GetSchema RPC. +func TestGetSchemaRPC(t *testing.T) { + testcases := []struct { + name string + queries []string + deferQueries []string + getSchemaQueryType querypb.SchemaTableType + getSchemaTables []string + mapToExpect map[string]string + }{ + { + name: "All views", + queries: []string{ + "create view vitess_view1 as select id from vitess_a", + "create view vitess_view2 as select id from vitess_b", + }, + deferQueries: []string{ + "drop view vitess_view1", + "drop view vitess_view2", + }, + mapToExpect: map[string]string{ + "vitess_view1": "CREATE ALGORITHM=UNDEFINED DEFINER=`vt_dba`@`localhost` SQL SECURITY DEFINER VIEW `vitess_view1` AS select `vitess_a`.`id` AS `id` from `vitess_a`", + "vitess_view2": "CREATE ALGORITHM=UNDEFINED DEFINER=`vt_dba`@`localhost` SQL SECURITY DEFINER VIEW `vitess_view2` AS select `vitess_b`.`id` AS `id` from `vitess_b`", + }, + getSchemaQueryType: querypb.SchemaTableType_VIEWS, + }, { + name: "Views listed", + queries: []string{ + "create view vitess_view1 as select eid from vitess_a", + "create view vitess_view2 as select eid from vitess_b", + "create view vitess_view3 as select eid from vitess_c", + }, + deferQueries: []string{ + "drop view vitess_view1", + "drop view vitess_view2", + "drop view vitess_view3", + }, + mapToExpect: map[string]string{ + "vitess_view3": "CREATE ALGORITHM=UNDEFINED DEFINER=`vt_dba`@`localhost` SQL SECURITY DEFINER VIEW `vitess_view3` AS select `vitess_c`.`eid` AS `eid` from `vitess_c`", + "vitess_view2": "CREATE ALGORITHM=UNDEFINED DEFINER=`vt_dba`@`localhost` SQL SECURITY DEFINER VIEW `vitess_view2` AS select `vitess_b`.`eid` AS `eid` from `vitess_b`", + // These shouldn't be part of the result so we verify it is empty. + "vitess_view1": "", + "unknown_view": "", + }, + getSchemaTables: []string{"vitess_view3", "vitess_view2", "unknown_view"}, + getSchemaQueryType: querypb.SchemaTableType_VIEWS, + }, { + name: "All tables", + queries: []string{ + "create table vitess_temp1 (id int);", + "create table vitess_temp2 (id int);", + "create table vitess_temp3 (id int);", + }, + deferQueries: []string{ + "drop table vitess_temp1", + "drop table vitess_temp2", + "drop table vitess_temp3", + }, + mapToExpect: map[string]string{ + "vitess_temp1": "CREATE TABLE `vitess_temp1` (\n `id` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + "vitess_temp2": "CREATE TABLE `vitess_temp2` (\n `id` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + "vitess_temp3": "CREATE TABLE `vitess_temp3` (\n `id` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + }, + getSchemaQueryType: querypb.SchemaTableType_TABLES, + }, { + name: "Tables listed", + queries: []string{ + "create table vitess_temp1 (eid int);", + "create table vitess_temp2 (eid int);", + "create table vitess_temp3 (eid int);", + }, + deferQueries: []string{ + "drop table vitess_temp1", + "drop table vitess_temp2", + "drop table vitess_temp3", + }, + mapToExpect: map[string]string{ + "vitess_temp1": "CREATE TABLE `vitess_temp1` (\n `eid` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + "vitess_temp3": "CREATE TABLE `vitess_temp3` (\n `eid` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + // These shouldn't be part of the result so we verify it is empty. + "vitess_temp2": "", + "unknown_table": "", + }, + getSchemaQueryType: querypb.SchemaTableType_TABLES, + getSchemaTables: []string{"vitess_temp1", "vitess_temp3", "unknown_table"}, + }, { + name: "All tables and views", + queries: []string{ + "create table vitess_temp1 (id int);", + "create table vitess_temp2 (id int);", + "create table vitess_temp3 (id int);", + "create view vitess_view1 as select id from vitess_a", + "create view vitess_view2 as select id from vitess_b", + }, + deferQueries: []string{ + "drop table vitess_temp1", + "drop table vitess_temp2", + "drop table vitess_temp3", + "drop view vitess_view1", + "drop view vitess_view2", + }, + mapToExpect: map[string]string{ + "vitess_view1": "CREATE ALGORITHM=UNDEFINED DEFINER=`vt_dba`@`localhost` SQL SECURITY DEFINER VIEW `vitess_view1` AS select `vitess_a`.`id` AS `id` from `vitess_a`", + "vitess_view2": "CREATE ALGORITHM=UNDEFINED DEFINER=`vt_dba`@`localhost` SQL SECURITY DEFINER VIEW `vitess_view2` AS select `vitess_b`.`id` AS `id` from `vitess_b`", + "vitess_temp1": "CREATE TABLE `vitess_temp1` (\n `id` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + "vitess_temp2": "CREATE TABLE `vitess_temp2` (\n `id` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + "vitess_temp3": "CREATE TABLE `vitess_temp3` (\n `id` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + }, + getSchemaQueryType: querypb.SchemaTableType_ALL, + }, { + name: "Listed tables and views", + queries: []string{ + "create table vitess_temp1 (eid int);", + "create table vitess_temp2 (eid int);", + "create table vitess_temp3 (eid int);", + "create view vitess_view1 as select eid from vitess_a", + "create view vitess_view2 as select eid from vitess_b", + "create view vitess_view3 as select eid from vitess_c", + }, + deferQueries: []string{ + "drop table vitess_temp1", + "drop table vitess_temp2", + "drop table vitess_temp3", + "drop view vitess_view1", + "drop view vitess_view2", + "drop view vitess_view3", + }, + mapToExpect: map[string]string{ + "vitess_view1": "CREATE ALGORITHM=UNDEFINED DEFINER=`vt_dba`@`localhost` SQL SECURITY DEFINER VIEW `vitess_view1` AS select `vitess_a`.`eid` AS `eid` from `vitess_a`", + "vitess_view3": "CREATE ALGORITHM=UNDEFINED DEFINER=`vt_dba`@`localhost` SQL SECURITY DEFINER VIEW `vitess_view3` AS select `vitess_c`.`eid` AS `eid` from `vitess_c`", + "vitess_temp1": "CREATE TABLE `vitess_temp1` (\n `eid` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + "vitess_temp3": "CREATE TABLE `vitess_temp3` (\n `eid` int DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", + // These shouldn't be part of the result so we verify it is empty. + "vitess_temp2": "", + "vitess_view2": "", + "unknown_view": "", + "unknown_table": "", + }, + getSchemaQueryType: querypb.SchemaTableType_ALL, + getSchemaTables: []string{"vitess_temp1", "vitess_temp3", "unknown_table", "vitess_view3", "vitess_view1", "unknown_view"}, + }, + } + + for _, testcase := range testcases { + t.Run(testcase.name, func(t *testing.T) { + client := framework.NewClient() + client.UpdateContext(callerid.NewContext( + context.Background(), + &vtrpcpb.CallerID{}, + &querypb.VTGateCallerID{Username: "dev"})) + + for _, query := range testcase.queries { + _, err := client.Execute(query, nil) + require.NoError(t, err) + } + defer func() { + for _, query := range testcase.deferQueries { + _, err := client.Execute(query, nil) + require.NoError(t, err) + } + }() + + timeout := 1 * time.Minute + wait := time.After(timeout) + for { + select { + case <-wait: + t.Errorf("Schema tracking hasn't caught up") + return + case <-time.After(1 * time.Second): + schemaDefs, err := client.GetSchema(testcase.getSchemaQueryType, testcase.getSchemaTables...) + require.NoError(t, err) + success := true + for tableName, expectedCreateStatement := range testcase.mapToExpect { + if schemaDefs[tableName] != expectedCreateStatement { + success = false + break + } + } + if success { + return + } + } + } + }) + } +} diff --git a/go/vt/vttablet/endtoend/views_test.go b/go/vt/vttablet/endtoend/views_test.go index e3e911e2c43..4ef70345180 100644 --- a/go/vt/vttablet/endtoend/views_test.go +++ b/go/vt/vttablet/endtoend/views_test.go @@ -271,31 +271,6 @@ func TestViewAndTableUnique(t *testing.T) { require.ErrorContains(t, err, "Table 'vitess_view' already exists") } -// TestGetSchemaRPC will validate GetSchema rpc.. -func TestGetSchemaRPC(t *testing.T) { - client := framework.NewClient() - - client.Execute("delete from _vt.views", nil) - viewSchemaDef, err := client.GetSchema(querypb.SchemaTableType_VIEWS) - require.NoError(t, err) - require.Zero(t, len(viewSchemaDef)) - - client.UpdateContext(callerid.NewContext( - context.Background(), - &vtrpcpb.CallerID{}, - &querypb.VTGateCallerID{Username: "dev"})) - - defer client.Execute("drop view vitess_view", nil) - - _, err = client.Execute("create view vitess_view as select 1 from vitess_a", nil) - require.NoError(t, err) - waitForResult(t, client, 1, 1*time.Minute) - - viewSchemaDef, err = client.GetSchema(querypb.SchemaTableType_VIEWS) - require.NoError(t, err) - require.Equal(t, "CREATE ALGORITHM=UNDEFINED DEFINER=`vt_dba`@`localhost` SQL SECURITY DEFINER VIEW `vitess_view` AS select 1 AS `1` from `vitess_a`", viewSchemaDef["vitess_view"]) -} - func waitForResult(t *testing.T, client *framework.QueryClient, rowCount int, timeout time.Duration) { t.Helper() wait := time.After(timeout) diff --git a/go/vt/vttablet/tabletserver/health_streamer.go b/go/vt/vttablet/tabletserver/health_streamer.go index fd641f1c8df..ad9acf495d8 100644 --- a/go/vt/vttablet/tabletserver/health_streamer.go +++ b/go/vt/vttablet/tabletserver/health_streamer.go @@ -27,14 +27,11 @@ import ( "github.com/spf13/pflag" - "vitess.io/vitess/go/vt/vttablet/tabletserver/planbuilder" "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/sidecardb" - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/dbconfigs" @@ -378,15 +375,6 @@ func (hs *healthStreamer) reload(full map[string]*schema.Table, created, altered if err != nil { return err } - err = hs.reloadViews(ctx, conn, views) - if err != nil { - if len(tables) == 0 { - return err - } - // there are some tables, we need to send that in the health stream. - // making views to nil will prevent any views notification. - views = nil - } // no change detected if len(tables) == 0 && len(views) == 0 { @@ -440,122 +428,3 @@ func (hs *healthStreamer) reloadTables(ctx context.Context, conn *connpool.DBCon } return nil } - -type viewDefAndStmt struct { - def string - stmt string -} - -func (hs *healthStreamer) reloadViews(ctx context.Context, conn *connpool.DBConn, views []string) error { - if len(views) == 0 { - return nil - } - - /* Retrieve changed views definition */ - viewsDefStmt := map[string]*viewDefAndStmt{} - callback := func(qr *sqltypes.Result) error { - for _, row := range qr.Rows { - viewsDefStmt[row[0].ToString()] = &viewDefAndStmt{def: row[1].ToString()} - } - return nil - } - alloc := func() *sqltypes.Result { return &sqltypes.Result{} } - bufferSize := 1000 - - viewsBV, err := sqltypes.BuildBindVariable(views) - if err != nil { - return err - } - bv := map[string]*querypb.BindVariable{"tableNames": viewsBV} - - err = hs.getViewDefinition(ctx, conn, bv, callback, alloc, bufferSize) - if err != nil { - return err - } - - /* Retrieve create statement for views */ - viewsDefStmt, err = hs.getCreateViewStatement(ctx, conn, viewsDefStmt) - if err != nil { - return err - } - - /* update the views copy table */ - err = hs.updateViewsTable(ctx, conn, bv, viewsDefStmt) - return err -} - -func (hs *healthStreamer) getViewDefinition(ctx context.Context, conn *connpool.DBConn, bv map[string]*querypb.BindVariable, callback func(qr *sqltypes.Result) error, alloc func() *sqltypes.Result, bufferSize int) error { - var viewsDefQuery string - viewsDefQuery = sqlparser.BuildParsedQuery(mysql.FetchViewDefinition).Query - - stmt, err := sqlparser.Parse(viewsDefQuery) - if err != nil { - return err - } - viewsDefQuery, err = planbuilder.GenerateFullQuery(stmt).GenerateQuery(bv, nil) - if err != nil { - return err - } - return conn.Stream(ctx, viewsDefQuery, callback, alloc, bufferSize, 0) -} - -func (hs *healthStreamer) getCreateViewStatement(ctx context.Context, conn *connpool.DBConn, viewsDefStmt map[string]*viewDefAndStmt) (map[string]*viewDefAndStmt, error) { - for k, v := range viewsDefStmt { - res, err := conn.Exec(ctx, sqlparser.BuildParsedQuery(mysql.FetchCreateStatement, k).Query, 1, false) - if err != nil { - return nil, err - } - for _, row := range res.Rows { - v.stmt = row[1].ToString() - } - } - return viewsDefStmt, nil -} - -func (hs *healthStreamer) updateViewsTable(ctx context.Context, conn *connpool.DBConn, bv map[string]*querypb.BindVariable, viewsDefStmt map[string]*viewDefAndStmt) error { - stmt, err := sqlparser.Parse( - sqlparser.BuildParsedQuery(mysql.DeleteFromViewsTable, sidecardb.GetIdentifier()).Query) - if err != nil { - return err - } - clearViewQuery, err := planbuilder.GenerateFullQuery(stmt).GenerateQuery(bv, nil) - if err != nil { - return err - } - - stmt, err = sqlparser.Parse( - sqlparser.BuildParsedQuery(mysql.InsertIntoViewsTable, sidecardb.GetIdentifier()).Query) - if err != nil { - return err - } - insertViewsParsedQuery := planbuilder.GenerateFullQuery(stmt) - - // Reload the views in a transaction. - _, err = conn.Exec(ctx, "begin", 1, false) - if err != nil { - return err - } - defer conn.Exec(ctx, "rollback", 1, false) - - _, err = conn.Exec(ctx, clearViewQuery, 1, false) - if err != nil { - return err - } - - for k, v := range viewsDefStmt { - bv["table_name"] = sqltypes.StringBindVariable(k) - bv["create_statement"] = sqltypes.StringBindVariable(v.stmt) - bv["view_definition"] = sqltypes.StringBindVariable(v.def) - insertViewQuery, err := insertViewsParsedQuery.GenerateQuery(bv, nil) - if err != nil { - return err - } - _, err = conn.Exec(ctx, insertViewQuery, 1, false) - if err != nil { - return err - } - } - - _, err = conn.Exec(ctx, "commit", 1, false) - return err -} diff --git a/go/vt/vttablet/tabletserver/health_streamer_test.go b/go/vt/vttablet/tabletserver/health_streamer_test.go index f3310abfd8b..7f19d640d7f 100644 --- a/go/vt/vttablet/tabletserver/health_streamer_test.go +++ b/go/vt/vttablet/tabletserver/health_streamer_test.go @@ -378,8 +378,8 @@ func TestReloadView(t *testing.T) { db.AddQuery(mysql.BaseShowPrimary, sqltypes.MakeTestResult( sqltypes.MakeTestFields("table_name | column_name", "varchar|varchar"), )) - db.AddQueryPattern(".*SELECT table_name, view_definition.*schema_engine_views.*", &sqltypes.Result{}) - db.AddQuery("SELECT TABLE_NAME, CREATE_TIME FROM _vt.schema_engine_tables", &sqltypes.Result{}) + db.AddQueryPattern(".*SELECT table_name, view_definition.*views.*", &sqltypes.Result{}) + db.AddQuery("SELECT TABLE_NAME, CREATE_TIME FROM _vt.`tables`", &sqltypes.Result{}) hs.InitDBConfig(target, configs.DbaWithDB()) se.InitDBConfig(configs.DbaWithDB()) @@ -411,7 +411,6 @@ func TestReloadView(t *testing.T) { viewDefinitionsOutput *sqltypes.Result expClearQuery string - expHsClearQuery string expInsertQuery []string expViewsChanged []string }{ @@ -427,13 +426,10 @@ func TestReloadView(t *testing.T) { expViewsChanged: []string{"view_a", "view_b"}, expGetViewDefinitionsQuery: "select table_name, view_definition from information_schema.views where table_schema = database() and table_name in ('view_a', 'view_b')", expCreateStmtQuery: []string{"show create table view_a", "show create table view_b"}, - expClearQuery: "delete from _vt.schema_engine_views where TABLE_SCHEMA = database() and TABLE_NAME in ('view_a', 'view_b')", - expHsClearQuery: "delete from _vt.views where table_schema = database() and table_name in ('view_a', 'view_b')", + expClearQuery: "delete from _vt.views where TABLE_SCHEMA = database() and TABLE_NAME in ('view_a', 'view_b')", expInsertQuery: []string{ - "insert into _vt.schema_engine_views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'view_a', 'create_view_a', 'def_a')", - "insert into _vt.schema_engine_views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'view_b', 'create_view_b', 'def_b')", - "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'view_a', 'create_view_a', 'def_a')", - "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'view_b', 'create_view_b', 'def_b')", + "insert into _vt.views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'view_a', 'create_view_a', 'def_a')", + "insert into _vt.views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'view_b', 'create_view_b', 'def_b')", }, }, { @@ -447,11 +443,9 @@ func TestReloadView(t *testing.T) { expViewsChanged: []string{"view_b"}, expGetViewDefinitionsQuery: "select table_name, view_definition from information_schema.views where table_schema = database() and table_name in ('view_b')", expCreateStmtQuery: []string{"show create table view_b"}, - expHsClearQuery: "delete from _vt.views where table_schema = database() and table_name in ('view_b')", - expClearQuery: "delete from _vt.schema_engine_views where TABLE_SCHEMA = database() and TABLE_NAME in ('view_b')", + expClearQuery: "delete from _vt.views where TABLE_SCHEMA = database() and TABLE_NAME in ('view_b')", expInsertQuery: []string{ - "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'view_b', 'create_view_mod_b', 'def_mod_b')", - "insert into _vt.schema_engine_views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'view_b', 'create_view_mod_b', 'def_mod_b')", + "insert into _vt.views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'view_b', 'create_view_mod_b', 'def_mod_b')", }, }, { @@ -467,19 +461,16 @@ func TestReloadView(t *testing.T) { expGetViewDefinitionsQuery: "select table_name, view_definition from information_schema.views where table_schema = database() and table_name in ('view_b', 'view_c', 'view_a')", expCreateStmtQuery: []string{"show create table view_a", "show create table view_c"}, expClearQuery: "delete from _vt.views where table_schema = database() and table_name in ('view_b', 'view_c', 'view_a')", - expHsClearQuery: "delete from _vt.schema_engine_views where TABLE_SCHEMA = database() and TABLE_NAME in ('view_b', 'view_c', 'view_a')", expInsertQuery: []string{ - "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'view_a', 'create_view_mod_a', 'def_mod_a')", - "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'view_c', 'create_view_c', 'def_c')", - "insert into _vt.schema_engine_views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'view_a', 'create_view_mod_a', 'def_mod_a')", - "insert into _vt.schema_engine_views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'view_c', 'create_view_c', 'def_c')", + "insert into _vt.views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'view_a', 'create_view_mod_a', 'def_mod_a')", + "insert into _vt.views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'view_c', 'create_view_c', 'def_c')", }, }, } // setting first test case result. db.AddQueryPattern("SELECT .* information_schema.innodb_tablespaces .*", tcases[0].showTablesWithSizesOutput) - db.AddQueryPattern(".*SELECT table_name, view_definition.*schema_engine_views.*", tcases[0].detectViewChangeOutput) + db.AddQueryPattern(".*SELECT table_name, view_definition.*views.*", tcases[0].detectViewChangeOutput) db.AddQuery(tcases[0].expGetViewDefinitionsQuery, tcases[0].viewDefinitionsOutput) for idx := range tcases[0].expCreateStmtQuery { @@ -489,7 +480,6 @@ func TestReloadView(t *testing.T) { db.AddQuery(tcases[0].expInsertQuery[idx], &sqltypes.Result{}) } db.AddQuery(tcases[0].expClearQuery, &sqltypes.Result{}) - db.AddQuery(tcases[0].expHsClearQuery, &sqltypes.Result{}) var tcCount atomic.Int32 ch := make(chan struct{}) @@ -500,7 +490,7 @@ func TestReloadView(t *testing.T) { sort.Strings(response.RealtimeStats.ViewSchemaChanged) assert.Equal(t, tcases[tcCount.Load()].expViewsChanged, response.RealtimeStats.ViewSchemaChanged) tcCount.Add(1) - db.AddQueryPattern(".*SELECT table_name, view_definition.*schema_engine_views.*", &sqltypes.Result{}) + db.AddQueryPattern(".*SELECT table_name, view_definition.*views.*", &sqltypes.Result{}) ch <- struct{}{} require.NoError(t, db.LastError()) } @@ -523,9 +513,8 @@ func TestReloadView(t *testing.T) { db.AddQuery(tcases[idx].expInsertQuery[i], &sqltypes.Result{}) } db.AddQuery(tcases[idx].expClearQuery, &sqltypes.Result{}) - db.AddQuery(tcases[idx].expHsClearQuery, &sqltypes.Result{}) db.AddQueryPattern("SELECT .* information_schema.innodb_tablespaces .*", tcases[idx].showTablesWithSizesOutput) - db.AddQueryPattern(".*SELECT table_name, view_definition.*schema_engine_views.*", tcases[idx].detectViewChangeOutput) + db.AddQueryPattern(".*SELECT table_name, view_definition.*views.*", tcases[idx].detectViewChangeOutput) case <-time.After(10 * time.Second): t.Fatalf("timed out") } diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index c55fb3ac6b1..0ac3dc78155 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -34,7 +34,6 @@ import ( "vitess.io/vitess/go/vt/callinfo" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/schema" - "vitess.io/vitess/go/vt/sidecardb" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/tableacl" "vitess.io/vitess/go/vt/vterrors" @@ -42,6 +41,7 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/connpool" p "vitess.io/vitess/go/vt/vttablet/tabletserver/planbuilder" "vitess.io/vitess/go/vt/vttablet/tabletserver/rules" + eschema "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" querypb "vitess.io/vitess/go/vt/proto/query" @@ -1124,46 +1124,50 @@ func (qre *QueryExecutor) GetSchemaDefinitions(tableType querypb.SchemaTableType switch tableType { case querypb.SchemaTableType_VIEWS: return qre.getViewDefinitions(tableNames, callback) + case querypb.SchemaTableType_TABLES: + return qre.getTableDefinitions(tableNames, callback) + case querypb.SchemaTableType_ALL: + return qre.getAllDefinitions(tableNames, callback) } return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid table type %v", tableType) } func (qre *QueryExecutor) getViewDefinitions(viewNames []string, callback func(schemaRes *querypb.GetSchemaResponse) error) error { - query := sqlparser.BuildParsedQuery(mysql.FetchViews, sidecardb.GetIdentifier()).Query - var bindVars map[string]*querypb.BindVariable - if len(viewNames) > 0 { - query = sqlparser.BuildParsedQuery(mysql.FetchUpdatedViews, sidecardb.GetIdentifier()).Query - bindVars = map[string]*querypb.BindVariable{ - "viewnames": sqltypes.StringBindVariable(strings.Join(viewNames, ",")), - } + query, err := eschema.GetFetchViewQuery(viewNames) + if err != nil { + return err } - return qre.generateFinalQueryAndStreamExecute(query, bindVars, func(result *sqltypes.Result) error { - schemaDef := make(map[string]string) - for _, row := range result.Rows { - schemaDef[row[0].ToString()] = row[1].ToString() - } - return callback(&querypb.GetSchemaResponse{TableDefinition: schemaDef}) - }) + return qre.executeGetSchemaQuery(query, callback) } -func (qre *QueryExecutor) generateFinalQueryAndStreamExecute(query string, bindVars map[string]*querypb.BindVariable, callback func(result *sqltypes.Result) error) error { - sql := query - if len(bindVars) > 0 { - stmt, err := sqlparser.Parse(query) - if err != nil { - return err - } - sql, _, err = qre.generateFinalSQL(sqlparser.NewParsedQuery(stmt), bindVars) - if err != nil { - return err - } +func (qre *QueryExecutor) getTableDefinitions(tableNames []string, callback func(schemaRes *querypb.GetSchemaResponse) error) error { + query, err := eschema.GetFetchTableQuery(tableNames) + if err != nil { + return err + } + return qre.executeGetSchemaQuery(query, callback) +} + +func (qre *QueryExecutor) getAllDefinitions(tableNames []string, callback func(schemaRes *querypb.GetSchemaResponse) error) error { + query, err := eschema.GetFetchTableAndViewsQuery(tableNames) + if err != nil { + return err } + return qre.executeGetSchemaQuery(query, callback) +} +func (qre *QueryExecutor) executeGetSchemaQuery(query string, callback func(schemaRes *querypb.GetSchemaResponse) error) error { conn, err := qre.getStreamConn() if err != nil { return err } defer conn.Recycle() - return qre.execStreamSQL(conn, false /* isTransaction */, sql, callback) + return qre.execStreamSQL(conn, false /* isTransaction */, query, func(result *sqltypes.Result) error { + schemaDef := make(map[string]string) + for _, row := range result.Rows { + schemaDef[row[0].ToString()] = row[1].ToString() + } + return callback(&querypb.GetSchemaResponse{TableDefinition: schemaDef}) + }) } diff --git a/go/vt/vttablet/tabletserver/schema/db.go b/go/vt/vttablet/tabletserver/schema/db.go index 89d794e9ffa..c8a33c17be0 100644 --- a/go/vt/vttablet/tabletserver/schema/db.go +++ b/go/vt/vttablet/tabletserver/schema/db.go @@ -28,14 +28,20 @@ import ( const ( // insertTableIntoSchemaEngineTables inserts a record in the datastore for the schema-engine tables. - insertTableIntoSchemaEngineTables = `INSERT INTO %s.schema_engine_tables(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, CREATE_TIME) + insertTableIntoSchemaEngineTables = `INSERT INTO %s.tables(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, CREATE_TIME) values (database(), :table_name, :create_statement, :create_time)` // deleteFromSchemaEngineTablesTable removes the tables from the table that have been modified. - deleteFromSchemaEngineTablesTable = `DELETE FROM %s.schema_engine_tables WHERE TABLE_SCHEMA = database() AND TABLE_NAME IN ::tableNames` + deleteFromSchemaEngineTablesTable = `DELETE FROM %s.tables WHERE TABLE_SCHEMA = database() AND TABLE_NAME IN ::tableNames` // readTableCreateTimes reads the tables create times - readTableCreateTimes = `SELECT TABLE_NAME, CREATE_TIME FROM %s.schema_engine_tables` + readTableCreateTimes = "SELECT TABLE_NAME, CREATE_TIME FROM %s.`tables`" + + // fetchUpdatedTables queries fetches information about updated tables + fetchUpdatedTables = `select table_name, create_statement from %s.tables where table_schema = database() and table_name in ::tableNames` + + // fetchTables queries fetches all information about tables + fetchTables = `select table_name, create_statement from %s.tables where table_schema = database()` // detectViewChange query detects if there is any view change from previous copy. detectViewChange = ` @@ -48,7 +54,7 @@ FROM ( UNION ALL SELECT table_name, view_definition - FROM %s.schema_engine_views + FROM %s.views WHERE table_schema = database() ) _inner GROUP BY table_name, view_definition @@ -56,11 +62,11 @@ HAVING COUNT(*) = 1 ` // insertViewIntoSchemaEngineViews using information_schema.views. - insertViewIntoSchemaEngineViews = `INSERT INTO %s.schema_engine_views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) + insertViewIntoSchemaEngineViews = `INSERT INTO %s.views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), :view_name, :create_statement, :view_definition)` // deleteFromSchemaEngineViewsTable removes the views from the table that have been modified. - deleteFromSchemaEngineViewsTable = `DELETE FROM %s.schema_engine_views WHERE TABLE_SCHEMA = database() AND TABLE_NAME IN ::viewNames` + deleteFromSchemaEngineViewsTable = `DELETE FROM %s.views WHERE TABLE_SCHEMA = database() AND TABLE_NAME IN ::viewNames` // fetchViewDefinitions retrieves view definition from information_schema.views table. fetchViewDefinitions = `select table_name, view_definition from information_schema.views @@ -68,6 +74,18 @@ where table_schema = database() and table_name in ::viewNames` // fetchCreateStatement retrieves create statement. fetchCreateStatement = `show create table %s` + + // fetchUpdatedViews queries fetches information about updated views + fetchUpdatedViews = `select table_name, create_statement from %s.views where table_schema = database() and table_name in ::viewNames` + + // fetchViews queries fetches all views + fetchViews = `select table_name, create_statement from %s.views where table_schema = database()` + + // fetchUpdatedTablesAndViews queries fetches information about updated tables and views + fetchUpdatedTablesAndViews = `select table_name, create_statement from %s.tables where table_schema = database() and table_name in ::tableNames union select table_name, create_statement from %s.views where table_schema = database() and table_name in ::tableNames` + + // fetchTablesAndViews queries fetches all information about tables and views + fetchTablesAndViews = `select table_name, create_statement from %s.tables where table_schema = database() union select table_name, create_statement from %s.views where table_schema = database()` ) // reloadTablesDataInDB reloads teh tables information we have stored in our database we use for schema-tracking. @@ -146,7 +164,7 @@ func reloadTablesDataInDB(ctx context.Context, conn *connpool.DBConn, tables []* // generateFullQuery generates the full query from the query as a string. func generateFullQuery(query string) (*sqlparser.ParsedQuery, error) { stmt, err := sqlparser.Parse( - sqlparser.BuildParsedQuery(query, sidecardb.GetIdentifier()).Query) + sqlparser.BuildParsedQuery(query, sidecardb.GetIdentifier(), sidecardb.GetIdentifier()).Query) if err != nil { return nil, err } @@ -372,3 +390,72 @@ func reloadDataInDB(ctx context.Context, conn *connpool.DBConn, altered []*Table } return nil } + +// GetFetchViewQuery gets the fetch query to run for getting the listed views. If no views are provided, then all the views are fetched. +func GetFetchViewQuery(viewNames []string) (string, error) { + if len(viewNames) == 0 { + parsedQuery, err := generateFullQuery(fetchViews) + if err != nil { + return "", err + } + return parsedQuery.Query, nil + } + + viewsBV, err := sqltypes.BuildBindVariable(viewNames) + if err != nil { + return "", err + } + bv := map[string]*querypb.BindVariable{"viewNames": viewsBV} + + parsedQuery, err := generateFullQuery(fetchUpdatedViews) + if err != nil { + return "", err + } + return parsedQuery.GenerateQuery(bv, nil) +} + +// GetFetchTableQuery gets the fetch query to run for getting the listed tables. If no tables are provided, then all the tables are fetched. +func GetFetchTableQuery(tableNames []string) (string, error) { + if len(tableNames) == 0 { + parsedQuery, err := generateFullQuery(fetchTables) + if err != nil { + return "", err + } + return parsedQuery.Query, nil + } + + tablesBV, err := sqltypes.BuildBindVariable(tableNames) + if err != nil { + return "", err + } + bv := map[string]*querypb.BindVariable{"tableNames": tablesBV} + + parsedQuery, err := generateFullQuery(fetchUpdatedTables) + if err != nil { + return "", err + } + return parsedQuery.GenerateQuery(bv, nil) +} + +// GetFetchTableAndViewsQuery gets the fetch query to run for getting the listed tables and views. If no table names are provided, then all the tables and views are fetched. +func GetFetchTableAndViewsQuery(tableNames []string) (string, error) { + if len(tableNames) == 0 { + parsedQuery, err := generateFullQuery(fetchTablesAndViews) + if err != nil { + return "", err + } + return parsedQuery.Query, nil + } + + tablesBV, err := sqltypes.BuildBindVariable(tableNames) + if err != nil { + return "", err + } + bv := map[string]*querypb.BindVariable{"tableNames": tablesBV} + + parsedQuery, err := generateFullQuery(fetchUpdatedTablesAndViews) + if err != nil { + return "", err + } + return parsedQuery.GenerateQuery(bv, nil) +} diff --git a/go/vt/vttablet/tabletserver/schema/db_test.go b/go/vt/vttablet/tabletserver/schema/db_test.go index 74f4b781566..a066b50a8c9 100644 --- a/go/vt/vttablet/tabletserver/schema/db_test.go +++ b/go/vt/vttablet/tabletserver/schema/db_test.go @@ -47,27 +47,31 @@ func TestGenerateFullQuery(t *testing.T) { }{ { name: "No bind variables", - query: "select TABLE_NAME, CREATE_TIME from schema_engine_tables", + query: "select TABLE_NAME, CREATE_TIME from `tables`", }, { name: "List bind variables", - query: "DELETE FROM %s.schema_engine_tables WHERE TABLE_SCHEMA = database() AND TABLE_NAME IN ::tableNames", + query: "DELETE FROM %s.`tables` WHERE TABLE_SCHEMA = database() AND TABLE_NAME IN ::tableNames", bv: map[string]*querypb.BindVariable{ "tableNames": tablesBV, }, - wantQuery: "delete from _vt.schema_engine_tables where TABLE_SCHEMA = database() and TABLE_NAME in ('t1', 'lead')", + wantQuery: "delete from _vt.`tables` where TABLE_SCHEMA = database() and TABLE_NAME in ('t1', 'lead')", }, { name: "Multiple bind variables", - query: "INSERT INTO %s.schema_engine_tables(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, CREATE_TIME) values (database(), :table_name, :create_statement, :create_time)", + query: "INSERT INTO %s.`tables`(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, CREATE_TIME) values (database(), :table_name, :create_statement, :create_time)", bv: map[string]*querypb.BindVariable{ "table_name": sqltypes.StringBindVariable("lead"), "create_statement": sqltypes.StringBindVariable("create table `lead`"), "create_time": sqltypes.Int64BindVariable(1), }, - wantQuery: "insert into _vt.schema_engine_tables(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, CREATE_TIME) values (database(), 'lead', 'create table `lead`', 1)", + wantQuery: "insert into _vt.`tables`(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, CREATE_TIME) values (database(), 'lead', 'create table `lead`', 1)", }, { name: "parser error", query: "insert syntax error", wantErr: "syntax error at position 20 near 'error'", + }, { + name: "Multiple %v replacements", + query: fetchTablesAndViews, + wantQuery: "select table_name, create_statement from _vt.`tables` where table_schema = database() union select table_name, create_statement from _vt.views where table_schema = database()", }, } for _, tt := range tests { @@ -150,7 +154,7 @@ func TestGetChangedViewNames(t *testing.T) { require.NoError(t, db.LastError()) // Failure - errMessage := "ERROR 1146 (42S02): Table '_vt.schema_engine_views' doesn't exist" + errMessage := "ERROR 1146 (42S02): Table '_vt.views' doesn't exist" db.AddRejectedQuery(query, errors.New(errMessage)) got, err = getChangedViewNames(context.Background(), conn, true) require.ErrorContains(t, err, errMessage) @@ -371,7 +375,7 @@ func TestReloadTablesInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_tables where table_schema = database() and table_name in ('t1', 'lead')": {}, + "delete from _vt.`tables` where table_schema = database() and table_name in ('t1', 'lead')": {}, }, }, { name: "Only tables to reload", @@ -390,13 +394,13 @@ func TestReloadTablesInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_tables where table_schema = database() and table_name in ('t1', 'lead')": {}, + "delete from _vt.`tables` where table_schema = database() and table_name in ('t1', 'lead')": {}, "show create table t1": sqltypes.MakeTestResult(showCreateTableFields, "t1|create_table_t1"), "show create table `lead`": sqltypes.MakeTestResult(showCreateTableFields, "lead|create_table_lead"), - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": {}, - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 'lead', 'create_table_lead', 1234)": {}, + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": {}, + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 'lead', 'create_table_lead', 1234)": {}, }, }, { name: "Reload and Delete", @@ -416,13 +420,13 @@ func TestReloadTablesInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_tables where table_schema = database() and table_name in ('t2', 'from', 't1', 'lead')": {}, + "delete from _vt.`tables` where table_schema = database() and table_name in ('t2', 'from', 't1', 'lead')": {}, "show create table t1": sqltypes.MakeTestResult(showCreateTableFields, "t1|create_table_t1"), "show create table `lead`": sqltypes.MakeTestResult(showCreateTableFields, "lead|create_table_lead"), - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": {}, - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 'lead', 'create_table_lead', 1234)": {}, + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": {}, + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 'lead', 'create_table_lead', 1234)": {}, }, }, { name: "Error In Insert", @@ -437,12 +441,12 @@ func TestReloadTablesInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_tables where table_schema = database() and table_name in ('t1')": {}, + "delete from _vt.`tables` where table_schema = database() and table_name in ('t1')": {}, "show create table t1": sqltypes.MakeTestResult(showCreateTableFields, "t1|create_table_t1"), }, queriesToReject: map[string]error{ - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": errors.New(errMessage), + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": errors.New(errMessage), }, expectedError: errMessage, }, @@ -492,7 +496,7 @@ func TestReloadViewsInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_views where table_schema = database() and table_name in ('v1', 'lead')": {}, + "delete from _vt.views where table_schema = database() and table_name in ('v1', 'lead')": {}, }, }, { name: "Only views to reload", @@ -511,7 +515,7 @@ func TestReloadViewsInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_views where table_schema = database() and table_name in ('v1', 'lead')": {}, + "delete from _vt.views where table_schema = database() and table_name in ('v1', 'lead')": {}, "select table_name, view_definition from information_schema.views where table_schema = database() and table_name in ('v1', 'lead')": sqltypes.MakeTestResult( getViewDefinitionsFields, "lead|select_lead", @@ -520,8 +524,8 @@ func TestReloadViewsInDB(t *testing.T) { "v1|create_view_v1|utf8mb4|utf8mb4_0900_ai_ci"), "show create table `lead`": sqltypes.MakeTestResult(showCreateTableFields, "lead|create_view_lead|utf8mb4|utf8mb4_0900_ai_ci"), - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": {}, - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'lead', 'create_view_lead', 'select_lead')": {}, + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": {}, + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'lead', 'create_view_lead', 'select_lead')": {}, }, }, { name: "Reload and delete", @@ -541,7 +545,7 @@ func TestReloadViewsInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_views where table_schema = database() and table_name in ('v2', 'from', 'v1', 'lead')": {}, + "delete from _vt.views where table_schema = database() and table_name in ('v2', 'from', 'v1', 'lead')": {}, "select table_name, view_definition from information_schema.views where table_schema = database() and table_name in ('v2', 'from', 'v1', 'lead')": sqltypes.MakeTestResult( getViewDefinitionsFields, "lead|select_lead", @@ -550,8 +554,8 @@ func TestReloadViewsInDB(t *testing.T) { "v1|create_view_v1|utf8mb4|utf8mb4_0900_ai_ci"), "show create table `lead`": sqltypes.MakeTestResult(showCreateTableFields, "lead|create_view_lead|utf8mb4|utf8mb4_0900_ai_ci"), - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": {}, - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'lead', 'create_view_lead', 'select_lead')": {}, + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": {}, + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'lead', 'create_view_lead', 'select_lead')": {}, }, }, { name: "Error In Insert", @@ -566,7 +570,7 @@ func TestReloadViewsInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_views where table_schema = database() and table_name in ('v1')": {}, + "delete from _vt.views where table_schema = database() and table_name in ('v1')": {}, "select table_name, view_definition from information_schema.views where table_schema = database() and table_name in ('v1')": sqltypes.MakeTestResult( getViewDefinitionsFields, "v1|select_v1"), @@ -574,7 +578,7 @@ func TestReloadViewsInDB(t *testing.T) { "v1|create_view_v1|utf8mb4|utf8mb4_0900_ai_ci"), }, queriesToReject: map[string]error{ - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": errors.New(errMessage), + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": errors.New(errMessage), }, expectedError: errMessage, }, @@ -629,7 +633,7 @@ func TestReloadDataInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_views where table_schema = database() and table_name in ('v1', 'lead')": {}, + "delete from _vt.views where table_schema = database() and table_name in ('v1', 'lead')": {}, }, }, { name: "Only views to reload", @@ -651,7 +655,7 @@ func TestReloadDataInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_views where table_schema = database() and table_name in ('v1', 'lead')": {}, + "delete from _vt.views where table_schema = database() and table_name in ('v1', 'lead')": {}, "select table_name, view_definition from information_schema.views where table_schema = database() and table_name in ('v1', 'lead')": sqltypes.MakeTestResult( getViewDefinitionsFields, "lead|select_lead", @@ -660,8 +664,8 @@ func TestReloadDataInDB(t *testing.T) { "v1|create_view_v1|utf8mb4|utf8mb4_0900_ai_ci"), "show create table `lead`": sqltypes.MakeTestResult(showCreateViewFields, "lead|create_view_lead|utf8mb4|utf8mb4_0900_ai_ci"), - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": {}, - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'lead', 'create_view_lead', 'select_lead')": {}, + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": {}, + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'lead', 'create_view_lead', 'select_lead')": {}, }, }, { name: "Reload and delete views", @@ -687,7 +691,7 @@ func TestReloadDataInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_views where table_schema = database() and table_name in ('v2', 'from', 'v1', 'lead')": {}, + "delete from _vt.views where table_schema = database() and table_name in ('v2', 'from', 'v1', 'lead')": {}, "select table_name, view_definition from information_schema.views where table_schema = database() and table_name in ('v2', 'from', 'v1', 'lead')": sqltypes.MakeTestResult( getViewDefinitionsFields, "lead|select_lead", @@ -696,8 +700,8 @@ func TestReloadDataInDB(t *testing.T) { "v1|create_view_v1|utf8mb4|utf8mb4_0900_ai_ci"), "show create table `lead`": sqltypes.MakeTestResult(showCreateViewFields, "lead|create_view_lead|utf8mb4|utf8mb4_0900_ai_ci"), - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": {}, - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'lead', 'create_view_lead', 'select_lead')": {}, + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": {}, + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'lead', 'create_view_lead', 'select_lead')": {}, }, }, { name: "Error In Inserting View Data", @@ -712,7 +716,7 @@ func TestReloadDataInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_views where table_schema = database() and table_name in ('v1')": {}, + "delete from _vt.views where table_schema = database() and table_name in ('v1')": {}, "select table_name, view_definition from information_schema.views where table_schema = database() and table_name in ('v1')": sqltypes.MakeTestResult( getViewDefinitionsFields, "v1|select_v1"), @@ -720,7 +724,7 @@ func TestReloadDataInDB(t *testing.T) { "v1|create_view_v1|utf8mb4|utf8mb4_0900_ai_ci"), }, queriesToReject: map[string]error{ - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": errors.New(errMessage), + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": errors.New(errMessage), }, expectedError: errMessage, }, { @@ -733,7 +737,7 @@ func TestReloadDataInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_tables where table_schema = database() and table_name in ('t1', 'lead')": {}, + "delete from _vt.`tables` where table_schema = database() and table_name in ('t1', 'lead')": {}, }, }, { name: "Only tables to reload", @@ -755,13 +759,13 @@ func TestReloadDataInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_tables where table_schema = database() and table_name in ('t1', 'lead')": {}, + "delete from _vt.`tables` where table_schema = database() and table_name in ('t1', 'lead')": {}, "show create table t1": sqltypes.MakeTestResult(showCreateTableFields, "t1|create_table_t1"), "show create table `lead`": sqltypes.MakeTestResult(showCreateTableFields, "lead|create_table_lead"), - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": {}, - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 'lead', 'create_table_lead', 1234)": {}, + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": {}, + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 'lead', 'create_table_lead', 1234)": {}, }, }, { name: "Reload and delete tables", @@ -787,13 +791,13 @@ func TestReloadDataInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_tables where table_schema = database() and table_name in ('t2', 'from', 't1', 'lead')": {}, + "delete from _vt.`tables` where table_schema = database() and table_name in ('t2', 'from', 't1', 'lead')": {}, "show create table t1": sqltypes.MakeTestResult(showCreateTableFields, "t1|create_table_t1"), "show create table `lead`": sqltypes.MakeTestResult(showCreateTableFields, "lead|create_table_lead"), - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": {}, - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 'lead', 'create_table_lead', 1234)": {}, + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": {}, + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 'lead', 'create_table_lead', 1234)": {}, }, }, { name: "Error In Inserting Table Data", @@ -808,12 +812,12 @@ func TestReloadDataInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_tables where table_schema = database() and table_name in ('t1')": {}, + "delete from _vt.`tables` where table_schema = database() and table_name in ('t1')": {}, "show create table t1": sqltypes.MakeTestResult(showCreateTableFields, "t1|create_table_t1"), }, queriesToReject: map[string]error{ - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": errors.New(errMessage), + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": errors.New(errMessage), }, expectedError: errMessage, }, { @@ -849,7 +853,7 @@ func TestReloadDataInDB(t *testing.T) { "begin": {}, "commit": {}, "rollback": {}, - "delete from _vt.schema_engine_views where table_schema = database() and table_name in ('v2', 'from', 'v1', 'lead')": {}, + "delete from _vt.views where table_schema = database() and table_name in ('v2', 'from', 'v1', 'lead')": {}, "select table_name, view_definition from information_schema.views where table_schema = database() and table_name in ('v2', 'from', 'v1', 'lead')": sqltypes.MakeTestResult( getViewDefinitionsFields, "lead|select_lead", @@ -858,15 +862,15 @@ func TestReloadDataInDB(t *testing.T) { "v1|create_view_v1|utf8mb4|utf8mb4_0900_ai_ci"), "show create table `lead`": sqltypes.MakeTestResult(showCreateViewFields, "lead|create_view_lead|utf8mb4|utf8mb4_0900_ai_ci"), - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": {}, - "insert into _vt.schema_engine_views(table_schema, table_name, create_statement, view_definition) values (database(), 'lead', 'create_view_lead', 'select_lead')": {}, - "delete from _vt.schema_engine_tables where table_schema = database() and table_name in ('t2', 't1', 'where')": {}, + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'v1', 'create_view_v1', 'select_v1')": {}, + "insert into _vt.views(table_schema, table_name, create_statement, view_definition) values (database(), 'lead', 'create_view_lead', 'select_lead')": {}, + "delete from _vt.`tables` where table_schema = database() and table_name in ('t2', 't1', 'where')": {}, "show create table t1": sqltypes.MakeTestResult(showCreateTableFields, "t1|create_table_t1"), "show create table `where`": sqltypes.MakeTestResult(showCreateTableFields, "where|create_table_where"), - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": {}, - "insert into _vt.schema_engine_tables(table_schema, table_name, create_statement, create_time) values (database(), 'where', 'create_table_where', 1234)": {}, + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 't1', 'create_table_t1', 1234)": {}, + "insert into _vt.`tables`(table_schema, table_name, create_statement, create_time) values (database(), 'where', 'create_table_where', 1234)": {}, }, }, } @@ -894,3 +898,84 @@ func TestReloadDataInDB(t *testing.T) { }) } } + +// TestGetFetchViewQuery tests the functionality for getting the fetch query to retrieve views. +func TestGetFetchViewQuery(t *testing.T) { + testcases := []struct { + name string + viewNames []string + expectedQuery string + }{ + { + name: "No views provided", + viewNames: []string{}, + expectedQuery: "select table_name, create_statement from _vt.views where table_schema = database()", + }, { + name: "Few views provided", + viewNames: []string{"v1", "v2", "lead"}, + expectedQuery: "select table_name, create_statement from _vt.views where table_schema = database() and table_name in ('v1', 'v2', 'lead')", + }, + } + + for _, testcase := range testcases { + t.Run(testcase.name, func(t *testing.T) { + query, err := GetFetchViewQuery(testcase.viewNames) + require.NoError(t, err) + require.Equal(t, testcase.expectedQuery, query) + }) + } +} + +// TestGetFetchTableQuery tests the functionality for getting the fetch query to retrieve tables. +func TestGetFetchTableQuery(t *testing.T) { + testcases := []struct { + name string + tableNames []string + expectedQuery string + }{ + { + name: "No tables provided", + tableNames: []string{}, + expectedQuery: "select table_name, create_statement from _vt.`tables` where table_schema = database()", + }, { + name: "Few tables provided", + tableNames: []string{"v1", "v2", "lead"}, + expectedQuery: "select table_name, create_statement from _vt.`tables` where table_schema = database() and table_name in ('v1', 'v2', 'lead')", + }, + } + + for _, testcase := range testcases { + t.Run(testcase.name, func(t *testing.T) { + query, err := GetFetchTableQuery(testcase.tableNames) + require.NoError(t, err) + require.Equal(t, testcase.expectedQuery, query) + }) + } +} + +// TestGetFetchTableAndViewsQuery tests the functionality for getting the fetch query to retrieve tables and views. +func TestGetFetchTableAndViewsQuery(t *testing.T) { + testcases := []struct { + name string + tableNames []string + expectedQuery string + }{ + { + name: "No tables provided", + tableNames: []string{}, + expectedQuery: "select table_name, create_statement from _vt.`tables` where table_schema = database() union select table_name, create_statement from _vt.views where table_schema = database()", + }, { + name: "Few tables provided", + tableNames: []string{"t1", "t2", "v1", "v2", "lead"}, + expectedQuery: "select table_name, create_statement from _vt.`tables` where table_schema = database() and table_name in ('t1', 't2', 'v1', 'v2', 'lead') union select table_name, create_statement from _vt.views where table_schema = database() and table_name in ('t1', 't2', 'v1', 'v2', 'lead')", + }, + } + + for _, testcase := range testcases { + t.Run(testcase.name, func(t *testing.T) { + query, err := GetFetchTableAndViewsQuery(testcase.tableNames) + require.NoError(t, err) + require.Equal(t, testcase.expectedQuery, query) + }) + } +} diff --git a/go/vt/vttablet/tabletserver/schema/engine_test.go b/go/vt/vttablet/tabletserver/schema/engine_test.go index c2d2237b3a4..591cae00705 100644 --- a/go/vt/vttablet/tabletserver/schema/engine_test.go +++ b/go/vt/vttablet/tabletserver/schema/engine_test.go @@ -1142,7 +1142,7 @@ func TestEngineReload(t *testing.T) { // Finding mismatches in the tables. // t5 exists in the database. - db.AddQuery("SELECT TABLE_NAME, CREATE_TIME FROM _vt.schema_engine_tables", sqltypes.MakeTestResult(sqltypes.MakeTestFields("table_name|create_time", "varchar|int64"), + db.AddQuery("SELECT TABLE_NAME, CREATE_TIME FROM _vt.`tables`", sqltypes.MakeTestResult(sqltypes.MakeTestFields("table_name|create_time", "varchar|int64"), "t1|123456789", "t2|123456789", "t4|123456789", @@ -1182,10 +1182,10 @@ func TestEngineReload(t *testing.T) { db.AddQuery("commit", &sqltypes.Result{}) db.AddQuery("rollback", &sqltypes.Result{}) // We are adding both the variants of the delete statements that we can see in the test, since the deleted tables are initially stored as a map, the order is not defined. - db.AddQuery("delete from _vt.schema_engine_tables where TABLE_SCHEMA = database() and TABLE_NAME in ('t5', 't4', 't3', 't2')", &sqltypes.Result{}) - db.AddQuery("delete from _vt.schema_engine_tables where TABLE_SCHEMA = database() and TABLE_NAME in ('t4', 't5', 't3', 't2')", &sqltypes.Result{}) - db.AddQuery("insert into _vt.schema_engine_tables(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, CREATE_TIME) values (database(), 't2', 'create_table_t2', 123456790)", &sqltypes.Result{}) - db.AddQuery("insert into _vt.schema_engine_tables(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, CREATE_TIME) values (database(), 't3', 'create_table_t3', 123456789)", &sqltypes.Result{}) + db.AddQuery("delete from _vt.`tables` where TABLE_SCHEMA = database() and TABLE_NAME in ('t5', 't4', 't3', 't2')", &sqltypes.Result{}) + db.AddQuery("delete from _vt.`tables` where TABLE_SCHEMA = database() and TABLE_NAME in ('t4', 't5', 't3', 't2')", &sqltypes.Result{}) + db.AddQuery("insert into _vt.`tables`(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, CREATE_TIME) values (database(), 't2', 'create_table_t2', 123456790)", &sqltypes.Result{}) + db.AddQuery("insert into _vt.`tables`(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, CREATE_TIME) values (database(), 't3', 'create_table_t3', 123456789)", &sqltypes.Result{}) } // Queries for reloading the views' information. @@ -1208,10 +1208,10 @@ func TestEngineReload(t *testing.T) { )) // We are adding both the variants of the delete statements that we can see in the test, since the deleted views are initially stored as a map, the order is not defined. - db.AddQuery("delete from _vt.schema_engine_views where TABLE_SCHEMA = database() and TABLE_NAME in ('v4', 'v5', 'v3', 'v2')", &sqltypes.Result{}) - db.AddQuery("delete from _vt.schema_engine_views where TABLE_SCHEMA = database() and TABLE_NAME in ('v5', 'v4', 'v3', 'v2')", &sqltypes.Result{}) - db.AddQuery("insert into _vt.schema_engine_views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'v2', 'create_table_v2', 'select_v2')", &sqltypes.Result{}) - db.AddQuery("insert into _vt.schema_engine_views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'v3', 'create_table_v3', 'select_v3')", &sqltypes.Result{}) + db.AddQuery("delete from _vt.views where TABLE_SCHEMA = database() and TABLE_NAME in ('v4', 'v5', 'v3', 'v2')", &sqltypes.Result{}) + db.AddQuery("delete from _vt.views where TABLE_SCHEMA = database() and TABLE_NAME in ('v5', 'v4', 'v3', 'v2')", &sqltypes.Result{}) + db.AddQuery("insert into _vt.views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'v2', 'create_table_v2', 'select_v2')", &sqltypes.Result{}) + db.AddQuery("insert into _vt.views(TABLE_SCHEMA, TABLE_NAME, CREATE_STATEMENT, VIEW_DEFINITION) values (database(), 'v3', 'create_table_v3', 'select_v3')", &sqltypes.Result{}) } // Verify the list of created, altered and dropped tables seen.