diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf index eb75b0e32af6..3431f5046f99 100644 --- a/docs/generated/sql/bnf/stmt_block.bnf +++ b/docs/generated/sql/bnf/stmt_block.bnf @@ -636,6 +636,7 @@ unreserved_keyword ::= | 'OF' | 'OFF' | 'OID' + | 'OIDS' | 'OIDVECTOR' | 'OPERATOR' | 'OPTION' diff --git a/pkg/sql/parser/parse_test.go b/pkg/sql/parser/parse_test.go index d48b4375e5b9..e9dcd4befc8f 100644 --- a/pkg/sql/parser/parse_test.go +++ b/pkg/sql/parser/parse_test.go @@ -2590,6 +2590,11 @@ func TestUnimplementedSyntax(t *testing.T) { {`CREATE TABLE a(LIKE b)`, 30840, ``}, + {`CREATE TABLE a(b INT) WITH OIDS`, 0, `create table with oids`}, + {`CREATE TABLE a(b INT) WITH foo = bar`, 0, `create table with foo`}, + + {`CREATE TABLE a AS SELECT b WITH NO DATA`, 0, `create table as with no data`}, + {`CREATE TABLE a(b INT AS (123) VIRTUAL)`, 0, `virtual computed columns`}, {`CREATE TABLE a(b INT REFERENCES c(x) MATCH FULL`, 0, `references match full`}, {`CREATE TABLE a(b INT REFERENCES c(x) MATCH PARTIAL`, 0, `references match partial`}, diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index 8f5aa7fef3c4..7b5f0b6da328 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -521,7 +521,7 @@ func newNameFromStr(s string) *tree.Name { %token NAN NAME NAMES NATURAL NEXT NO NO_INDEX_JOIN NORMAL %token NOT NOTHING NOTNULL NULL NULLIF NUMERIC -%token OF OFF OFFSET OID OIDVECTOR ON ONLY OPTION OPTIONS OR +%token OF OFF OFFSET OID OIDS OIDVECTOR ON ONLY OPTION OPTIONS OR %token ORDER ORDINALITY OUT OUTER OVER OVERLAPS OVERLAY OWNED OPERATOR %token PARENT PARTIAL PARTITION PASSWORD PAUSE PHYSICAL PLACING @@ -3659,7 +3659,7 @@ pause_stmt: // WEBDOCS/create-table.html // WEBDOCS/create-table-as.html create_table_stmt: - CREATE opt_temp TABLE table_name '(' opt_table_elem_list ')' opt_interleave opt_partition_by + CREATE opt_temp TABLE table_name '(' opt_table_elem_list ')' opt_interleave opt_partition_by opt_table_with { $$.val = &tree.CreateTable{ Table: $4.normalizableTableNameFromUnresolvedName(), @@ -3671,7 +3671,7 @@ create_table_stmt: PartitionBy: $9.partitionBy(), } } -| CREATE opt_temp TABLE IF NOT EXISTS table_name '(' opt_table_elem_list ')' opt_interleave opt_partition_by +| CREATE opt_temp TABLE IF NOT EXISTS table_name '(' opt_table_elem_list ')' opt_interleave opt_partition_by opt_table_with { $$.val = &tree.CreateTable{ Table: $7.normalizableTableNameFromUnresolvedName(), @@ -3684,30 +3684,40 @@ create_table_stmt: } } +opt_table_with: + /* EMPTY */ { /* no error */ } +| WITHOUT OIDS { /* SKIP DOC */ /* this is also the default in CockroachDB */ } +| WITH name error { return unimplemented(sqllex, "create table with " + $2) } + create_table_as_stmt: - CREATE opt_temp TABLE table_name opt_column_list AS select_stmt + CREATE opt_temp TABLE table_name opt_column_list opt_table_with AS select_stmt opt_create_as_data { $$.val = &tree.CreateTable{ Table: $4.normalizableTableNameFromUnresolvedName(), IfNotExists: false, Interleave: nil, Defs: nil, - AsSource: $7.slct(), + AsSource: $8.slct(), AsColumnNames: $5.nameList(), } } -| CREATE opt_temp TABLE IF NOT EXISTS table_name opt_column_list AS select_stmt +| CREATE opt_temp TABLE IF NOT EXISTS table_name opt_column_list opt_table_with AS select_stmt opt_create_as_data { $$.val = &tree.CreateTable{ Table: $7.normalizableTableNameFromUnresolvedName(), IfNotExists: true, Interleave: nil, Defs: nil, - AsSource: $10.slct(), + AsSource: $11.slct(), AsColumnNames: $8.nameList(), } } +opt_create_as_data: + /* EMPTY */ { /* no error */ } +| WITH DATA { /* SKIP DOC */ /* This is the default */ } +| WITH NO DATA { return unimplemented(sqllex, "create table as with no data") } + /* * Redundancy here is needed to avoid shift/reduce conflicts, * since TEMP is not a reserved word. See also OptTempTableName. @@ -3757,7 +3767,7 @@ table_elem: { $$.val = $1.constraintDef() } -| LIKE table_name { return unimplementedWithIssue(sqllex, 30840) } +| LIKE table_name error { return unimplementedWithIssue(sqllex, 30840) } opt_interleave: INTERLEAVE IN PARENT table_name '(' name_list ')' opt_interleave_drop_behavior @@ -8444,6 +8454,7 @@ unreserved_keyword: | OF | OFF | OID +| OIDS | OIDVECTOR | OPERATOR | OPTION