From f70002afb102b28d8ed6fed74d61472a3b73d4ca Mon Sep 17 00:00:00 2001 From: sai-roach Date: Mon, 21 Dec 2020 16:34:25 -0500 Subject: [PATCH 1/2] authors: add Sai Ravula to authors Release note: None authors: add Sai Ravula to authors Release note: None --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index dd60fdb052af..a0ab0db718de 100644 --- a/AUTHORS +++ b/AUTHORS @@ -269,6 +269,7 @@ Roland Crosby Roy Hvaara Rushi Agrawal Ryan Min +Sai Ravula Sam Huang Sankt Petersbug Sean Loiselle From a25cac65daf14c7abf83e70ec6c1766e07786bbc Mon Sep 17 00:00:00 2001 From: Oliver Tan Date: Tue, 12 Jan 2021 07:23:00 +1100 Subject: [PATCH 2/2] sql: add PARTITION ALL BY syntax for CREATE/ALTER TABLE Added `PARTITION ALL BY` syntax for `CREATE TABLE` and `ALTER TABLE` which is currently unimplemented. These will eventually become the building blocks for table-level implicit partitioning. This adds a `PartitionByIndex` and `PartitionByTable` construct for `tree`, which can disambiguate between index and table partition by definitions. This gives us a strongly typed way of determining ensuring the `ALL` syntax is only valid for `PartitionByTable`. Release note: None --- .../sql/bnf/alter_index_partition_by.bnf | 16 +- docs/generated/sql/bnf/alter_table.bnf | 4 +- .../sql/bnf/alter_table_partition_by.bnf | 6 - .../sql/bnf/create_index_interleaved_stmt.bnf | 32 +-- docs/generated/sql/bnf/create_index_stmt.bnf | 4 +- .../sql/bnf/create_inverted_index_stmt.bnf | 8 +- .../sql/bnf/create_table_partition_by.bnf | 6 - docs/generated/sql/bnf/create_table_stmt.bnf | 4 +- docs/generated/sql/bnf/index_def.bnf | 32 +-- docs/generated/sql/bnf/interleave.bnf | 8 +- docs/generated/sql/bnf/stmt_block.bnf | 66 +++-- docs/generated/sql/bnf/table_constraint.bnf | 16 +- pkg/ccl/importccl/read_import_pgdump.go | 12 +- .../testdata/logic_test/partitioning | 5 + pkg/cmd/cr2pg/main.go | 2 +- pkg/sql/alter_table.go | 10 +- pkg/sql/create_index.go | 10 +- pkg/sql/create_table.go | 43 ++-- pkg/sql/mutations/mutations.go | 8 +- pkg/sql/opt/testutils/testcat/create_index.go | 16 +- pkg/sql/opt/testutils/testcat/create_table.go | 21 +- pkg/sql/parser/parse_test.go | 6 + pkg/sql/parser/sql.y | 242 +++++++++++------- pkg/sql/sem/tree/alter_index.go | 4 +- pkg/sql/sem/tree/alter_table.go | 18 +- pkg/sql/sem/tree/create.go | 116 ++++++--- pkg/sql/sem/tree/pretty.go | 48 +++- 27 files changed, 456 insertions(+), 307 deletions(-) diff --git a/docs/generated/sql/bnf/alter_index_partition_by.bnf b/docs/generated/sql/bnf/alter_index_partition_by.bnf index 095f4d9a30d7..335bdf91f2eb 100644 --- a/docs/generated/sql/bnf/alter_index_partition_by.bnf +++ b/docs/generated/sql/bnf/alter_index_partition_by.bnf @@ -1,13 +1,5 @@ alter_oneindex_stmt ::= - 'ALTER' 'INDEX' table_name '@' index_name 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' table_name '@' index_name 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' table_name '@' index_name 'PARTITION' 'BY' 'NOTHING' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' index_name 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' index_name 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' index_name 'PARTITION' 'BY' 'NOTHING' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' 'IF' 'EXISTS' table_name '@' index_name 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' 'IF' 'EXISTS' table_name '@' index_name 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' 'IF' 'EXISTS' table_name '@' index_name 'PARTITION' 'BY' 'NOTHING' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' 'IF' 'EXISTS' index_name 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' 'IF' 'EXISTS' index_name 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* - | 'ALTER' 'INDEX' 'IF' 'EXISTS' index_name 'PARTITION' 'BY' 'NOTHING' ( ( ',' ( ( 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' | 'PARTITION' 'BY' 'NOTHING' ) ) ) )* + 'ALTER' 'INDEX' table_name '@' index_name partition_by_index ( ( ',' ( partition_by_index ) ) )* + | 'ALTER' 'INDEX' index_name partition_by_index ( ( ',' ( partition_by_index ) ) )* + | 'ALTER' 'INDEX' 'IF' 'EXISTS' table_name '@' index_name partition_by_index ( ( ',' ( partition_by_index ) ) )* + | 'ALTER' 'INDEX' 'IF' 'EXISTS' index_name partition_by_index ( ( ',' ( partition_by_index ) ) )* diff --git a/docs/generated/sql/bnf/alter_table.bnf b/docs/generated/sql/bnf/alter_table.bnf index 23487b138c68..829189de4725 100644 --- a/docs/generated/sql/bnf/alter_table.bnf +++ b/docs/generated/sql/bnf/alter_table.bnf @@ -1,3 +1,3 @@ alter_onetable_stmt ::= - 'ALTER' 'TABLE' table_name ( ( ( 'RENAME' ( 'COLUMN' | ) column_name 'TO' column_name | 'RENAME' 'CONSTRAINT' column_name 'TO' column_name | 'ADD' ( column_name typename col_qual_list ) | 'ADD' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DEFAULT' a_expr | 'DROP' 'DEFAULT' ) | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'NOT' 'NULL' | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'STORED' | 'ALTER' ( 'COLUMN' | ) column_name 'SET' 'NOT' 'NULL' | 'DROP' ( 'COLUMN' | ) 'IF' 'EXISTS' column_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' ( 'COLUMN' | ) column_name ( 'CASCADE' | 'RESTRICT' | ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DATA' | ) 'TYPE' typename ( 'COLLATE' collation_name | ) ( 'USING' a_expr | ) | 'ADD' ( 'CONSTRAINT' constraint_name constraint_elem | constraint_elem ) | 'ALTER' 'PRIMARY' 'KEY' 'USING' 'COLUMNS' '(' index_params ')' opt_hash_sharded opt_interleave | 'VALIDATE' 'CONSTRAINT' constraint_name | 'DROP' 'CONSTRAINT' 'IF' 'EXISTS' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' 'CONSTRAINT' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'EXPERIMENTAL_AUDIT' 'SET' audit_mode | partition_by | 'OWNER' 'TO' role_spec ) ) ( ( ',' ( 'RENAME' ( 'COLUMN' | ) column_name 'TO' column_name | 'RENAME' 'CONSTRAINT' column_name 'TO' column_name | 'ADD' ( column_name typename col_qual_list ) | 'ADD' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DEFAULT' a_expr | 'DROP' 'DEFAULT' ) | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'NOT' 'NULL' | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'STORED' | 'ALTER' ( 'COLUMN' | ) column_name 'SET' 'NOT' 'NULL' | 'DROP' ( 'COLUMN' | ) 'IF' 'EXISTS' column_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' ( 'COLUMN' | ) column_name ( 'CASCADE' | 'RESTRICT' | ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DATA' | ) 'TYPE' typename ( 'COLLATE' collation_name | ) ( 'USING' a_expr | ) | 'ADD' ( 'CONSTRAINT' constraint_name constraint_elem | constraint_elem ) | 'ALTER' 'PRIMARY' 'KEY' 'USING' 'COLUMNS' '(' index_params ')' opt_hash_sharded opt_interleave | 'VALIDATE' 'CONSTRAINT' constraint_name | 'DROP' 'CONSTRAINT' 'IF' 'EXISTS' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' 'CONSTRAINT' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'EXPERIMENTAL_AUDIT' 'SET' audit_mode | partition_by | 'OWNER' 'TO' role_spec ) ) )* ) - | 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name ( ( ( 'RENAME' ( 'COLUMN' | ) column_name 'TO' column_name | 'RENAME' 'CONSTRAINT' column_name 'TO' column_name | 'ADD' ( column_name typename col_qual_list ) | 'ADD' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DEFAULT' a_expr | 'DROP' 'DEFAULT' ) | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'NOT' 'NULL' | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'STORED' | 'ALTER' ( 'COLUMN' | ) column_name 'SET' 'NOT' 'NULL' | 'DROP' ( 'COLUMN' | ) 'IF' 'EXISTS' column_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' ( 'COLUMN' | ) column_name ( 'CASCADE' | 'RESTRICT' | ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DATA' | ) 'TYPE' typename ( 'COLLATE' collation_name | ) ( 'USING' a_expr | ) | 'ADD' ( 'CONSTRAINT' constraint_name constraint_elem | constraint_elem ) | 'ALTER' 'PRIMARY' 'KEY' 'USING' 'COLUMNS' '(' index_params ')' opt_hash_sharded opt_interleave | 'VALIDATE' 'CONSTRAINT' constraint_name | 'DROP' 'CONSTRAINT' 'IF' 'EXISTS' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' 'CONSTRAINT' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'EXPERIMENTAL_AUDIT' 'SET' audit_mode | partition_by | 'OWNER' 'TO' role_spec ) ) ( ( ',' ( 'RENAME' ( 'COLUMN' | ) column_name 'TO' column_name | 'RENAME' 'CONSTRAINT' column_name 'TO' column_name | 'ADD' ( column_name typename col_qual_list ) | 'ADD' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DEFAULT' a_expr | 'DROP' 'DEFAULT' ) | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'NOT' 'NULL' | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'STORED' | 'ALTER' ( 'COLUMN' | ) column_name 'SET' 'NOT' 'NULL' | 'DROP' ( 'COLUMN' | ) 'IF' 'EXISTS' column_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' ( 'COLUMN' | ) column_name ( 'CASCADE' | 'RESTRICT' | ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DATA' | ) 'TYPE' typename ( 'COLLATE' collation_name | ) ( 'USING' a_expr | ) | 'ADD' ( 'CONSTRAINT' constraint_name constraint_elem | constraint_elem ) | 'ALTER' 'PRIMARY' 'KEY' 'USING' 'COLUMNS' '(' index_params ')' opt_hash_sharded opt_interleave | 'VALIDATE' 'CONSTRAINT' constraint_name | 'DROP' 'CONSTRAINT' 'IF' 'EXISTS' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' 'CONSTRAINT' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'EXPERIMENTAL_AUDIT' 'SET' audit_mode | partition_by | 'OWNER' 'TO' role_spec ) ) )* ) + 'ALTER' 'TABLE' table_name ( ( ( 'RENAME' ( 'COLUMN' | ) column_name 'TO' column_name | 'RENAME' 'CONSTRAINT' column_name 'TO' column_name | 'ADD' ( column_name typename col_qual_list ) | 'ADD' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DEFAULT' a_expr | 'DROP' 'DEFAULT' ) | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'NOT' 'NULL' | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'STORED' | 'ALTER' ( 'COLUMN' | ) column_name 'SET' 'NOT' 'NULL' | 'DROP' ( 'COLUMN' | ) 'IF' 'EXISTS' column_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' ( 'COLUMN' | ) column_name ( 'CASCADE' | 'RESTRICT' | ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DATA' | ) 'TYPE' typename ( 'COLLATE' collation_name | ) ( 'USING' a_expr | ) | 'ADD' ( 'CONSTRAINT' constraint_name constraint_elem | constraint_elem ) | 'ALTER' 'PRIMARY' 'KEY' 'USING' 'COLUMNS' '(' index_params ')' opt_hash_sharded opt_interleave | 'VALIDATE' 'CONSTRAINT' constraint_name | 'DROP' 'CONSTRAINT' 'IF' 'EXISTS' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' 'CONSTRAINT' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'EXPERIMENTAL_AUDIT' 'SET' audit_mode | partition_by_table | 'OWNER' 'TO' role_spec ) ) ( ( ',' ( 'RENAME' ( 'COLUMN' | ) column_name 'TO' column_name | 'RENAME' 'CONSTRAINT' column_name 'TO' column_name | 'ADD' ( column_name typename col_qual_list ) | 'ADD' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DEFAULT' a_expr | 'DROP' 'DEFAULT' ) | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'NOT' 'NULL' | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'STORED' | 'ALTER' ( 'COLUMN' | ) column_name 'SET' 'NOT' 'NULL' | 'DROP' ( 'COLUMN' | ) 'IF' 'EXISTS' column_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' ( 'COLUMN' | ) column_name ( 'CASCADE' | 'RESTRICT' | ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DATA' | ) 'TYPE' typename ( 'COLLATE' collation_name | ) ( 'USING' a_expr | ) | 'ADD' ( 'CONSTRAINT' constraint_name constraint_elem | constraint_elem ) | 'ALTER' 'PRIMARY' 'KEY' 'USING' 'COLUMNS' '(' index_params ')' opt_hash_sharded opt_interleave | 'VALIDATE' 'CONSTRAINT' constraint_name | 'DROP' 'CONSTRAINT' 'IF' 'EXISTS' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' 'CONSTRAINT' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'EXPERIMENTAL_AUDIT' 'SET' audit_mode | partition_by_table | 'OWNER' 'TO' role_spec ) ) )* ) + | 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name ( ( ( 'RENAME' ( 'COLUMN' | ) column_name 'TO' column_name | 'RENAME' 'CONSTRAINT' column_name 'TO' column_name | 'ADD' ( column_name typename col_qual_list ) | 'ADD' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DEFAULT' a_expr | 'DROP' 'DEFAULT' ) | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'NOT' 'NULL' | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'STORED' | 'ALTER' ( 'COLUMN' | ) column_name 'SET' 'NOT' 'NULL' | 'DROP' ( 'COLUMN' | ) 'IF' 'EXISTS' column_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' ( 'COLUMN' | ) column_name ( 'CASCADE' | 'RESTRICT' | ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DATA' | ) 'TYPE' typename ( 'COLLATE' collation_name | ) ( 'USING' a_expr | ) | 'ADD' ( 'CONSTRAINT' constraint_name constraint_elem | constraint_elem ) | 'ALTER' 'PRIMARY' 'KEY' 'USING' 'COLUMNS' '(' index_params ')' opt_hash_sharded opt_interleave | 'VALIDATE' 'CONSTRAINT' constraint_name | 'DROP' 'CONSTRAINT' 'IF' 'EXISTS' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' 'CONSTRAINT' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'EXPERIMENTAL_AUDIT' 'SET' audit_mode | partition_by_table | 'OWNER' 'TO' role_spec ) ) ( ( ',' ( 'RENAME' ( 'COLUMN' | ) column_name 'TO' column_name | 'RENAME' 'CONSTRAINT' column_name 'TO' column_name | 'ADD' ( column_name typename col_qual_list ) | 'ADD' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' ( column_name typename col_qual_list ) | 'ADD' 'COLUMN' 'IF' 'NOT' 'EXISTS' ( column_name typename col_qual_list ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DEFAULT' a_expr | 'DROP' 'DEFAULT' ) | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'NOT' 'NULL' | 'ALTER' ( 'COLUMN' | ) column_name 'DROP' 'STORED' | 'ALTER' ( 'COLUMN' | ) column_name 'SET' 'NOT' 'NULL' | 'DROP' ( 'COLUMN' | ) 'IF' 'EXISTS' column_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' ( 'COLUMN' | ) column_name ( 'CASCADE' | 'RESTRICT' | ) | 'ALTER' ( 'COLUMN' | ) column_name ( 'SET' 'DATA' | ) 'TYPE' typename ( 'COLLATE' collation_name | ) ( 'USING' a_expr | ) | 'ADD' ( 'CONSTRAINT' constraint_name constraint_elem | constraint_elem ) | 'ALTER' 'PRIMARY' 'KEY' 'USING' 'COLUMNS' '(' index_params ')' opt_hash_sharded opt_interleave | 'VALIDATE' 'CONSTRAINT' constraint_name | 'DROP' 'CONSTRAINT' 'IF' 'EXISTS' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'DROP' 'CONSTRAINT' constraint_name ( 'CASCADE' | 'RESTRICT' | ) | 'EXPERIMENTAL_AUDIT' 'SET' audit_mode | partition_by_table | 'OWNER' 'TO' role_spec ) ) )* ) diff --git a/docs/generated/sql/bnf/alter_table_partition_by.bnf b/docs/generated/sql/bnf/alter_table_partition_by.bnf index 27443fea8482..0a4b791333ff 100644 --- a/docs/generated/sql/bnf/alter_table_partition_by.bnf +++ b/docs/generated/sql/bnf/alter_table_partition_by.bnf @@ -1,7 +1 @@ alter_onetable_stmt ::= - 'ALTER' 'TABLE' table_name 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' - | 'ALTER' 'TABLE' table_name 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' - | 'ALTER' 'TABLE' table_name 'PARTITION' 'BY' 'NOTHING' - | 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' - | 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' - | 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'PARTITION' 'BY' 'NOTHING' diff --git a/docs/generated/sql/bnf/create_index_interleaved_stmt.bnf b/docs/generated/sql/bnf/create_index_interleaved_stmt.bnf index 6fc19cf4e48d..d56defd29eba 100644 --- a/docs/generated/sql/bnf/create_index_interleaved_stmt.bnf +++ b/docs/generated/sql/bnf/create_index_interleaved_stmt.bnf @@ -1,17 +1,17 @@ create_index_stmt ::= - 'CREATE' 'UNIQUE' 'INDEX' 'CONCURRENTLY' '...' opt_hash_sharded 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'UNIQUE' 'INDEX' 'CONCURRENTLY' '...' opt_hash_sharded 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'UNIQUE' 'INDEX' '...' opt_hash_sharded 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'UNIQUE' 'INDEX' '...' opt_hash_sharded 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'INDEX' 'CONCURRENTLY' '...' opt_hash_sharded 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'INDEX' 'CONCURRENTLY' '...' opt_hash_sharded 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'INDEX' '...' opt_hash_sharded 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'INDEX' '...' opt_hash_sharded 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'UNIQUE' 'INVERTED' 'INDEX' 'CONCURRENTLY' '...' 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'UNIQUE' 'INVERTED' 'INDEX' 'CONCURRENTLY' '...' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'UNIQUE' 'INVERTED' 'INDEX' '...' 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'UNIQUE' 'INVERTED' 'INDEX' '...' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'INVERTED' 'INDEX' 'CONCURRENTLY' '...' 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'INVERTED' 'INDEX' 'CONCURRENTLY' '...' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'INVERTED' 'INDEX' '...' 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause - | 'CREATE' 'INVERTED' 'INDEX' '...' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')' opt_with_storage_parameter_list opt_where_clause + 'CREATE' 'UNIQUE' 'INDEX' 'CONCURRENTLY' '...' opt_hash_sharded 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'UNIQUE' 'INDEX' 'CONCURRENTLY' '...' opt_hash_sharded 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'UNIQUE' 'INDEX' '...' opt_hash_sharded 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'UNIQUE' 'INDEX' '...' opt_hash_sharded 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'INDEX' 'CONCURRENTLY' '...' opt_hash_sharded 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'INDEX' 'CONCURRENTLY' '...' opt_hash_sharded 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'INDEX' '...' opt_hash_sharded 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'INDEX' '...' opt_hash_sharded 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'UNIQUE' 'INVERTED' 'INDEX' 'CONCURRENTLY' '...' 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'UNIQUE' 'INVERTED' 'INDEX' 'CONCURRENTLY' '...' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'UNIQUE' 'INVERTED' 'INDEX' '...' 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'UNIQUE' 'INVERTED' 'INDEX' '...' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'INVERTED' 'INDEX' 'CONCURRENTLY' '...' 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'INVERTED' 'INDEX' 'CONCURRENTLY' '...' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'INVERTED' 'INDEX' '...' 'STORING' '(' stored_columns ')' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' 'INVERTED' 'INDEX' '...' 'INTERLEAVE' 'IN' 'PARENT' parent_table '(' interleave_prefix ')'_index opt_with_storage_parameter_list opt_where_clause diff --git a/docs/generated/sql/bnf/create_index_stmt.bnf b/docs/generated/sql/bnf/create_index_stmt.bnf index 1598d2ac0a5d..0a20488e87e8 100644 --- a/docs/generated/sql/bnf/create_index_stmt.bnf +++ b/docs/generated/sql/bnf/create_index_stmt.bnf @@ -1,5 +1,5 @@ create_index_stmt ::= - 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name ( 'USING' name | ) '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets | ) ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause - | 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name ( 'USING' name | ) '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets | ) ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause + 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name ( 'USING' name | ) '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets | ) ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by_index ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause + | 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name ( 'USING' name | ) '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets | ) ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by_index ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause diff --git a/docs/generated/sql/bnf/create_inverted_index_stmt.bnf b/docs/generated/sql/bnf/create_inverted_index_stmt.bnf index 843e1576859f..0147a5b4f1ec 100644 --- a/docs/generated/sql/bnf/create_inverted_index_stmt.bnf +++ b/docs/generated/sql/bnf/create_inverted_index_stmt.bnf @@ -1,5 +1,5 @@ create_index_stmt ::= - 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name opt_index_access_method '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' opt_hash_sharded ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause - | 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name opt_index_access_method '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' opt_hash_sharded ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause - | 'CREATE' ( 'UNIQUE' | ) 'INVERTED' 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause - | 'CREATE' ( 'UNIQUE' | ) 'INVERTED' 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause + 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name opt_index_access_method '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' opt_hash_sharded ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by_index ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause + | 'CREATE' ( 'UNIQUE' | ) 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name opt_index_access_method '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' opt_hash_sharded ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by_index ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause + | 'CREATE' ( 'UNIQUE' | ) 'INVERTED' 'INDEX' ( 'CONCURRENTLY' | ) opt_index_name 'ON' table_name '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by_index ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause + | 'CREATE' ( 'UNIQUE' | ) 'INVERTED' 'INDEX' ( 'CONCURRENTLY' | ) 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' ( ( ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) ( ( ',' ( func_expr_windowless index_elem_options | '(' a_expr ')' index_elem_options | name index_elem_options ) ) )* ) ')' ( ( 'COVERING' | 'STORING' | 'INCLUDE' ) '(' name_list ')' | ) opt_interleave opt_partition_by_index ( 'WITH' '(' ( ( storage_parameter ) ( ( ',' storage_parameter ) )* ) ')' ) opt_where_clause diff --git a/docs/generated/sql/bnf/create_table_partition_by.bnf b/docs/generated/sql/bnf/create_table_partition_by.bnf index f001d9fa94a2..6f05f7a357bb 100644 --- a/docs/generated/sql/bnf/create_table_partition_by.bnf +++ b/docs/generated/sql/bnf/create_table_partition_by.bnf @@ -1,7 +1 @@ create_table_stmt ::= - 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' table_definition ')' 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' opt_table_with opt_create_table_on_commit opt_locality - | 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' table_definition ')' 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' opt_table_with opt_create_table_on_commit opt_locality - | 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' table_definition ')' 'PARTITION' 'BY' 'NOTHING' opt_table_with opt_create_table_on_commit opt_locality - | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' table_definition ')' 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' opt_table_with opt_create_table_on_commit opt_locality - | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' table_definition ')' 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' opt_table_with opt_create_table_on_commit opt_locality - | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' table_definition ')' 'PARTITION' 'BY' 'NOTHING' opt_table_with opt_create_table_on_commit opt_locality diff --git a/docs/generated/sql/bnf/create_table_stmt.bnf b/docs/generated/sql/bnf/create_table_stmt.bnf index c9778099215f..2bab8fb5f56d 100644 --- a/docs/generated/sql/bnf/create_table_stmt.bnf +++ b/docs/generated/sql/bnf/create_table_stmt.bnf @@ -1,3 +1,3 @@ create_table_stmt ::= - 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' ( ( ( ( column_def | index_def | family_def | table_constraint opt_validate_behavior | 'LIKE' table_name like_table_option_list ) ) ( ( ',' ( column_def | index_def | family_def | table_constraint opt_validate_behavior | 'LIKE' table_name like_table_option_list ) ) )* ) | ) ')' opt_interleave opt_partition_by ( opt_with_storage_parameter_list ) ( 'ON' 'COMMIT' 'PRESERVE' 'ROWS' ) opt_locality - | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' ( ( ( ( column_def | index_def | family_def | table_constraint opt_validate_behavior | 'LIKE' table_name like_table_option_list ) ) ( ( ',' ( column_def | index_def | family_def | table_constraint opt_validate_behavior | 'LIKE' table_name like_table_option_list ) ) )* ) | ) ')' opt_interleave opt_partition_by ( opt_with_storage_parameter_list ) ( 'ON' 'COMMIT' 'PRESERVE' 'ROWS' ) opt_locality + 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' ( ( ( ( column_def | index_def | family_def | table_constraint opt_validate_behavior | 'LIKE' table_name like_table_option_list ) ) ( ( ',' ( column_def | index_def | family_def | table_constraint opt_validate_behavior | 'LIKE' table_name like_table_option_list ) ) )* ) | ) ')' opt_interleave opt_partition_by_table ( opt_with_storage_parameter_list ) ( 'ON' 'COMMIT' 'PRESERVE' 'ROWS' ) opt_locality + | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' ( ( ( ( column_def | index_def | family_def | table_constraint opt_validate_behavior | 'LIKE' table_name like_table_option_list ) ) ( ( ',' ( column_def | index_def | family_def | table_constraint opt_validate_behavior | 'LIKE' table_name like_table_option_list ) ) )* ) | ) ')' opt_interleave opt_partition_by_table ( opt_with_storage_parameter_list ) ( 'ON' 'COMMIT' 'PRESERVE' 'ROWS' ) opt_locality diff --git a/docs/generated/sql/bnf/index_def.bnf b/docs/generated/sql/bnf/index_def.bnf index 66efe0a175d7..c18eb11169a1 100644 --- a/docs/generated/sql/bnf/index_def.bnf +++ b/docs/generated/sql/bnf/index_def.bnf @@ -1,19 +1,19 @@ index_def ::= - 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'COVERING' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'STORING' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'COVERING' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'STORING' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'COVERING' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'STORING' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'COVERING' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'STORING' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause + 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'COVERING' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'STORING' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'COVERING' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'STORING' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'COVERING' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'STORING' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'COVERING' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'STORING' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'UNIQUE' 'INDEX' opt_index_name '(' index_elem ( ( ',' index_elem ) )* ')' opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause | 'INVERTED' 'INDEX' name '(' index_elem ( ( ',' index_elem ) )* ')' opt_with_storage_parameter_list opt_where_clause | 'INVERTED' 'INDEX' '(' index_elem ( ( ',' index_elem ) )* ')' opt_with_storage_parameter_list opt_where_clause diff --git a/docs/generated/sql/bnf/interleave.bnf b/docs/generated/sql/bnf/interleave.bnf index bf4701674aff..7e71696f8c8a 100644 --- a/docs/generated/sql/bnf/interleave.bnf +++ b/docs/generated/sql/bnf/interleave.bnf @@ -1,5 +1,5 @@ create_table_stmt ::= - 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' table_definition ')' 'INTERLEAVE' 'IN' 'PARENT' table_name '(' name_list ')' opt_partition_by 'WITH' '(' storage_parameter ( ( ',' storage_parameter ) )* ')' 'ON' 'COMMIT' 'PRESERVE' 'ROWS' opt_locality - | 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' table_definition ')' opt_partition_by 'WITH' '(' storage_parameter ( ( ',' storage_parameter ) )* ')' 'ON' 'COMMIT' 'PRESERVE' 'ROWS' opt_locality - | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' table_definition ')' 'INTERLEAVE' 'IN' 'PARENT' table_name '(' name_list ')' opt_partition_by 'WITH' '(' storage_parameter ( ( ',' storage_parameter ) )* ')' 'ON' 'COMMIT' 'PRESERVE' 'ROWS' opt_locality - | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' table_definition ')' opt_partition_by 'WITH' '(' storage_parameter ( ( ',' storage_parameter ) )* ')' 'ON' 'COMMIT' 'PRESERVE' 'ROWS' opt_locality + 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' table_definition ')' 'INTERLEAVE' 'IN' 'PARENT' table_name '(' name_list ')' opt_partition_by_table 'WITH' '(' storage_parameter ( ( ',' storage_parameter ) )* ')' 'ON' 'COMMIT' 'PRESERVE' 'ROWS' opt_locality + | 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' table_definition ')' opt_partition_by_table 'WITH' '(' storage_parameter ( ( ',' storage_parameter ) )* ')' 'ON' 'COMMIT' 'PRESERVE' 'ROWS' opt_locality + | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' table_definition ')' 'INTERLEAVE' 'IN' 'PARENT' table_name '(' name_list ')' opt_partition_by_table 'WITH' '(' storage_parameter ( ( ',' storage_parameter ) )* ')' 'ON' 'COMMIT' 'PRESERVE' 'ROWS' opt_locality + | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' table_definition ')' opt_partition_by_table 'WITH' '(' storage_parameter ( ( ',' storage_parameter ) )* ')' 'ON' 'COMMIT' 'PRESERVE' 'ROWS' opt_locality diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf index 263e25cb9a22..2f913a23f02c 100644 --- a/docs/generated/sql/bnf/stmt_block.bnf +++ b/docs/generated/sql/bnf/stmt_block.bnf @@ -1304,10 +1304,10 @@ create_database_stmt ::= | 'CREATE' 'DATABASE' 'IF' 'NOT' 'EXISTS' database_name opt_with opt_template_clause opt_encoding_clause opt_lc_collate_clause opt_lc_ctype_clause opt_connection_limit opt_primary_region_clause opt_regions_list opt_survival_goal_clause create_index_stmt ::= - 'CREATE' opt_unique 'INDEX' opt_concurrently opt_index_name 'ON' table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'CREATE' opt_unique 'INDEX' opt_concurrently 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'CREATE' opt_unique 'INVERTED' 'INDEX' opt_concurrently opt_index_name 'ON' table_name '(' index_params ')' opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'CREATE' opt_unique 'INVERTED' 'INDEX' opt_concurrently 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' index_params ')' opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause + 'CREATE' opt_unique 'INDEX' opt_concurrently opt_index_name 'ON' table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' opt_unique 'INDEX' opt_concurrently 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' opt_unique 'INVERTED' 'INDEX' opt_concurrently opt_index_name 'ON' table_name '(' index_params ')' opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'CREATE' opt_unique 'INVERTED' 'INDEX' opt_concurrently 'IF' 'NOT' 'EXISTS' index_name 'ON' table_name '(' index_params ')' opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause create_schema_stmt ::= 'CREATE' 'SCHEMA' qualifiable_schema_name @@ -1316,8 +1316,8 @@ create_schema_stmt ::= | 'CREATE' 'SCHEMA' 'IF' 'NOT' 'EXISTS' opt_schema_name 'AUTHORIZATION' role_spec create_table_stmt ::= - 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' opt_table_elem_list ')' opt_interleave opt_partition_by opt_table_with opt_create_table_on_commit opt_locality - | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' opt_table_elem_list ')' opt_interleave opt_partition_by opt_table_with opt_create_table_on_commit opt_locality + 'CREATE' opt_persistence_temp_table 'TABLE' table_name '(' opt_table_elem_list ')' opt_interleave opt_partition_by_table opt_table_with opt_create_table_on_commit opt_locality + | 'CREATE' opt_persistence_temp_table 'TABLE' 'IF' 'NOT' 'EXISTS' table_name '(' opt_table_elem_list ')' opt_interleave opt_partition_by_table opt_table_with opt_create_table_on_commit opt_locality create_table_as_stmt ::= 'CREATE' opt_persistence_temp_table 'TABLE' table_name create_as_opt_col_list opt_table_with 'AS' select_stmt opt_create_table_on_commit @@ -1823,7 +1823,7 @@ opt_interleave ::= 'INTERLEAVE' 'IN' 'PARENT' table_name '(' name_list ')' | -opt_partition_by ::= +opt_partition_by_index ::= partition_by | @@ -1846,6 +1846,10 @@ opt_table_elem_list ::= table_elem_list | +opt_partition_by_table ::= + partition_by_table + | + opt_table_with ::= opt_with_storage_parameter_list @@ -1931,8 +1935,8 @@ column_def ::= column_name typename col_qual_list index_def ::= - 'INDEX' opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause - | 'UNIQUE' 'INDEX' opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause + 'INDEX' opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause + | 'UNIQUE' 'INDEX' opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause | 'INVERTED' 'INDEX' opt_name '(' index_params ')' opt_with_storage_parameter_list opt_where_clause family_def ::= @@ -2289,13 +2293,15 @@ storing ::= | 'INCLUDE' partition_by ::= - 'PARTITION' 'BY' 'LIST' '(' name_list ')' '(' list_partitions ')' - | 'PARTITION' 'BY' 'RANGE' '(' name_list ')' '(' range_partitions ')' - | 'PARTITION' 'BY' 'NOTHING' + 'PARTITION' 'BY' partition_by_inner storage_parameter_list ::= ( storage_parameter ) ( ( ',' storage_parameter ) )* +partition_by_table ::= + partition_by + | 'PARTITION' 'ALL' 'BY' partition_by_inner + create_as_table_defs ::= ( column_name create_as_col_qual_list ) ( ( ',' column_name create_as_col_qual_list | ',' family_def | ',' create_as_constraint_def ) )* @@ -2336,7 +2342,7 @@ constraint_name ::= constraint_elem ::= 'CHECK' '(' a_expr ')' - | 'UNIQUE' opt_without_index '(' index_params ')' opt_storing opt_interleave opt_partition_by opt_where_clause + | 'UNIQUE' opt_without_index '(' index_params ')' opt_storing opt_interleave opt_partition_by_index opt_where_clause | 'PRIMARY' 'KEY' '(' index_params ')' opt_hash_sharded opt_interleave | 'FOREIGN' 'KEY' '(' name_list ')' 'REFERENCES' table_name opt_column_list key_match reference_actions @@ -2498,14 +2504,14 @@ alter_table_cmd ::= | 'DROP' 'CONSTRAINT' 'IF' 'EXISTS' constraint_name opt_drop_behavior | 'DROP' 'CONSTRAINT' constraint_name opt_drop_behavior | 'EXPERIMENTAL_AUDIT' 'SET' audit_mode - | partition_by + | partition_by_table | 'OWNER' 'TO' role_spec var_set_list ::= ( var_name '=' 'COPY' 'FROM' 'PARENT' | var_name '=' var_value ) ( ( ',' var_name '=' var_value | ',' var_name '=' 'COPY' 'FROM' 'PARENT' ) )* alter_index_cmd ::= - partition_by + partition_by_index sequence_option_elem ::= 'NO' 'CYCLE' @@ -2586,11 +2592,10 @@ func_expr_windowless ::= index_elem_options ::= opt_class opt_asc_desc opt_nulls_order -list_partitions ::= - ( list_partition ) ( ( ',' list_partition ) )* - -range_partitions ::= - ( range_partition ) ( ( ',' range_partition ) )* +partition_by_inner ::= + 'LIST' '(' name_list ')' '(' list_partitions ')' + | 'RANGE' '(' name_list ')' '(' range_partitions ')' + | 'NOTHING' storage_parameter ::= name '=' var_value @@ -2779,6 +2784,9 @@ audit_mode ::= 'READ' 'WRITE' | 'OFF' +partition_by_index ::= + partition_by + signed_iconst64 ::= signed_iconst @@ -2857,11 +2865,11 @@ opt_class ::= name | -list_partition ::= - partition 'VALUES' 'IN' '(' expr_list ')' opt_partition_by +list_partitions ::= + ( list_partition ) ( ( ',' list_partition ) )* -range_partition ::= - partition 'VALUES' 'FROM' '(' expr_list ')' 'TO' '(' expr_list ')' opt_partition_by +range_partitions ::= + ( range_partition ) ( ( ',' range_partition ) )* create_as_col_qualification ::= create_as_col_qualification_elem @@ -2978,6 +2986,12 @@ tuple1_unambiguous_values ::= a_expr ',' | a_expr ',' expr_list +list_partition ::= + partition 'VALUES' 'IN' '(' expr_list ')' opt_partition_by + +range_partition ::= + partition 'VALUES' 'FROM' '(' expr_list ')' 'TO' '(' expr_list ')' opt_partition_by + create_as_col_qualification_elem ::= 'PRIMARY' 'KEY' @@ -3043,6 +3057,10 @@ trim_list ::= | 'FROM' expr_list | expr_list +opt_partition_by ::= + partition_by + | + create_as_param ::= column_name diff --git a/docs/generated/sql/bnf/table_constraint.bnf b/docs/generated/sql/bnf/table_constraint.bnf index aae6bf3e3863..10c48ff605cd 100644 --- a/docs/generated/sql/bnf/table_constraint.bnf +++ b/docs/generated/sql/bnf/table_constraint.bnf @@ -1,17 +1,17 @@ table_constraint ::= 'CONSTRAINT' constraint_name 'CHECK' '(' a_expr ')' - | 'CONSTRAINT' constraint_name 'UNIQUE' opt_without_index '(' index_params ')' 'COVERING' '(' name_list ')' opt_interleave opt_partition_by opt_where_clause - | 'CONSTRAINT' constraint_name 'UNIQUE' opt_without_index '(' index_params ')' 'STORING' '(' name_list ')' opt_interleave opt_partition_by opt_where_clause - | 'CONSTRAINT' constraint_name 'UNIQUE' opt_without_index '(' index_params ')' 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by opt_where_clause - | 'CONSTRAINT' constraint_name 'UNIQUE' opt_without_index '(' index_params ')' opt_interleave opt_partition_by opt_where_clause + | 'CONSTRAINT' constraint_name 'UNIQUE' opt_without_index '(' index_params ')' 'COVERING' '(' name_list ')' opt_interleave opt_partition_by_index opt_where_clause + | 'CONSTRAINT' constraint_name 'UNIQUE' opt_without_index '(' index_params ')' 'STORING' '(' name_list ')' opt_interleave opt_partition_by_index opt_where_clause + | 'CONSTRAINT' constraint_name 'UNIQUE' opt_without_index '(' index_params ')' 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by_index opt_where_clause + | 'CONSTRAINT' constraint_name 'UNIQUE' opt_without_index '(' index_params ')' opt_interleave opt_partition_by_index opt_where_clause | 'CONSTRAINT' constraint_name 'PRIMARY' 'KEY' '(' index_params ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets opt_interleave | 'CONSTRAINT' constraint_name 'PRIMARY' 'KEY' '(' index_params ')' opt_interleave | 'CONSTRAINT' constraint_name 'FOREIGN' 'KEY' '(' name_list ')' 'REFERENCES' table_name opt_column_list key_match reference_actions | 'CHECK' '(' a_expr ')' - | 'UNIQUE' opt_without_index '(' index_params ')' 'COVERING' '(' name_list ')' opt_interleave opt_partition_by opt_where_clause - | 'UNIQUE' opt_without_index '(' index_params ')' 'STORING' '(' name_list ')' opt_interleave opt_partition_by opt_where_clause - | 'UNIQUE' opt_without_index '(' index_params ')' 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by opt_where_clause - | 'UNIQUE' opt_without_index '(' index_params ')' opt_interleave opt_partition_by opt_where_clause + | 'UNIQUE' opt_without_index '(' index_params ')' 'COVERING' '(' name_list ')' opt_interleave opt_partition_by_index opt_where_clause + | 'UNIQUE' opt_without_index '(' index_params ')' 'STORING' '(' name_list ')' opt_interleave opt_partition_by_index opt_where_clause + | 'UNIQUE' opt_without_index '(' index_params ')' 'INCLUDE' '(' name_list ')' opt_interleave opt_partition_by_index opt_where_clause + | 'UNIQUE' opt_without_index '(' index_params ')' opt_interleave opt_partition_by_index opt_where_clause | 'PRIMARY' 'KEY' '(' index_params ')' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets opt_interleave | 'PRIMARY' 'KEY' '(' index_params ')' opt_interleave | 'FOREIGN' 'KEY' '(' name_list ')' 'REFERENCES' table_name opt_column_list key_match reference_actions diff --git a/pkg/ccl/importccl/read_import_pgdump.go b/pkg/ccl/importccl/read_import_pgdump.go index cbe29a527705..519982af6c54 100644 --- a/pkg/ccl/importccl/read_import_pgdump.go +++ b/pkg/ccl/importccl/read_import_pgdump.go @@ -352,12 +352,12 @@ func readPostgresStmt( break } var idx tree.TableDef = &tree.IndexTableDef{ - Name: stmt.Name, - Columns: stmt.Columns, - Storing: stmt.Storing, - Inverted: stmt.Inverted, - Interleave: stmt.Interleave, - PartitionBy: stmt.PartitionBy, + Name: stmt.Name, + Columns: stmt.Columns, + Storing: stmt.Storing, + Inverted: stmt.Inverted, + Interleave: stmt.Interleave, + PartitionByIndex: stmt.PartitionByIndex, } if stmt.Unique { idx = &tree.UniqueConstraintTableDef{IndexTableDef: *idx.(*tree.IndexTableDef)} diff --git a/pkg/ccl/logictestccl/testdata/logic_test/partitioning b/pkg/ccl/logictestccl/testdata/logic_test/partitioning index 83f2e1cb9abb..b3795d9d7b6f 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/partitioning +++ b/pkg/ccl/logictestccl/testdata/logic_test/partitioning @@ -17,6 +17,11 @@ CREATE TABLE t (a INT, b INT, c INT) PARTITION BY LIST (a) ( PARTITION p1 VALUES IN (0) ) +statement error PARTITION ALL BY not yet implemented +CREATE TABLE t (a INT, b INT) PARTITION ALL BY LIST (b) ( + PARTITION p1 VALUES IN (0) +) + statement error declared partition columns \(a, b, c\) exceed the number of columns in index being partitioned \(a, b\) CREATE TABLE t (a INT, b INT, c INT, PRIMARY KEY (a, b)) PARTITION BY LIST (a, b, c) ( PARTITION p1 VALUES IN (0) diff --git a/pkg/cmd/cr2pg/main.go b/pkg/cmd/cr2pg/main.go index 4718ce419fa5..fa95e9940f2a 100644 --- a/pkg/cmd/cr2pg/main.go +++ b/pkg/cmd/cr2pg/main.go @@ -61,7 +61,7 @@ func main() { switch stmt := stmt.(type) { case *tree.CreateTable: stmt.Interleave = nil - stmt.PartitionBy = nil + stmt.PartitionByTable = nil var newdefs tree.TableDefs for _, def := range stmt.Defs { switch def := def.(type) { diff --git a/pkg/sql/alter_table.go b/pkg/sql/alter_table.go index fd2f2cc7a672..0c309f7c1318 100644 --- a/pkg/sql/alter_table.go +++ b/pkg/sql/alter_table.go @@ -35,6 +35,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry" "github.com/cockroachdb/cockroach/pkg/sql/stats" "github.com/cockroachdb/cockroach/pkg/sql/types" + "github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented" "github.com/cockroachdb/cockroach/pkg/util/log/eventpb" "github.com/cockroachdb/cockroach/pkg/util/protoutil" "github.com/cockroachdb/errors" @@ -219,10 +220,10 @@ func (n *alterTableNode) startExec(params runParams) error { if err := idx.FillColumns(d.Columns); err != nil { return err } - if d.PartitionBy != nil { + if d.PartitionByIndex.ContainsPartitions() { partitioning, err := CreatePartitioning( params.ctx, params.p.ExecCfg().Settings, - params.EvalContext(), n.tableDesc, &idx, d.PartitionBy) + params.EvalContext(), n.tableDesc, &idx, d.PartitionByIndex.PartitionBy) if err != nil { return err } @@ -738,7 +739,10 @@ func (n *alterTableNode) startExec(params runParams) error { } descriptorChanged = true - case *tree.AlterTablePartitionBy: + case *tree.AlterTablePartitionByTable: + if t.All { + return unimplemented.New("ALTER TABLE PARTITION ALL BY", "PARTITION ALL BY not yet implemented") + } partitioning, err := CreatePartitioning( params.ctx, params.p.ExecCfg().Settings, params.EvalContext(), diff --git a/pkg/sql/create_index.go b/pkg/sql/create_index.go index f57500b1e8a2..39b24473b806 100644 --- a/pkg/sql/create_index.go +++ b/pkg/sql/create_index.go @@ -169,7 +169,7 @@ func MakeIndexDescriptor( return nil, pgerror.New(pgcode.InvalidSQLStatementName, "inverted indexes don't support interleaved tables") } - if n.PartitionBy != nil { + if n.PartitionByIndex.ContainsPartitions() { return nil, pgerror.New(pgcode.InvalidSQLStatementName, "inverted indexes don't support partitioning") } @@ -209,7 +209,7 @@ func MakeIndexDescriptor( } if n.Sharded != nil { - if n.PartitionBy != nil { + if n.PartitionByIndex.ContainsPartitions() { return nil, pgerror.New(pgcode.FeatureNotSupported, "sharded indexes don't support partitioning") } if n.Interleave != nil { @@ -391,7 +391,7 @@ func (n *createIndexNode) startExec(params runParams) error { // Warn against creating a non-partitioned index on a partitioned table, // which is undesirable in most cases. - if n.n.PartitionBy == nil && n.tableDesc.GetPrimaryIndex().Partitioning.NumColumns > 0 { + if n.n.PartitionByIndex == nil && n.tableDesc.GetPrimaryIndex().Partitioning.NumColumns > 0 { params.p.BufferClientNotice( params.ctx, errors.WithHint( @@ -427,9 +427,9 @@ func (n *createIndexNode) startExec(params runParams) error { } indexDesc.Version = encodingVersion - if n.n.PartitionBy != nil { + if n.n.PartitionByIndex.ContainsPartitions() { partitioning, err := CreatePartitioning(params.ctx, params.p.ExecCfg().Settings, - params.EvalContext(), n.tableDesc, indexDesc, n.n.PartitionBy) + params.EvalContext(), n.tableDesc, indexDesc, n.n.PartitionByIndex.PartitionBy) if err != nil { return err } diff --git a/pkg/sql/create_table.go b/pkg/sql/create_table.go index 23f5dcd21ac9..a2ef852399f4 100644 --- a/pkg/sql/create_table.go +++ b/pkg/sql/create_table.go @@ -251,10 +251,10 @@ func (n *createTableNode) startExec(params runParams) error { // Warn against creating non-partitioned indexes on a partitioned table, // which is undesirable in most cases. - if n.n.PartitionBy != nil { + if n.n.PartitionByTable.ContainsPartitions() { for _, def := range n.n.Defs { if d, ok := def.(*tree.IndexTableDef); ok { - if d.PartitionBy == nil { + if d.PartitionByIndex == nil { params.p.BufferClientNotice( params.ctx, errors.WithHint( @@ -1372,7 +1372,7 @@ func NewTableDesc( if !sessionData.HashShardedIndexesEnabled { return nil, hashShardedIndexesDisabledError } - if n.PartitionBy != nil { + if n.PartitionByTable.ContainsPartitions() { return nil, pgerror.New(pgcode.FeatureNotSupported, "sharded indexes don't support partitioning") } if n.Interleave != nil { @@ -1473,7 +1473,7 @@ func NewTableDesc( var primaryIndexColumnSet map[string]struct{} setupShardedIndexForNewTable := func(d *tree.IndexTableDef, idx *descpb.IndexDescriptor) error { - if n.PartitionBy != nil { + if n.PartitionByTable.ContainsPartitions() { return pgerror.New(pgcode.FeatureNotSupported, "sharded indexes don't support partitioning") } shardCol, newColumn, err := setupShardedIndex( @@ -1553,8 +1553,8 @@ func NewTableDesc( idx.GeoConfig = *geoindex.DefaultGeographyIndexConfig() } } - if d.PartitionBy != nil { - partitioning, err := CreatePartitioning(ctx, st, evalCtx, &desc, &idx, d.PartitionBy) + if d.PartitionByIndex.ContainsPartitions() { + partitioning, err := CreatePartitioning(ctx, st, evalCtx, &desc, &idx, d.PartitionByIndex.PartitionBy) if err != nil { return nil, err } @@ -1606,8 +1606,8 @@ func NewTableDesc( if err := idx.FillColumns(d.Columns); err != nil { return nil, err } - if d.PartitionBy != nil { - partitioning, err := CreatePartitioning(ctx, st, evalCtx, &desc, &idx, d.PartitionBy) + if d.PartitionByIndex.ContainsPartitions() { + partitioning, err := CreatePartitioning(ctx, st, evalCtx, &desc, &idx, d.PartitionByIndex.PartitionBy) if err != nil { return nil, err } @@ -1714,16 +1714,23 @@ func NewTableDesc( } } - if n.PartitionBy != nil { - partitioning, err := CreatePartitioning( - ctx, st, evalCtx, &desc, desc.GetPrimaryIndex(), n.PartitionBy) - if err != nil { - return nil, err + // Do not use ContainsPartitions() for this check, as we may have to do something special for + // PARTITION BY NOTHING. + if n.PartitionByTable != nil { + if n.PartitionByTable.All { + return nil, unimplemented.New("CREATE TABLE PARTITION ALL BY", "PARTITION ALL BY not yet implemented") } - { - newPrimaryIndex := *desc.GetPrimaryIndex() - newPrimaryIndex.Partitioning = partitioning - desc.SetPrimaryIndex(newPrimaryIndex) + if n.PartitionByTable.PartitionBy != nil { + partitioning, err := CreatePartitioning( + ctx, st, evalCtx, &desc, desc.GetPrimaryIndex(), n.PartitionByTable.PartitionBy) + if err != nil { + return nil, err + } + { + newPrimaryIndex := *desc.GetPrimaryIndex() + newPrimaryIndex.Partitioning = partitioning + desc.SetPrimaryIndex(newPrimaryIndex) + } } } @@ -1809,7 +1816,7 @@ func NewTableDesc( "interleaved unique constraints without an index are not supported", ) } - if d.PartitionBy != nil { + if d.PartitionByIndex.ContainsPartitions() { return nil, pgerror.New(pgcode.FeatureNotSupported, "partitioned unique constraints without an index are not supported", ) diff --git a/pkg/sql/mutations/mutations.go b/pkg/sql/mutations/mutations.go index 02409c6756b6..37817be6f409 100644 --- a/pkg/sql/mutations/mutations.go +++ b/pkg/sql/mutations/mutations.go @@ -554,8 +554,8 @@ var postgresStatementMutator MultiStatementMutation = func(rng *rand.Rand, stmts stmt.Interleave = nil changed = true } - if stmt.PartitionBy != nil { - stmt.PartitionBy = nil + if stmt.PartitionByTable != nil { + stmt.PartitionByTable = nil changed = true } for i := 0; i < len(stmt.Defs); i++ { @@ -580,8 +580,8 @@ var postgresStatementMutator MultiStatementMutation = func(rng *rand.Rand, stmts def.Interleave = nil changed = true } - if def.PartitionBy != nil { - def.PartitionBy = nil + if def.PartitionByIndex != nil { + def.PartitionByIndex = nil changed = true } if def.WithoutIndex { diff --git a/pkg/sql/opt/testutils/testcat/create_index.go b/pkg/sql/opt/testutils/testcat/create_index.go index 75d09589a12a..8b5bb5006b63 100644 --- a/pkg/sql/opt/testutils/testcat/create_index.go +++ b/pkg/sql/opt/testutils/testcat/create_index.go @@ -33,14 +33,14 @@ func (tc *Catalog) CreateIndex(stmt *tree.CreateIndex, version descpb.IndexDescr // Convert stmt to a tree.IndexTableDef so that Table.addIndex can be used // to add the index to the table. indexTableDef := &tree.IndexTableDef{ - Name: stmt.Name, - Columns: stmt.Columns, - Sharded: stmt.Sharded, - Storing: stmt.Storing, - Interleave: stmt.Interleave, - Inverted: stmt.Inverted, - PartitionBy: stmt.PartitionBy, - Predicate: stmt.Predicate, + Name: stmt.Name, + Columns: stmt.Columns, + Sharded: stmt.Sharded, + Storing: stmt.Storing, + Interleave: stmt.Interleave, + Inverted: stmt.Inverted, + PartitionByIndex: stmt.PartitionByIndex, + Predicate: stmt.Predicate, } idxType := nonUniqueIndex diff --git a/pkg/sql/opt/testutils/testcat/create_table.go b/pkg/sql/opt/testutils/testcat/create_table.go index f2eb278d7c1e..c1b382c0c596 100644 --- a/pkg/sql/opt/testutils/testcat/create_table.go +++ b/pkg/sql/opt/testutils/testcat/create_table.go @@ -171,8 +171,8 @@ func (tc *Catalog) CreateTable(stmt *tree.CreateTable) *Table { } else { tab.addPrimaryColumnIndex("rowid") } - if stmt.PartitionBy != nil { - tab.Indexes[0].partitionBy = stmt.PartitionBy + if stmt.PartitionByTable != nil { + tab.Indexes[0].partitionBy = stmt.PartitionByTable.PartitionBy } // Add check constraints. @@ -553,13 +553,16 @@ func (tt *Table) addIndexWithVersion( } idx := &Index{ - IdxName: tt.makeIndexName(def.Name, typ), - Unique: typ != nonUniqueIndex, - Inverted: def.Inverted, - IdxZone: &zonepb.ZoneConfig{}, - table: tt, - partitionBy: def.PartitionBy, - version: version, + IdxName: tt.makeIndexName(def.Name, typ), + Unique: typ != nonUniqueIndex, + Inverted: def.Inverted, + IdxZone: &zonepb.ZoneConfig{}, + table: tt, + version: version, + } + + if def.PartitionByIndex != nil { + idx.partitionBy = def.PartitionByIndex.PartitionBy } // Look for name suffixes indicating this is a mutation index. diff --git a/pkg/sql/parser/parse_test.go b/pkg/sql/parser/parse_test.go index bd80fe97f365..e57a717d746b 100644 --- a/pkg/sql/parser/parse_test.go +++ b/pkg/sql/parser/parse_test.go @@ -291,7 +291,10 @@ func TestParse(t *testing.T) { {`CREATE TABLE a (b INT8 CONSTRAINT c CHECK (d))`}, {`CREATE TABLE a (b INT8 CONSTRAINT c REFERENCES d)`}, + {`CREATE TABLE a (b INT8) PARTITION BY NOTHING`}, + {`CREATE TABLE a (b INT8) PARTITION ALL BY NOTHING`}, {`CREATE TABLE a (b INT8) PARTITION BY LIST (b) (PARTITION p1 VALUES IN (1, DEFAULT), PARTITION p2 VALUES IN ((1, 2), (3, 4)))`}, + {`CREATE TABLE a (b INT8) PARTITION ALL BY LIST (b) (PARTITION p1 VALUES IN (1, DEFAULT), PARTITION p2 VALUES IN ((1, 2), (3, 4)))`}, // This monstrosity was added on the assumption that it's more readable // than all on one line. Feel free to rip it out if you come across it // and disagree. @@ -313,6 +316,7 @@ func TestParse(t *testing.T) { {`CREATE INDEX ON a (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1))`}, {`CREATE INDEX IF NOT EXISTS a ON b (c) PARTITION BY LIST (d) (PARTITION e VALUES IN (1))`}, {`ALTER TABLE a PARTITION BY LIST (b) (PARTITION p1 VALUES IN (1))`}, + {`ALTER TABLE a PARTITION ALL BY LIST (b) (PARTITION p1 VALUES IN (1))`}, {`ALTER INDEX a@idx PARTITION BY LIST (b) (PARTITION p1 VALUES IN (1))`}, {`CREATE TABLE a AS SELECT * FROM b`}, @@ -2774,6 +2778,8 @@ SKIP_MISSING_FOREIGN_KEYS, SKIP_MISSING_SEQUENCES, SKIP_MISSING_SEQUENCE_OWNERS, {`CREATE TABLE a (b INT) PARTITION BY RANGE (b) (PARTITION p1 VALUES FROM (MINVALUE) TO (1), PARTITION p2 VALUES FROM (2, MAXVALUE) TO (4, 4), PARTITION p3 VALUES FROM (4, 4) TO (MAXVALUE))`, `CREATE TABLE a (b INT8) PARTITION BY RANGE (b) (PARTITION p1 VALUES FROM (minvalue) TO (1), PARTITION p2 VALUES FROM (2, maxvalue) TO (4, 4), PARTITION p3 VALUES FROM (4, 4) TO (maxvalue))`}, + {`CREATE TABLE a (b INT) PARTITION ALL BY RANGE (b) (PARTITION p1 VALUES FROM (MINVALUE) TO (1), PARTITION p2 VALUES FROM (2, MAXVALUE) TO (4, 4), PARTITION p3 VALUES FROM (4, 4) TO (MAXVALUE))`, + `CREATE TABLE a (b INT8) PARTITION ALL BY RANGE (b) (PARTITION p1 VALUES FROM (minvalue) TO (1), PARTITION p2 VALUES FROM (2, maxvalue) TO (4, 4), PARTITION p3 VALUES FROM (4, 4) TO (maxvalue))`}, // Check that JSONB operators have higher precedence than '='. {`SELECT '{}'::JSONB ? 'a' = false`, `SELECT ('{}'::JSONB ? 'a') = false`}, diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index 42f3e674c5e0..b870058160c4 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -446,6 +446,12 @@ func (u *sqlSymUnion) interleave() *tree.InterleaveDef { func (u *sqlSymUnion) partitionBy() *tree.PartitionBy { return u.val.(*tree.PartitionBy) } +func (u *sqlSymUnion) partitionByTable() *tree.PartitionByTable { + return u.val.(*tree.PartitionByTable) +} +func (u *sqlSymUnion) partitionByIndex() *tree.PartitionByIndex { + return u.val.(*tree.PartitionByIndex) +} func (u *sqlSymUnion) createTableOnCommitSetting() tree.CreateTableOnCommitSetting { return u.val.(tree.CreateTableOnCommitSetting) } @@ -1002,7 +1008,9 @@ func (u *sqlSymUnion) objectNamePrefixList() tree.ObjectNamePrefixList { %type like_table_option %type opt_create_table_on_commit %type <*tree.InterleaveDef> opt_interleave -%type <*tree.PartitionBy> opt_partition_by partition_by +%type <*tree.PartitionBy> opt_partition_by partition_by partition_by_inner +%type <*tree.PartitionByTable> opt_partition_by_table partition_by_table +%type <*tree.PartitionByIndex> opt_partition_by_index partition_by_index %type partition opt_partition %type opt_create_table_inherits %type list_partition @@ -1989,10 +1997,10 @@ alter_table_cmd: $$.val = &tree.AlterTableSetAudit{Mode: $3.auditMode()} } // ALTER TABLE PARTITION BY ... -| partition_by +| partition_by_table { - $$.val = &tree.AlterTablePartitionBy{ - PartitionBy: $1.partitionBy(), + $$.val = &tree.AlterTablePartitionByTable{ + PartitionByTable: $1.partitionByTable(), } } // ALTER TABLE INJECT STATISTICS @@ -2026,10 +2034,10 @@ alter_index_cmds: } alter_index_cmd: - partition_by + partition_by_index { $$.val = &tree.AlterIndexPartitionBy{ - PartitionBy: $1.partitionBy(), + PartitionByIndex: $1.partitionByIndex(), } } @@ -5657,7 +5665,7 @@ alter_schema_stmt: // WEBDOCS/create-table.html // WEBDOCS/create-table-as.html create_table_stmt: - CREATE opt_persistence_temp_table TABLE table_name '(' opt_table_elem_list ')' opt_create_table_inherits opt_interleave opt_partition_by opt_table_with opt_create_table_on_commit opt_locality + CREATE opt_persistence_temp_table TABLE table_name '(' opt_table_elem_list ')' opt_create_table_inherits opt_interleave opt_partition_by_table opt_table_with opt_create_table_on_commit opt_locality { name := $4.unresolvedObjectName().ToTableName() $$.val = &tree.CreateTable{ @@ -5666,14 +5674,14 @@ create_table_stmt: Interleave: $9.interleave(), Defs: $6.tblDefs(), AsSource: nil, - PartitionBy: $10.partitionBy(), + PartitionByTable: $10.partitionByTable(), Persistence: $2.persistence(), StorageParams: $11.storageParams(), OnCommit: $12.createTableOnCommitSetting(), Locality: $13.locality(), } } -| CREATE opt_persistence_temp_table TABLE IF NOT EXISTS table_name '(' opt_table_elem_list ')' opt_create_table_inherits opt_interleave opt_partition_by opt_table_with opt_create_table_on_commit opt_locality +| CREATE opt_persistence_temp_table TABLE IF NOT EXISTS table_name '(' opt_table_elem_list ')' opt_create_table_inherits opt_interleave opt_partition_by_table opt_table_with opt_create_table_on_commit opt_locality { name := $7.unresolvedObjectName().ToTableName() $$.val = &tree.CreateTable{ @@ -5682,7 +5690,7 @@ create_table_stmt: Interleave: $12.interleave(), Defs: $9.tblDefs(), AsSource: nil, - PartitionBy: $13.partitionBy(), + PartitionByTable: $13.partitionByTable(), Persistence: $2.persistence(), StorageParams: $14.storageParams(), OnCommit: $15.createTableOnCommitSetting(), @@ -5958,22 +5966,70 @@ opt_partition_by: $$.val = (*tree.PartitionBy)(nil) } +partition_by_index: + partition_by + { + $$.val = &tree.PartitionByIndex{ + PartitionBy: $1.partitionBy(), + } + } + +opt_partition_by_index: + partition_by + { + $$.val = &tree.PartitionByIndex{ + PartitionBy: $1.partitionBy(), + } + } +| /* EMPTY */ + { + $$.val = (*tree.PartitionByIndex)(nil) + } + +partition_by_table: + partition_by + { + $$.val = &tree.PartitionByTable{ + PartitionBy: $1.partitionBy(), + } + } +| PARTITION ALL BY partition_by_inner + { + $$.val = &tree.PartitionByTable{ + All: true, + PartitionBy: $4.partitionBy(), + } + } + +opt_partition_by_table: + partition_by_table +| /* EMPTY */ + { + $$.val = (*tree.PartitionByTable)(nil) + } + partition_by: - PARTITION BY LIST '(' name_list ')' '(' list_partitions ')' + PARTITION BY partition_by_inner + { + $$.val = $3.partitionBy() + } + +partition_by_inner: + LIST '(' name_list ')' '(' list_partitions ')' { $$.val = &tree.PartitionBy{ - Fields: $5.nameList(), - List: $8.listPartitions(), + Fields: $3.nameList(), + List: $6.listPartitions(), } } -| PARTITION BY RANGE '(' name_list ')' '(' range_partitions ')' +| RANGE '(' name_list ')' '(' range_partitions ')' { $$.val = &tree.PartitionBy{ - Fields: $5.nameList(), - Range: $8.rangePartitions(), + Fields: $3.nameList(), + Range: $6.rangePartitions(), } } -| PARTITION BY NOTHING +| NOTHING { $$.val = (*tree.PartitionBy)(nil) } @@ -6160,31 +6216,31 @@ generated_as: index_def: - INDEX opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause + INDEX opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause { $$.val = &tree.IndexTableDef{ - Name: tree.Name($2), - Columns: $4.idxElems(), - Sharded: $6.shardedIndexDef(), - Storing: $7.nameList(), - Interleave: $8.interleave(), - PartitionBy: $9.partitionBy(), - StorageParams: $10.storageParams(), - Predicate: $11.expr(), + Name: tree.Name($2), + Columns: $4.idxElems(), + Sharded: $6.shardedIndexDef(), + Storing: $7.nameList(), + Interleave: $8.interleave(), + PartitionByIndex: $9.partitionByIndex(), + StorageParams: $10.storageParams(), + Predicate: $11.expr(), } } -| UNIQUE INDEX opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause +| UNIQUE INDEX opt_index_name '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause { $$.val = &tree.UniqueConstraintTableDef{ IndexTableDef: tree.IndexTableDef { - Name: tree.Name($3), - Columns: $5.idxElems(), - Sharded: $7.shardedIndexDef(), - Storing: $8.nameList(), - Interleave: $9.interleave(), - PartitionBy: $10.partitionBy(), - StorageParams: $11.storageParams(), - Predicate: $12.expr(), + Name: tree.Name($3), + Columns: $5.idxElems(), + Sharded: $7.shardedIndexDef(), + Storing: $8.nameList(), + Interleave: $9.interleave(), + PartitionByIndex: $10.partitionByIndex(), + StorageParams: $11.storageParams(), + Predicate: $12.expr(), }, } } @@ -6230,7 +6286,7 @@ constraint_elem: } } | UNIQUE opt_without_index '(' index_params ')' - opt_storing opt_interleave opt_partition_by opt_deferrable opt_where_clause + opt_storing opt_interleave opt_partition_by_index opt_deferrable opt_where_clause { $$.val = &tree.UniqueConstraintTableDef{ WithoutIndex: $2.bool(), @@ -6238,7 +6294,7 @@ constraint_elem: Columns: $4.idxElems(), Storing: $6.nameList(), Interleave: $7.interleave(), - PartitionBy: $8.partitionBy(), + PartitionByIndex: $8.partitionByIndex(), Predicate: $10.expr(), }, } @@ -6912,76 +6968,76 @@ enum_val_list: // %SeeAlso: CREATE TABLE, SHOW INDEXES, SHOW CREATE, // WEBDOCS/create-index.html create_index_stmt: - CREATE opt_unique INDEX opt_concurrently opt_index_name ON table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause + CREATE opt_unique INDEX opt_concurrently opt_index_name ON table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause { table := $7.unresolvedObjectName().ToTableName() $$.val = &tree.CreateIndex{ - Name: tree.Name($5), - Table: table, - Unique: $2.bool(), - Columns: $10.idxElems(), - Sharded: $12.shardedIndexDef(), - Storing: $13.nameList(), - Interleave: $14.interleave(), - PartitionBy: $15.partitionBy(), - StorageParams: $16.storageParams(), - Predicate: $17.expr(), - Inverted: $8.bool(), - Concurrently: $4.bool(), - } - } -| CREATE opt_unique INDEX opt_concurrently IF NOT EXISTS index_name ON table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause + Name: tree.Name($5), + Table: table, + Unique: $2.bool(), + Columns: $10.idxElems(), + Sharded: $12.shardedIndexDef(), + Storing: $13.nameList(), + Interleave: $14.interleave(), + PartitionByIndex: $15.partitionByIndex(), + StorageParams: $16.storageParams(), + Predicate: $17.expr(), + Inverted: $8.bool(), + Concurrently: $4.bool(), + } + } +| CREATE opt_unique INDEX opt_concurrently IF NOT EXISTS index_name ON table_name opt_index_access_method '(' index_params ')' opt_hash_sharded opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause { table := $10.unresolvedObjectName().ToTableName() $$.val = &tree.CreateIndex{ - Name: tree.Name($8), - Table: table, - Unique: $2.bool(), - IfNotExists: true, - Columns: $13.idxElems(), - Sharded: $15.shardedIndexDef(), - Storing: $16.nameList(), - Interleave: $17.interleave(), - PartitionBy: $18.partitionBy(), - Inverted: $11.bool(), - StorageParams: $19.storageParams(), - Predicate: $20.expr(), - Concurrently: $4.bool(), - } - } -| CREATE opt_unique INVERTED INDEX opt_concurrently opt_index_name ON table_name '(' index_params ')' opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause + Name: tree.Name($8), + Table: table, + Unique: $2.bool(), + IfNotExists: true, + Columns: $13.idxElems(), + Sharded: $15.shardedIndexDef(), + Storing: $16.nameList(), + Interleave: $17.interleave(), + PartitionByIndex: $18.partitionByIndex(), + Inverted: $11.bool(), + StorageParams: $19.storageParams(), + Predicate: $20.expr(), + Concurrently: $4.bool(), + } + } +| CREATE opt_unique INVERTED INDEX opt_concurrently opt_index_name ON table_name '(' index_params ')' opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause { table := $8.unresolvedObjectName().ToTableName() $$.val = &tree.CreateIndex{ - Name: tree.Name($6), - Table: table, - Unique: $2.bool(), - Inverted: true, - Columns: $10.idxElems(), - Storing: $12.nameList(), - Interleave: $13.interleave(), - PartitionBy: $14.partitionBy(), - StorageParams: $15.storageParams(), - Predicate: $16.expr(), - Concurrently: $5.bool(), + Name: tree.Name($6), + Table: table, + Unique: $2.bool(), + Inverted: true, + Columns: $10.idxElems(), + Storing: $12.nameList(), + Interleave: $13.interleave(), + PartitionByIndex: $14.partitionByIndex(), + StorageParams: $15.storageParams(), + Predicate: $16.expr(), + Concurrently: $5.bool(), } } -| CREATE opt_unique INVERTED INDEX opt_concurrently IF NOT EXISTS index_name ON table_name '(' index_params ')' opt_storing opt_interleave opt_partition_by opt_with_storage_parameter_list opt_where_clause +| CREATE opt_unique INVERTED INDEX opt_concurrently IF NOT EXISTS index_name ON table_name '(' index_params ')' opt_storing opt_interleave opt_partition_by_index opt_with_storage_parameter_list opt_where_clause { table := $11.unresolvedObjectName().ToTableName() $$.val = &tree.CreateIndex{ - Name: tree.Name($9), - Table: table, - Unique: $2.bool(), - Inverted: true, - IfNotExists: true, - Columns: $13.idxElems(), - Storing: $15.nameList(), - Interleave: $16.interleave(), - PartitionBy: $17.partitionBy(), - StorageParams: $18.storageParams(), - Predicate: $19.expr(), - Concurrently: $5.bool(), + Name: tree.Name($9), + Table: table, + Unique: $2.bool(), + Inverted: true, + IfNotExists: true, + Columns: $13.idxElems(), + Storing: $15.nameList(), + Interleave: $16.interleave(), + PartitionByIndex: $17.partitionByIndex(), + StorageParams: $18.storageParams(), + Predicate: $19.expr(), + Concurrently: $5.bool(), } } | CREATE opt_unique INDEX error // SHOW HELP: CREATE INDEX diff --git a/pkg/sql/sem/tree/alter_index.go b/pkg/sql/sem/tree/alter_index.go index 96ddf97e40f3..e7f68df8c27c 100644 --- a/pkg/sql/sem/tree/alter_index.go +++ b/pkg/sql/sem/tree/alter_index.go @@ -57,10 +57,10 @@ var _ AlterIndexCmd = &AlterIndexPartitionBy{} // AlterIndexPartitionBy represents an ALTER INDEX PARTITION BY // command. type AlterIndexPartitionBy struct { - *PartitionBy + *PartitionByIndex } // Format implements the NodeFormatter interface. func (node *AlterIndexPartitionBy) Format(ctx *FmtCtx) { - ctx.FormatNode(node.PartitionBy) + ctx.FormatNode(node.PartitionByIndex) } diff --git a/pkg/sql/sem/tree/alter_table.go b/pkg/sql/sem/tree/alter_table.go index 004115b2cd60..5d640c657a6d 100644 --- a/pkg/sql/sem/tree/alter_table.go +++ b/pkg/sql/sem/tree/alter_table.go @@ -74,7 +74,7 @@ func (*AlterTableRenameConstraint) alterTableCmd() {} func (*AlterTableSetAudit) alterTableCmd() {} func (*AlterTableSetDefault) alterTableCmd() {} func (*AlterTableValidateConstraint) alterTableCmd() {} -func (*AlterTablePartitionBy) alterTableCmd() {} +func (*AlterTablePartitionByTable) alterTableCmd() {} func (*AlterTableInjectStats) alterTableCmd() {} func (*AlterTableOwner) alterTableCmd() {} @@ -91,7 +91,7 @@ var _ AlterTableCmd = &AlterTableRenameConstraint{} var _ AlterTableCmd = &AlterTableSetAudit{} var _ AlterTableCmd = &AlterTableSetDefault{} var _ AlterTableCmd = &AlterTableValidateConstraint{} -var _ AlterTableCmd = &AlterTablePartitionBy{} +var _ AlterTableCmd = &AlterTablePartitionByTable{} var _ AlterTableCmd = &AlterTableInjectStats{} var _ AlterTableCmd = &AlterTableOwner{} @@ -478,20 +478,20 @@ func (node *AlterTableDropStored) Format(ctx *FmtCtx) { ctx.WriteString(" DROP STORED") } -// AlterTablePartitionBy represents an ALTER TABLE PARTITION BY -// command. -type AlterTablePartitionBy struct { - *PartitionBy +// AlterTablePartitionByTable represents an ALTER TABLE PARTITION [ALL] +// BY command. +type AlterTablePartitionByTable struct { + *PartitionByTable } // TelemetryCounter implements the AlterTableCmd interface. -func (node *AlterTablePartitionBy) TelemetryCounter() telemetry.Counter { +func (node *AlterTablePartitionByTable) TelemetryCounter() telemetry.Counter { return sqltelemetry.SchemaChangeAlterCounterWithExtra("table", "partition_by") } // Format implements the NodeFormatter interface. -func (node *AlterTablePartitionBy) Format(ctx *FmtCtx) { - ctx.FormatNode(node.PartitionBy) +func (node *AlterTablePartitionByTable) Format(ctx *FmtCtx) { + ctx.FormatNode(node.PartitionByTable) } // AuditMode represents a table audit mode diff --git a/pkg/sql/sem/tree/create.go b/pkg/sql/sem/tree/create.go index d087b8af6a5e..feabd730a49d 100644 --- a/pkg/sql/sem/tree/create.go +++ b/pkg/sql/sem/tree/create.go @@ -185,12 +185,12 @@ type CreateIndex struct { Sharded *ShardedIndexDef // Extra columns to be stored together with the indexed ones as an optimization // for improved reading performance. - Storing NameList - Interleave *InterleaveDef - PartitionBy *PartitionBy - StorageParams StorageParams - Predicate Expr - Concurrently bool + Storing NameList + Interleave *InterleaveDef + PartitionByIndex *PartitionByIndex + StorageParams StorageParams + Predicate Expr + Concurrently bool } // Format implements the NodeFormatter interface. @@ -237,8 +237,8 @@ func (node *CreateIndex) Format(ctx *FmtCtx) { if node.Interleave != nil { ctx.FormatNode(node.Interleave) } - if node.PartitionBy != nil { - ctx.FormatNode(node.PartitionBy) + if node.PartitionByIndex != nil { + ctx.FormatNode(node.PartitionByIndex) } if node.StorageParams != nil { ctx.WriteString(" WITH (") @@ -778,15 +778,15 @@ type ColumnFamilyConstraint struct { // IndexTableDef represents an index definition within a CREATE TABLE // statement. type IndexTableDef struct { - Name Name - Columns IndexElemList - Sharded *ShardedIndexDef - Storing NameList - Interleave *InterleaveDef - Inverted bool - PartitionBy *PartitionBy - StorageParams StorageParams - Predicate Expr + Name Name + Columns IndexElemList + Sharded *ShardedIndexDef + Storing NameList + Interleave *InterleaveDef + Inverted bool + PartitionByIndex *PartitionByIndex + StorageParams StorageParams + Predicate Expr } // Format implements the NodeFormatter interface. @@ -813,8 +813,8 @@ func (node *IndexTableDef) Format(ctx *FmtCtx) { if node.Interleave != nil { ctx.FormatNode(node.Interleave) } - if node.PartitionBy != nil { - ctx.FormatNode(node.PartitionBy) + if node.PartitionByIndex != nil { + ctx.FormatNode(node.PartitionByIndex) } if node.StorageParams != nil { ctx.WriteString(" WITH (") @@ -885,8 +885,8 @@ func (node *UniqueConstraintTableDef) Format(ctx *FmtCtx) { if node.Interleave != nil { ctx.FormatNode(node.Interleave) } - if node.PartitionBy != nil { - ctx.FormatNode(node.PartitionBy) + if node.PartitionByIndex != nil { + ctx.FormatNode(node.PartitionByIndex) } if node.Predicate != nil { ctx.WriteString(" WHERE ") @@ -1095,8 +1095,51 @@ const ( PartitionByRange PartitionByType = "RANGE" ) +// PartitionByIndex represents a PARTITION BY definition within +// a CREATE/ALTER INDEX statement. +type PartitionByIndex struct { + *PartitionBy +} + +// ContainsPartitions determines if the partition by table contains +// a partition clause which is not PARTITION BY NOTHING. +func (node *PartitionByIndex) ContainsPartitions() bool { + return node != nil && node.PartitionBy != nil +} + +// PartitionByTable represents a PARTITION [ALL] BY definition within +// a CREATE/ALTER TABLE statement. +type PartitionByTable struct { + // All denotes PARTITION ALL BY. + All bool + + *PartitionBy +} + +// Format implements the NodeFormatter interface. +func (node *PartitionByTable) Format(ctx *FmtCtx) { + if node == nil { + ctx.WriteString(` PARTITION BY NOTHING`) + return + } + ctx.WriteString(` PARTITION `) + if node.All { + ctx.WriteString(`ALL `) + } + ctx.WriteString(`BY `) + node.PartitionBy.formatListOrRange(ctx) +} + +// ContainsPartitions determines if the partition by table contains +// a partition clause which is not PARTITION BY NOTHING. +func (node *PartitionByTable) ContainsPartitions() bool { + return node != nil && node.PartitionBy != nil +} + // PartitionBy represents an PARTITION BY definition within a CREATE/ALTER -// TABLE/INDEX statement. +// TABLE/INDEX statement or within a subpartition statement. +// This is wrapped by top level PartitionByTable/PartitionByIndex +// structs for table and index definitions respectively. type PartitionBy struct { Fields NameList // Exactly one of List or Range is required to be non-empty. @@ -1106,14 +1149,19 @@ type PartitionBy struct { // Format implements the NodeFormatter interface. func (node *PartitionBy) Format(ctx *FmtCtx) { + ctx.WriteString(` PARTITION BY `) + node.formatListOrRange(ctx) +} + +func (node *PartitionBy) formatListOrRange(ctx *FmtCtx) { if node == nil { - ctx.WriteString(` PARTITION BY NOTHING`) + ctx.WriteString(`NOTHING`) return } if len(node.List) > 0 { - ctx.WriteString(` PARTITION BY LIST (`) + ctx.WriteString(`LIST (`) } else if len(node.Range) > 0 { - ctx.WriteString(` PARTITION BY RANGE (`) + ctx.WriteString(`RANGE (`) } ctx.FormatNode(&node.Fields) ctx.WriteString(`) (`) @@ -1210,13 +1258,13 @@ const ( // CreateTable represents a CREATE TABLE statement. type CreateTable struct { - IfNotExists bool - Table TableName - Interleave *InterleaveDef - PartitionBy *PartitionBy - Persistence Persistence - StorageParams StorageParams - OnCommit CreateTableOnCommitSetting + IfNotExists bool + Table TableName + Interleave *InterleaveDef + PartitionByTable *PartitionByTable + Persistence Persistence + StorageParams StorageParams + OnCommit CreateTableOnCommitSetting // In CREATE...AS queries, Defs represents a list of ColumnTableDefs, one for // each column, and a ConstraintTableDef for each constraint on a subset of // these columns. @@ -1281,8 +1329,8 @@ func (node *CreateTable) FormatBody(ctx *FmtCtx) { if node.Interleave != nil { ctx.FormatNode(node.Interleave) } - if node.PartitionBy != nil { - ctx.FormatNode(node.PartitionBy) + if node.PartitionByTable != nil { + ctx.FormatNode(node.PartitionByTable) } // No storage parameters are implemented, so we never list the storage // parameters in the output format. diff --git a/pkg/sql/sem/tree/pretty.go b/pkg/sql/sem/tree/pretty.go index 9e5d7c1862f7..5dc003edf42b 100644 --- a/pkg/sql/sem/tree/pretty.go +++ b/pkg/sql/sem/tree/pretty.go @@ -1238,8 +1238,8 @@ func (node *CreateTable) doc(p *PrettyCfg) pretty.Doc { if node.Interleave != nil { clauses = append(clauses, p.Doc(node.Interleave)) } - if node.PartitionBy != nil { - clauses = append(clauses, p.Doc(node.PartitionBy)) + if node.PartitionByTable != nil { + clauses = append(clauses, p.Doc(node.PartitionByTable)) } if node.Locality != nil { clauses = append(clauses, p.Doc(node.Locality)) @@ -1404,6 +1404,24 @@ func (node *NullIfExpr) doc(p *PrettyCfg) pretty.Doc { ), ")", "") } +func (node *PartitionByTable) doc(p *PrettyCfg) pretty.Doc { + // Final layout: + // + // PARTITION [ALL] BY NOTHING + // + // PARTITION [ALL] BY LIST (...) + // ( ..values.. ) + // + // PARTITION [ALL] BY RANGE (...) + // ( ..values.. ) + var kw string + kw = `PARTITION ` + if node.All { + kw += `ALL ` + } + return node.PartitionBy.docInner(p, kw+`BY `) +} + func (node *PartitionBy) doc(p *PrettyCfg) pretty.Doc { // Final layout: // @@ -1412,15 +1430,19 @@ func (node *PartitionBy) doc(p *PrettyCfg) pretty.Doc { // PARTITION BY LIST (...) // ( ..values.. ) // + // PARTITION BY RANGE (...) + // ( ..values.. ) + return node.docInner(p, `PARTITION BY `) +} + +func (node *PartitionBy) docInner(p *PrettyCfg, kw string) pretty.Doc { if node == nil { - return pretty.Keyword("PARTITION BY NOTHING") + return pretty.Keyword(kw + `NOTHING`) } - - var kw string if len(node.List) > 0 { - kw = `PARTITION BY LIST` + kw += `LIST` } else if len(node.Range) > 0 { - kw = `PARTITION BY RANGE` + kw += `RANGE` } title := pretty.ConcatSpace(pretty.Keyword(kw), p.bracket("(", p.Doc(&node.Fields), ")")) @@ -1587,8 +1609,8 @@ func (node *CreateIndex) doc(p *PrettyCfg) pretty.Doc { if node.Interleave != nil { clauses = append(clauses, p.Doc(node.Interleave)) } - if node.PartitionBy != nil { - clauses = append(clauses, p.Doc(node.PartitionBy)) + if node.PartitionByIndex != nil { + clauses = append(clauses, p.Doc(node.PartitionByIndex)) } if node.StorageParams != nil { clauses = append(clauses, p.bracketKeyword( @@ -1660,8 +1682,8 @@ func (node *IndexTableDef) doc(p *PrettyCfg) pretty.Doc { if node.Interleave != nil { clauses = append(clauses, p.Doc(node.Interleave)) } - if node.PartitionBy != nil { - clauses = append(clauses, p.Doc(node.PartitionBy)) + if node.PartitionByIndex != nil { + clauses = append(clauses, p.Doc(node.PartitionByIndex)) } if node.StorageParams != nil { clauses = append( @@ -1723,8 +1745,8 @@ func (node *UniqueConstraintTableDef) doc(p *PrettyCfg) pretty.Doc { if node.Interleave != nil { clauses = append(clauses, p.Doc(node.Interleave)) } - if node.PartitionBy != nil { - clauses = append(clauses, p.Doc(node.PartitionBy)) + if node.PartitionByIndex != nil { + clauses = append(clauses, p.Doc(node.PartitionByIndex)) } if node.Predicate != nil { clauses = append(clauses, p.nestUnder(pretty.Keyword("WHERE"), p.Doc(node.Predicate)))