Skip to content

Commit 5c0f9cc

Browse files
authored
Allow to use the optional IN PARTITION expression in ALTER TABLE (#206)
1 parent e31c88c commit 5c0f9cc

8 files changed

+107
-2
lines changed

parser/ast.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,7 @@ type AlterTableUpdate struct {
14801480
UpdatePos Pos
14811481
StatementEnd Pos
14821482
Assignments []*UpdateAssignment
1483+
InPartition *PartitionClause
14831484
WhereClause Expr
14841485
}
14851486

@@ -1504,6 +1505,10 @@ func (a *AlterTableUpdate) String() string {
15041505
}
15051506
builder.WriteString(assignment.String())
15061507
}
1508+
if a.InPartition != nil {
1509+
builder.WriteString(" IN ")
1510+
builder.WriteString(a.InPartition.String())
1511+
}
15071512
builder.WriteString(" WHERE ")
15081513
builder.WriteString(a.WhereClause.String())
15091514
return builder.String()
@@ -1517,6 +1522,11 @@ func (a *AlterTableUpdate) Accept(visitor ASTVisitor) error {
15171522
return err
15181523
}
15191524
}
1525+
if a.InPartition != nil {
1526+
if err := a.InPartition.Accept(visitor); err != nil {
1527+
return err
1528+
}
1529+
}
15201530
if err := a.WhereClause.Accept(visitor); err != nil {
15211531
return err
15221532
}

parser/parser_alter.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,7 @@ func (p *Parser) parseAlterTableDelete(pos Pos) (AlterTableClause, error) {
860860
}, nil
861861
}
862862

863-
// Syntax: ALTER TABLE UPDATE column1 = expr1 [, column2 = expr2, ...] WHERE condition
863+
// Syntax: ALTER TABLE UPDATE column1 = expr1 [, column2 = expr2, ...] [IN PARTITION partition_id] WHERE condition
864864
func (p *Parser) parseAlterTableUpdate(pos Pos) (AlterTableClause, error) {
865865
if err := p.expectKeyword(KeywordUpdate); err != nil {
866866
return nil, err
@@ -883,6 +883,13 @@ func (p *Parser) parseAlterTableUpdate(pos Pos) (AlterTableClause, error) {
883883
assignments = append(assignments, assignment)
884884
}
885885

886+
var inPartition *PartitionClause
887+
if p.tryConsumeKeywords(KeywordIn) {
888+
inPartition, err = p.parsePartitionClause(p.Pos())
889+
if err != nil {
890+
return nil, err
891+
}
892+
}
886893
if err := p.expectKeyword(KeywordWhere); err != nil {
887894
return nil, err
888895
}
@@ -896,6 +903,7 @@ func (p *Parser) parseAlterTableUpdate(pos Pos) (AlterTableClause, error) {
896903
UpdatePos: pos,
897904
StatementEnd: whereExpr.End(),
898905
Assignments: assignments,
906+
InPartition: inPartition,
899907
WhereClause: whereExpr,
900908
}, nil
901909
}
@@ -911,7 +919,10 @@ func (p *Parser) parseUpdateAssignment(pos Pos) (*UpdateAssignment, error) {
911919
return nil, err
912920
}
913921

914-
expr, err := p.parseExpr(p.Pos())
922+
// Why don't we use parseExpr here? Because `ALTER TABLE UPDATE` syntax allows to
923+
// use `IN PARTITION` keywords after assignments. So we need to limit the precedence
924+
// to avoid parsing `IN PARTITION` as part of the expression.
925+
expr, err := p.parseSubExpr(p.Pos(), precedenceIn)
915926
if err != nil {
916927
return nil, err
917928
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active';
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- Origin SQL:
2+
ALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active';
3+
4+
5+
-- Format SQL:
6+
ALTER TABLE test.users UPDATE status = 'inactive' IN PARTITION '2024-01-01' WHERE status = 'active';

parser/testdata/ddl/output/alter_table_update.sql.golden.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
}
7272
}
7373
],
74+
"InPartition": null,
7475
"WhereClause": {
7576
"LeftExpr": {
7677
"Name": "status",
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
[
2+
{
3+
"AlterPos": 0,
4+
"StatementEnd": 98,
5+
"TableIdentifier": {
6+
"Database": {
7+
"Name": "test",
8+
"QuoteType": 1,
9+
"NamePos": 12,
10+
"NameEnd": 16
11+
},
12+
"Table": {
13+
"Name": "users",
14+
"QuoteType": 1,
15+
"NamePos": 17,
16+
"NameEnd": 22
17+
}
18+
},
19+
"OnCluster": null,
20+
"AlterExprs": [
21+
{
22+
"UpdatePos": 23,
23+
"StatementEnd": 98,
24+
"Assignments": [
25+
{
26+
"AssignmentPos": 30,
27+
"Column": {
28+
"Ident": {
29+
"Name": "status",
30+
"QuoteType": 1,
31+
"NamePos": 30,
32+
"NameEnd": 36
33+
},
34+
"DotIdent": null
35+
},
36+
"Expr": {
37+
"LiteralPos": 40,
38+
"LiteralEnd": 48,
39+
"Literal": "inactive"
40+
}
41+
}
42+
],
43+
"InPartition": {
44+
"PartitionPos": 53,
45+
"Expr": {
46+
"LiteralPos": 64,
47+
"LiteralEnd": 74,
48+
"Literal": "2024-01-01"
49+
},
50+
"ID": null,
51+
"All": false
52+
},
53+
"WhereClause": {
54+
"LeftExpr": {
55+
"Name": "status",
56+
"QuoteType": 1,
57+
"NamePos": 82,
58+
"NameEnd": 88
59+
},
60+
"Operation": "=",
61+
"RightExpr": {
62+
"LiteralPos": 92,
63+
"LiteralEnd": 98,
64+
"Literal": "active"
65+
},
66+
"HasGlobal": false,
67+
"HasNot": false
68+
}
69+
}
70+
]
71+
}
72+
]

parser/testdata/ddl/output/alter_table_update_with_cluster.sql.golden.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
}
6161
}
6262
],
63+
"InPartition": null,
6364
"WhereClause": {
6465
"LeftExpr": {
6566
"Name": "id",

parser/walk.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,9 @@ func Walk(node Expr, fn WalkFunc) bool {
895895
return false
896896
}
897897
}
898+
if !Walk(n.InPartition, fn) {
899+
return false
900+
}
898901
if !Walk(n.WhereClause, fn) {
899902
return false
900903
}

0 commit comments

Comments
 (0)