Skip to content

Commit

Permalink
sql: add syntax for experimental domiciling
Browse files Browse the repository at this point in the history
This commit adds the PLACEMENT [RESTRICTED | DEFAULT] flag to CREATE
DATABASE and adds the ALTER DATABASE PLACEMENT statement. These will
be used to support #59756.

Release note: None
  • Loading branch information
pawalt committed Jul 26, 2021
1 parent 3fd1428 commit af6652c
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 9 deletions.
4 changes: 2 additions & 2 deletions docs/generated/sql/bnf/create_database_stmt.bnf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
create_database_stmt ::=
'CREATE' 'DATABASE' database_name ( 'WITH' | ) opt_template_clause ( 'ENCODING' ( '=' | ) encoding | ) opt_lc_collate_clause opt_lc_ctype_clause ( 'CONNECTION' 'LIMIT' ( '=' | ) limit | ) ( ( 'PRIMARY' 'REGION' ( '=' | ) region_name ) | ) ( ( 'REGIONS' ) ( '=' | ) region_name_list | ) ( ( 'SURVIVE' ( '=' | ) 'REGION' 'FAILURE' | 'SURVIVE' ( '=' | ) 'ZONE' 'FAILURE' ) | )
| 'CREATE' 'DATABASE' 'IF' 'NOT' 'EXISTS' database_name ( 'WITH' | ) opt_template_clause ( 'ENCODING' ( '=' | ) encoding | ) opt_lc_collate_clause opt_lc_ctype_clause ( 'CONNECTION' 'LIMIT' ( '=' | ) limit | ) ( ( 'PRIMARY' 'REGION' ( '=' | ) region_name ) | ) ( ( 'REGIONS' ) ( '=' | ) region_name_list | ) ( ( 'SURVIVE' ( '=' | ) 'REGION' 'FAILURE' | 'SURVIVE' ( '=' | ) 'ZONE' 'FAILURE' ) | )
'CREATE' 'DATABASE' database_name ( 'WITH' | ) opt_template_clause ( 'ENCODING' ( '=' | ) encoding | ) opt_lc_collate_clause opt_lc_ctype_clause ( 'CONNECTION' 'LIMIT' ( '=' | ) limit | ) ( ( 'PRIMARY' 'REGION' ( '=' | ) region_name ) | ) ( ( 'REGIONS' ) ( '=' | ) region_name_list | ) ( ( 'SURVIVE' ( '=' | ) 'REGION' 'FAILURE' | 'SURVIVE' ( '=' | ) 'ZONE' 'FAILURE' ) | ) opt_placement_clause
| 'CREATE' 'DATABASE' 'IF' 'NOT' 'EXISTS' database_name ( 'WITH' | ) opt_template_clause ( 'ENCODING' ( '=' | ) encoding | ) opt_lc_collate_clause opt_lc_ctype_clause ( 'CONNECTION' 'LIMIT' ( '=' | ) limit | ) ( ( 'PRIMARY' 'REGION' ( '=' | ) region_name ) | ) ( ( 'REGIONS' ) ( '=' | ) region_name_list | ) ( ( 'SURVIVE' ( '=' | ) 'REGION' 'FAILURE' | 'SURVIVE' ( '=' | ) 'ZONE' 'FAILURE' ) | ) opt_placement_clause
14 changes: 12 additions & 2 deletions docs/generated/sql/bnf/stmt_block.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,7 @@ unreserved_keyword ::=
| 'PAUSE'
| 'PAUSED'
| 'PHYSICAL'
| 'PLACEMENT'
| 'PLAN'
| 'PLANS'
| 'POINTM'
Expand Down Expand Up @@ -1042,6 +1043,7 @@ unreserved_keyword ::=
| 'RESET'
| 'RESTORE'
| 'RESTRICT'
| 'RESTRICTED'
| 'RESUME'
| 'RETRY'
| 'REVISION_HISTORY'
Expand Down Expand Up @@ -1338,8 +1340,8 @@ for_schedules_clause ::=
| 'FOR' 'SCHEDULE' a_expr

create_database_stmt ::=
'CREATE' 'DATABASE' 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' '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' 'DATABASE' 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 opt_placement_clause
| '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 opt_placement_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_index opt_with_storage_parameter_list opt_where_clause
Expand Down Expand Up @@ -1883,6 +1885,10 @@ opt_survival_goal_clause ::=
survival_goal_clause
|

opt_placement_clause ::=
placement_clause
|

opt_unique ::=
'UNIQUE'
|
Expand Down Expand Up @@ -2393,6 +2399,10 @@ region_or_regions ::=
region_name_list ::=
name_list

placement_clause ::=
'PLACEMENT' 'RESTRICTED'
| 'PLACEMENT' 'DEFAULT'

