Skip to content

Commit

Permalink
sql: add ON UPDATE syntax
Browse files Browse the repository at this point in the history
Previously, we did not have parsing implemented for ON UPDATE
expressions on columns. This PR adds parsing for ON UPDATE expressions.

Release note: None
  • Loading branch information
pawalt committed Aug 12, 2021
1 parent 65abfcc commit 572ad64
Show file tree
Hide file tree
Showing 13 changed files with 182 additions and 8 deletions.
4 changes: 4 additions & 0 deletions docs/generated/sql/bnf/alter_column.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ alter_onetable_stmt ::=
| 'ALTER' 'TABLE' table_name 'ALTER' 'COLUMN' column_name 'DROP' 'DEFAULT'
| 'ALTER' 'TABLE' table_name 'ALTER' column_name 'SET' 'DEFAULT' a_expr
| 'ALTER' 'TABLE' table_name 'ALTER' column_name 'DROP' 'DEFAULT'
| 'ALTER' 'TABLE' table_name 'ALTER' 'COLUMN' column_name alter_column_on_update
| 'ALTER' 'TABLE' table_name 'ALTER' column_name alter_column_on_update
| 'ALTER' 'TABLE' table_name 'ALTER' 'COLUMN' column_name alter_column_visible
| 'ALTER' 'TABLE' table_name 'ALTER' column_name alter_column_visible
| 'ALTER' 'TABLE' table_name 'ALTER' 'COLUMN' column_name 'DROP' 'NOT' 'NULL'
Expand Down Expand Up @@ -31,6 +33,8 @@ alter_onetable_stmt ::=
| 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'ALTER' 'COLUMN' column_name 'DROP' 'DEFAULT'
| 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'ALTER' column_name 'SET' 'DEFAULT' a_expr
| 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'ALTER' column_name 'DROP' 'DEFAULT'
| 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'ALTER' 'COLUMN' column_name alter_column_on_update
| 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'ALTER' column_name alter_column_on_update
| 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'ALTER' 'COLUMN' column_name alter_column_visible
| 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'ALTER' column_name alter_column_visible
| 'ALTER' 'TABLE' 'IF' 'EXISTS' table_name 'ALTER' 'COLUMN' column_name 'DROP' 'NOT' 'NULL'
Expand Down
4 changes: 2 additions & 2 deletions docs/generated/sql/bnf/alter_table.bnf
Original file line number Diff line number Diff line change
@@ -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 alter_column_visible | '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 ) ) ( ( ',' ( '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 alter_column_visible | '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 ) ) )* )
| '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 alter_column_visible | '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 ) ) ( ( ',' ( '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 alter_column_visible | '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 ) ) )* )
'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 alter_column_on_update | 'ALTER' ( 'COLUMN' | ) column_name alter_column_visible | '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 ) ) ( ( ',' ( '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 alter_column_on_update | 'ALTER' ( 'COLUMN' | ) column_name alter_column_visible | '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 ) ) )* )
| '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 alter_column_on_update | 'ALTER' ( 'COLUMN' | ) column_name alter_column_visible | '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 ) ) ( ( ',' ( '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 alter_column_on_update | 'ALTER' ( 'COLUMN' | ) column_name alter_column_visible | '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 ) ) )* )
2 changes: 2 additions & 0 deletions docs/generated/sql/bnf/col_qualification.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ col_qualification ::=
| 'CONSTRAINT' constraint_name 'PRIMARY' 'KEY' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets
| 'CONSTRAINT' constraint_name 'CHECK' '(' a_expr ')'
| 'CONSTRAINT' constraint_name 'DEFAULT' b_expr
| 'CONSTRAINT' constraint_name 'ON' 'UPDATE' b_expr
| 'CONSTRAINT' constraint_name 'REFERENCES' table_name opt_name_parens key_match reference_actions
| 'CONSTRAINT' constraint_name generated_as '(' a_expr ')' 'STORED'
| 'CONSTRAINT' constraint_name generated_as '(' a_expr ')' 'VIRTUAL'
Expand All @@ -20,6 +21,7 @@ col_qualification ::=
| 'PRIMARY' 'KEY' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' n_buckets
| 'CHECK' '(' a_expr ')'
| 'DEFAULT' b_expr
| 'ON' 'UPDATE' b_expr
| 'REFERENCES' table_name opt_name_parens key_match reference_actions
| generated_as '(' a_expr ')' 'STORED'
| generated_as '(' a_expr ')' 'VIRTUAL'
Expand Down
10 changes: 8 additions & 2 deletions docs/generated/sql/bnf/stmt_block.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -2634,6 +2634,7 @@ alter_table_cmd ::=
| 'ADD' 'COLUMN' column_def
| 'ADD' 'COLUMN' 'IF' 'NOT' 'EXISTS' column_def
| 'ALTER' opt_column column_name alter_column_default
| 'ALTER' opt_column column_name alter_column_on_update
| 'ALTER' opt_column column_name alter_column_visible
| 'ALTER' opt_column column_name 'DROP' 'NOT' 'NULL'
| 'ALTER' opt_column column_name 'DROP' 'STORED'
Expand Down Expand Up @@ -2911,6 +2912,10 @@ alter_column_default ::=
'SET' 'DEFAULT' a_expr
| 'DROP' 'DEFAULT'

alter_column_on_update ::=
'SET' 'ON' 'UPDATE' b_expr
| 'DROP' 'ON' 'UPDATE'

