diff --git a/internal/endtoend/testdata/insert_values/mysql/go/query.sql.go b/internal/endtoend/testdata/insert_values/mysql/go/query.sql.go index 88a7a46b62..09bb17a30f 100644 --- a/internal/endtoend/testdata/insert_values/mysql/go/query.sql.go +++ b/internal/endtoend/testdata/insert_values/mysql/go/query.sql.go @@ -10,6 +10,27 @@ import ( "database/sql" ) +const insertMultipleValues = `-- name: InsertMultipleValues :exec +INSERT INTO foo (a, b) VALUES (?, ?), (?, ?) +` + +type InsertMultipleValuesParams struct { + A sql.NullString + B sql.NullInt32 + A_2 sql.NullString + B_2 sql.NullInt32 +} + +func (q *Queries) InsertMultipleValues(ctx context.Context, arg InsertMultipleValuesParams) error { + _, err := q.db.ExecContext(ctx, insertMultipleValues, + arg.A, + arg.B, + arg.A_2, + arg.B_2, + ) + return err +} + const insertValues = `-- name: InsertValues :exec INSERT INTO foo (a, b) VALUES (?, ?) ` diff --git a/internal/endtoend/testdata/insert_values/mysql/query.sql b/internal/endtoend/testdata/insert_values/mysql/query.sql index 78a29ccd39..2a669b3619 100644 --- a/internal/endtoend/testdata/insert_values/mysql/query.sql +++ b/internal/endtoend/testdata/insert_values/mysql/query.sql @@ -2,3 +2,6 @@ CREATE TABLE foo (a text, b integer); /* name: InsertValues :exec */ INSERT INTO foo (a, b) VALUES (?, ?); + +/* name: InsertMultipleValues :exec */ +INSERT INTO foo (a, b) VALUES (?, ?), (?, ?); \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_values/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/insert_values/postgresql/pgx/v4/go/query.sql.go index c22a9d7a46..37ab6b3c2b 100644 --- a/internal/endtoend/testdata/insert_values/postgresql/pgx/v4/go/query.sql.go +++ b/internal/endtoend/testdata/insert_values/postgresql/pgx/v4/go/query.sql.go @@ -10,6 +10,27 @@ import ( "database/sql" ) +const insertMultipleValues = `-- name: InsertMultipleValues :exec +INSERT INTO foo (a, b) VALUES ($1, $2), ($3, $4) +` + +type InsertMultipleValuesParams struct { + A sql.NullString + B sql.NullInt32 + A_2 sql.NullString + B_2 sql.NullInt32 +} + +func (q *Queries) InsertMultipleValues(ctx context.Context, arg InsertMultipleValuesParams) error { + _, err := q.db.Exec(ctx, insertMultipleValues, + arg.A, + arg.B, + arg.A_2, + arg.B_2, + ) + return err +} + const insertValues = `-- name: InsertValues :exec INSERT INTO foo (a, b) VALUES ($1, $2) ` diff --git a/internal/endtoend/testdata/insert_values/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/insert_values/postgresql/pgx/v4/query.sql index b2ec168840..757a65e9c1 100644 --- a/internal/endtoend/testdata/insert_values/postgresql/pgx/v4/query.sql +++ b/internal/endtoend/testdata/insert_values/postgresql/pgx/v4/query.sql @@ -2,3 +2,6 @@ CREATE TABLE foo (a text, b integer); -- name: InsertValues :exec INSERT INTO foo (a, b) VALUES ($1, $2); + +/* name: InsertMultipleValues :exec */ +INSERT INTO foo (a, b) VALUES ($1, $2), ($3, $4); \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_values/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/insert_values/postgresql/pgx/v5/go/query.sql.go index 73fd9ad7a5..254afa141d 100644 --- a/internal/endtoend/testdata/insert_values/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/insert_values/postgresql/pgx/v5/go/query.sql.go @@ -11,6 +11,27 @@ import ( "github.com/jackc/pgx/v5/pgtype" ) +const insertMultipleValues = `-- name: InsertMultipleValues :exec +INSERT INTO foo (a, b) VALUES ($1, $2), ($3, $4) +` + +type InsertMultipleValuesParams struct { + A pgtype.Text + B pgtype.Int4 + A_2 pgtype.Text + B_2 pgtype.Int4 +} + +func (q *Queries) InsertMultipleValues(ctx context.Context, arg InsertMultipleValuesParams) error { + _, err := q.db.Exec(ctx, insertMultipleValues, + arg.A, + arg.B, + arg.A_2, + arg.B_2, + ) + return err +} + const insertValues = `-- name: InsertValues :exec INSERT INTO foo (a, b) VALUES ($1, $2) ` diff --git a/internal/endtoend/testdata/insert_values/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/insert_values/postgresql/pgx/v5/query.sql index b2ec168840..757a65e9c1 100644 --- a/internal/endtoend/testdata/insert_values/postgresql/pgx/v5/query.sql +++ b/internal/endtoend/testdata/insert_values/postgresql/pgx/v5/query.sql @@ -2,3 +2,6 @@ CREATE TABLE foo (a text, b integer); -- name: InsertValues :exec INSERT INTO foo (a, b) VALUES ($1, $2); + +/* name: InsertMultipleValues :exec */ +INSERT INTO foo (a, b) VALUES ($1, $2), ($3, $4); \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_values/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/insert_values/postgresql/stdlib/go/query.sql.go index 558a9fe4dc..3111ed4366 100644 --- a/internal/endtoend/testdata/insert_values/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/insert_values/postgresql/stdlib/go/query.sql.go @@ -10,6 +10,27 @@ import ( "database/sql" ) +const insertMultipleValues = `-- name: InsertMultipleValues :exec +INSERT INTO foo (a, b) VALUES ($1, $2), ($3, $4) +` + +type InsertMultipleValuesParams struct { + A sql.NullString + B sql.NullInt32 + A_2 sql.NullString + B_2 sql.NullInt32 +} + +func (q *Queries) InsertMultipleValues(ctx context.Context, arg InsertMultipleValuesParams) error { + _, err := q.db.ExecContext(ctx, insertMultipleValues, + arg.A, + arg.B, + arg.A_2, + arg.B_2, + ) + return err +} + const insertValues = `-- name: InsertValues :exec INSERT INTO foo (a, b) VALUES ($1, $2) ` diff --git a/internal/endtoend/testdata/insert_values/postgresql/stdlib/query.sql b/internal/endtoend/testdata/insert_values/postgresql/stdlib/query.sql index b2ec168840..757a65e9c1 100644 --- a/internal/endtoend/testdata/insert_values/postgresql/stdlib/query.sql +++ b/internal/endtoend/testdata/insert_values/postgresql/stdlib/query.sql @@ -2,3 +2,6 @@ CREATE TABLE foo (a text, b integer); -- name: InsertValues :exec INSERT INTO foo (a, b) VALUES ($1, $2); + +/* name: InsertMultipleValues :exec */ +INSERT INTO foo (a, b) VALUES ($1, $2), ($3, $4); \ No newline at end of file diff --git a/internal/endtoend/testdata/insert_values/sqlite/go/query.sql.go b/internal/endtoend/testdata/insert_values/sqlite/go/query.sql.go index 93c59625f2..7022ee9a11 100644 --- a/internal/endtoend/testdata/insert_values/sqlite/go/query.sql.go +++ b/internal/endtoend/testdata/insert_values/sqlite/go/query.sql.go @@ -10,6 +10,27 @@ import ( "database/sql" ) +const insertMultipleValues = `-- name: InsertMultipleValues :exec +INSERT INTO foo (a, b) VALUES (?, ?), (?, ?) +` + +type InsertMultipleValuesParams struct { + A sql.NullString + B sql.NullInt64 + A_2 sql.NullString + B_2 sql.NullInt64 +} + +func (q *Queries) InsertMultipleValues(ctx context.Context, arg InsertMultipleValuesParams) error { + _, err := q.db.ExecContext(ctx, insertMultipleValues, + arg.A, + arg.B, + arg.A_2, + arg.B_2, + ) + return err +} + const insertValues = `-- name: InsertValues :exec INSERT INTO foo (a, b) VALUES (?, ?) ` diff --git a/internal/endtoend/testdata/insert_values/sqlite/query.sql b/internal/endtoend/testdata/insert_values/sqlite/query.sql index 78a29ccd39..2a669b3619 100644 --- a/internal/endtoend/testdata/insert_values/sqlite/query.sql +++ b/internal/endtoend/testdata/insert_values/sqlite/query.sql @@ -2,3 +2,6 @@ CREATE TABLE foo (a text, b integer); /* name: InsertValues :exec */ INSERT INTO foo (a, b) VALUES (?, ?); + +/* name: InsertMultipleValues :exec */ +INSERT INTO foo (a, b) VALUES (?, ?), (?, ?); \ No newline at end of file diff --git a/internal/engine/sqlite/convert.go b/internal/engine/sqlite/convert.go index d1e9a8c050..e941bb9121 100644 --- a/internal/engine/sqlite/convert.go +++ b/internal/engine/sqlite/convert.go @@ -882,27 +882,41 @@ func (c *cc) convertInsert_stmtContext(n *parser.Insert_stmtContext) ast.Node { insert.SelectStmt = ss } } else { + var valuesLists ast.List + var values *ast.List + for _, cn := range n.GetChildren() { + switch cn := cn.(type) { + case antlr.TerminalNode: + switch cn.GetSymbol().GetTokenType() { + case parser.SQLiteParserVALUES_: + values = &ast.List{} + case parser.SQLiteParserOPEN_PAR: + if values != nil { + values = &ast.List{} + } + case parser.SQLiteParserCOMMA: + case parser.SQLiteParserCLOSE_PAR: + if values != nil { + valuesLists.Items = append(valuesLists.Items, values) + } + } + case parser.IExprContext: + if values != nil { + values.Items = append(values.Items, c.convert(cn)) + } + } + } + insert.SelectStmt = &ast.SelectStmt{ FromClause: &ast.List{}, TargetList: &ast.List{}, - ValuesLists: c.convertExprLists(n.AllExpr()), + ValuesLists: &valuesLists, } } return insert } -func (c *cc) convertExprLists(lists []parser.IExprContext) *ast.List { - list := &ast.List{Items: []ast.Node{}} - n := len(lists) - inner := &ast.List{Items: []ast.Node{}} - for i := 0; i < n; i++ { - inner.Items = append(inner.Items, c.convert(lists[i])) - } - list.Items = append(list.Items, inner) - return list -} - func (c *cc) convertColumnNames(cols []parser.IColumn_nameContext) *ast.List { list := &ast.List{Items: []ast.Node{}} for _, c := range cols {