opt_name ::=
name
|
Expand Down
41 changes: 36 additions & 5 deletions pkg/sql/parser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,9 @@ func (u *sqlSymUnion) locality() *tree.Locality {
func (u *sqlSymUnion) survivalGoal() tree.SurvivalGoal {
return u.val.(tree.SurvivalGoal)
}
func (u *sqlSymUnion) dataPlacement() tree.DataPlacement {
return u.val.(tree.DataPlacement)
}
func (u *sqlSymUnion) objectNamePrefix() tree.ObjectNamePrefix {
return u.val.(tree.ObjectNamePrefix)
}
Expand Down Expand Up @@ -796,7 +799,7 @@ func (u *sqlSymUnion) alterDefaultPrivilegesTargetObject() tree.AlterDefaultPriv
%token <str> OF OFF OFFSET OID OIDS OIDVECTOR ON ONLY OPT OPTION OPTIONS OR
%token <str> ORDER ORDINALITY OTHERS OUT OUTER OVER OVERLAPS OVERLAY OWNED OWNER OPERATOR

%token <str> PARENT PARTIAL PARTITION PARTITIONS PASSWORD PAUSE PAUSED PHYSICAL PLACING
%token <str> PARENT PARTIAL PARTITION PARTITIONS PASSWORD PAUSE PAUSED PHYSICAL PLACEMENT PLACING
%token <str> PLAN PLANS POINT POINTM POINTZ POINTZM POLYGON POLYGONM POLYGONZ POLYGONZM
%token <str> POSITION PRECEDING PRECISION PREPARE PRESERVE PRIMARY PRIORITY PRIVILEGES
%token <str> PROCEDURAL PUBLIC PUBLICATION
Expand All @@ -806,8 +809,8 @@ func (u *sqlSymUnion) alterDefaultPrivilegesTargetObject() tree.AlterDefaultPriv
%token <str> RANGE RANGES READ REAL REASSIGN RECURSIVE RECURRING REF REFERENCES REFRESH
%token <str> REGCLASS REGION REGIONAL REGIONS REGPROC REGPROCEDURE REGNAMESPACE REGTYPE REINDEX
%token <str> REMOVE_PATH RENAME REPEATABLE REPLACE REPLICATION
%token <str> RELEASE RESET RESTORE RESTRICT RESUME RETURNING RETRY REVISION_HISTORY REVOKE RIGHT
%token <str> ROLE ROLES ROLLBACK ROLLUP ROUTINES ROW ROWS RSHIFT RULE RUNNING
%token <str> RELEASE RESET RESTORE RESTRICT RESTRICTED RESUME RETURNING RETRY REVISION_HISTORY
%token <str> REVOKE RIGHT ROLE ROLES ROLLBACK ROLLUP ROUTINES ROW ROWS RSHIFT RULE RUNNING

%token <str> SAVEPOINT SCANS SCATTER SCHEDULE SCHEDULES SCHEMA SCHEMAS SCRUB SEARCH SECOND SELECT SEQUENCE SEQUENCES
%token <str> SERIALIZABLE SERVER SESSION SESSIONS SESSION_USER SET SETS SETTING SETTINGS
Expand Down Expand Up @@ -899,6 +902,7 @@ func (u *sqlSymUnion) alterDefaultPrivilegesTargetObject() tree.AlterDefaultPriv
%type <tree.Statement> alter_database_primary_region_stmt
%type <tree.Statement> alter_zone_database_stmt
%type <tree.Statement> alter_database_owner
%type <tree.Statement> alter_database_placement_stmt

// ALTER INDEX
%type <tree.Statement> alter_oneindex_stmt
Expand Down Expand Up @@ -1107,6 +1111,7 @@ func (u *sqlSymUnion) alterDefaultPrivilegesTargetObject() tree.AlterDefaultPriv
%type <str> opt_template_clause opt_encoding_clause opt_lc_collate_clause opt_lc_ctype_clause
%type <tree.NameList> opt_regions_list
%type <str> region_name primary_region_clause opt_primary_region_clause
%type <tree.DataPlacement> opt_placement_clause placement_clause
%type <tree.NameList> region_name_list
%type <tree.SurvivalGoal> survival_goal_clause opt_survival_goal_clause
%type <*tree.Locality> locality opt_locality
Expand Down Expand Up @@ -1638,6 +1643,7 @@ alter_database_stmt:
| alter_database_drop_region_stmt
| alter_database_survival_goal_stmt
| alter_database_primary_region_stmt
| alter_database_placement_stmt
// ALTER DATABASE has its error help token here because the ALTER DATABASE
// prefix is spread over multiple non-terminals.
| ALTER DATABASE error // SHOW HELP: ALTER DATABASE
Expand All @@ -1648,6 +1654,10 @@ alter_database_owner:
$$.val = &tree.AlterDatabaseOwner{Name: tree.Name($3), Owner: $6.user()}
}

alter_database_placement_stmt:
ALTER DATABASE database_name SET placement_clause
{ return unimplemented(sqllex, "alter database placement") }

