Skip to content

Commit 0a10b2c

Browse files
committed
Add UNDROP TABLE statement support
Adds support for parsing and explaining UNDROP TABLE statements: - UNDROP TABLE name - UNDROP TABLE db.name - UNDROP TABLE name ON CLUSTER cluster - UNDROP TABLE name UUID 'uuid' Fixes 7 statements in 02681_undrop_query test (16→9 pending).
1 parent b622b65 commit 0a10b2c

6 files changed

Lines changed: 79 additions & 8 deletions

File tree

ast/ast.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,19 @@ func (d *DropQuery) Pos() token.Position { return d.Position }
499499
func (d *DropQuery) End() token.Position { return d.Position }
500500
func (d *DropQuery) statementNode() {}
501501

502+
// UndropQuery represents an UNDROP TABLE statement.
503+
type UndropQuery struct {
504+
Position token.Position `json:"-"`
505+
Database string `json:"database,omitempty"`
506+
Table string `json:"table"`
507+
OnCluster string `json:"on_cluster,omitempty"`
508+
UUID string `json:"uuid,omitempty"`
509+
}
510+
511+
func (u *UndropQuery) Pos() token.Position { return u.Position }
512+
func (u *UndropQuery) End() token.Position { return u.Position }
513+
func (u *UndropQuery) statementNode() {}
514+
502515
// AlterQuery represents an ALTER statement.
503516
type AlterQuery struct {
504517
Position token.Position `json:"-"`

internal/explain/explain.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ func Node(sb *strings.Builder, node interface{}, depth int) {
113113
explainCreateQuery(sb, n, indent, depth)
114114
case *ast.DropQuery:
115115
explainDropQuery(sb, n, indent, depth)
116+
case *ast.UndropQuery:
117+
explainUndropQuery(sb, n, indent, depth)
116118
case *ast.RenameQuery:
117119
explainRenameQuery(sb, n, indent, depth)
118120
case *ast.ExchangeQuery:

internal/explain/statements.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,21 @@ func explainDropQuery(sb *strings.Builder, n *ast.DropQuery, indent string, dept
505505
}
506506
}
507507

508+
func explainUndropQuery(sb *strings.Builder, n *ast.UndropQuery, indent string, depth int) {
509+
name := n.Table
510+
// Check if we have a database-qualified name (for UNDROP TABLE db.table)
511+
hasDatabase := n.Database != ""
512+
if hasDatabase {
513+
// Database-qualified: UndropQuery db table (children 2)
514+
fmt.Fprintf(sb, "%sUndropQuery %s %s (children %d)\n", indent, EscapeIdentifier(n.Database), EscapeIdentifier(name), 2)
515+
fmt.Fprintf(sb, "%s Identifier %s\n", indent, EscapeIdentifier(n.Database))
516+
fmt.Fprintf(sb, "%s Identifier %s\n", indent, EscapeIdentifier(name))
517+
} else {
518+
fmt.Fprintf(sb, "%sUndropQuery %s (children %d)\n", indent, EscapeIdentifier(name), 1)
519+
fmt.Fprintf(sb, "%s Identifier %s\n", indent, EscapeIdentifier(name))
520+
}
521+
}
522+
508523
func explainRenameQuery(sb *strings.Builder, n *ast.RenameQuery, indent string, depth int) {
509524
if n == nil {
510525
fmt.Fprintf(sb, "%s*ast.RenameQuery\n", indent)

parser/parser.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ func (p *Parser) parseStatement() ast.Statement {
180180
return p.parseAlter()
181181
case token.TRUNCATE:
182182
return p.parseTruncate()
183+
case token.UNDROP:
184+
return p.parseUndrop()
183185
case token.USE:
184186
return p.parseUse()
185187
case token.DESCRIBE, token.DESC:
@@ -4446,6 +4448,50 @@ func (p *Parser) parseTruncate() *ast.TruncateQuery {
44464448
return trunc
44474449
}
44484450

4451+
func (p *Parser) parseUndrop() *ast.UndropQuery {
4452+
undrop := &ast.UndropQuery{
4453+
Position: p.current.Pos,
4454+
}
4455+
4456+
p.nextToken() // skip UNDROP
4457+
4458+
if p.currentIs(token.TABLE) {
4459+
p.nextToken()
4460+
}
4461+
4462+
// Parse table name (can start with a number in ClickHouse)
4463+
tableName := p.parseIdentifierName()
4464+
if tableName != "" {
4465+
if p.currentIs(token.DOT) {
4466+
p.nextToken()
4467+
undrop.Database = tableName
4468+
undrop.Table = p.parseIdentifierName()
4469+
} else {
4470+
undrop.Table = tableName
4471+
}
4472+
}
4473+
4474+
// Handle ON CLUSTER
4475+
if p.currentIs(token.ON) {
4476+
p.nextToken()
4477+
if p.currentIs(token.CLUSTER) {
4478+
p.nextToken()
4479+
undrop.OnCluster = p.parseIdentifierName()
4480+
}
4481+
}
4482+
4483+
// Handle UUID
4484+
if p.currentIs(token.IDENT) && strings.ToUpper(p.current.Value) == "UUID" {
4485+
p.nextToken()
4486+
if p.currentIs(token.STRING) {
4487+
undrop.UUID = p.current.Value
4488+
p.nextToken()
4489+
}
4490+
}
4491+
4492+
return undrop
4493+
}
4494+
44494495
func (p *Parser) parseUse() *ast.UseQuery {
44504496
use := &ast.UseQuery{
44514497
Position: p.current.Pos,
Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"explain_todo": {
3-
"stmt16": true,
43
"stmt22": true,
54
"stmt23": true,
65
"stmt25": true,
@@ -9,12 +8,6 @@
98
"stmt32": true,
109
"stmt34": true,
1110
"stmt36": true,
12-
"stmt38": true,
13-
"stmt45": true,
14-
"stmt54": true,
15-
"stmt62": true,
16-
"stmt76": true,
17-
"stmt78": true,
18-
"stmt8": true
11+
"stmt38": true
1912
}
2013
}

token/token.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ const (
191191
TRUE
192192
TRUNCATE
193193
TTL
194+
UNDROP
194195
UNION
195196
UPDATE
196197
USE
@@ -387,6 +388,7 @@ var tokens = [...]string{
387388
TRUE: "TRUE",
388389
TRUNCATE: "TRUNCATE",
389390
TTL: "TTL",
391+
UNDROP: "UNDROP",
390392
UNION: "UNION",
391393
UPDATE: "UPDATE",
392394
USE: "USE",

0 commit comments

Comments
 (0)