Skip to content

Commit 006f4e8

Browse files
Merge pull request #1 from fahmifan/feat/sqlc-switch-sqlite-order-by-support
fix(sqlite): populate SelectStmt.SortClause during AST conversion
2 parents 348b5da + f7bf98b commit 006f4e8

3 files changed

Lines changed: 140 additions & 15 deletions

File tree

internal/endtoend/testdata/sqlc_switch/sqlite/go/query.sql.go

Lines changed: 84 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/sqlc_switch/sqlite/query.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@ SELECT * FROM authors
33
WHERE sqlc.switch(@filter,
44
sqlc.when('named', 'name IS NOT NULL'),
55
sqlc.else( '1 = 1'));
6+
7+
-- name: ListAuthors :many
8+
SELECT id, name, created_at FROM authors
9+
ORDER BY sqlc.switch(@sort,
10+
sqlc.when('name_asc', 'authors.name ASC'),
11+
sqlc.when('recent', 'authors.created_at DESC, authors.id DESC'),
12+
sqlc.else( 'authors.id ASC'));

internal/engine/sqlite/convert.go

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,13 @@ func (c *cc) convertMultiSelect_stmtContext(n *parser.Select_stmtContext) ast.No
514514
limitCount, limitOffset := c.convertLimit_stmtContext(n.Limit_stmt())
515515
selectStmt.LimitCount = limitCount
516516
selectStmt.LimitOffset = limitOffset
517+
518+
if n.Order_by_stmt() != nil {
519+
if sortClause, ok := c.convert(n.Order_by_stmt()).(*ast.List); ok {
520+
selectStmt.SortClause = sortClause
521+
}
522+
}
523+
517524
// Only set WithClause if there are CTEs
518525
if len(ctes.Items) > 0 {
519526
selectStmt.WithClause = &ast.WithClause{Ctes: &ctes}
@@ -622,21 +629,48 @@ func (c *cc) convertWildCardField(n *parser.Result_columnContext) *ast.ColumnRef
622629
}
623630

624631
func (c *cc) convertOrderby_stmtContext(n parser.IOrder_by_stmtContext) ast.Node {
625-
if orderBy, ok := n.(*parser.Order_by_stmtContext); ok {
626-
list := &ast.List{Items: []ast.Node{}}
627-
for _, o := range orderBy.AllOrdering_term() {
628-
term, ok := o.(*parser.Ordering_termContext)
629-
if !ok {
630-
continue
631-
}
632-
list.Items = append(list.Items, &ast.CaseExpr{
633-
Xpr: c.convert(term.Expr()),
634-
Location: term.Expr().GetStart().GetStart(),
635-
})
632+
orderBy, ok := n.(*parser.Order_by_stmtContext)
633+
if !ok || orderBy == nil {
634+
return &ast.List{}
635+
}
636+
637+
list := &ast.List{Items: []ast.Node{}}
638+
for _, o := range orderBy.AllOrdering_term() {
639+
term, ok := o.(*parser.Ordering_termContext)
640+
if !ok {
641+
continue
636642
}
637-
return list
643+
list.Items = append(list.Items, c.convertOrderingTerm(term))
644+
}
645+
646+
return list
647+
}
648+
649+
func (c *cc) convertOrderingTerm(term *parser.Ordering_termContext) *ast.SortBy {
650+
sortByDir := ast.SortByDirDefault
651+
if ad := term.Asc_desc(); ad != nil {
652+
if ad.ASC_() != nil {
653+
sortByDir = ast.SortByDirAsc
654+
} else {
655+
sortByDir = ast.SortByDirDesc
656+
}
657+
}
658+
659+
sortByNulls := ast.SortByNullsDefault
660+
if term.NULLS_() != nil {
661+
if term.FIRST_() != nil {
662+
sortByNulls = ast.SortByNullsFirst
663+
} else {
664+
sortByNulls = ast.SortByNullsLast
665+
}
666+
}
667+
668+
return &ast.SortBy{
669+
Node: c.convert(term.Expr()),
670+
SortbyDir: sortByDir,
671+
SortbyNulls: sortByNulls,
672+
UseOp: &ast.List{},
638673
}
639-
return todo("convertOrderby_stmtContext", n)
640674
}
641675

642676
func (c *cc) convertLimit_stmtContext(n parser.ILimit_stmtContext) (ast.Node, ast.Node) {
@@ -826,7 +860,7 @@ func (c *cc) convertUnaryExpr(n *parser.Expr_unaryContext) ast.Node {
826860
if opCtx.MINUS() != nil {
827861
// Negative number: -expr
828862
return &ast.A_Expr{
829-
Name: &ast.List{Items: []ast.Node{&ast.String{Str: "-"}}},
863+
Name: &ast.List{Items: []ast.Node{&ast.String{Str: "-"}}},
830864
Rexpr: expr,
831865
}
832866
}
@@ -837,7 +871,7 @@ func (c *cc) convertUnaryExpr(n *parser.Expr_unaryContext) ast.Node {
837871
if opCtx.TILDE() != nil {
838872
// Bitwise NOT: ~expr
839873
return &ast.A_Expr{
840-
Name: &ast.List{Items: []ast.Node{&ast.String{Str: "~"}}},
874+
Name: &ast.List{Items: []ast.Node{&ast.String{Str: "~"}}},
841875
Rexpr: expr,
842876
}
843877
}

0 commit comments

Comments
 (0)