Skip to content

Commit

Permalink
dolphin: add support for union query
Browse files Browse the repository at this point in the history
  • Loading branch information
aitva committed Feb 14, 2021
1 parent 3a58ee9 commit 86e579d
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 1 deletion.
12 changes: 12 additions & 0 deletions internal/endtoend/testdata/select_union/mysql/sqlc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "1",
"packages": [
{
"engine": "mysql",
"path": "go",
"name": "querytest",
"schema": "query.sql",
"queries": "query.sql"
}
]
}
29 changes: 29 additions & 0 deletions internal/endtoend/testdata/select_union/postgres/go/db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions internal/endtoend/testdata/select_union/postgres/go/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions internal/endtoend/testdata/select_union/postgres/go/query.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions internal/endtoend/testdata/select_union/postgres/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CREATE TABLE foo (a text, b text);

-- name: SelectUnion :many
SELECT * FROM foo
UNION
SELECT * FROM foo;
91 changes: 90 additions & 1 deletion internal/engine/dolphin/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,10 +442,13 @@ func (c *cc) convertSelectField(n *pcast.SelectField) *ast.ResTarget {
}

func (c *cc) convertSelectStmt(n *pcast.SelectStmt) *ast.SelectStmt {
op, all := c.convertSetOprType(n.AfterSetOperator)
stmt := &ast.SelectStmt{
TargetList: c.convertFieldList(n.Fields),
FromClause: c.convertTableRefsClause(n.From),
WhereClause: c.convert(n.Where),
Op: op,
All: all,
}
if n.Limit != nil {
stmt.LimitCount = c.convert(n.Limit.Count)
Expand Down Expand Up @@ -937,11 +940,97 @@ func (c *cc) convertSetDefaultRoleStmt(n *pcast.SetDefaultRoleStmt) ast.Node {
return todo(n)
}

func (c *cc) convertSetOprType(n *pcast.SetOprType) (op ast.SetOperation, all bool) {
if n == nil {
return
}

switch *n {
case pcast.Union:
op = ast.Union
case pcast.UnionAll:
op = ast.Union
all = true
case pcast.Intersect:
op = ast.Intersect
case pcast.IntersectAll:
op = ast.Intersect
all = true
case pcast.Except:
op = ast.Except
case pcast.ExceptAll:
op = ast.Except
all = true
}
return
}

// convertSetOprSelectList converts a list of SELECT from the Pingcap parser
// into a tree. It is called for UNION, INTERSECT or EXCLUDE operation.
//
// Given an union with the following nodes:
// [Select{1}, Select{2}, Select{3}, Select{4}]
//
// The function will return:
// Select{
// Larg: Select{
// Larg: Select{
// Larg: Select{1},
// Rarg: Select{2},
// Op: Union
// },
// Rarg: Select{3},
// Op: Union,
// },
// Rarg: Select{4},
// Op: Union,
// }
func (c *cc) convertSetOprSelectList(n *pcast.SetOprSelectList) ast.Node {
return todo(n)
selectStmts := make([]*ast.SelectStmt, len(n.Selects))
for i, node := range n.Selects {
selectStmts[i] = c.convertSelectStmt(node.(*pcast.SelectStmt))
}

op, all := c.convertSetOprType(n.AfterSetOperator)
tree := &ast.SelectStmt{
TargetList: &ast.List{},
FromClause: &ast.List{},
WhereClause: nil,
Op: op,
All: all,
}
for _, stmt := range selectStmts {
// We move Op and All from the child to the parent.
op, all := stmt.Op, stmt.All
stmt.Op, stmt.All = ast.None, false

switch {
case tree.Larg == nil:
tree.Larg = stmt
case tree.Rarg == nil:
tree.Rarg = stmt
tree.Op = op
tree.All = all
default:
tree = &ast.SelectStmt{
TargetList: &ast.List{},
FromClause: &ast.List{},
WhereClause: nil,
Larg: tree,
Rarg: stmt,
Op: op,
All: all,
}
}
}

return tree
}

func (c *cc) convertSetOprStmt(n *pcast.SetOprStmt) ast.Node {
if n.SelectList != nil {
return c.convertSetOprSelectList(n.SelectList)
}
return todo(n)
}

Expand Down

0 comments on commit 86e579d

Please sign in to comment.