From fe494a944fa8f927664d60b74fa3ab32fd617d90 Mon Sep 17 00:00:00 2001 From: Raphael 'kena' Poss Date: Fri, 19 Oct 2018 17:06:33 +0200 Subject: [PATCH 1/4] sql/parser: ensure that CREATE/DROP SCHEMA attempts land in stats Release note (sql change): Attempts to use `CREATE/DROP SCHEMA` will now be collected as telemetry if statistics reporting is enabled, to gauge demand for user-defined schemas. --- pkg/sql/parser/parse_test.go | 2 ++ pkg/sql/parser/sql.y | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pkg/sql/parser/parse_test.go b/pkg/sql/parser/parse_test.go index 12b77d36c07a..b3086d31358b 100644 --- a/pkg/sql/parser/parse_test.go +++ b/pkg/sql/parser/parse_test.go @@ -2560,6 +2560,7 @@ func TestUnimplementedSyntax(t *testing.T) { {`CREATE OPERATOR a`, 0, `create operator`}, {`CREATE PUBLICATION a`, 0, `create publication`}, {`CREATE RULE a`, 0, `create rule`}, + {`CREATE SCHEMA a`, 26443, `create`}, {`CREATE SERVER a`, 0, `create server`}, {`CREATE SUBSCRIPTION a`, 0, `create subscription`}, {`CREATE TEXT SEARCH a`, 7821, `create text`}, @@ -2578,6 +2579,7 @@ func TestUnimplementedSyntax(t *testing.T) { {`DROP OPERATOR a`, 0, `drop operator`}, {`DROP PUBLICATION a`, 0, `drop publication`}, {`DROP RULE a`, 0, `drop rule`}, + {`DROP SCHEMA a`, 26443, `drop`}, {`DROP SERVER a`, 0, `drop server`}, {`DROP SUBSCRIPTION a`, 0, `drop subscription`}, {`DROP TEXT SEARCH a`, 7821, `drop text`}, diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index e1d89180f2be..ad27abdb9d5e 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -1975,6 +1975,7 @@ create_unsupported: | CREATE OPERATOR error { return unimplemented(sqllex, "create operator") } | CREATE PUBLICATION error { return unimplemented(sqllex, "create publication") } | CREATE opt_or_replace RULE error { return unimplemented(sqllex, "create rule") } +| CREATE SCHEMA error { return unimplementedWithIssueDetail(sqllex, 26443, "create") } | CREATE SERVER error { return unimplemented(sqllex, "create server") } | CREATE SUBSCRIPTION error { return unimplemented(sqllex, "create subscription") } | CREATE TEXT error { return unimplementedWithIssueDetail(sqllex, 7821, "create text") } @@ -2007,6 +2008,7 @@ drop_unsupported: | DROP OPERATOR error { return unimplemented(sqllex, "drop operator") } | DROP PUBLICATION error { return unimplemented(sqllex, "drop publication") } | DROP RULE error { return unimplemented(sqllex, "drop rule") } +| DROP SCHEMA error { return unimplementedWithIssueDetail(sqllex, 26443, "drop") } | DROP SERVER error { return unimplemented(sqllex, "drop server") } | DROP SUBSCRIPTION error { return unimplemented(sqllex, "drop subscription") } | DROP TEXT error { return unimplementedWithIssueDetail(sqllex, 7821, "drop text") } From c3f49cd307f761447f2a5dedbdea7679d2871819 Mon Sep 17 00:00:00 2001 From: Raphael 'kena' Poss Date: Fri, 19 Oct 2018 17:38:23 +0200 Subject: [PATCH 2/4] sql/parser: mark constraint deferrability options for telemetry Release note (sql change): Attempts to use `DEFERRABLE` and other constraint deferrability options will now be collected as telemetry if statistics reporting is enabled, to gauge demand for tuning time of constraint checking. --- docs/generated/sql/bnf/stmt_block.bnf | 2 ++ pkg/sql/parser/parse_test.go | 8 ++++++++ pkg/sql/parser/sql.y | 20 +++++++++++++++----- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf index 7ce3200db9d6..6f92417b1df0 100644 --- a/docs/generated/sql/bnf/stmt_block.bnf +++ b/docs/generated/sql/bnf/stmt_block.bnf @@ -558,6 +558,7 @@ unreserved_keyword ::= | 'DAY' | 'DEALLOCATE' | 'DELETE' + | 'DEFERRED' | 'DISCARD' | 'DOMAIN' | 'DOUBLE' @@ -589,6 +590,7 @@ unreserved_keyword ::= | 'HIGH' | 'HISTOGRAM' | 'HOUR' + | 'IMMEDIATE' | 'IMPORT' | 'INCREMENT' | 'INCREMENTAL' diff --git a/pkg/sql/parser/parse_test.go b/pkg/sql/parser/parse_test.go index b3086d31358b..dcf69fd536c5 100644 --- a/pkg/sql/parser/parse_test.go +++ b/pkg/sql/parser/parse_test.go @@ -2605,6 +2605,14 @@ func TestUnimplementedSyntax(t *testing.T) { {`CREATE TABLE a(b INT REFERENCES c(x) MATCH PARTIAL`, 0, `references match partial`}, {`CREATE TABLE a(b INT REFERENCES c(x) MATCH SIMPLE`, 0, `references match simple`}, + {`CREATE TABLE a(b INT, FOREIGN KEY (b) REFERENCES c(x) DEFERRABLE)`, 31632, `deferrable`}, + {`CREATE TABLE a(b INT, FOREIGN KEY (b) REFERENCES c(x) INITIALLY DEFERRED)`, 31632, `initially deferred`}, + {`CREATE TABLE a(b INT, FOREIGN KEY (b) REFERENCES c(x) INITIALLY IMMEDIATE)`, 31632, `initially immediate`}, + {`CREATE TABLE a(b INT, FOREIGN KEY (b) REFERENCES c(x) DEFERRABLE INITIALLY DEFERRED)`, 31632, `initially deferred`}, + {`CREATE TABLE a(b INT, FOREIGN KEY (b) REFERENCES c(x) DEFERRABLE INITIALLY IMMEDIATE)`, 31632, `initially immediate`}, + {`CREATE TABLE a(b INT, UNIQUE (b) DEFERRABLE)`, 31632, `deferrable`}, + {`CREATE TABLE a(b INT, CHECK (b > 0) DEFERRABLE)`, 31632, `deferrable`}, + {`CREATE SEQUENCE a AS DOUBLE PRECISION`, 25110, `FLOAT8`}, {`CREATE SEQUENCE a OWNED BY b`, 26382, ``}, diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index ad27abdb9d5e..84a095c13a4c 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -485,7 +485,7 @@ func newNameFromStr(s string) *tree.Name { %token CURRENT_USER CYCLE %token DATA DATABASE DATABASES DATE DAY DEC DECIMAL DEFAULT -%token DEALLOCATE DEFERRABLE DELETE DESC +%token DEALLOCATE DEFERRABLE DEFERRED DELETE DESC %token DISCARD DISTINCT DO DOMAIN DOUBLE DROP %token ELSE ENCODING END ENUM ESCAPE EXCEPT @@ -502,7 +502,7 @@ func newNameFromStr(s string) *tree.Name { %token HAVING HIGH HISTOGRAM HOUR -%token IMPORT INCREMENT INCREMENTAL IF IFERROR IFNULL ILIKE IN ISERROR +%token IMMEDIATE IMPORT INCREMENT INCREMENTAL IF IFERROR IFNULL ILIKE IN ISERROR %token INET INET_CONTAINED_BY_OR_EQUALS INET_CONTAINS_OR_CONTAINED_BY %token INET_CONTAINS_OR_EQUALS INDEX INDEXES INJECT INTERLEAVE INITIALLY %token INNER INSERT INT INT2VECTOR INT2 INT4 INT8 INT64 INTEGER @@ -4036,13 +4036,13 @@ table_constraint: } constraint_elem: - CHECK '(' a_expr ')' + CHECK '(' a_expr ')' opt_deferrable { $$.val = &tree.CheckConstraintTableDef{ Expr: $3.expr(), } } -| UNIQUE '(' index_params ')' opt_storing opt_interleave opt_partition_by +| UNIQUE '(' index_params ')' opt_storing opt_interleave opt_partition_by opt_deferrable { $$.val = &tree.UniqueConstraintTableDef{ IndexTableDef: tree.IndexTableDef{ @@ -4063,7 +4063,7 @@ constraint_elem: } } | FOREIGN KEY '(' name_list ')' REFERENCES table_name - opt_column_list key_match reference_actions + opt_column_list key_match reference_actions opt_deferrable { $$.val = &tree.ForeignKeyConstraintTableDef{ Table: $7.normalizableTableNameFromUnresolvedName(), @@ -4073,6 +4073,14 @@ constraint_elem: } } +opt_deferrable: + /* EMPTY */ { /* no error */ } +| DEFERRABLE { return unimplementedWithIssueDetail(sqllex, 31632, "deferrable") } +| DEFERRABLE INITIALLY DEFERRED { return unimplementedWithIssueDetail(sqllex, 31632, "def initially deferred") } +| DEFERRABLE INITIALLY IMMEDIATE { return unimplementedWithIssueDetail(sqllex, 31632, "def initially immediate") } +| INITIALLY DEFERRED { return unimplementedWithIssueDetail(sqllex, 31632, "initially deferred") } +| INITIALLY IMMEDIATE { return unimplementedWithIssueDetail(sqllex, 31632, "initially immediate") } + storing: COVERING | STORING @@ -8379,6 +8387,7 @@ unreserved_keyword: | DAY | DEALLOCATE | DELETE +| DEFERRED | DISCARD | DOMAIN | DOUBLE @@ -8410,6 +8419,7 @@ unreserved_keyword: | HIGH | HISTOGRAM | HOUR +| IMMEDIATE | IMPORT | INCREMENT | INCREMENTAL From a5e2b2c492c51fa785f12b2abab7a5b6063c9d51 Mon Sep 17 00:00:00 2001 From: Raphael 'kena' Poss Date: Fri, 19 Oct 2018 17:48:34 +0200 Subject: [PATCH 3/4] sql/parser: track CREATE TABLE (LIKE ...) for telemetry Release note (sql change): Attempts to use `CREATE TABLE (LIKE...)` will now be collected as telemetry if statistics reporting is enabled, to gauge demand for this feature. --- pkg/sql/parser/parse_test.go | 2 ++ pkg/sql/parser/sql.y | 1 + 2 files changed, 3 insertions(+) diff --git a/pkg/sql/parser/parse_test.go b/pkg/sql/parser/parse_test.go index dcf69fd536c5..352759958b34 100644 --- a/pkg/sql/parser/parse_test.go +++ b/pkg/sql/parser/parse_test.go @@ -2600,6 +2600,8 @@ func TestUnimplementedSyntax(t *testing.T) { {`CREATE TEMP VIEW a AS SELECT b`, 5807, ``}, {`CREATE TEMP SEQUENCE a`, 5807, ``}, + {`CREATE TABLE a(LIKE b)`, 30840, ``}, + {`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 84a095c13a4c..812960c84e34 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -3757,6 +3757,7 @@ table_elem: { $$.val = $1.constraintDef() } +| LIKE table_name { return unimplementedWithIssue(sqllex, 30840) } opt_interleave: INTERLEAVE IN PARENT table_name '(' name_list ')' opt_interleave_drop_behavior From df3712aed2b01c94e3033694129c7a01e9f6ae79 Mon Sep 17 00:00:00 2001 From: Raphael 'kena' Poss Date: Fri, 19 Oct 2018 17:51:27 +0200 Subject: [PATCH 4/4] sql/parser: track usage of CREATE TABLE ... WITH in telemetry Release note (sql change): Attempts to use `CREATE TABLE ... WITH` will now be collected as telemetry if statistics reporting is enabled, to gauge demand for these features. --- docs/generated/sql/bnf/stmt_block.bnf | 1 + pkg/sql/parser/parse_test.go | 5 +++++ pkg/sql/parser/sql.y | 27 +++++++++++++++++++-------- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf index 6f92417b1df0..1183b850b6a9 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 352759958b34..08068cb02dd5 100644 --- a/pkg/sql/parser/parse_test.go +++ b/pkg/sql/parser/parse_test.go @@ -2602,6 +2602,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 812960c84e34..4ba6d4e5e4d2 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 @@ -8466,6 +8476,7 @@ unreserved_keyword: | OF | OFF | OID +| OIDS | OIDVECTOR | OPERATOR | OPTION