diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index c70d4345fcf..0856c4b5619 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -66,6 +66,7 @@ type ( SetFromTables(tables TableNames) SetComments(comments Comments) GetComments() Comments + SetFullyParsed(fullyParsed bool) Statement } @@ -74,6 +75,7 @@ type ( iDBDDLStatement() IsFullyParsed() bool GetDatabaseName() string + SetFullyParsed(bool) Statement } @@ -664,41 +666,69 @@ func (*TruncateTable) IsFullyParsed() bool { return true } +// SetFullyParsed implements the DDLStatement interface +func (*TruncateTable) SetFullyParsed(bool) {} + // IsFullyParsed implements the DDLStatement interface func (*RenameTable) IsFullyParsed() bool { return true } +// SetFullyParsed implements the DDLStatement interface +func (node *RenameTable) SetFullyParsed(fullyParsed bool) {} + // IsFullyParsed implements the DDLStatement interface func (node *CreateTable) IsFullyParsed() bool { return node.FullyParsed } +// SetFullyParsed implements the DDLStatement interface +func (node *CreateTable) SetFullyParsed(fullyParsed bool) { + node.FullyParsed = fullyParsed +} + // IsFullyParsed implements the DDLStatement interface func (node *AlterTable) IsFullyParsed() bool { return node.FullyParsed } +// SetFullyParsed implements the DDLStatement interface +func (node *AlterTable) SetFullyParsed(fullyParsed bool) { + node.FullyParsed = fullyParsed +} + // IsFullyParsed implements the DDLStatement interface func (node *CreateView) IsFullyParsed() bool { return true } +// SetFullyParsed implements the DDLStatement interface +func (node *CreateView) SetFullyParsed(fullyParsed bool) {} + // IsFullyParsed implements the DDLStatement interface func (node *DropView) IsFullyParsed() bool { return true } +// SetFullyParsed implements the DDLStatement interface +func (node *DropView) SetFullyParsed(fullyParsed bool) {} + // IsFullyParsed implements the DDLStatement interface func (node *DropTable) IsFullyParsed() bool { return true } +// SetFullyParsed implements the DDLStatement interface +func (node *DropTable) SetFullyParsed(fullyParsed bool) {} + // IsFullyParsed implements the DDLStatement interface func (node *AlterView) IsFullyParsed() bool { return true } +// SetFullyParsed implements the DDLStatement interface +func (node *AlterView) SetFullyParsed(fullyParsed bool) {} + // IsTemporary implements the DDLStatement interface func (*TruncateTable) IsTemporary() bool { return false @@ -1308,16 +1338,29 @@ func (node *DropDatabase) IsFullyParsed() bool { return true } +// SetFullyParsed implements the DBDDLStatement interface +func (node *DropDatabase) SetFullyParsed(fullyParsed bool) {} + // IsFullyParsed implements the DBDDLStatement interface func (node *CreateDatabase) IsFullyParsed() bool { return node.FullyParsed } +// SetFullyParsed implements the DBDDLStatement interface +func (node *CreateDatabase) SetFullyParsed(fullyParsed bool) { + node.FullyParsed = fullyParsed +} + // IsFullyParsed implements the DBDDLStatement interface func (node *AlterDatabase) IsFullyParsed() bool { return node.FullyParsed } +// SetFullyParsed implements the DBDDLStatement interface +func (node *AlterDatabase) SetFullyParsed(fullyParsed bool) { + node.FullyParsed = fullyParsed +} + // GetDatabaseName implements the DBDDLStatement interface func (node *DropDatabase) GetDatabaseName() string { return node.DBName.String() diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index dc3759a7df4..d518fc07b95 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -1018,8 +1018,13 @@ var ( }, { input: "alter table a upgrade partitioning", }, { - input: "alter table a partition by range (id) (partition p0 values less than (10), partition p1 values less than (maxvalue))", - output: "alter table a", + input: "alter table a partition by range (id) (partition p0 values less than (10), partition p1 values less than (maxvalue))", + output: "alter table a", + partialDDL: true, + }, { + input: "create database a garbage values", + output: "create database a", + partialDDL: true, }, { input: "alter table `Post With Space` drop foreign key `Post With Space_ibfk_1`", }, { @@ -1065,15 +1070,17 @@ var ( }, { input: "alter table a add check (ch_1) not enforced", }, { - input: "alter table a drop check ch_1", - output: "alter table a", + input: "alter table a drop check ch_1", + output: "alter table a", + partialDDL: true, }, { input: "alter table a drop foreign key kx", }, { input: "alter table a drop primary key", }, { - input: "alter table a drop constraint", - output: "alter table a", + input: "alter table a drop constraint", + output: "alter table a", + partialDDL: true, }, { input: "alter table a drop id", output: "alter table a drop column id", @@ -1109,13 +1116,16 @@ var ( input: "alter schema d collate = 'utf8_bin' character set = geostd8 character set = geostd8", output: "alter database d collate 'utf8_bin' character set geostd8 character set geostd8", }, { - input: "create table a", + input: "create table a", + partialDDL: true, }, { - input: "CREATE TABLE a", - output: "create table a", + input: "CREATE TABLE a", + output: "create table a", + partialDDL: true, }, { - input: "create table `a`", - output: "create table a", + input: "create table `a`", + output: "create table a", + partialDDL: true, }, { input: "create table a (\n\t`a` int\n)", output: "create table a (\n\ta int\n)", @@ -1141,11 +1151,13 @@ var ( input: "create table if not exists a (\n\t`a` int\n)", output: "create table if not exists a (\n\ta int\n)", }, { - input: "create table a ignore me this is garbage", - output: "create table a", + input: "create table a ignore me this is garbage", + output: "create table a", + partialDDL: true, }, { - input: "create table a (a int, b char, c garbage)", - output: "create table a", + input: "create table a (a int, b char, c garbage)", + output: "create table a", + partialDDL: true, }, { input: "create table a (b1 bool not null primary key, b2 boolean not null)", output: "create table a (\n\tb1 bool not null primary key,\n\tb2 boolean not null\n)", @@ -1823,6 +1835,10 @@ var ( input: "create database test_db default collate 'utf8mb4_general_ci' collate utf8mb4_general_ci", }, { input: "create database test_db character set geostd8", + }, { + input: "alter table corder zzzz zzzz zzzz", + output: "alter table corder", + partialDDL: true, }, { input: "create database test_db character set * unparsable", output: "create database test_db", @@ -1961,9 +1977,9 @@ func TestValid(t *testing.T) { // For mysql 8.0 syntax, the query is not entirely parsed. // Add more structs as we go on adding full parsing support for DDL constructs for 5.7 syntax. switch x := tree.(type) { - case *CreateDatabase: + case DBDDLStatement: assert.Equal(t, !tcase.partialDDL, x.IsFullyParsed()) - case *AlterDatabase: + case DDLStatement: assert.Equal(t, !tcase.partialDDL, x.IsFullyParsed()) } // This test just exercises the tree walking functionality. diff --git a/go/vt/sqlparser/parser.go b/go/vt/sqlparser/parser.go index b1e4c8086dd..b17f9832dce 100644 --- a/go/vt/sqlparser/parser.go +++ b/go/vt/sqlparser/parser.go @@ -82,6 +82,12 @@ func Parse2(sql string) (Statement, BindVars, error) { return nil, nil, fmt.Errorf("extra characters encountered after end of DDL: '%s'", string(val)) } log.Warningf("ignoring error parsing DDL '%s': %v", sql, tokenizer.LastError) + switch x := tokenizer.partialDDL.(type) { + case DBDDLStatement: + x.SetFullyParsed(false) + case DDLStatement: + x.SetFullyParsed(false) + } tokenizer.ParseTree = tokenizer.partialDDL return tokenizer.ParseTree, tokenizer.BindVars, nil } diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index e00082b2367..b00f2efcaa1 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -8711,9 +8711,9 @@ yydefault: { // Change this to an alter statement if yyDollar[4].colIdent.Lowered() == "primary" { - yyLOCAL = &AlterTable{Table: yyDollar[6].tableName, AlterOptions: append([]AlterOption{&DropKey{Type: PrimaryKeyType}}, yyDollar[7].alterOptionsUnion()...)} + yyLOCAL = &AlterTable{FullyParsed: true, Table: yyDollar[6].tableName, AlterOptions: append([]AlterOption{&DropKey{Type: PrimaryKeyType}}, yyDollar[7].alterOptionsUnion()...)} } else { - yyLOCAL = &AlterTable{Table: yyDollar[6].tableName, AlterOptions: append([]AlterOption{&DropKey{Type: NormalKeyType, Name: yyDollar[4].colIdent}}, yyDollar[7].alterOptionsUnion()...)} + yyLOCAL = &AlterTable{FullyParsed: true, Table: yyDollar[6].tableName, AlterOptions: append([]AlterOption{&DropKey{Type: NormalKeyType, Name: yyDollar[4].colIdent}}, yyDollar[7].alterOptionsUnion()...)} } } yyVAL.union = yyLOCAL diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index b24cd40c06f..fbf1da2c1a8 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -2332,9 +2332,9 @@ drop_statement: { // Change this to an alter statement if $4.Lowered() == "primary" { - $$ = &AlterTable{Table: $6,AlterOptions: append([]AlterOption{&DropKey{Type:PrimaryKeyType}},$7...)} + $$ = &AlterTable{FullyParsed:true, Table: $6,AlterOptions: append([]AlterOption{&DropKey{Type:PrimaryKeyType}},$7...)} } else { - $$ = &AlterTable{Table: $6,AlterOptions: append([]AlterOption{&DropKey{Type:NormalKeyType, Name:$4}},$7...)} + $$ = &AlterTable{FullyParsed: true, Table: $6,AlterOptions: append([]AlterOption{&DropKey{Type:NormalKeyType, Name:$4}},$7...)} } } | DROP comment_opt VIEW exists_opt view_name_list restrict_or_cascade_opt