alter_column_visible ::=
'SET' 'VISIBLE'
| 'SET' 'NOT' 'VISIBLE'
Expand Down Expand Up @@ -3034,6 +3039,7 @@ col_qualification_elem ::=
| 'PRIMARY' 'KEY' 'USING' 'HASH' 'WITH' 'BUCKET_COUNT' '=' a_expr
| 'CHECK' '(' a_expr ')'
| 'DEFAULT' b_expr
| 'ON' 'UPDATE' b_expr
| 'REFERENCES' table_name opt_name_parens key_match reference_actions
| generated_as '(' a_expr ')' 'STORED'
| generated_as '(' a_expr ')' 'VIRTUAL'
Expand All @@ -3044,10 +3050,10 @@ family_name ::=
name

reference_on_update ::=
'ON' 'UPDATE' reference_action
'ON_UPDATE' 'UPDATE' reference_action

reference_on_delete ::=
'ON' 'DELETE' reference_action
'ON_DELETE' 'DELETE' reference_action

group_by_item ::=
a_expr
Expand Down
3 changes: 3 additions & 0 deletions pkg/sql/alter_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -1160,6 +1160,9 @@ func applyColumnMutation(
}
}

case *tree.AlterTableSetOnUpdate:
return errors.Newf("unimplemented")

case *tree.AlterTableSetVisible:
column, err := tableDesc.FindActiveOrNewColumnByName(col.ColName())
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/lexbase/predicates.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func init() {
"reset",
"role",
"user",
"on",
} {
reservedOrLookaheadKeywords[s] = struct{}{}
}
Expand Down
16 changes: 15 additions & 1 deletion pkg/sql/parser/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,15 @@ func (l *lexer) Lex(lval *sqlSymType) int {
*lval = l.tokens[l.lastPos]

switch lval.id {
case NOT, WITH, AS, GENERATED, NULLS, RESET, ROLE, USER:
case NOT, WITH, AS, GENERATED, NULLS, RESET, ROLE, USER, ON:
nextID := int32(0)
if l.lastPos+1 < len(l.tokens) {
nextID = l.tokens[l.lastPos+1].id
}
secondID := int32(0)
if l.lastPos+2 < len(l.tokens) {
secondID = l.tokens[l.lastPos+2].id
}

// If you update these cases, update lex.lookaheadKeywords.
switch lval.id {
Expand Down Expand Up @@ -131,6 +135,16 @@ func (l *lexer) Lex(lval *sqlSymType) int {
case ALL:
lval.id = USER_ALL
}
case ON:
switch nextID {
case DELETE:
lval.id = ON_DELETE
case UPDATE:
switch secondID {
case NO, RESTRICT, CASCADE, SET:
lval.id = ON_UPDATE_LA
}
}
}
}

Expand Down
27 changes: 24 additions & 3 deletions pkg/sql/parser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,8 @@ func (u *sqlSymUnion) setVar() *tree.SetVar {
// extensions (CREATE FAMILY/CREATE FAMILY family_name). RESET_ALL is used
// to differentiate `RESET var` from `RESET ALL`. ROLE_ALL and USER_ALL are
// used in ALTER ROLE statements that affect all roles.
%token NOT_LA NULLS_LA WITH_LA AS_LA GENERATED_ALWAYS GENERATED_BY_DEFAULT RESET_ALL ROLE_ALL USER_ALL
%token NOT_LA NULLS_LA WITH_LA AS_LA GENERATED_ALWAYS GENERATED_BY_DEFAULT RESET_ALL ROLE_ALL
%token USER_ALL ON_UPDATE_LA ON_DELETE

%union {
id int32
Expand Down Expand Up @@ -1113,6 +1114,7 @@ func (u *sqlSymUnion) setVar() *tree.SetVar {
%type <tree.SelectStatement> set_operation

%type <tree.Expr> alter_column_default
%type <tree.Expr> alter_column_on_update
%type <tree.Expr> alter_column_visible
%type <tree.Direction> opt_asc_desc
%type <tree.NullsOrder> opt_nulls_order
Expand Down Expand Up @@ -2122,6 +2124,11 @@ alter_table_cmd:
{
$$.val = &tree.AlterTableSetDefault{Column: tree.Name($3), Default: $4.expr()}
}
// ALTER TABLE <name> ALTER [COLUMN] <colname> {ON UPDATE <expr>|DROP ON UPDATE}
| ALTER opt_column column_name alter_column_on_update
{
$$.val = &tree.AlterTableSetOnUpdate{Column: tree.Name($3), Expr: $4.expr()}
}
// ALTER TABLE <name> ALTER [COLUMN] <colname> SET {VISIBLE|NOT VISIBLE}
| ALTER opt_column column_name alter_column_visible
{
Expand Down Expand Up @@ -2286,6 +2293,16 @@ alter_column_default:
$$.val = nil
}

alter_column_on_update:
SET ON UPDATE b_expr
{
$$.val = $4.expr()
}
| DROP ON UPDATE
{
$$.val = nil
}

alter_column_visible:
SET VISIBLE
{
Expand Down Expand Up @@ -6708,6 +6725,10 @@ col_qualification_elem:
{
$$.val = &tree.ColumnDefault{Expr: $2.expr()}
}
| ON UPDATE b_expr
{
$$.val = &tree.ColumnOnUpdate{Expr: $3.expr()}
}
| REFERENCES table_name opt_name_parens key_match reference_actions
{
name := $2.unresolvedObjectName().ToTableName()
Expand Down Expand Up @@ -7088,13 +7109,13 @@ reference_actions:
}

reference_on_update:
ON UPDATE reference_action
ON_UPDATE_LA UPDATE reference_action
{
$$.val = $3.referenceAction()
}

reference_on_delete:
ON DELETE reference_action
ON_DELETE DELETE reference_action
{
$$.val = $3.referenceAction()
}
Expand Down
Loading

0 comments on commit 572ad64

Please sign in to comment.