Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions go/vt/sqlparser/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,15 +572,20 @@ type (
IfExists bool
}

// IgnoreOrReplaceType represents conflict handling mode for CREATE TABLE ... SELECT
IgnoreOrReplaceType int8

// CreateTable represents a CREATE TABLE statement.
CreateTable struct {
Temp bool
Table TableName
IfNotExists bool
TableSpec *TableSpec
OptLike *OptLike
Comments *ParsedComments
FullyParsed bool
Temp bool
Table TableName
IfNotExists bool
TableSpec *TableSpec
OptLike *OptLike
Comments *ParsedComments
IgnoreOrReplace IgnoreOrReplaceType
Select TableStatement
FullyParsed bool
}

// CreateView represents a CREATE VIEW query
Expand Down
1 change: 1 addition & 0 deletions go/vt/sqlparser/ast_clone.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion go/vt/sqlparser/ast_copy_on_rewrite.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion go/vt/sqlparser/ast_equals.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions go/vt/sqlparser/ast_format.go
Original file line number Diff line number Diff line change
Expand Up @@ -2434,6 +2434,16 @@ func (node *CreateTable) Format(buf *TrackedBuffer) {
if node.TableSpec != nil {
buf.astPrintf(node, " %v", node.TableSpec)
}
if node.Select != nil {
switch node.IgnoreOrReplace {
case IgnoreType:
buf.WriteString(" ignore")
case ReplaceType:
buf.WriteString(" replace")
}
buf.literal(" as")
buf.astPrintf(node, " %v", node.Select)
}
}

// Format formats the node.
Expand Down
11 changes: 11 additions & 0 deletions go/vt/sqlparser/ast_format_fast.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions go/vt/sqlparser/ast_path.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions go/vt/sqlparser/ast_rewrite.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions go/vt/sqlparser/ast_visit.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion go/vt/sqlparser/cached_size.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions go/vt/sqlparser/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -1134,3 +1134,10 @@ const (
IndexTypeSpatial
IndexTypeFullText
)

// Constant for Enum Type - IgnoreOrReplaceType
const (
NoIgnoreOrReplace IgnoreOrReplaceType = iota
IgnoreType
ReplaceType
)
115 changes: 113 additions & 2 deletions go/vt/sqlparser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6184,6 +6184,117 @@ func TestCreateTableLike(t *testing.T) {
}
}

func TestCreateTableSelect(t *testing.T) {
testCases := []struct {
input string
output string
}{
{
"create table t2 select * from t1",
"create table t2 as select * from t1",
},
{
"create table t2 as select * from t1",
"create table t2 as select * from t1",
},
{
"create table t2(id int) select * from t1",
"create table t2 (\n\tid int\n) as select * from t1",
},
{
"create table t2(id int) as select * from t1",
"create table t2 (\n\tid int\n) as select * from t1",
},
{
"create table t2(id int) (select * from t1)",
"create table t2 (\n\tid int\n) as select * from t1",
},
{
"create table t2(id int) as (select * from t1)",
"create table t2 (\n\tid int\n) as select * from t1",
},
{
"create table t2(id int auto_increment, name varchar(255), primary key(id), unique key by_name(name)) select * from t1",
"create table t2 (\n\tid int auto_increment,\n\t`name` varchar(255),\n\tprimary key (id),\n\tunique key by_name (`name`)\n) as select * from t1",
},
{
"create table ks.t2 as select id, name from unsharded_ks.t1",
"create table ks.t2 as select id, `name` from unsharded_ks.t1",
},
{
"create table ks.t2(id int, name varchar(255)) select id, name from unsharded_ks.t1",
"create table ks.t2 (\n\tid int,\n\t`name` varchar(255)\n) as select id, `name` from unsharded_ks.t1",
},
{
"create table if not exists t2(id int) select * from t1",
"create table if not exists t2 (\n\tid int\n) as select * from t1",
},
{
"create table t2 as select id, count(*) as count from t1 group by id having count >= 1",
"create table t2 as select id, count(*) as `count` from t1 group by id having `count` >= 1",
},
{
"create table t3 as select t1.id, t2.name from t1 join t2 on t1.id = t2.id where t1.id > 10 order by t1.id limit 10",
"create table t3 as select t1.id, t2.`name` from t1 join t2 on t1.id = t2.id where t1.id > 10 order by t1.id asc limit 10",
},
// temporary table
{
"create temporary table t2 select id from t1",
"create temporary table t2 as select id from t1",
},
{
"create temporary table t2 as select id from t1",
"create temporary table t2 as select id from t1",
},
{
"create temporary table t2(id int) select id from t1",
"create temporary table t2 (\n\tid int\n) as select id from t1",
},
{
"create temporary table t2(id int) as select id from t1",
"create temporary table t2 (\n\tid int\n) as select id from t1",
},
// with table_options and partition_options
{
`create table t2(id int) engine=innodb default charset=utf8mb4 collate=utf8mb4_bin
partition by range (id) (partition p0 values less than (100), partition p1 values less than (200), partition p2 values less than (300), partition p3 values less than maxvalue)
as select * from t1`,
`create table t2 (
id int
) engine innodb,
charset utf8mb4,
collate utf8mb4_bin
partition by range (id)
(partition p0 values less than (100),
partition p1 values less than (200),
partition p2 values less than (300),
partition p3 values less than maxvalue) as select * from t1`,
},
// with ignore or replace
{
"create table t2(id int unique key) ignore as select * from t1",
"create table t2 (\n\tid int unique key\n) ignore as select * from t1",
},
{
"create table t2 replace select * from t1",
"create table t2 replace as select * from t1",
},
}
parser := NewTestParser()
for _, tcase := range testCases {
tree, err := parser.ParseStrictDDL(tcase.input)
if err != nil {
t.Errorf("input: %s, err: %v", tcase.input, err)
continue
}
assert.True(t, tree.(*CreateTable).FullyParsed)
assert.NotNil(t, tree.(*CreateTable).Select, "Select field should not be nil")
if got, want := String(tree.(*CreateTable)), tcase.output; got != want {
t.Errorf("Parse(%s):\n%s, want\n%s", tcase.input, got, want)
}
}
}

func TestCreateTableEscaped(t *testing.T) {
testCases := []struct {
input string
Expand Down Expand Up @@ -6687,8 +6798,8 @@ func TestParseMultipleEdgeCases(t *testing.T) {
want: []string{"set charset ';'", "select 1 from a"},
}, {
name: "Partial DDL",
input: "create table a ignore me this is garbage; select 1 from a",
wantErr: "syntax error at position 22 near 'ignore'",
input: "create table a disregard me this is garbage; select 1 from a",
wantErr: "syntax error at position 25 near 'disregard'",
}}
parser := NewTestParser()
for _, test := range tests {
Expand Down
Loading
Loading