From fb3ef16913e8722ea173cd7c15b2b0669a1298c2 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 31 Jan 2025 23:06:07 +0100 Subject: [PATCH] [release-20.0] Fix panic inside schema tracker (#17659) (#17672) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/vtgate/schema/tracker.go | 4 ++-- go/vt/vtgate/schema/tracker_test.go | 21 +++++++++++++++++++++ go/vt/wrangler/vdiff.go | 2 +- go/vt/wrangler/vdiff_test.go | 7 +++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/go/vt/vtgate/schema/tracker.go b/go/vt/vtgate/schema/tracker.go index a1b2009d0e1..0a324007fa2 100644 --- a/go/vt/vtgate/schema/tracker.go +++ b/go/vt/vtgate/schema/tracker.go @@ -353,7 +353,7 @@ func (t *Tracker) updatedTableSchema(th *discovery.TabletHealth) bool { func (t *Tracker) updateTables(keyspace string, res map[string]string) { for tableName, tableDef := range res { - stmt, err := t.parser.Parse(tableDef) + stmt, err := t.parser.ParseStrictDDL(tableDef) if err != nil { log.Warningf("error parsing table definition for %s: %v", tableName, err) continue @@ -535,7 +535,7 @@ func (vm *viewMap) set(ks, tbl, sql string) { m = make(map[tableNameStr]sqlparser.SelectStatement) vm.m[ks] = m } - stmt, err := vm.parser.Parse(sql) + stmt, err := vm.parser.ParseStrictDDL(sql) if err != nil { log.Warningf("ignoring view '%s', parsing error in view definition: '%s'", tbl, sql) return diff --git a/go/vt/vtgate/schema/tracker_test.go b/go/vt/vtgate/schema/tracker_test.go index 1ee15ba99cb..e5280c78ed8 100644 --- a/go/vt/vtgate/schema/tracker_test.go +++ b/go/vt/vtgate/schema/tracker_test.go @@ -202,6 +202,9 @@ func TestTableTracking(t *testing.T) { tables( tbl("t4", "create table t4(name varchar(50) primary key)"), ), + tables( + tbl("t5", "create table t5(name varchar(50) primary key with broken syntax)"), + ), } testcases := []testCases{{ @@ -234,6 +237,15 @@ func TestTableTracking(t *testing.T) { "t3": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_DATETIME, CollationName: "binary", Size: 0, Nullable: true}}, "t4": {{Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}}, }, + }, { + testName: "new broken table", + updTbl: []string{"t5"}, + expTbl: map[string][]vindexes.Column{ + "t1": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_INT64, CollationName: "binary", Nullable: true}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}, {Name: sqlparser.NewIdentifierCI("email"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: false, Default: &sqlparser.Literal{Val: "a@b.com"}}}, + "T1": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}, {Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}}, + "t3": {{Name: sqlparser.NewIdentifierCI("id"), Type: querypb.Type_DATETIME, CollationName: "binary", Size: 0, Nullable: true}}, + "t4": {{Name: sqlparser.NewIdentifierCI("name"), Type: querypb.Type_VARCHAR, Size: 50, Nullable: true}}, + }, }} testTracker(t, false, schemaResponse, testcases) @@ -253,6 +265,7 @@ func TestViewsTracking(t *testing.T) { tbl("t3", "create view t3 as select 1 from tbl3"), ), tables(tbl("t4", "create view t4 as select 1 from tbl4")), + tables(tbl("t4", "create view t5 as select 1 from tbl4 with broken syntax")), } testcases := []testCases{{ @@ -281,6 +294,14 @@ func TestViewsTracking(t *testing.T) { "V1": "select 1, 2 from tbl2", "t3": "select 1 from tbl3", "t4": "select 1 from tbl4"}, + }, { + testName: "new broken t5", + updView: []string{"t5"}, + expView: map[string]string{ + "t1": "select 1 from tbl1", + "V1": "select 1, 2 from tbl2", + "t3": "select 1 from tbl3", + "t4": "select 1 from tbl4"}, }} testTracker(t, false, schemaDefResult, testcases) diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 4caad42ce1f..f098b1b6f51 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -540,7 +540,7 @@ func findPKs(env *vtenv.Environment, table *tabletmanagerdatapb.TableDefinition, // column in the table definition leveraging MySQL's collation inheritance // rules. func getColumnCollations(venv *vtenv.Environment, table *tabletmanagerdatapb.TableDefinition) (map[string]collations.ID, map[string]*evalengine.EnumSetValues, error) { - createstmt, err := venv.Parser().Parse(table.Schema) + createstmt, err := venv.Parser().ParseStrictDDL(table.Schema) if err != nil { return nil, nil, err } diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go index 3ac6edb373c..44c3a22a336 100644 --- a/go/vt/wrangler/vdiff_test.go +++ b/go/vt/wrangler/vdiff_test.go @@ -1311,6 +1311,13 @@ func TestGetColumnCollations(t *testing.T) { "size": {"'small'", "'medium'", "'large'"}, }, }, + { + name: "invalid schema", + table: &tabletmanagerdatapb.TableDefinition{ + Schema: "create table t1 (c1 varchar(10), size set('small', 'medium', 'large'), primary key(c1) with syntax error)", + }, + wantErr: true, + }, } env := vtenv.NewTestEnv() for _, tt := range tests {