diff --git a/internal/endtoend/testdata/on_duplicate_key_update/mysql/db/db.go b/internal/endtoend/testdata/on_duplicate_key_update/mysql/db/db.go new file mode 100644 index 0000000000..c3c034ae37 --- /dev/null +++ b/internal/endtoend/testdata/on_duplicate_key_update/mysql/db/db.go @@ -0,0 +1,29 @@ +// Code generated by sqlc. DO NOT EDIT. + +package db + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/on_duplicate_key_update/mysql/db/models.go b/internal/endtoend/testdata/on_duplicate_key_update/mysql/db/models.go new file mode 100644 index 0000000000..3bc48237ef --- /dev/null +++ b/internal/endtoend/testdata/on_duplicate_key_update/mysql/db/models.go @@ -0,0 +1,13 @@ +// Code generated by sqlc. DO NOT EDIT. + +package db + +import ( + "database/sql" +) + +type Author struct { + ID int64 + Name string + Bio sql.NullString +} diff --git a/internal/endtoend/testdata/on_duplicate_key_update/mysql/db/query.sql.go b/internal/endtoend/testdata/on_duplicate_key_update/mysql/db/query.sql.go new file mode 100644 index 0000000000..4f2406ac33 --- /dev/null +++ b/internal/endtoend/testdata/on_duplicate_key_update/mysql/db/query.sql.go @@ -0,0 +1,27 @@ +// Code generated by sqlc. DO NOT EDIT. +// source: query.sql + +package db + +import ( + "context" + "database/sql" +) + +const upsertAuthor = `-- name: UpsertAuthor :exec +INSERT INTO authors (name, bio) +VALUES (?, ?) +ON DUPLICATE KEY + UPDATE bio = ? +` + +type UpsertAuthorParams struct { + Name string + Bio sql.NullString + Bio_2 sql.NullString +} + +func (q *Queries) UpsertAuthor(ctx context.Context, arg UpsertAuthorParams) error { + _, err := q.db.ExecContext(ctx, upsertAuthor, arg.Name, arg.Bio, arg.Bio_2) + return err +} diff --git a/internal/endtoend/testdata/on_duplicate_key_update/mysql/query.sql b/internal/endtoend/testdata/on_duplicate_key_update/mysql/query.sql new file mode 100644 index 0000000000..25b98d3b15 --- /dev/null +++ b/internal/endtoend/testdata/on_duplicate_key_update/mysql/query.sql @@ -0,0 +1,13 @@ +-- https://github.com/kyleconroy/sqlc/issues/921 +CREATE TABLE authors ( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name text NOT NULL, + bio text, + UNIQUE(name) +); + +-- name: UpsertAuthor :exec +INSERT INTO authors (name, bio) +VALUES (?, ?) +ON DUPLICATE KEY + UPDATE bio = ?; diff --git a/internal/endtoend/testdata/on_duplicate_key_update/mysql/sqlc.json b/internal/endtoend/testdata/on_duplicate_key_update/mysql/sqlc.json new file mode 100644 index 0000000000..0895d9fa2e --- /dev/null +++ b/internal/endtoend/testdata/on_duplicate_key_update/mysql/sqlc.json @@ -0,0 +1,11 @@ +{ + "version":"1", + "packages":[ + { + "path":"db", + "engine":"mysql", + "schema":"query.sql", + "queries":"query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/on_duplicate_key_update/postgresql/db/db.go b/internal/endtoend/testdata/on_duplicate_key_update/postgresql/db/db.go new file mode 100644 index 0000000000..c3c034ae37 --- /dev/null +++ b/internal/endtoend/testdata/on_duplicate_key_update/postgresql/db/db.go @@ -0,0 +1,29 @@ +// Code generated by sqlc. DO NOT EDIT. + +package db + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/on_duplicate_key_update/postgresql/db/models.go b/internal/endtoend/testdata/on_duplicate_key_update/postgresql/db/models.go new file mode 100644 index 0000000000..3bc48237ef --- /dev/null +++ b/internal/endtoend/testdata/on_duplicate_key_update/postgresql/db/models.go @@ -0,0 +1,13 @@ +// Code generated by sqlc. DO NOT EDIT. + +package db + +import ( + "database/sql" +) + +type Author struct { + ID int64 + Name string + Bio sql.NullString +} diff --git a/internal/endtoend/testdata/on_duplicate_key_update/postgresql/db/query.sql.go b/internal/endtoend/testdata/on_duplicate_key_update/postgresql/db/query.sql.go new file mode 100644 index 0000000000..d96cde7f11 --- /dev/null +++ b/internal/endtoend/testdata/on_duplicate_key_update/postgresql/db/query.sql.go @@ -0,0 +1,26 @@ +// Code generated by sqlc. DO NOT EDIT. +// source: query.sql + +package db + +import ( + "context" + "database/sql" +) + +const upsertAuthor = `-- name: UpsertAuthor :exec +INSERT INTO authors (name, bio) +VALUES ($1, $2) +ON CONFLICT (name) DO UPDATE +SET bio = $2 +` + +type UpsertAuthorParams struct { + Name string + Bio sql.NullString +} + +func (q *Queries) UpsertAuthor(ctx context.Context, arg UpsertAuthorParams) error { + _, err := q.db.ExecContext(ctx, upsertAuthor, arg.Name, arg.Bio) + return err +} diff --git a/internal/endtoend/testdata/on_duplicate_key_update/postgresql/query.sql b/internal/endtoend/testdata/on_duplicate_key_update/postgresql/query.sql new file mode 100644 index 0000000000..b2a51c5f42 --- /dev/null +++ b/internal/endtoend/testdata/on_duplicate_key_update/postgresql/query.sql @@ -0,0 +1,12 @@ +-- https://github.com/kyleconroy/sqlc/issues/921 +CREATE TABLE authors ( + id BIGSERIAL PRIMARY KEY, + name text NOT NULL UNIQUE, + bio text +); + +-- name: UpsertAuthor :exec +INSERT INTO authors (name, bio) +VALUES ($1, $2) +ON CONFLICT (name) DO UPDATE +SET bio = $2; diff --git a/internal/endtoend/testdata/on_duplicate_key_update/postgresql/sqlc.json b/internal/endtoend/testdata/on_duplicate_key_update/postgresql/sqlc.json new file mode 100644 index 0000000000..00a8a0fcfd --- /dev/null +++ b/internal/endtoend/testdata/on_duplicate_key_update/postgresql/sqlc.json @@ -0,0 +1,11 @@ +{ + "version":"1", + "packages":[ + { + "path":"db", + "engine":"postgresql", + "schema":"query.sql", + "queries":"query.sql" + } + ] +} diff --git a/internal/engine/dolphin/convert.go b/internal/engine/dolphin/convert.go index 6f8236e1c7..4cf484c60a 100644 --- a/internal/engine/dolphin/convert.go +++ b/internal/engine/dolphin/convert.go @@ -407,6 +407,18 @@ func (c *cc) convertInsertStmt(n *pcast.InsertStmt) *ast.InsertStmt { ValuesLists: c.convertLists(n.Lists), } } + + if n.OnDuplicate != nil { + targetList := &ast.List{} + for _, a := range n.OnDuplicate { + targetList.Items = append(targetList.Items, c.convertAssignment(a)) + } + insert.OnConflictClause = &ast.OnConflictClause{ + TargetList: targetList, + Location: n.OriginTextPosition(), + } + } + return insert }