Skip to content

Commit

Permalink
sqlite basic insert support
Browse files Browse the repository at this point in the history
  • Loading branch information
javiercbk committed May 31, 2022
1 parent b0d6f13 commit 6c971f3
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 1 deletion.
7 changes: 7 additions & 0 deletions internal/endtoend/testdata/insert_select/sqlite/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE bar (name text not null, ready bool not null);
CREATE TABLE foo (name text not null, meta text not null);

/* name: InsertSelect :exec */
INSERT INTO foo (name, meta)
SELECT name, ?
FROM bar WHERE ready = ?;
12 changes: 12 additions & 0 deletions internal/endtoend/testdata/insert_select/sqlite/sqlc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "1",
"packages": [
{
"engine": "_lemon",
"path": "go",
"name": "querytest",
"schema": "query.sql",
"queries": "query.sql"
}
]
}
31 changes: 31 additions & 0 deletions internal/endtoend/testdata/insert_values/sqlite/go/db.go

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

14 changes: 14 additions & 0 deletions internal/endtoend/testdata/insert_values/sqlite/go/models.go

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

25 changes: 25 additions & 0 deletions internal/endtoend/testdata/insert_values/sqlite/go/query.sql.go

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

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


/* name: InsertAll :exec */
INSERT INTO foo (a, b) VALUES (?, ?);
12 changes: 12 additions & 0 deletions internal/endtoend/testdata/insert_values/sqlite/sqlc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "1",
"packages": [
{
"engine": "_lemon",
"path": "go",
"name": "querytest",
"schema": "query.sql",
"queries": "query.sql"
}
]
}
64 changes: 63 additions & 1 deletion internal/engine/sqlite/convert.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package sqlite

import (
"github.com/antlr/antlr4/runtime/Go/antlr"
"strconv"
"strings"

"github.com/antlr/antlr4/runtime/Go/antlr"

"github.com/kyleconroy/sqlc/internal/engine/sqlite/parser"
"github.com/kyleconroy/sqlc/internal/sql/ast"
)
Expand Down Expand Up @@ -134,6 +135,64 @@ func convertDelete_stmtContext(c *parser.Delete_stmtContext) ast.Node {
return &ast.TODO{}
}

func convertInsert_stmtContext(c *parser.Insert_stmtContext) ast.Node {
if c == nil {
return nil
}
values := c.AllExpr()
if len(values) == 0 {
// TODO: add INSERT WITH SELECT support
return &ast.TODO{}
}
tableName := c.Table_name().GetText()
// we MUST have the columns in the update,
// otherwise the parser does not give ANY context,
// on "expression groups"
columns := convertCols(c.AllColumn_name())
insertStmt := &ast.InsertStmt{
Relation: &ast.RangeVar{
Relname: &tableName,
},
Cols: columns,
ReturningList: &ast.List{},
SelectStmt: convertSelectStmt(values, len(c.AllColumn_name())),
}
return insertStmt
}

func convertSelectStmt(values []parser.IExprContext, columns int) ast.Node {
valueList := &ast.List{Items: []ast.Node{}}
// the sqlite parse will give us values in a single slice
// so INSERT INTO a (b, c) VALUES (?, ?), (?, ?);
// will produce a 4 element slice. sqlite forces
// each column to have an expression so
// INSERT INTO a (b, c) VALUES (?); is invalid
// even if c is nullable
for i := 0; i < len(values); i++ {
inner := &ast.List{Items: []ast.Node{}}
for ; i < columns; i++ {
inner.Items = append(inner.Items, convert(values[i]))
}
valueList.Items = append(valueList.Items, inner)
}
return &ast.SelectStmt{
FromClause: &ast.List{},
TargetList: &ast.List{},
ValuesLists: valueList,
}
}

func convertCols(columns []parser.IColumn_nameContext) *ast.List {
out := &ast.List{}
for _, c := range columns {
colName := c.GetText()
out.Items = append(out.Items, &ast.ResTarget{
Name: &colName,
})
}
return out
}

func convertDrop_stmtContext(c *parser.Drop_stmtContext) ast.Node {
if c.TABLE_() != nil {
name := ast.TableName{
Expand Down Expand Up @@ -481,6 +540,9 @@ func convert(node node) ast.Node {
case *parser.Delete_stmtContext:
return convertDelete_stmtContext(n)

case *parser.Insert_stmtContext:
return convertInsert_stmtContext(n)

case *parser.ExprContext:
return convertExprContext(n)

Expand Down

0 comments on commit 6c971f3

Please sign in to comment.