From 3c5194caa27314cdf7e0d7e9daab53695231bceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Proen=C3=A7a?= Date: Tue, 27 Feb 2024 00:21:53 +0000 Subject: [PATCH] feat: use bind params in bulkInsertQuery --- .../dialects/abstract/query-generator.d.ts | 7 +- .../src/dialects/abstract/query-generator.js | 14 +- .../src/dialects/abstract/query-interface.js | 14 +- .../core/src/dialects/db2/query-generator.js | 2 +- .../core/src/dialects/ibmi/query-generator.js | 9 +- .../src/dialects/mssql/query-generator.js | 2 +- .../integration/model/bulk-create.test.js | 2 +- .../unit/dialects/db2/query-generator.test.js | 47 ++- .../dialects/mariadb/query-generator.test.js | 123 ++++++-- .../dialects/mysql/query-generator.test.js | 127 ++++++-- .../dialects/postgres/query-generator.test.js | 275 +++++++++++++++--- .../snowflake/query-generator.test.js | 223 ++++++++++++-- .../dialects/sqlite/query-generator.test.js | 146 ++++++++-- .../query-generator/bulk-insert-query.test.ts | 4 +- .../unit/query-interface/bulk-insert.test.ts | 29 +- packages/core/test/unit/sql/insert.test.js | 18 +- 16 files changed, 863 insertions(+), 179 deletions(-) diff --git a/packages/core/src/dialects/abstract/query-generator.d.ts b/packages/core/src/dialects/abstract/query-generator.d.ts index 8df8c459623f..4575f427b082 100644 --- a/packages/core/src/dialects/abstract/query-generator.d.ts +++ b/packages/core/src/dialects/abstract/query-generator.d.ts @@ -40,6 +40,7 @@ type InsertOptions = ParameterOptions & type BulkInsertOptions = ParameterOptions & { hasTrigger?: boolean; + bindParam?: false | ((value: unknown) => string); updateOnDuplicate?: string[]; ignoreDuplicates?: boolean; @@ -93,13 +94,13 @@ export class AbstractQueryGenerator extends AbstractQueryGeneratorTypeScript { valueHash: object, columnDefinitions?: { [columnName: string]: NormalizedAttributeOptions }, options?: InsertOptions, - ): { query: string; bind?: unknown[] }; + ): { query: string; bind?: Record }; bulkInsertQuery( tableName: TableName, newEntries: object[], options?: BulkInsertOptions, columnDefinitions?: { [columnName: string]: NormalizedAttributeOptions }, - ): string; + ): { query: string; bind?: Record }; addColumnQuery( table: TableName, @@ -114,7 +115,7 @@ export class AbstractQueryGenerator extends AbstractQueryGeneratorTypeScript { where: WhereOptions, options?: UpdateOptions, columnDefinitions?: { [columnName: string]: NormalizedAttributeOptions }, - ): { query: string; bind?: unknown[] }; + ): { query: string; bind?: Record }; arithmeticQuery( operator: string, diff --git a/packages/core/src/dialects/abstract/query-generator.js b/packages/core/src/dialects/abstract/query-generator.js index 2a590bf5c9d8..9bb15956dac0 100644 --- a/packages/core/src/dialects/abstract/query-generator.js +++ b/packages/core/src/dialects/abstract/query-generator.js @@ -292,6 +292,8 @@ export class AbstractQueryGenerator extends AbstractQueryGeneratorTypeScript { options ||= {}; fieldMappedAttributes ||= {}; + const bind = Object.create(null); + const bindParam = options.bindParam ?? this.bindParam(bind); const tuples = []; const serials = {}; const allAttributes = []; @@ -318,7 +320,7 @@ export class AbstractQueryGenerator extends AbstractQueryGeneratorTypeScript { return this.escape(fieldValueHash[key] ?? null, { // model // TODO: make bulkInsertQuery accept model instead of fieldValueHashes - // bindParam // TODO: support bind params + bindParam, type: fieldMappedAttributes[key]?.type, replacements: options.replacements, }); @@ -386,7 +388,7 @@ export class AbstractQueryGenerator extends AbstractQueryGeneratorTypeScript { returning += returnValues.returningFragment; } - return joinSQLFragments([ + const query = joinSQLFragments([ 'INSERT', ignoreDuplicates, 'INTO', @@ -399,6 +401,14 @@ export class AbstractQueryGenerator extends AbstractQueryGeneratorTypeScript { returning, ';', ]); + + const result = { query }; + + if (bindParam !== false) { + result.bind = bind; + } + + return result; } /** diff --git a/packages/core/src/dialects/abstract/query-interface.js b/packages/core/src/dialects/abstract/query-interface.js index d61304e8801b..526ff2942f06 100644 --- a/packages/core/src/dialects/abstract/query-interface.js +++ b/packages/core/src/dialects/abstract/query-interface.js @@ -475,14 +475,24 @@ export class AbstractQueryInterface extends AbstractQueryInterfaceTypeScript { * @returns {Promise} */ async bulkInsert(tableName, records, options, attributes) { + if (options?.bind) { + assertNoReservedBind(options.bind); + } + options = { ...options, type: QueryTypes.INSERT }; - const sql = this.queryGenerator.bulkInsertQuery(tableName, records, options, attributes); + const { bind, query } = this.queryGenerator.bulkInsertQuery( + tableName, + records, + options, + attributes, + ); // unlike bind, replacements are handled by QueryGenerator, not QueryRaw delete options.replacements; + options.bind = combineBinds(options.bind, bind); - const results = await this.sequelize.queryRaw(sql, options); + const results = await this.sequelize.queryRaw(query, options); return results[0]; } diff --git a/packages/core/src/dialects/db2/query-generator.js b/packages/core/src/dialects/db2/query-generator.js index 51bb3fbb715b..a06c207dd0a2 100644 --- a/packages/core/src/dialects/db2/query-generator.js +++ b/packages/core/src/dialects/db2/query-generator.js @@ -343,7 +343,7 @@ export class Db2QueryGenerator extends Db2QueryGeneratorTypeScript { const generatedQuery = template(allQueries.join(';'), this._templateSettings)(replacements); - return generatedQuery; + return { query: generatedQuery }; } updateQuery(tableName, attrValueHash, where, options, attributes) { diff --git a/packages/core/src/dialects/ibmi/query-generator.js b/packages/core/src/dialects/ibmi/query-generator.js index 2b00ec60f392..279eec8a3820 100644 --- a/packages/core/src/dialects/ibmi/query-generator.js +++ b/packages/core/src/dialects/ibmi/query-generator.js @@ -350,13 +350,18 @@ export class IBMiQueryGenerator extends IBMiQueryGeneratorTypeScript { bulkInsertQuery(tableName, fieldValueHashes, options, fieldMappedAttributes) { // remove the final semi-colon - let query = super.bulkInsertQuery(tableName, fieldValueHashes, options, fieldMappedAttributes); + let { bind, query } = super.bulkInsertQuery( + tableName, + fieldValueHashes, + options, + fieldMappedAttributes, + ); if (query.at(-1) === ';') { query = query.slice(0, -1); query = `SELECT * FROM FINAL TABLE (${query})`; } - return query; + return { bind, query }; } // bindParam(bind) { diff --git a/packages/core/src/dialects/mssql/query-generator.js b/packages/core/src/dialects/mssql/query-generator.js index b3312e351b60..d91ca155fc53 100644 --- a/packages/core/src/dialects/mssql/query-generator.js +++ b/packages/core/src/dialects/mssql/query-generator.js @@ -305,7 +305,7 @@ export class MsSqlQueryGenerator extends MsSqlQueryGeneratorTypeScript { offset += 1000; } - return `${commands.join(';')};`; + return { query: `${commands.join(';')};` }; } updateQuery(tableName, attrValueHash, where, options = {}, attributes) { diff --git a/packages/core/test/integration/model/bulk-create.test.js b/packages/core/test/integration/model/bulk-create.test.js index 2b4412e2f5d9..7e97e576fe95 100644 --- a/packages/core/test/integration/model/bulk-create.test.js +++ b/packages/core/test/integration/model/bulk-create.test.js @@ -195,7 +195,7 @@ describe('Model', () => { default: { // mysql, sqlite expect(sql).to.include( - 'INSERT INTO `Beers` (`id`,`style`,`createdAt`,`updatedAt`) VALUES (NULL', + 'INSERT INTO `Beers` (`id`,`style`,`createdAt`,`updatedAt`) VALUES (', ); } } diff --git a/packages/core/test/unit/dialects/db2/query-generator.test.js b/packages/core/test/unit/dialects/db2/query-generator.test.js index 1d4ea171454f..4d3cb639cca2 100644 --- a/packages/core/test/unit/dialects/db2/query-generator.test.js +++ b/packages/core/test/unit/dialects/db2/query-generator.test.js @@ -346,12 +346,14 @@ if (dialect === 'db2') { bulkInsertQuery: [ { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }]], - expectation: 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\');', + expectation: { query: 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\');' }, }, { arguments: ['myTable', [{ name: "foo';DROP TABLE myTable;" }, { name: 'bar' }]], - expectation: - "INSERT INTO \"myTable\" (\"name\") VALUES ('foo'';DROP TABLE myTable;'),('bar');", + expectation: { + query: + "INSERT INTO \"myTable\" (\"name\") VALUES ('foo'';DROP TABLE myTable;'),('bar');", + }, }, { arguments: [ @@ -361,7 +363,9 @@ if (dialect === 'db2') { { name: 'bar', birthday: new Date(Date.UTC(2012, 2, 27, 10, 1, 55)) }, ], ], - expectation: `INSERT INTO "myTable" ("name","birthday") VALUES ('foo','2011-03-27 10:01:55.000'),('bar','2012-03-27 10:01:55.000');`, + expectation: { + query: `INSERT INTO "myTable" ("name","birthday") VALUES ('foo','2011-03-27 10:01:55.000'),('bar','2012-03-27 10:01:55.000');`, + }, }, { arguments: [ @@ -371,7 +375,9 @@ if (dialect === 'db2') { { name: 'bar', foo: 2 }, ], ], - expectation: 'INSERT INTO "myTable" ("name","foo") VALUES (\'foo\',1),(\'bar\',2);', + expectation: { + query: 'INSERT INTO "myTable" ("name","foo") VALUES (\'foo\',1),(\'bar\',2);', + }, }, { arguments: [ @@ -381,8 +387,10 @@ if (dialect === 'db2') { { name: 'bar', nullValue: null }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',NULL,NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',NULL,NULL);', + }, }, { arguments: [ @@ -392,8 +400,10 @@ if (dialect === 'db2') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',2,NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',2,NULL);', + }, context: { options: { omitNull: false } }, }, { @@ -404,8 +414,10 @@ if (dialect === 'db2') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',2,NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',2,NULL);', + }, context: { options: { omitNull: true } }, // Note: We don't honour this because it makes little sense when some rows may have nulls and others not }, { @@ -416,8 +428,10 @@ if (dialect === 'db2') { { name: 'bar', foo: 2, undefinedValue: undefined }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","foo","nullValue","undefinedValue") VALUES (\'foo\',1,NULL,NULL),(\'bar\',2,NULL,NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","foo","nullValue","undefinedValue") VALUES (\'foo\',1,NULL,NULL),(\'bar\',2,NULL,NULL);', + }, context: { options: { omitNull: true } }, // Note: As above }, { @@ -428,12 +442,13 @@ if (dialect === 'db2') { { name: 'bar', value: false }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","value") VALUES (\'foo\',true),(\'bar\',false);', + expectation: { + query: 'INSERT INTO "myTable" ("name","value") VALUES (\'foo\',true),(\'bar\',false);', + }, }, { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true }], - expectation: 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\');', + expectation: { query: 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\');' }, }, ], diff --git a/packages/core/test/unit/dialects/mariadb/query-generator.test.js b/packages/core/test/unit/dialects/mariadb/query-generator.test.js index 3ff33ca50efc..a39d28a3581e 100644 --- a/packages/core/test/unit/dialects/mariadb/query-generator.test.js +++ b/packages/core/test/unit/dialects/mariadb/query-generator.test.js @@ -351,12 +351,23 @@ if (dialect === 'mariadb') { bulkInsertQuery: [ { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }]], - expectation: "INSERT INTO `myTable` (`name`) VALUES ('foo'),('bar');", + expectation: { + query: 'INSERT INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: ['myTable', [{ name: "foo';DROP TABLE myTable;" }, { name: 'bar' }]], - expectation: - "INSERT INTO `myTable` (`name`) VALUES ('foo\\';DROP TABLE myTable;'),('bar');", + expectation: { + query: 'INSERT INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: "foo';DROP TABLE myTable;", + sequelize_2: 'bar', + }, + }, }, { arguments: [ @@ -366,8 +377,16 @@ if (dialect === 'mariadb') { { name: 'bar', birthday: new Date(Date.UTC(2012, 2, 27, 10, 1, 55)) }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`birthday`) VALUES ('foo','2011-03-27 10:01:55.000'),('bar','2012-03-27 10:01:55.000');", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`birthday`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: '2011-03-27 10:01:55.000', + sequelize_3: 'bar', + sequelize_4: '2012-03-27 10:01:55.000', + }, + }, }, { arguments: [ @@ -377,7 +396,16 @@ if (dialect === 'mariadb') { { name: 'bar', foo: 2 }, ], ], - expectation: "INSERT INTO `myTable` (`name`,`foo`) VALUES ('foo',1),('bar',2);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: 'bar', + sequelize_4: 2, + }, + }, }, { arguments: [ @@ -387,8 +415,18 @@ if (dialect === 'mariadb') { { name: 'bar', nullValue: null }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL),('bar',NULL,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: null, + sequelize_6: null, + }, + }, }, { arguments: [ @@ -398,8 +436,18 @@ if (dialect === 'mariadb') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL),('bar',2,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: false } }, }, { @@ -410,8 +458,18 @@ if (dialect === 'mariadb') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL),('bar',2,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: true } }, // Note: We don't honour this because it makes little sense when some rows may have nulls and others not }, { @@ -422,8 +480,20 @@ if (dialect === 'mariadb') { { name: 'bar', foo: 2, undefinedValue: undefined }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`,`undefinedValue`) VALUES ('foo',1,NULL,NULL),('bar',2,NULL,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`,`undefinedValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3,$sequelize_4),($sequelize_5,$sequelize_6,$sequelize_7,$sequelize_8);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: null, + sequelize_5: 'bar', + sequelize_6: 2, + sequelize_7: null, + sequelize_8: null, + }, + }, context: { options: { omitNull: true } }, // Note: As above }, { @@ -434,11 +504,16 @@ if (dialect === 'mariadb') { { name: 'bar', value: false }, ], ], - expectation: "INSERT INTO `myTable` (`name`,`value`) VALUES ('foo',true),('bar',false);", - }, - { - arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true }], - expectation: "INSERT IGNORE INTO `myTable` (`name`) VALUES ('foo'),('bar');", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`value`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: 'bar', + sequelize_4: 0, + }, + }, }, { arguments: [ @@ -446,8 +521,14 @@ if (dialect === 'mariadb') { [{ name: 'foo' }, { name: 'bar' }], { updateOnDuplicate: ['name'] }, ], - expectation: - "INSERT INTO `myTable` (`name`) VALUES ('foo'),('bar') ON DUPLICATE KEY UPDATE `name`=VALUES(`name`);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, ], diff --git a/packages/core/test/unit/dialects/mysql/query-generator.test.js b/packages/core/test/unit/dialects/mysql/query-generator.test.js index f9943aeb33ee..7862318e4a91 100644 --- a/packages/core/test/unit/dialects/mysql/query-generator.test.js +++ b/packages/core/test/unit/dialects/mysql/query-generator.test.js @@ -346,12 +346,23 @@ if (dialect === 'mysql') { bulkInsertQuery: [ { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }]], - expectation: "INSERT INTO `myTable` (`name`) VALUES ('foo'),('bar');", + expectation: { + query: 'INSERT INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: ['myTable', [{ name: "foo';DROP TABLE myTable;" }, { name: 'bar' }]], - expectation: - "INSERT INTO `myTable` (`name`) VALUES ('foo\\';DROP TABLE myTable;'),('bar');", + expectation: { + query: 'INSERT INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: "foo';DROP TABLE myTable;", + sequelize_2: 'bar', + }, + }, }, { arguments: [ @@ -361,8 +372,16 @@ if (dialect === 'mysql') { { name: 'bar', birthday: new Date(Date.UTC(2012, 2, 27, 10, 1, 55)) }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`birthday`) VALUES ('foo','2011-03-27 10:01:55.000'),('bar','2012-03-27 10:01:55.000');", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`birthday`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: '2011-03-27 10:01:55.000', + sequelize_3: 'bar', + sequelize_4: '2012-03-27 10:01:55.000', + }, + }, }, { arguments: [ @@ -372,7 +391,16 @@ if (dialect === 'mysql') { { name: 'bar', foo: 2 }, ], ], - expectation: "INSERT INTO `myTable` (`name`,`foo`) VALUES ('foo',1),('bar',2);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: 'bar', + sequelize_4: 2, + }, + }, }, { arguments: [ @@ -382,8 +410,18 @@ if (dialect === 'mysql') { { name: 'bar', nullValue: null }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL),('bar',NULL,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: null, + sequelize_6: null, + }, + }, }, { arguments: [ @@ -393,8 +431,18 @@ if (dialect === 'mysql') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL),('bar',2,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: false } }, }, { @@ -405,8 +453,18 @@ if (dialect === 'mysql') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL),('bar',2,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: true } }, // Note: We don't honour this because it makes little sense when some rows may have nulls and others not }, { @@ -417,8 +475,20 @@ if (dialect === 'mysql') { { name: 'bar', foo: 2, undefinedValue: undefined }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`,`undefinedValue`) VALUES ('foo',1,NULL,NULL),('bar',2,NULL,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`,`undefinedValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3,$sequelize_4),($sequelize_5,$sequelize_6,$sequelize_7,$sequelize_8);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: null, + sequelize_5: 'bar', + sequelize_6: 2, + sequelize_7: null, + sequelize_8: null, + }, + }, context: { options: { omitNull: true } }, // Note: As above }, { @@ -429,11 +499,26 @@ if (dialect === 'mysql') { { name: 'bar', value: false }, ], ], - expectation: "INSERT INTO `myTable` (`name`,`value`) VALUES ('foo',true),('bar',false);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`value`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: 'bar', + sequelize_4: 0, + }, + }, }, { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true }], - expectation: "INSERT IGNORE INTO `myTable` (`name`) VALUES ('foo'),('bar');", + expectation: { + query: 'INSERT IGNORE INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: [ @@ -441,8 +526,14 @@ if (dialect === 'mysql') { [{ name: 'foo' }, { name: 'bar' }], { updateOnDuplicate: ['name'] }, ], - expectation: - "INSERT INTO `myTable` (`name`) VALUES ('foo'),('bar') ON DUPLICATE KEY UPDATE `name`=VALUES(`name`);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2) ON DUPLICATE KEY UPDATE `name`=VALUES(`name`);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, ], diff --git a/packages/core/test/unit/dialects/postgres/query-generator.test.js b/packages/core/test/unit/dialects/postgres/query-generator.test.js index af4efbea26e2..fe5a494f2d34 100644 --- a/packages/core/test/unit/dialects/postgres/query-generator.test.js +++ b/packages/core/test/unit/dialects/postgres/query-generator.test.js @@ -562,16 +562,35 @@ if (dialect.startsWith('postgres')) { bulkInsertQuery: [ { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }]], - expectation: 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\');', + expectation: { + query: 'INSERT INTO "myTable" ("name") VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true }], - expectation: - 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\') ON CONFLICT DO NOTHING;', + expectation: { + query: + 'INSERT INTO "myTable" ("name") VALUES ($sequelize_1),($sequelize_2) ON CONFLICT DO NOTHING;', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { returning: true }], - expectation: 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\') RETURNING *;', + expectation: { + query: + 'INSERT INTO "myTable" ("name") VALUES ($sequelize_1),($sequelize_2) RETURNING *;', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: [ @@ -579,8 +598,14 @@ if (dialect.startsWith('postgres')) { [{ name: 'foo' }, { name: 'bar' }], { returning: ['id', 'sentToId'] }, ], - expectation: - 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\') RETURNING "id", "sentToId";', + expectation: { + query: + 'INSERT INTO "myTable" ("name") VALUES ($sequelize_1),($sequelize_2) RETURNING "id", "sentToId";', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: [ @@ -588,13 +613,24 @@ if (dialect.startsWith('postgres')) { [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true, returning: true }, ], - expectation: - 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\') ON CONFLICT DO NOTHING RETURNING *;', + expectation: { + query: + 'INSERT INTO "myTable" ("name") VALUES ($sequelize_1),($sequelize_2) ON CONFLICT DO NOTHING RETURNING *;', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: ['myTable', [{ name: "foo';DROP TABLE myTable;" }, { name: 'bar' }]], - expectation: - "INSERT INTO \"myTable\" (\"name\") VALUES ('foo'';DROP TABLE myTable;'),('bar');", + expectation: { + query: 'INSERT INTO "myTable" ("name") VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: "foo';DROP TABLE myTable;", + sequelize_2: 'bar', + }, + }, }, { arguments: [ @@ -610,8 +646,16 @@ if (dialect.startsWith('postgres')) { }, ], ], - expectation: - "INSERT INTO \"myTable\" (\"name\",\"birthday\") VALUES ('foo','2011-03-27 10:01:55.000 +00:00'),('bar','2012-03-27 10:01:55.000 +00:00');", + expectation: { + query: + 'INSERT INTO "myTable" ("name","birthday") VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: '2011-03-27 10:01:55.000 +00:00', + sequelize_3: 'bar', + sequelize_4: '2012-03-27 10:01:55.000 +00:00', + }, + }, }, { arguments: [ @@ -621,7 +665,16 @@ if (dialect.startsWith('postgres')) { { name: 'bar', foo: 2 }, ], ], - expectation: 'INSERT INTO "myTable" ("name","foo") VALUES (\'foo\',1),(\'bar\',2);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","foo") VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: 'bar', + sequelize_4: 2, + }, + }, }, { arguments: [ @@ -631,8 +684,16 @@ if (dialect.startsWith('postgres')) { { name: 'bar', nullValue: null }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","nullValue") VALUES (\'foo\',NULL),(\'bar\',NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","nullValue") VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: null, + sequelize_3: 'bar', + sequelize_4: null, + }, + }, }, { arguments: [ @@ -642,8 +703,16 @@ if (dialect.startsWith('postgres')) { { name: 'bar', nullValue: null }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","nullValue") VALUES (\'foo\',NULL),(\'bar\',NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","nullValue") VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: null, + sequelize_3: 'bar', + sequelize_4: null, + }, + }, context: { options: { omitNull: false } }, }, { @@ -654,8 +723,16 @@ if (dialect.startsWith('postgres')) { { name: 'bar', nullValue: null }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","nullValue") VALUES (\'foo\',NULL),(\'bar\',NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","nullValue") VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: null, + sequelize_3: 'bar', + sequelize_4: null, + }, + }, context: { options: { omitNull: true } }, // Note: We don't honour this because it makes little sense when some rows may have nulls and others not }, { @@ -666,8 +743,16 @@ if (dialect.startsWith('postgres')) { { name: 'bar', nullValue: undefined }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","nullValue") VALUES (\'foo\',NULL),(\'bar\',NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","nullValue") VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: null, + sequelize_3: 'bar', + sequelize_4: null, + }, + }, context: { options: { omitNull: true } }, // Note: As above }, { @@ -675,7 +760,14 @@ if (dialect.startsWith('postgres')) { { schema: 'mySchema', tableName: 'myTable' }, [{ name: 'foo' }, { name: 'bar' }], ], - expectation: 'INSERT INTO "mySchema"."myTable" ("name") VALUES (\'foo\'),(\'bar\');', + expectation: { + query: + 'INSERT INTO "mySchema"."myTable" ("name") VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: [ @@ -685,16 +777,28 @@ if (dialect.startsWith('postgres')) { { name: JSON.stringify({ info: 'Look ma another " quote' }) }, ], ], - expectation: - 'INSERT INTO "mySchema"."myTable" ("name") VALUES (\'{"info":"Look ma a \\" quote"}\'),(\'{"info":"Look ma another \\" quote"}\');', + expectation: { + query: + 'INSERT INTO "mySchema"."myTable" ("name") VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: '{"info":"Look ma a \\" quote"}', + sequelize_2: '{"info":"Look ma another \\" quote"}', + }, + }, }, { arguments: [ { schema: 'mySchema', tableName: 'myTable' }, [{ name: "foo';DROP TABLE mySchema.myTable;" }, { name: 'bar' }], ], - expectation: - 'INSERT INTO "mySchema"."myTable" ("name") VALUES (\'foo\'\';DROP TABLE mySchema.myTable;\'),(\'bar\');', + expectation: { + query: + 'INSERT INTO "mySchema"."myTable" ("name") VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: "foo';DROP TABLE mySchema.myTable;", + sequelize_2: 'bar', + }, + }, }, { arguments: [ @@ -702,19 +806,37 @@ if (dialect.startsWith('postgres')) { [{ name: 'foo' }, { name: 'bar' }], { updateOnDuplicate: ['name'], upsertKeys: ['name'] }, ], - expectation: - 'INSERT INTO "mySchema"."myTable" ("name") VALUES (\'foo\'),(\'bar\') ON CONFLICT ("name") DO UPDATE SET "name"=EXCLUDED."name";', + expectation: { + query: + 'INSERT INTO "mySchema"."myTable" ("name") VALUES ($sequelize_1),($sequelize_2) ON CONFLICT ("name") DO UPDATE SET "name"=EXCLUDED."name";', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, // Variants when quoteIdentifiers is false { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }]], - expectation: "INSERT INTO myTable (name) VALUES ('foo'),('bar');", + expectation: { + query: 'INSERT INTO myTable (name) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, context: { options: { quoteIdentifiers: false } }, }, { arguments: ['myTable', [{ name: "foo';DROP TABLE myTable;" }, { name: 'bar' }]], - expectation: "INSERT INTO myTable (name) VALUES ('foo'';DROP TABLE myTable;'),('bar');", + expectation: { + query: 'INSERT INTO myTable (name) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: "foo';DROP TABLE myTable;", + sequelize_2: 'bar', + }, + }, context: { options: { quoteIdentifiers: false } }, }, { @@ -731,8 +853,16 @@ if (dialect.startsWith('postgres')) { }, ], ], - expectation: - "INSERT INTO myTable (name,birthday) VALUES ('foo','2011-03-27 10:01:55.000 +00:00'),('bar','2012-03-27 10:01:55.000 +00:00');", + expectation: { + query: + 'INSERT INTO myTable (name,birthday) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: '2011-03-27 10:01:55.000 +00:00', + sequelize_3: 'bar', + sequelize_4: '2012-03-27 10:01:55.000 +00:00', + }, + }, context: { options: { quoteIdentifiers: false } }, }, { @@ -743,7 +873,16 @@ if (dialect.startsWith('postgres')) { { name: 'bar', foo: 2 }, ], ], - expectation: "INSERT INTO myTable (name,foo) VALUES ('foo',1),('bar',2);", + expectation: { + query: + 'INSERT INTO myTable (name,foo) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: 'bar', + sequelize_4: 2, + }, + }, context: { options: { quoteIdentifiers: false } }, }, { @@ -754,7 +893,16 @@ if (dialect.startsWith('postgres')) { { name: 'bar', nullValue: null }, ], ], - expectation: `INSERT INTO myTable (name,nullValue) VALUES ('foo',NULL),('bar',NULL);`, + expectation: { + query: + 'INSERT INTO myTable (name,nullValue) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: null, + sequelize_3: 'bar', + sequelize_4: null, + }, + }, context: { options: { quoteIdentifiers: false } }, }, { @@ -765,7 +913,16 @@ if (dialect.startsWith('postgres')) { { name: 'bar', nullValue: null }, ], ], - expectation: `INSERT INTO myTable (name,nullValue) VALUES ('foo',NULL),('bar',NULL);`, + expectation: { + query: + 'INSERT INTO myTable (name,nullValue) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: null, + sequelize_3: 'bar', + sequelize_4: null, + }, + }, context: { options: { quoteIdentifiers: false, omitNull: false } }, }, { @@ -776,7 +933,16 @@ if (dialect.startsWith('postgres')) { { name: 'bar', nullValue: null }, ], ], - expectation: `INSERT INTO myTable (name,nullValue) VALUES ('foo',NULL),('bar',NULL);`, + expectation: { + query: + 'INSERT INTO myTable (name,nullValue) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: null, + sequelize_3: 'bar', + sequelize_4: null, + }, + }, context: { options: { omitNull: true, quoteIdentifiers: false } }, // Note: We don't honour this because it makes little sense when some rows may have nulls and others not }, { @@ -787,7 +953,16 @@ if (dialect.startsWith('postgres')) { { name: 'bar', nullValue: undefined }, ], ], - expectation: `INSERT INTO myTable (name,nullValue) VALUES ('foo',NULL),('bar',NULL);`, + expectation: { + query: + 'INSERT INTO myTable (name,nullValue) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: null, + sequelize_3: 'bar', + sequelize_4: null, + }, + }, context: { options: { omitNull: true, quoteIdentifiers: false } }, // Note: As above }, { @@ -795,7 +970,13 @@ if (dialect.startsWith('postgres')) { { schema: 'mySchema', tableName: 'myTable' }, [{ name: 'foo' }, { name: 'bar' }], ], - expectation: `INSERT INTO mySchema.myTable (name) VALUES ('foo'),('bar');`, + expectation: { + query: 'INSERT INTO mySchema.myTable (name) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, context: { options: { quoteIdentifiers: false } }, }, { @@ -806,8 +987,13 @@ if (dialect.startsWith('postgres')) { { name: JSON.stringify({ info: 'Look ma another " quote' }) }, ], ], - expectation: - 'INSERT INTO mySchema.myTable (name) VALUES (\'{"info":"Look ma a \\" quote"}\'),(\'{"info":"Look ma another \\" quote"}\');', + expectation: { + query: 'INSERT INTO mySchema.myTable (name) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: '{"info":"Look ma a \\" quote"}', + sequelize_2: '{"info":"Look ma another \\" quote"}', + }, + }, context: { options: { quoteIdentifiers: false } }, }, { @@ -815,8 +1001,13 @@ if (dialect.startsWith('postgres')) { { schema: 'mySchema', tableName: 'myTable' }, [{ name: "foo';DROP TABLE mySchema.myTable;" }, { name: 'bar' }], ], - expectation: - "INSERT INTO mySchema.myTable (name) VALUES ('foo'';DROP TABLE mySchema.myTable;'),('bar');", + expectation: { + query: 'INSERT INTO mySchema.myTable (name) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: "foo';DROP TABLE mySchema.myTable;", + sequelize_2: 'bar', + }, + }, context: { options: { quoteIdentifiers: false } }, }, ], diff --git a/packages/core/test/unit/dialects/snowflake/query-generator.test.js b/packages/core/test/unit/dialects/snowflake/query-generator.test.js index 07ccd99f904d..d5f071564e8e 100644 --- a/packages/core/test/unit/dialects/snowflake/query-generator.test.js +++ b/packages/core/test/unit/dialects/snowflake/query-generator.test.js @@ -618,12 +618,23 @@ if (dialect === 'snowflake') { bulkInsertQuery: [ { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }]], - expectation: 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\');', + expectation: { + query: 'INSERT INTO "myTable" ("name") VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: ['myTable', [{ name: "foo';DROP TABLE myTable;" }, { name: 'bar' }]], - expectation: - "INSERT INTO \"myTable\" (\"name\") VALUES ('foo'';DROP TABLE myTable;'),('bar');", + expectation: { + query: 'INSERT INTO "myTable" ("name") VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: "foo';DROP TABLE myTable;", + sequelize_2: 'bar', + }, + }, }, { arguments: [ @@ -633,7 +644,16 @@ if (dialect === 'snowflake') { { name: 'bar', birthday: new Date(Date.UTC(2012, 2, 27, 10, 1, 55)) }, ], ], - expectation: `INSERT INTO "myTable" ("name","birthday") VALUES ('foo','2011-03-27 10:01:55.000'),('bar','2012-03-27 10:01:55.000');`, + expectation: { + query: + 'INSERT INTO "myTable" ("name","birthday") VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: '2011-03-27 10:01:55.000', + sequelize_3: 'bar', + sequelize_4: '2012-03-27 10:01:55.000', + }, + }, }, { arguments: [ @@ -643,7 +663,16 @@ if (dialect === 'snowflake') { { name: 'bar', foo: 2 }, ], ], - expectation: 'INSERT INTO "myTable" ("name","foo") VALUES (\'foo\',1),(\'bar\',2);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","foo") VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: 'bar', + sequelize_4: 2, + }, + }, }, { arguments: [ @@ -653,8 +682,18 @@ if (dialect === 'snowflake') { { name: 'bar', nullValue: null }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',NULL,NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: null, + sequelize_6: null, + }, + }, }, { arguments: [ @@ -664,8 +703,18 @@ if (dialect === 'snowflake') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',2,NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: false } }, }, { @@ -676,8 +725,18 @@ if (dialect === 'snowflake') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',2,NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: true } }, // Note: We don't honour this because it makes little sense when some rows may have nulls and others not }, { @@ -688,8 +747,20 @@ if (dialect === 'snowflake') { { name: 'bar', foo: 2, undefinedValue: undefined }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","foo","nullValue","undefinedValue") VALUES (\'foo\',1,NULL,NULL),(\'bar\',2,NULL,NULL);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","foo","nullValue","undefinedValue") VALUES ($sequelize_1,$sequelize_2,$sequelize_3,$sequelize_4),($sequelize_5,$sequelize_6,$sequelize_7,$sequelize_8);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: null, + sequelize_5: 'bar', + sequelize_6: 2, + sequelize_7: null, + sequelize_8: null, + }, + }, context: { options: { omitNull: true } }, // Note: As above }, { @@ -700,23 +771,49 @@ if (dialect === 'snowflake') { { name: 'bar', value: false }, ], ], - expectation: - 'INSERT INTO "myTable" ("name","value") VALUES (\'foo\',true),(\'bar\',false);', + expectation: { + query: + 'INSERT INTO "myTable" ("name","value") VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: true, + sequelize_3: 'bar', + sequelize_4: false, + }, + }, }, { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true }], - expectation: 'INSERT IGNORE INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\');', + expectation: { + query: 'INSERT IGNORE INTO "myTable" ("name") VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, // Variants when quoteIdentifiers is false { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }]], - expectation: "INSERT INTO myTable (name) VALUES ('foo'),('bar');", + expectation: { + query: 'INSERT INTO myTable (name) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, context: { options: { quoteIdentifiers: false } }, }, { arguments: ['myTable', [{ name: "foo';DROP TABLE myTable;" }, { name: 'bar' }]], - expectation: "INSERT INTO myTable (name) VALUES ('foo'';DROP TABLE myTable;'),('bar');", + expectation: { + query: 'INSERT INTO myTable (name) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: "foo';DROP TABLE myTable;", + sequelize_2: 'bar', + }, + }, context: { options: { quoteIdentifiers: false } }, }, { @@ -727,19 +824,36 @@ if (dialect === 'snowflake') { { name: 'bar', foo: 2 }, ], ], - expectation: "INSERT INTO myTable (name,foo) VALUES ('foo',1),('bar',2);", + expectation: { + query: + 'INSERT INTO myTable (name,foo) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: 'bar', + sequelize_4: 2, + }, + }, context: { options: { quoteIdentifiers: false } }, }, { arguments: [ 'myTable', [ - { name: 'foo', foo: 1, nullValue: null }, - { name: 'bar', nullValue: null }, + { name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55)) }, + { name: 'bar', birthday: new Date(Date.UTC(2012, 2, 27, 10, 1, 55)) }, ], ], - expectation: - "INSERT INTO myTable (name,foo,nullValue) VALUES ('foo',1,NULL),('bar',NULL,NULL);", + expectation: { + query: + 'INSERT INTO myTable (name,birthday) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: '2011-03-27 10:01:55.000', + sequelize_3: 'bar', + sequelize_4: '2012-03-27 10:01:55.000', + }, + }, context: { options: { quoteIdentifiers: false } }, }, { @@ -750,8 +864,18 @@ if (dialect === 'snowflake') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - "INSERT INTO myTable (name,foo,nullValue) VALUES ('foo',1,NULL),('bar',2,NULL);", + expectation: { + query: + 'INSERT INTO myTable (name,foo,nullValue) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: false, quoteIdentifiers: false } }, }, { @@ -762,8 +886,18 @@ if (dialect === 'snowflake') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - "INSERT INTO myTable (name,foo,nullValue) VALUES ('foo',1,NULL),('bar',2,NULL);", + expectation: { + query: + 'INSERT INTO myTable (name,foo,nullValue) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: true, quoteIdentifiers: false } }, // Note: We don't honour this because it makes little sense when some rows may have nulls and others not }, { @@ -774,8 +908,20 @@ if (dialect === 'snowflake') { { name: 'bar', foo: 2, undefinedValue: undefined }, ], ], - expectation: - "INSERT INTO myTable (name,foo,nullValue,undefinedValue) VALUES ('foo',1,NULL,NULL),('bar',2,NULL,NULL);", + expectation: { + query: + 'INSERT INTO myTable (name,foo,nullValue,undefinedValue) VALUES ($sequelize_1,$sequelize_2,$sequelize_3,$sequelize_4),($sequelize_5,$sequelize_6,$sequelize_7,$sequelize_8);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: null, + sequelize_5: 'bar', + sequelize_6: 2, + sequelize_7: null, + sequelize_8: null, + }, + }, context: { options: { omitNull: true, quoteIdentifiers: false } }, // Note: As above }, { @@ -786,12 +932,27 @@ if (dialect === 'snowflake') { { name: 'bar', value: false }, ], ], - expectation: "INSERT INTO myTable (name,value) VALUES ('foo',true),('bar',false);", + expectation: { + query: + 'INSERT INTO myTable (name,value) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: true, + sequelize_3: 'bar', + sequelize_4: false, + }, + }, context: { options: { quoteIdentifiers: false } }, }, { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true }], - expectation: "INSERT IGNORE INTO myTable (name) VALUES ('foo'),('bar');", + expectation: { + query: 'INSERT IGNORE INTO myTable (name) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, context: { options: { quoteIdentifiers: false } }, }, ], diff --git a/packages/core/test/unit/dialects/sqlite/query-generator.test.js b/packages/core/test/unit/dialects/sqlite/query-generator.test.js index 15ce27a5d27d..394657a8551d 100644 --- a/packages/core/test/unit/dialects/sqlite/query-generator.test.js +++ b/packages/core/test/unit/dialects/sqlite/query-generator.test.js @@ -294,11 +294,23 @@ if (dialect === 'sqlite') { bulkInsertQuery: [ { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }]], - expectation: "INSERT INTO `myTable` (`name`) VALUES ('foo'),('bar');", + expectation: { + query: 'INSERT INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: ['myTable', [{ name: "'bar'" }, { name: 'foo' }]], - expectation: "INSERT INTO `myTable` (`name`) VALUES ('''bar'''),('foo');", + expectation: { + query: 'INSERT INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: "'bar'", + sequelize_2: 'foo', + }, + }, }, { arguments: [ @@ -314,8 +326,16 @@ if (dialect === 'sqlite') { }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`birthday`) VALUES ('foo','2011-03-27 10:01:55.000 +00:00'),('bar','2012-03-27 10:01:55.000 +00:00');", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`birthday`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: '2011-03-27 10:01:55.000 +00:00', + sequelize_3: 'bar', + sequelize_4: '2012-03-27 10:01:55.000 +00:00', + }, + }, }, { arguments: [ @@ -325,7 +345,16 @@ if (dialect === 'sqlite') { { name: 'foo', value: 1 }, ], ], - expectation: "INSERT INTO `myTable` (`name`,`value`) VALUES ('bar',NULL),('foo',1);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`value`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'bar', + sequelize_2: null, + sequelize_3: 'foo', + sequelize_4: 1, + }, + }, }, { arguments: [ @@ -335,7 +364,16 @@ if (dialect === 'sqlite') { { name: 'bar', value: 2 }, ], ], - expectation: "INSERT INTO `myTable` (`name`,`value`) VALUES ('bar',NULL),('bar',2);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`value`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'bar', + sequelize_2: null, + sequelize_3: 'bar', + sequelize_4: 2, + }, + }, }, { arguments: [ @@ -345,7 +383,16 @@ if (dialect === 'sqlite') { { name: 'bar', value: false }, ], ], - expectation: "INSERT INTO `myTable` (`name`,`value`) VALUES ('foo',1),('bar',0);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`value`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: 'bar', + sequelize_4: 0, + }, + }, }, { arguments: [ @@ -355,7 +402,16 @@ if (dialect === 'sqlite') { { name: 'bar', value: false }, ], ], - expectation: "INSERT INTO `myTable` (`name`,`value`) VALUES ('foo',0),('bar',0);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`value`) VALUES ($sequelize_1,$sequelize_2),($sequelize_3,$sequelize_4);', + bind: { + sequelize_1: 'foo', + sequelize_2: 0, + sequelize_3: 'bar', + sequelize_4: 0, + }, + }, }, { arguments: [ @@ -365,8 +421,18 @@ if (dialect === 'sqlite') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL),('bar',2,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, }, { arguments: [ @@ -376,8 +442,18 @@ if (dialect === 'sqlite') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL),('bar',2,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: false } }, }, { @@ -388,8 +464,18 @@ if (dialect === 'sqlite') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL),('bar',2,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: true } }, // Note: We don't honour this because it makes little sense when some rows may have nulls and others not }, { @@ -400,13 +486,29 @@ if (dialect === 'sqlite') { { name: 'bar', foo: 2, nullValue: null }, ], ], - expectation: - "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL),('bar',2,NULL);", + expectation: { + query: + 'INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ($sequelize_1,$sequelize_2,$sequelize_3),($sequelize_4,$sequelize_5,$sequelize_6);', + bind: { + sequelize_1: 'foo', + sequelize_2: 1, + sequelize_3: null, + sequelize_4: 'bar', + sequelize_5: 2, + sequelize_6: null, + }, + }, context: { options: { omitNull: true } }, // Note: As above }, { arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true }], - expectation: "INSERT OR IGNORE INTO `myTable` (`name`) VALUES ('foo'),('bar');", + expectation: { + query: 'INSERT OR IGNORE INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2);', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, { arguments: [ @@ -414,8 +516,14 @@ if (dialect === 'sqlite') { [{ name: 'foo' }, { name: 'bar' }], { updateOnDuplicate: ['name'], upsertKeys: ['name'] }, ], - expectation: - "INSERT INTO `myTable` (`name`) VALUES ('foo'),('bar') ON CONFLICT (`name`) DO UPDATE SET `name`=EXCLUDED.`name`;", + expectation: { + query: + 'INSERT INTO `myTable` (`name`) VALUES ($sequelize_1),($sequelize_2) ON CONFLICT (`name`) DO UPDATE SET `name`=EXCLUDED.`name`;', + bind: { + sequelize_1: 'foo', + sequelize_2: 'bar', + }, + }, }, ], diff --git a/packages/core/test/unit/query-generator/bulk-insert-query.test.ts b/packages/core/test/unit/query-generator/bulk-insert-query.test.ts index 507e1a52ea11..483e9f67506f 100644 --- a/packages/core/test/unit/query-generator/bulk-insert-query.test.ts +++ b/packages/core/test/unit/query-generator/bulk-insert-query.test.ts @@ -19,7 +19,7 @@ describe('QueryGenerator#bulkInsertQuery', () => { it('parses named replacements in literals', async () => { const { User } = vars; - const sql = queryGenerator.bulkInsertQuery( + const { query } = queryGenerator.bulkInsertQuery( User.table, [ { @@ -33,7 +33,7 @@ describe('QueryGenerator#bulkInsertQuery', () => { }, ); - expectsql(sql, { + expectsql(query, { default: `INSERT INTO [Users] ([firstName]) VALUES ('a string');`, mssql: `INSERT INTO [Users] ([firstName]) VALUES (N'a string');`, // TODO: ibmi should be the same as `default`, since the 'returning' option is not specified diff --git a/packages/core/test/unit/query-interface/bulk-insert.test.ts b/packages/core/test/unit/query-interface/bulk-insert.test.ts index 44de78e6e412..7c78b4f75532 100644 --- a/packages/core/test/unit/query-interface/bulk-insert.test.ts +++ b/packages/core/test/unit/query-interface/bulk-insert.test.ts @@ -33,10 +33,13 @@ describe('QueryInterface#bulkInsert', () => { expectPerDialect(() => firstCall, { default: toMatchRegex( - /^INSERT INTO (?:`|")Users(?:`|") \((?:`|")firstName(?:`|")\) VALUES (?:\('\w+'\),){999}\('\w+'\);$/, + /^INSERT INTO (?:`|")Users(?:`|") \((?:`|")firstName(?:`|")\) VALUES (?:\(\$sequelize_\d+\),){999}\(\$sequelize_\d+\);$/, + ), + db2: toMatchRegex( + /^INSERT INTO "Users" \("firstName"\) VALUES (?:\('\w+'\),){999}\('\w+'\);$/, ), ibmi: toMatchRegex( - /^SELECT \* FROM FINAL TABLE \(INSERT INTO "Users" \("firstName"\) VALUES (?:\('\w+'\),){999}\('\w+'\)\)$/, + /^SELECT \* FROM FINAL TABLE \(INSERT INTO "Users" \("firstName"\) VALUES (?:\(\$sequelize_\d+\),){999}\(\$sequelize_\d+\)\)$/, ), mssql: toMatchRegex( /^INSERT INTO \[Users\] \(\[firstName\]\) VALUES (?:\(N'\w+'\),){999}\(N'\w+'\);$/, @@ -57,10 +60,13 @@ describe('QueryInterface#bulkInsert', () => { expectPerDialect(() => firstCall, { default: toMatchRegex( - /^INSERT INTO (?:`|")Users(?:`|") \((?:`|")firstName(?:`|")\) VALUES (?:\('\w+'\),){1999}\('\w+'\);$/, + /^INSERT INTO (?:`|")Users(?:`|") \((?:`|")firstName(?:`|")\) VALUES (?:\(\$sequelize_\d+\),){1999}\(\$sequelize_\d+\);$/, + ), + db2: toMatchRegex( + /^INSERT INTO "Users" \("firstName"\) VALUES (?:\('\w+'\),){1999}\('\w+'\);$/, ), ibmi: toMatchRegex( - /^SELECT \* FROM FINAL TABLE \(INSERT INTO "Users" \("firstName"\) VALUES (?:\('\w+'\),){1999}\('\w+'\)\)$/, + /^SELECT \* FROM FINAL TABLE \(INSERT INTO "Users" \("firstName"\) VALUES (?:\(\$sequelize_\d+\),){1999}\(\$sequelize_\d+\)\)$/, ), mssql: toMatchRegex( /^(?:INSERT INTO \[Users\] \(\[firstName\]\) VALUES (?:\(N'\w+'\),){999}\(N'\w+'\);){2}$/, @@ -88,18 +94,23 @@ describe('QueryInterface#bulkInsert', () => { ); expect(stub.callCount).to.eq(1); - const firstCall = stub.getCall(0).args[0]; + const firstCall = stub.getCall(0); - expectPerDialect(() => firstCall, { - default: toMatchSql('INSERT INTO "Users" ("firstName") VALUES (\':injection\');'), + expectPerDialect(() => firstCall.args[0], { + default: toMatchSql('INSERT INTO "Users" ("firstName") VALUES ($sequelize_1);'), 'mysql mariadb sqlite': toMatchSql( - "INSERT INTO `Users` (`firstName`) VALUES (':injection');", + 'INSERT INTO `Users` (`firstName`) VALUES ($sequelize_1);', ), + db2: toMatchSql(`INSERT INTO "Users" ("firstName") VALUES (':injection');`), mssql: toMatchSql(`INSERT INTO [Users] ([firstName]) VALUES (N':injection');`), // TODO: db2 should use the same system as ibmi ibmi: toMatchSql( - `SELECT * FROM FINAL TABLE (INSERT INTO "Users" ("firstName") VALUES (':injection'))`, + `SELECT * FROM FINAL TABLE (INSERT INTO "Users" ("firstName") VALUES ($sequelize_1))`, ), }); + expectPerDialect(() => firstCall.args[1]?.bind, { + default: { sequelize_1: ':injection' }, + 'db2 mssql': {}, + }); }); }); diff --git a/packages/core/test/unit/sql/insert.test.js b/packages/core/test/unit/sql/insert.test.js index f61d43606476..cf86ae2a7ec1 100644 --- a/packages/core/test/unit/sql/insert.test.js +++ b/packages/core/test/unit/sql/insert.test.js @@ -342,19 +342,19 @@ describe(Support.getTestDialectTeaser('SQL'), () => { ), { default: "INSERT INTO `users` (`user_name`,`pass_word`) VALUES ('testuser','12345');", - ibmi: 'SELECT * FROM FINAL TABLE (INSERT INTO "users" ("user_name","pass_word") VALUES (\'testuser\',\'12345\'))', + ibmi: 'SELECT * FROM FINAL TABLE (INSERT INTO "users" ("user_name","pass_word") VALUES ($sequelize_1,$sequelize_2))', snowflake: - 'INSERT INTO "users" ("user_name","pass_word") VALUES (\'testuser\',\'12345\');', + 'INSERT INTO "users" ("user_name","pass_word") VALUES ($sequelize_1,$sequelize_2);', postgres: - 'INSERT INTO "users" ("user_name","pass_word") VALUES (\'testuser\',\'12345\') ON CONFLICT ("user_name") DO UPDATE SET "user_name"=EXCLUDED."user_name","pass_word"=EXCLUDED."pass_word","updated_at"=EXCLUDED."updated_at";', + 'INSERT INTO "users" ("user_name","pass_word") VALUES ($sequelize_1,$sequelize_2) ON CONFLICT ("user_name") DO UPDATE SET "user_name"=EXCLUDED."user_name","pass_word"=EXCLUDED."pass_word","updated_at"=EXCLUDED."updated_at";', mssql: "INSERT INTO [users] ([user_name],[pass_word]) VALUES (N'testuser',N'12345');", db2: 'INSERT INTO "users" ("user_name","pass_word") VALUES (\'testuser\',\'12345\');', mariadb: - "INSERT INTO `users` (`user_name`,`pass_word`) VALUES ('testuser','12345') ON DUPLICATE KEY UPDATE `user_name`=VALUES(`user_name`),`pass_word`=VALUES(`pass_word`),`updated_at`=VALUES(`updated_at`);", + 'INSERT INTO `users` (`user_name`,`pass_word`) VALUES ($sequelize_1,$sequelize_2) ON DUPLICATE KEY UPDATE `user_name`=VALUES(`user_name`),`pass_word`=VALUES(`pass_word`),`updated_at`=VALUES(`updated_at`);', mysql: - "INSERT INTO `users` (`user_name`,`pass_word`) VALUES ('testuser','12345') ON DUPLICATE KEY UPDATE `user_name`=VALUES(`user_name`),`pass_word`=VALUES(`pass_word`),`updated_at`=VALUES(`updated_at`);", + 'INSERT INTO `users` (`user_name`,`pass_word`) VALUES ($sequelize_1,$sequelize_2) ON DUPLICATE KEY UPDATE `user_name`=VALUES(`user_name`),`pass_word`=VALUES(`pass_word`),`updated_at`=VALUES(`updated_at`);', sqlite: - "INSERT INTO `users` (`user_name`,`pass_word`) VALUES ('testuser','12345') ON CONFLICT (`user_name`) DO UPDATE SET `user_name`=EXCLUDED.`user_name`,`pass_word`=EXCLUDED.`pass_word`,`updated_at`=EXCLUDED.`updated_at`;", + 'INSERT INTO `users` (`user_name`,`pass_word`) VALUES ($sequelize_1,$sequelize_2) ON CONFLICT (`user_name`) DO UPDATE SET `user_name`=EXCLUDED.`user_name`,`pass_word`=EXCLUDED.`pass_word`,`updated_at`=EXCLUDED.`updated_at`;', }, ); }); @@ -377,8 +377,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { postgres: 'INSERT INTO "ms" ("id") VALUES (0),(DEFAULT);', db2: 'INSERT INTO "ms" VALUES (1);INSERT INTO "ms" ("id") VALUES (0),(NULL);', ibmi: 'SELECT * FROM FINAL TABLE (INSERT INTO "ms" ("id") VALUES (0),(DEFAULT))', - snowflake: 'INSERT INTO "ms" ("id") VALUES (0),(NULL);', - default: 'INSERT INTO `ms` (`id`) VALUES (0),(NULL);', + snowflake: 'INSERT INTO "ms" ("id") VALUES ($sequelize_1),($sequelize_2);', + default: 'INSERT INTO `ms` (`id`) VALUES ($sequelize_1),($sequelize_2);', }, }, ); @@ -441,7 +441,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { expectsql(result, { default: new Error(`conflictWhere not supported for dialect ${dialect.name}`), 'postgres sqlite': - "INSERT INTO [users] ([user_name],[pass_word]) VALUES ('testuser','12345') ON CONFLICT ([user_name]) WHERE [deleted_at] IS NULL DO UPDATE SET [user_name]=EXCLUDED.[user_name],[pass_word]=EXCLUDED.[pass_word],[updated_at]=EXCLUDED.[updated_at];", + 'INSERT INTO [users] ([user_name],[pass_word]) VALUES ($sequelize_1,$sequelize_2) ON CONFLICT ([user_name]) WHERE [deleted_at] IS NULL DO UPDATE SET [user_name]=EXCLUDED.[user_name],[pass_word]=EXCLUDED.[pass_word],[updated_at]=EXCLUDED.[updated_at];', }); }); }