Skip to content

Commit 790309d

Browse files
committed
Fix order by clause in sqlite
1 parent 34f8c1b commit 790309d

File tree

8 files changed

+241
-0
lines changed

8 files changed

+241
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"contexts": ["base"]
3+
}

internal/endtoend/testdata/order_by_binds/sqlite/go/db.go

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

internal/endtoend/testdata/order_by_binds/sqlite/go/models.go

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

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

Lines changed: 101 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-- name: ListAuthorsColumnSort :many
2+
SELECT * FROM authors
3+
WHERE id > sqlc.arg(min_id)
4+
ORDER BY CASE WHEN sqlc.arg(sort_column) = 'name' THEN name END;
5+
6+
-- name: ListAuthorsColumnSortFnWtihArg :many
7+
SELECT * FROM authors
8+
ORDER BY id % ?;
9+
10+
-- name: ListAuthorsNameSort :many
11+
SELECT * FROM authors
12+
WHERE id > sqlc.arg(min_id)
13+
ORDER BY name ASC;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CREATE TABLE authors (
2+
id INTEGER PRIMARY KEY AUTOINCREMENT,
3+
name TEXT NOT NULL,
4+
bio TEXT
5+
);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": "1",
3+
"packages": [
4+
{
5+
"path": "go",
6+
"engine": "sqlite",
7+
"name": "querytest",
8+
"schema": "schema.sql",
9+
"queries": "query.sql"
10+
}
11+
]
12+
}

internal/engine/sqlite/convert.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,11 @@ func (c *cc) convertMultiSelect_stmtContext(n *parser.Select_stmtContext) ast.No
512512
}
513513

514514
limitCount, limitOffset := c.convertLimit_stmtContext(n.Limit_stmt())
515+
sortClause := c.buildSortClause(n.Order_by_stmt())
516+
515517
selectStmt.LimitCount = limitCount
516518
selectStmt.LimitOffset = limitOffset
519+
selectStmt.SortClause = sortClause
517520
selectStmt.WithClause = &ast.WithClause{Ctes: &ctes}
518521
return selectStmt
519522
}
@@ -1212,3 +1215,61 @@ func (c *cc) convert(node node) ast.Node {
12121215
return todo("convert(case=default)", n)
12131216
}
12141217
}
1218+
1219+
// buildSortClause converts an IOrder_by_stmtContext into an *ast.List of *ast.SortBy nodes.
1220+
func (c *cc) buildSortClause(orderByNode parser.IOrder_by_stmtContext) *ast.List {
1221+
if orderByNode == nil {
1222+
return nil
1223+
}
1224+
1225+
orderByCtx, ok := orderByNode.(*parser.Order_by_stmtContext)
1226+
if !ok {
1227+
if debug.Active {
1228+
log.Printf("sqlite.buildSortClause: unexpected type %T for IOrder_by_stmtContext", orderByNode)
1229+
}
1230+
return nil
1231+
}
1232+
1233+
if len(orderByCtx.AllOrdering_term()) == 0 {
1234+
return nil
1235+
}
1236+
1237+
sortItems := &ast.List{Items: []ast.Node{}}
1238+
for _, otermIP := range orderByCtx.AllOrdering_term() {
1239+
oterm, ok := otermIP.(*parser.Ordering_termContext)
1240+
if !ok {
1241+
if debug.Active {
1242+
log.Printf("sqlite.buildSortClause: unexpected type %T for IOrdering_termContext", otermIP)
1243+
}
1244+
continue
1245+
}
1246+
1247+
sortByDir := ast.SortByDirDefault
1248+
if adNode := oterm.Asc_desc(); adNode != nil {
1249+
// Asc_descContext has ASC_() and DESC_() methods which return TerminalNode
1250+
if adNode.ASC_() != nil {
1251+
sortByDir = ast.SortByDirAsc
1252+
} else if adNode.DESC_() != nil {
1253+
sortByDir = ast.SortByDirDesc
1254+
}
1255+
}
1256+
1257+
sortByNulls := ast.SortByNullsDefault
1258+
if oterm.NULLS_() != nil { // NULLS_() is a TerminalNode
1259+
if oterm.FIRST_() != nil { // FIRST_() is a TerminalNode
1260+
sortByNulls = ast.SortByNullsFirst
1261+
} else if oterm.LAST_() != nil { // LAST_() is a TerminalNode
1262+
sortByNulls = ast.SortByNullsLast
1263+
}
1264+
}
1265+
1266+
sortItems.Items = append(sortItems.Items, &ast.SortBy{
1267+
Node: c.convert(oterm.Expr()),
1268+
SortbyDir: sortByDir,
1269+
SortbyNulls: sortByNulls,
1270+
UseOp: &ast.List{}, // Typically empty for standard SQLite ORDER BY
1271+
Location: oterm.GetStart().GetStart(),
1272+
})
1273+
}
1274+
return sortItems
1275+
}

0 commit comments

Comments
 (0)