alter_database_add_region_stmt:
ALTER DATABASE database_name ADD REGION region_name
{
Expand Down Expand Up @@ -8336,7 +8346,7 @@ transaction_deferrable_mode:
// %Text: CREATE DATABASE [IF NOT EXISTS] <name>
// %SeeAlso: WEBDOCS/create-database.html
create_database_stmt:
CREATE DATABASE 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 DATABASE 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 opt_placement_clause
{
$$.val = &tree.CreateDatabase{
Name: tree.Name($3),
Expand All @@ -8348,9 +8358,10 @@ create_database_stmt:
PrimaryRegion: tree.Name($10),
Regions: $11.nameList(),
SurvivalGoal: $12.survivalGoal(),
Placement: $13.dataPlacement(),
}
}
| 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 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 opt_placement_clause
{
$$.val = &tree.CreateDatabase{
IfNotExists: true,
Expand All @@ -8363,6 +8374,7 @@ create_database_stmt:
PrimaryRegion: tree.Name($13),
Regions: $14.nameList(),
SurvivalGoal: $15.survivalGoal(),
Placement: $16.dataPlacement(),
}
}
| CREATE DATABASE error // SHOW HELP: CREATE DATABASE
Expand All @@ -8379,6 +8391,23 @@ primary_region_clause:
$$ = $4
}

opt_placement_clause:
placement_clause
| /* EMPTY */
{
$$.val = tree.DataPlacementUnspecified
}

placement_clause:
PLACEMENT RESTRICTED
{
$$.val = tree.DataPlacementRestricted
}
| PLACEMENT DEFAULT
{
$$.val = tree.DataPlacementDefault
}

opt_regions_list:
region_or_regions opt_equal region_name_list
{
Expand Down Expand Up @@ -12972,6 +13001,7 @@ unreserved_keyword:
| PAUSE
| PAUSED
| PHYSICAL
| PLACEMENT
| PLAN
| PLANS
| POINTM
Expand Down Expand Up @@ -13009,6 +13039,7 @@ unreserved_keyword:
| RESET
| RESTORE
| RESTRICT
| RESTRICTED
| RESUME
| RETRY
| REVISION_HISTORY
Expand Down
7 changes: 7 additions & 0 deletions pkg/sql/parser/testdata/create_database
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,13 @@ CREATE DATABASE IF NOT EXISTS a PRIMARY REGION "us-west-1" -- fully parenthesize
CREATE DATABASE IF NOT EXISTS a PRIMARY REGION "us-west-1" -- literals removed
CREATE DATABASE IF NOT EXISTS _ PRIMARY REGION _ -- identifiers removed

parse
CREATE DATABASE a PRIMARY REGION "us-west-1" PLACEMENT RESTRICTED
----
CREATE DATABASE a PRIMARY REGION "us-west-1" PLACEMENT RESTRICTED
CREATE DATABASE a PRIMARY REGION "us-west-1" PLACEMENT RESTRICTED -- fully parenthesized
CREATE DATABASE a PRIMARY REGION "us-west-1" PLACEMENT RESTRICTED -- literals removed
CREATE DATABASE _ PRIMARY REGION _ PLACEMENT RESTRICTED -- identifiers removed

error
CREATE DATABASE a b
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/sem/tree/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ go_library(
"constants.go",
"copy.go",
"create.go",
"data_placement.go",
"datum.go",
"decimal.go",
"delete.go",
Expand Down
7 changes: 7 additions & 0 deletions pkg/sql/sem/tree/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type CreateDatabase struct {
PrimaryRegion Name
Regions NameList
SurvivalGoal SurvivalGoal
Placement DataPlacement
}

// Format implements the NodeFormatter interface.
Expand Down Expand Up @@ -111,6 +112,12 @@ func (node *CreateDatabase) Format(ctx *FmtCtx) {
ctx.WriteString(" ")
ctx.FormatNode(&node.SurvivalGoal)
}
// Only want to print if the user has turned on restricted so that
// SHOW CREATE DATABASE doesn't expose PLACEMENT.
if node.Placement == DataPlacementRestricted {
ctx.WriteString(" ")
ctx.FormatNode(&node.Placement)
}
}

// IndexElem represents a column with a direction in a CREATE INDEX statement.
Expand Down
41 changes: 41 additions & 0 deletions pkg/sql/sem/tree/data_placement.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package tree

import "github.com/cockroachdb/errors"

// DataPlacement represents the desired data placement strategy for a given
// database.
type DataPlacement uint32

const (
// DataPlacementUnspecified indicates an unspecified placement policy.
// This will get translated to the default value when persisted.
DataPlacementUnspecified DataPlacement = iota
// DataPlacementDefault indicates specified default data placement policy,
DataPlacementDefault
// DataPlacementRestricted indicates the database will not use non-voters for
// REGIONAL BY [TABLE | ROW] tables.
DataPlacementRestricted
)

// Format implements the NodeFormatter interface.
func (node *DataPlacement) Format(ctx *FmtCtx) {
ctx.WriteString("PLACEMENT ")
switch *node {
case DataPlacementRestricted:
ctx.WriteString("RESTRICTED")
case DataPlacementDefault, DataPlacementUnspecified:
ctx.WriteString("DEFAULT")
default:
panic(errors.AssertionFailedf("unknown data placement strategy: %d", *node))
}
}

0 comments on commit af6652c

Please sign in to comment.