Skip to content

Commit a110ae1

Browse files
authored
Support schema-qualified table names in INSERT/UPDATE
1 parent a0234dd commit a110ae1

3 files changed

Lines changed: 66 additions & 6 deletions

File tree

ast.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2721,9 +2721,11 @@ type InsertStatement struct {
27212721
InsertOrIgnore Pos // position of IGNORE keyword after INSERT OR
27222722
Into Pos // position of INTO keyword
27232723

2724-
Table *Ident // table name
2725-
As Pos // position of AS keyword
2726-
Alias *Ident // optional alias
2724+
Schema *Ident // optional schema name
2725+
Dot Pos // position of DOT between schema and table name
2726+
Table *Ident // table name
2727+
As Pos // position of AS keyword
2728+
Alias *Ident // optional alias
27272729

27282730
ColumnsLparen Pos // position of column list left paren
27292731
Columns []*Ident // optional column list
@@ -2748,6 +2750,7 @@ func (s *InsertStatement) Clone() *InsertStatement {
27482750
}
27492751
other := *s
27502752
other.WithClause = s.WithClause.Clone()
2753+
other.Schema = s.Schema.Clone()
27512754
other.Table = s.Table.Clone()
27522755
other.Alias = s.Alias.Clone()
27532756
other.Columns = cloneIdents(s.Columns)
@@ -2783,7 +2786,12 @@ func (s *InsertStatement) String() string {
27832786
}
27842787
}
27852788

2786-
fmt.Fprintf(&buf, " INTO %s", s.Table.String())
2789+
buf.WriteString(" INTO ")
2790+
if s.Schema != nil {
2791+
buf.WriteString(s.Schema.String())
2792+
buf.WriteString(".")
2793+
}
2794+
buf.WriteString(s.Table.String())
27872795
if s.Alias != nil {
27882796
fmt.Fprintf(&buf, " AS %s", s.Alias.String())
27892797
}

parser.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,10 +1475,18 @@ func (p *Parser) parseInsertStatement(inTrigger bool, withClause *WithClause) (_
14751475
}
14761476
stmt.Into, _, _ = p.scan()
14771477

1478-
// Parse table name & optional alias.
1478+
// Parse table name & optional schema & alias.
14791479
if stmt.Table, err = p.parseIdent("table name"); err != nil {
14801480
return &stmt, err
14811481
}
1482+
// Check for schema.table syntax
1483+
if p.peek() == DOT {
1484+
stmt.Schema = stmt.Table
1485+
stmt.Dot, _, _ = p.scan()
1486+
if stmt.Table, err = p.parseIdent("table name"); err != nil {
1487+
return &stmt, err
1488+
}
1489+
}
14821490
if p.peek() == AS {
14831491
stmt.As, _, _ = p.scan()
14841492
if stmt.Alias, err = p.parseIdent("alias"); err != nil {
@@ -1731,7 +1739,7 @@ func (p *Parser) parseUpdateStatement(inTrigger bool, withClause *WithClause) (_
17311739
return nil, p.errorExpected(p.pos, p.tok, "table name")
17321740
}
17331741
ident, _ := p.parseIdent("table name")
1734-
if stmt.Table, err = p.parseQualifiedTableName(ident, false, false, false); err != nil {
1742+
if stmt.Table, err = p.parseQualifiedTableName(ident, true, false, false); err != nil {
17351743
return &stmt, err
17361744
}
17371745

parser_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3685,6 +3685,34 @@ func TestParser_ParseStatement(t *testing.T) {
36853685
},
36863686
})
36873687

3688+
// Test schema-qualified table name
3689+
AssertParseStatement(t, `INSERT INTO main.tableau VALUES (1, 2), (3, 4)`, &sql.InsertStatement{
3690+
Insert: pos(0),
3691+
Into: pos(7),
3692+
Schema: &sql.Ident{NamePos: pos(12), Name: "main"},
3693+
Dot: pos(16),
3694+
Table: &sql.Ident{NamePos: pos(17), Name: "tableau"},
3695+
Values: pos(25),
3696+
ValueLists: []*sql.ExprList{
3697+
{
3698+
Lparen: pos(32),
3699+
Exprs: []sql.Expr{
3700+
&sql.NumberLit{ValuePos: pos(33), Value: "1"},
3701+
&sql.NumberLit{ValuePos: pos(36), Value: "2"},
3702+
},
3703+
Rparen: pos(37),
3704+
},
3705+
{
3706+
Lparen: pos(40),
3707+
Exprs: []sql.Expr{
3708+
&sql.NumberLit{ValuePos: pos(41), Value: "3"},
3709+
&sql.NumberLit{ValuePos: pos(44), Value: "4"},
3710+
},
3711+
Rparen: pos(45),
3712+
},
3713+
},
3714+
})
3715+
36883716
AssertParseStatementError(t, `INSERT`, `1:6: expected INTO, found 'EOF'`)
36893717
AssertParseStatementError(t, `INSERT OR`, `1:9: expected ROLLBACK, REPLACE, ABORT, FAIL, or IGNORE, found 'EOF'`)
36903718
AssertParseStatementError(t, `INSERT INTO`, `1:11: expected table name, found 'EOF'`)
@@ -3856,6 +3884,22 @@ func TestParser_ParseStatement(t *testing.T) {
38563884
}},
38573885
})
38583886

3887+
// Test schema-qualified table name
3888+
AssertParseStatement(t, `UPDATE main.tableau SET n2=n1`, &sql.UpdateStatement{
3889+
Update: pos(0),
3890+
Table: &sql.QualifiedTableName{
3891+
Schema: &sql.Ident{NamePos: pos(7), Name: "main"},
3892+
Dot: pos(11),
3893+
Name: &sql.Ident{NamePos: pos(12), Name: "tableau"},
3894+
},
3895+
Set: pos(20),
3896+
Assignments: []*sql.Assignment{{
3897+
Columns: []*sql.Ident{{NamePos: pos(24), Name: "n2"}},
3898+
Eq: pos(26),
3899+
Expr: &sql.Ident{NamePos: pos(27), Name: "n1"},
3900+
}},
3901+
})
3902+
38593903
AssertParseStatementError(t, `UPDATE`, `1:6: expected table name, found 'EOF'`)
38603904
AssertParseStatementError(t, `UPDATE OR`, `1:9: expected ROLLBACK, REPLACE, ABORT, FAIL, or IGNORE, found 'EOF'`)
38613905
AssertParseStatementError(t, `UPDATE tbl`, `1:10: expected SET, found 'EOF'`)

0 commit comments

Comments
 (0)