Skip to content

Commit

Permalink
fix(postgres): update upsert regex to match the last RETURNING *
Browse files Browse the repository at this point in the history
  • Loading branch information
Americas committed Oct 12, 2019
1 parent bd59b87 commit 1655b1f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
8 changes: 6 additions & 2 deletions lib/dialects/postgres/query-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,12 @@ class PostgresQueryGenerator extends AbstractQueryGenerator {
const insert = this.insertQuery(tableName, insertValues, model.rawAttributes, upsertOptions);
const update = this.updateQuery(tableName, updateValues, where, upsertOptions, model.rawAttributes);

insert.query = insert.query.replace('RETURNING *', `RETURNING ${primaryField} INTO primary_key`);
update.query = update.query.replace('RETURNING *', `RETURNING ${primaryField} INTO primary_key`);
if (options.returning) {
const returningRegex = /RETURNING \*(?![\s\S]*RETURNING \*)/;

insert.query = insert.query.replace(returningRegex, `RETURNING ${primaryField} INTO primary_key`);
update.query = update.query.replace(returningRegex, `RETURNING ${primaryField} INTO primary_key`);
}

return this.exceptionFn(
'sequelize_upsert',
Expand Down
50 changes: 50 additions & 0 deletions test/unit/dialects/postgres/query-generator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ if (dialect.startsWith('postgres')) {
expectation: 'CREATE DATABASE "myDatabase" ENCODING = \'UTF8\' LC_COLLATE = \'en_US.UTF-8\' LC_CTYPE = \'zh_TW.UTF-8\' TEMPLATE = \'template0\';'
}
],

dropDatabaseQuery: [
{
arguments: ['myDatabase'],
expectation: 'DROP DATABASE IF EXISTS "myDatabase";'
}
],

arithmeticQuery: [
{
title: 'Should use the plus operator',
Expand Down Expand Up @@ -87,6 +89,7 @@ if (dialect.startsWith('postgres')) {
expectation: 'UPDATE "myTable" SET "foo"="foo"- \'bar\''
}
],

attributesToSQL: [
{
arguments: [{ id: 'INTEGER' }],
Expand Down Expand Up @@ -1091,6 +1094,53 @@ if (dialect.startsWith('postgres')) {
}
],

upsertQuery: [
{
arguments: [
'myTable',
{ name: 'foo' },
{ name: 'foo' },
{ id: 2 },
{ primaryKeyField: 'id' },
{ returning: false }
],
expectation: 'CREATE OR REPLACE FUNCTION pg_temp.sequelize_upsert(OUT created boolean, OUT primary_key text) AS $func$ BEGIN INSERT INTO "myTable" ("name") VALUES (\'foo\'); created := true; EXCEPTION WHEN unique_violation THEN UPDATE "myTable" SET "name"=\'foo\' WHERE "id" = 2; created := false; END; $func$ LANGUAGE plpgsql; SELECT * FROM pg_temp.sequelize_upsert();'
},
{
arguments: [
'myTable',
{ name: 'RETURNING *', json: '{"foo":"RETURNING *"}' },
{ name: 'RETURNING *', json: '{"foo":"RETURNING *"}' },
{ id: 2 },
{ primaryKeyField: 'id' },
{ returning: false }
],
expectation: 'CREATE OR REPLACE FUNCTION pg_temp.sequelize_upsert(OUT created boolean, OUT primary_key text) AS $func$ BEGIN INSERT INTO "myTable" ("name","json") VALUES (\'RETURNING *\',\'{"foo":"RETURNING *"}\'); created := true; EXCEPTION WHEN unique_violation THEN UPDATE "myTable" SET "name"=\'RETURNING *\',"json"=\'{"foo":"RETURNING *"}\' WHERE "id" = 2; created := false; END; $func$ LANGUAGE plpgsql; SELECT * FROM pg_temp.sequelize_upsert();'
},
{
arguments: [
'myTable',
{ name: 'foo' },
{ name: 'foo' },
{ id: 2 },
{ primaryKeyField: 'id' },
{ returning: true }
],
expectation: 'CREATE OR REPLACE FUNCTION pg_temp.sequelize_upsert(OUT created boolean, OUT primary_key text) AS $func$ BEGIN INSERT INTO "myTable" ("name") VALUES (\'foo\') RETURNING "id" INTO primary_key; created := true; EXCEPTION WHEN unique_violation THEN UPDATE "myTable" SET "name"=\'foo\' WHERE "id" = 2 RETURNING "id" INTO primary_key; created := false; END; $func$ LANGUAGE plpgsql; SELECT * FROM pg_temp.sequelize_upsert();'
},
{
arguments: [
'myTable',
{ name: 'RETURNING *', json: '{"foo":"RETURNING *"}' },
{ name: 'RETURNING *', json: '{"foo":"RETURNING *"}' },
{ id: 2 },
{ primaryKeyField: 'id' },
{ returning: true }
],
expectation: 'CREATE OR REPLACE FUNCTION pg_temp.sequelize_upsert(OUT created boolean, OUT primary_key text) AS $func$ BEGIN INSERT INTO "myTable" ("name","json") VALUES (\'RETURNING *\',\'{"foo":"RETURNING *"}\') RETURNING "id" INTO primary_key; created := true; EXCEPTION WHEN unique_violation THEN UPDATE "myTable" SET "name"=\'RETURNING *\',"json"=\'{"foo":"RETURNING *"}\' WHERE "id" = 2 RETURNING "id" INTO primary_key; created := false; END; $func$ LANGUAGE plpgsql; SELECT * FROM pg_temp.sequelize_upsert();'
}
],

removeIndexQuery: [
{
arguments: ['User', 'user_foo_bar'],
Expand Down

0 comments on commit 1655b1f

Please sign in to comment.