diff --git a/.gitignore b/.gitignore index cef2286c5..1dbafa2bf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ raw .DS_Store .vagrant node_modules +package-lock.json test.sqlite3 npm-debug.log tmp diff --git a/src/dialects/mssql/schema/columncompiler.js b/src/dialects/mssql/schema/columncompiler.js index 25369abf0..4272f74e9 100644 --- a/src/dialects/mssql/schema/columncompiler.js +++ b/src/dialects/mssql/schema/columncompiler.js @@ -58,6 +58,8 @@ assign(ColumnCompiler_MSSQL.prototype, { longtext: 'nvarchar(max)', + // TODO: mssql supports check constraints as of SQL Server 2008 + // so make enu here more like postgres enu: 'nvarchar(100)', uuid: 'uniqueidentifier', diff --git a/src/dialects/postgres/query/compiler.js b/src/dialects/postgres/query/compiler.js index 00233aa60..5e75410cf 100644 --- a/src/dialects/postgres/query/compiler.js +++ b/src/dialects/postgres/query/compiler.js @@ -92,7 +92,7 @@ assign(QueryCompiler_PG.prototype, { sql += ' and table_schema = ?'; bindings.push(schema); } else { - sql += ' and table_schema = current_schema'; + sql += ' and table_schema = current_schema()'; } return { diff --git a/src/dialects/postgres/schema/compiler.js b/src/dialects/postgres/schema/compiler.js index cedb4b0b5..0b5b993f6 100644 --- a/src/dialects/postgres/schema/compiler.js +++ b/src/dialects/postgres/schema/compiler.js @@ -19,7 +19,7 @@ SchemaCompiler_PG.prototype.hasTable = function(tableName) { sql += ' and table_schema = ?'; bindings.push(this.schema); } else { - sql += ' and table_schema = current_schema'; + sql += ' and table_schema = current_schema()'; } this.pushQuery({ @@ -40,7 +40,7 @@ SchemaCompiler_PG.prototype.hasColumn = function(tableName, columnName) { sql += ' and table_schema = ?'; bindings.push(this.schema); } else { - sql += ' and table_schema = current_schema'; + sql += ' and table_schema = current_schema()'; } this.pushQuery({ diff --git a/src/dialects/redshift/index.js b/src/dialects/redshift/index.js new file mode 100644 index 000000000..0f2bd1935 --- /dev/null +++ b/src/dialects/redshift/index.js @@ -0,0 +1,74 @@ + +// Redshift +// ------- +import inherits from 'inherits'; +import Client_PG from '../postgres'; +import { assign, map, } from 'lodash' + +import Transaction from './transaction'; +import QueryCompiler from './query/compiler'; +import ColumnBuilder from './schema/columnbuilder'; +import ColumnCompiler from './schema/columncompiler'; +import TableCompiler from './schema/tablecompiler'; +import SchemaCompiler from './schema/compiler'; + +function Client_Redshift(config) { + Client_PG.apply(this, arguments) +} +inherits(Client_Redshift, Client_PG) + +assign(Client_Redshift.prototype, { + transaction() { + return new Transaction(this, ...arguments) + }, + + queryCompiler() { + return new QueryCompiler(this, ...arguments) + }, + + columnBuilder() { + return new ColumnBuilder(this, ...arguments); + }, + + columnCompiler() { + return new ColumnCompiler(this, ...arguments) + }, + + tableCompiler() { + return new TableCompiler(this, ...arguments) + }, + + schemaCompiler() { + return new SchemaCompiler(this, ...arguments) + }, + + dialect: 'redshift', + + driverName: 'pg-redshift', + + _driver() { + return require('pg') + }, + + // Ensures the response is returned in the same format as other clients. + processResponse(obj, runner) { + const resp = obj.response; + if (obj.output) return obj.output.call(runner, resp); + if (obj.method === 'raw') return resp; + if (resp.command === 'SELECT') { + if (obj.method === 'first') return resp.rows[0]; + if (obj.method === 'pluck') return map(resp.rows, obj.pluck); + return resp.rows; + } + if ( + resp.command === 'INSERT' || + resp.command === 'UPDATE' || + resp.command === 'DELETE' + ) { + return resp.rowCount; + } + return resp; + } +}) + +export default Client_Redshift; diff --git a/src/dialects/redshift/query/compiler.js b/src/dialects/redshift/query/compiler.js new file mode 100644 index 000000000..be1c2f5e3 --- /dev/null +++ b/src/dialects/redshift/query/compiler.js @@ -0,0 +1,101 @@ + +// Redshift Query Builder & Compiler +// ------ +import inherits from 'inherits'; + +import QueryCompiler from '../../../query/compiler'; +import QueryCompiler_PG from '../../postgres/query/compiler'; +import * as helpers from '../../../helpers'; + +import { assign, reduce } from 'lodash'; + +function QueryCompiler_Redshift(client, builder) { + QueryCompiler_PG.call(this, client, builder); +} +inherits(QueryCompiler_Redshift, QueryCompiler_PG); + +assign(QueryCompiler_Redshift.prototype, { + truncate() { + return `truncate ${this.tableName.toLowerCase()}`; + }, + + // Compiles an `insert` query, allowing for multiple + // inserts using a single query statement. + insert() { + const sql = QueryCompiler.prototype.insert.apply(this, arguments); + if (sql === '') return sql; + this._slightReturn(); + return { + sql, + }; + }, + + // Compiles an `update` query, warning on unsupported returning + update() { + const sql = QueryCompiler.prototype.update.apply(this, arguments); + this._slightReturn(); + return { + sql, + }; + }, + + // Compiles an `delete` query, warning on unsupported returning + del() { + const sql = QueryCompiler.prototype.del.apply(this, arguments); + this._slightReturn(); + return { + sql, + }; + }, + + // simple: if trying to return, warn + _slightReturn(){ + if (this.single.isReturning) { + helpers.warn('insert/update/delete returning is not supported by redshift dialect'); + } + }, + + forUpdate() { + helpers.warn('table lock is not supported by redshift dialect'); + return ''; + }, + + forShare() { + helpers.warn('lock for share is not supported by redshift dialect'); + return ''; + }, + + // Compiles a columnInfo query + columnInfo() { + const column = this.single.columnInfo; + + let sql = 'select * from information_schema.columns where table_name = ? and table_catalog = ?'; + const bindings = [this.single.table.toLowerCase(), this.client.database().toLowerCase()]; + + if (this.single.schema) { + sql += ' and table_schema = ?'; + bindings.push(this.single.schema); + } else { + sql += ' and table_schema = current_schema()'; + } + + return { + sql, + bindings, + output(resp) { + const out = reduce(resp.rows, function(columns, val) { + columns[val.column_name] = { + type: val.data_type, + maxLength: val.character_maximum_length, + nullable: (val.is_nullable === 'YES'), + defaultValue: val.column_default + }; + return columns; + }, {}); + return column && out[column] || out; + } + }; + } +}) + +export default QueryCompiler_Redshift; diff --git a/src/dialects/redshift/schema/columnbuilder.js b/src/dialects/redshift/schema/columnbuilder.js new file mode 100644 index 000000000..a5869e364 --- /dev/null +++ b/src/dialects/redshift/schema/columnbuilder.js @@ -0,0 +1,23 @@ +"use strict"; + +import inherits from 'inherits'; +import { warn } from '../../../helpers'; +import ColumnBuilder from '../../../schema/columnbuilder'; + +function ColumnBuilder_Redshift() { + ColumnBuilder.apply(this, arguments); +} +inherits(ColumnBuilder_Redshift, ColumnBuilder); + +// primary needs to set not null on non-preexisting columns, or fail +ColumnBuilder_Redshift.prototype.primary = function () { + this.notNullable(); + return ColumnBuilder.prototype.primary.apply(this, arguments); +}; + +ColumnBuilder_Redshift.prototype.index = function () { + warn('Redshift does not support the creation of indexes.'); + return this; +} + +export default ColumnBuilder_Redshift; diff --git a/src/dialects/redshift/schema/columncompiler.js b/src/dialects/redshift/schema/columncompiler.js new file mode 100644 index 000000000..b8e579471 --- /dev/null +++ b/src/dialects/redshift/schema/columncompiler.js @@ -0,0 +1,59 @@ + +// Redshift Column Compiler +// ------- + +import inherits from 'inherits'; +import ColumnCompiler_PG from '../../postgres/schema/columncompiler'; + +import { assign } from 'lodash' + +function ColumnCompiler_Redshift() { + ColumnCompiler_PG.apply(this, arguments); +} +inherits(ColumnCompiler_Redshift, ColumnCompiler_PG); + +assign(ColumnCompiler_Redshift.prototype, { + // Types: + // ------ + bigincrements: 'bigint identity(1,1) primary key not null', + binary: 'varchar(max)', + bit(column) { + return column.length !== false ? `char(${column.length})` : 'char(1)'; + }, + blob: 'varchar(max)', + enu: 'varchar(255)', + enum: 'varchar(255)', + increments: 'integer identity(1,1) primary key not null', + json: 'varchar(max)', + jsonb: 'varchar(max)', + longblob: 'varchar(max)', + mediumblob: 'varchar(16777218)', + set: 'text', + text: 'varchar(max)', + datetime(without) { + return without ? 'timestamp' : 'timestamptz'; + }, + timestamp(without) { + return without ? 'timestamp' : 'timestamptz'; + }, + tinyblob: 'varchar(256)', + uuid: 'char(36)', + varbinary: 'varchar(max)', + bigint: 'bigint', + bool: 'boolean', + double: 'double precision', + floating: 'real', + smallint: 'smallint', + tinyint: 'smallint', + + // Modifiers: + // ------ + comment(comment) { + this.pushAdditional(function() { + this.pushQuery(`comment on column ${this.tableCompiler.tableName()}.` + + this.formatter.wrap(this.args[0]) + " is " + (comment ? `'${comment}'` : 'NULL')); + }, comment); + } +}) + +export default ColumnCompiler_Redshift; \ No newline at end of file diff --git a/src/dialects/redshift/schema/compiler.js b/src/dialects/redshift/schema/compiler.js new file mode 100644 index 000000000..ece26c77e --- /dev/null +++ b/src/dialects/redshift/schema/compiler.js @@ -0,0 +1,14 @@ +/* eslint max-len: 0 */ + +// Redshift Table Builder & Compiler +// ------- + +import inherits from 'inherits'; +import SchemaCompiler_PG from '../../postgres/schema/compiler'; + +function SchemaCompiler_Redshift() { + SchemaCompiler_PG.apply(this, arguments); +} +inherits(SchemaCompiler_Redshift, SchemaCompiler_PG); + +export default SchemaCompiler_Redshift; diff --git a/src/dialects/redshift/schema/tablecompiler.js b/src/dialects/redshift/schema/tablecompiler.js new file mode 100644 index 000000000..4c5a99750 --- /dev/null +++ b/src/dialects/redshift/schema/tablecompiler.js @@ -0,0 +1,73 @@ +/* eslint max-len: 0 */ + +// Redshift Table Builder & Compiler +// ------- + +import { warn } from '../../../helpers'; +import inherits from 'inherits'; +import { has } from 'lodash'; +import TableCompiler_PG from '../../postgres/schema/tablecompiler'; + +function TableCompiler_Redshift() { + TableCompiler_PG.apply(this, arguments); +} +inherits(TableCompiler_Redshift, TableCompiler_PG); + +TableCompiler_Redshift.prototype.index = function(columns, indexName, indexType) { + warn('Redshift does not support the creation of indexes.'); +}; + +TableCompiler_Redshift.prototype.dropIndex = function(columns, indexName) { + warn('Redshift does not support the deletion of indexes.'); +}; + +// TODO: have to disable setting not null on columns that already exist... + +// Adds the "create" query to the query sequence. +TableCompiler_Redshift.prototype.createQuery = function(columns, ifNot) { + const createStatement = ifNot ? 'create table if not exists ' : 'create table '; + let sql = createStatement + this.tableName() + ' (' + columns.sql.join(', ') + ')'; + if (this.single.inherits) sql += ` like (${this.formatter.wrap(this.single.inherits)})`; + this.pushQuery({ + sql, + bindings: columns.bindings + }); + const hasComment = has(this.single, 'comment'); + if (hasComment) this.comment(this.single.comment); +}; + +TableCompiler_Redshift.prototype.primary = function(columns, constraintName) { + const self = this; + constraintName = constraintName ? self.formatter.wrap(constraintName) : self.formatter.wrap(`${this.tableNameRaw}_pkey`); + if (columns.constructor !== Array){ + columns = [columns]; + } + const thiscolumns = self.grouped.columns; + + if (thiscolumns) { + for (let i = 0; i < columns.length; i++){ + let exists = thiscolumns.find(tcb => tcb.grouping === "columns" && + tcb.builder && + tcb.builder._method === "add" && + tcb.builder._args && + tcb.builder._args.indexOf(columns[i]) > -1); + if (exists) { + exists = exists.builder; + } + const nullable = !(exists && + exists._modifiers && + exists._modifiers["nullable"] && + exists._modifiers["nullable"][0] === false); + if (nullable){ + if (exists){ + return warn("Redshift does not allow primary keys to contain nullable columns."); + } else { + return warn("Redshift does not allow primary keys to contain nonexistent columns."); + } + } + } + } + return self.pushQuery(`alter table ${self.tableName()} add constraint ${constraintName} primary key (${self.formatter.columnize(columns)})`); +}; + +export default TableCompiler_Redshift; diff --git a/src/dialects/redshift/transaction.js b/src/dialects/redshift/transaction.js new file mode 100644 index 000000000..1a8bacc43 --- /dev/null +++ b/src/dialects/redshift/transaction.js @@ -0,0 +1,21 @@ + +import Promise from 'bluebird'; +import { warn } from '../../helpers'; +import Transaction from '../../transaction'; + +export default class Redshift_Transaction extends Transaction { + savepoint(conn) { + warn('Redshift does not support savepoints.'); + return Promise.resolve() + } + + release(conn, value) { + warn('Redshift does not support savepoints.'); + return Promise.resolve() + } + + rollbackTo(conn, error) { + warn('Redshift does not support savepoints.'); + return Promise.resolve() + } +} diff --git a/src/raw.js b/src/raw.js index ad4789547..bf381ef72 100644 --- a/src/raw.js +++ b/src/raw.js @@ -147,7 +147,6 @@ function replaceRawArrBindings(raw, formatter) { function replaceKeyBindings(raw, formatter) { const values = raw.bindings - let { sql } = raw const regex = /\\?(:(\w+):(?=::)|:(\w+):(?!:)|:(\w+))/g diff --git a/test/index.js b/test/index.js index 1f0dd05f1..dec5ae100 100644 --- a/test/index.js +++ b/test/index.js @@ -25,6 +25,7 @@ describe('Query Building Tests', function() { require('./unit/schema/mysql')('maria') require('./unit/schema/mysql')('mysql2') require('./unit/schema/postgres') + require('./unit/schema/redshift') require('./unit/schema/sqlite3') require('./unit/schema/oracle') require('./unit/schema/mssql') diff --git a/test/integration/builder/additional.js b/test/integration/builder/additional.js index 6c859a472..e4dce259f 100644 --- a/test/integration/builder/additional.js +++ b/test/integration/builder/additional.js @@ -159,6 +159,7 @@ module.exports = function(knex) { .testSql(function(tester) { tester('mysql', 'truncate `test_table_two`'); tester('postgresql', 'truncate "test_table_two" restart identity'); + tester('pg-redshift', 'truncate "test_table_two"'); tester('sqlite3', "delete from `test_table_two`"); tester('oracle', "truncate table \"test_table_two\""); tester('mssql', 'truncate table [test_table_two]'); @@ -195,6 +196,7 @@ module.exports = function(knex) { mysql2: 'SHOW TABLES', mariadb: 'SHOW TABLES', postgresql: "SELECT table_name FROM information_schema.tables WHERE table_schema='public'", + redshift: "SELECT table_name FROM information_schema.tables WHERE table_schema='public'", sqlite3: "SELECT name FROM sqlite_master WHERE type='table';", oracle: "select TABLE_NAME from USER_TABLES", mssql: "SELECT table_name FROM information_schema.tables WHERE table_schema='dbo'" @@ -246,6 +248,21 @@ module.exports = function(knex) { "type": "uuid" } }); + tester('pg-redshift', 'select * from information_schema.columns where table_name = ? and table_catalog = ? and table_schema = current_schema()', + null, { + "enum_value": { + "defaultValue": null, + "maxLength": 255, + "nullable": true, + "type": "character varying" + }, + "uuid": { + "defaultValue": null, + "maxLength": 36, + "nullable": false, + "type": "character" + } + }); tester('sqlite3', 'PRAGMA table_info(\`datatype_test\`)', [], { "enum_value": { "defaultValue": null, @@ -313,6 +330,13 @@ module.exports = function(knex) { "nullable": false, "type": "uuid" }); + tester('pg-redshift', 'select * from information_schema.columns where table_name = ? and table_catalog = ? and table_schema = current_schema()', + null, { + "defaultValue": null, + "maxLength": 36, + "nullable": false, + "type": "character" + }); tester('sqlite3', 'PRAGMA table_info(\`datatype_test\`)', [], { "defaultValue": null, "maxLength": "36", @@ -386,6 +410,7 @@ module.exports = function(knex) { }).testSql(function(tester) { tester('mysql', ["show fields from `accounts` where field = ?"]); tester('postgresql', ["alter table \"accounts\" rename \"about\" to \"about_col\""]); + tester('pg-redshift', ["alter table \"accounts\" rename \"about\" to \"about_col\""]); tester('sqlite3', ["PRAGMA table_info(`accounts`)"]); tester('oracle', ["alter table \"accounts\" rename column \"about\" to \"about_col\""]); tester('mssql', ["exec sp_rename ?, ?, 'COLUMN'"]); @@ -423,6 +448,7 @@ module.exports = function(knex) { }).testSql(function(tester) { tester('mysql', ["alter table `accounts` drop `first_name`"]); tester('postgresql', ['alter table "accounts" drop column "first_name"']); + tester('pg-redshift', ['alter table "accounts" drop column "first_name"']); tester('sqlite3', ["PRAGMA table_info(`accounts`)"]); tester('oracle', ['alter table "accounts" drop ("first_name")']); //tester('oracledb', ['alter table "accounts" drop ("first_name")']); @@ -443,6 +469,7 @@ module.exports = function(knex) { it('.timeout() should throw TimeoutError', function() { var dialect = knex.client.dialect; if(dialect === 'sqlite3') { return; } //TODO -- No built-in support for sleeps + if (/redshift/.test(dialect)) { return; } var testQueries = { 'postgresql': function() { return knex.raw('SELECT pg_sleep(1)'); @@ -487,6 +514,7 @@ module.exports = function(knex) { it('.timeout(ms, {cancel: true}) should throw TimeoutError and cancel slow query', function() { var dialect = knex.client.dialect; if(dialect === 'sqlite3') { return; } //TODO -- No built-in support for sleeps + if (/redshift/.test(dialect)) { return; } // There's unexpected behavior caused by knex releasing a connection back // to the pool because of a timeout when a long query is still running. diff --git a/test/integration/builder/aggregate.js b/test/integration/builder/aggregate.js index 524d696d4..f4b14115f 100644 --- a/test/integration/builder/aggregate.js +++ b/test/integration/builder/aggregate.js @@ -33,6 +33,14 @@ module.exports = function(knex) { sum: '10' }] ); + tester( + 'pg-redshift', + 'select sum("logins") from "accounts"', + [], + [{ + sum: '10' + }] + ); tester( 'sqlite3', 'select sum(`logins`) from `accounts`', @@ -67,7 +75,7 @@ module.exports = function(knex) { function checkResRange(key, resp) { return Math.abs(10/6 - +(resp[0][key])) < 0.001; } - function checkResRangeMssql(key, resp) { + function checkResRangeMssql(key, resp) { return +(resp[0][key]) === 1; } @@ -77,6 +85,8 @@ module.exports = function(knex) { tester('sqlite3', 'select avg(`logins`) from `accounts`', [], checkResRange.bind(null, 'avg(`logins`)')); // postgres: '1.6666666666666667' tester('postgresql', 'select avg("logins") from "accounts"', [], checkResRange.bind(null, 'avg')); + // postgres: '1.6666666666666667' + tester('pg-redshift', 'select avg("logins") from "accounts"', [], checkResRangeMssql.bind(null, 'avg')); // oracle: 1.66666666666667 tester('oracle', 'select avg("logins") from "accounts"', [], checkResRange.bind(null, 'AVG("LOGINS")')); // mssql: 1 @@ -104,6 +114,14 @@ module.exports = function(knex) { count: '6' }] ); + tester( + 'pg-redshift', + 'select count("id") from "accounts"', + [], + [{ + count: '6' + }] + ); tester( 'sqlite3', 'select count(`id`) from `accounts`', @@ -155,6 +173,16 @@ module.exports = function(knex) { min: 1 }] ); + tester( + 'pg-redshift', + 'select count("id"), max("logins"), min("logins") from "accounts"', + [], + [{ + count: '6', + max: 2, + min: 1 + }] + ); tester( 'sqlite3', 'select count(`id`), max(`logins`), min(`logins`) from `accounts`', @@ -210,6 +238,16 @@ module.exports = function(knex) { avg: 1.5 }] ); + tester( + 'pg-redshift', + 'select count(distinct "id"), sum(distinct "logins"), avg(distinct "logins") from "accounts"', + [], + [{ + count: '6', + sum: '3', + avg: '1' + }] + ); tester( 'sqlite3', 'select count(distinct `id`), sum(distinct `logins`), avg(distinct `logins`) from `accounts`', @@ -244,10 +282,10 @@ module.exports = function(knex) { it("support the groupBy function", function() { - return knex('accounts').count('id').groupBy('logins').testSql(function(tester) { + return knex('accounts').count('id').groupBy('logins').orderBy('logins', 'asc').testSql(function(tester) { tester( 'mysql', - 'select count(`id`) from `accounts` group by `logins`', + 'select count(`id`) from `accounts` group by `logins` order by `logins` asc', [], [{ 'count(`id`)': 2 @@ -257,7 +295,17 @@ module.exports = function(knex) { ); tester( 'postgresql', - 'select count("id") from "accounts" group by "logins"', + 'select count("id") from "accounts" group by "logins" order by "logins" asc', + [], + [{ + count: '2' + },{ + count: '4' + }] + ); + tester( + 'pg-redshift', + 'select count("id") from "accounts" group by "logins" order by "logins" asc', [], [{ count: '2' @@ -267,7 +315,7 @@ module.exports = function(knex) { ); tester( 'sqlite3', - 'select count(`id`) from `accounts` group by `logins`', + 'select count(`id`) from `accounts` group by `logins` order by `logins` asc', [], [{ 'count(`id`)': 2 @@ -277,7 +325,7 @@ module.exports = function(knex) { ); tester( 'oracle', - 'select count("id") from "accounts" group by "logins"', + 'select count("id") from "accounts" group by "logins" order by "logins" asc', [], [{ 'COUNT("ID")': 2 @@ -287,7 +335,7 @@ module.exports = function(knex) { ); tester( 'mssql', - 'select count([id]) from [accounts] group by [logins]', + 'select count([id]) from [accounts] group by [logins] order by [logins] asc', [], [{ '': 2 @@ -314,6 +362,14 @@ module.exports = function(knex) { count: '6' }] ); + tester( + 'pg-redshift', + 'select count("id") from "accounts" group by "first_name"', + [], + [{ + count: '6' + }] + ); tester( 'sqlite3', 'select count(`id`) from `accounts` group by `first_name`', diff --git a/test/integration/builder/deletes.js b/test/integration/builder/deletes.js index f5b6a3c71..9b0530f8f 100644 --- a/test/integration/builder/deletes.js +++ b/test/integration/builder/deletes.js @@ -23,6 +23,12 @@ module.exports = function(knex) { [1], 1 ); + tester( + 'pg-redshift', + 'delete from "accounts" where "id" = ?', + [1], + 1 + ); tester( 'sqlite3', 'delete from `accounts` where `id` = ?', @@ -71,6 +77,12 @@ module.exports = function(knex) { phone: null }] ); + tester( + 'pg-redshift', + 'delete from "accounts" where "id" = ?', + [2], + 1 + ); tester( 'sqlite3', 'delete from `accounts` where `id` = ?', diff --git a/test/integration/builder/inserts.js b/test/integration/builder/inserts.js index 30c9e1024..1316f84bc 100644 --- a/test/integration/builder/inserts.js +++ b/test/integration/builder/inserts.js @@ -1,4 +1,4 @@ -/*global describe, expect, it, d*/ +/*global before, describe, expect, it, d*/ 'use strict'; @@ -33,6 +33,12 @@ module.exports = function(knex) { ['Lorem ipsum Dolore labore incididunt enim.', d,'test@example.com','Test','User', 1, d], ['1'] ); + tester( + 'pg-redshift', + 'insert into "accounts" ("about", "created_at", "email", "first_name", "last_name", "logins", "updated_at") values (?, ?, ?, ?, ?, ?, ?)', + ['Lorem ipsum Dolore labore incididunt enim.', d,'test@example.com','Test','User', 1, d], + 1 + ); tester( 'sqlite3', 'insert into `accounts` (`about`, `created_at`, `email`, `first_name`, `last_name`, `logins`, `updated_at`) values (?, ?, ?, ?, ?, ?, ?)', @@ -86,6 +92,12 @@ module.exports = function(knex) { ['Lorem ipsum Dolore labore incididunt enim.', d,'test2@example.com','Test','User',1, d,'Lorem ipsum Dolore labore incididunt enim.', d,'test3@example.com','Test','User',2, d], ['2','3'] ); + tester( + 'pg-redshift', + 'insert into "accounts" ("about", "created_at", "email", "first_name", "last_name", "logins", "updated_at") values (?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?)', + ['Lorem ipsum Dolore labore incididunt enim.', d,'test2@example.com','Test','User',1, d,'Lorem ipsum Dolore labore incididunt enim.', d,'test3@example.com','Test','User',2, d], + 2 + ); tester( 'sqlite3', 'insert into `accounts` (`about`, `created_at`, `email`, `first_name`, `last_name`, `logins`, `updated_at`) select ? as `about`, ? as `created_at`, ? as `email`, ? as `first_name`, ? as `last_name`, ? as `logins`, ? as `updated_at` union all select ? as `about`, ? as `created_at`, ? as `email`, ? as `first_name`, ? as `last_name`, ? as `logins`, ? as `updated_at`', @@ -125,25 +137,25 @@ module.exports = function(knex) { status: 1 }], 'id') .testSql(function(tester) { - tester( - 'oracle', - "begin execute immediate 'insert into \"test_table_two\" (\"account_id\", \"details\", \"status\") values (:1, :2, :3) returning ROWID into :4' using ?, ?, ?, out ?; execute immediate 'insert into \"test_table_two\" (\"account_id\", \"details\", \"status\") values (:1, :2, :3) returning ROWID into :4' using ?, ?, ?, out ?; execute immediate 'insert into \"test_table_two\" (\"account_id\", \"details\", \"status\") values (:1, :2, :3) returning ROWID into :4' using ?, ?, ?, out ?;end;", - [ - 1, - 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', - 0, - function (v) {return v.toString() === '[object ReturningHelper:id]';}, - 2, - 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', - 1, - function (v) {return v.toString() === '[object ReturningHelper:id]';}, - 3, - '', - 1, - function (v) {return v.toString() === '[object ReturningHelper:id]';} - ], - [1, 2, 3] - ); + tester( + 'oracle', + "begin execute immediate 'insert into \"test_table_two\" (\"account_id\", \"details\", \"status\") values (:1, :2, :3) returning ROWID into :4' using ?, ?, ?, out ?; execute immediate 'insert into \"test_table_two\" (\"account_id\", \"details\", \"status\") values (:1, :2, :3) returning ROWID into :4' using ?, ?, ?, out ?; execute immediate 'insert into \"test_table_two\" (\"account_id\", \"details\", \"status\") values (:1, :2, :3) returning ROWID into :4' using ?, ?, ?, out ?;end;", + [ + 1, + 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', + 0, + function (v) {return v.toString() === '[object ReturningHelper:id]';}, + 2, + 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', + 1, + function (v) {return v.toString() === '[object ReturningHelper:id]';}, + 3, + '', + 1, + function (v) {return v.toString() === '[object ReturningHelper:id]';} + ], + [1, 2, 3] + ); }).asCallback(function(err) { if (err) return ok(err); ok(); @@ -182,6 +194,12 @@ module.exports = function(knex) { ['Lorem ipsum Dolore labore incididunt enim.', d,'test4@example.com','Test','User',2, d,'Lorem ipsum Dolore labore incididunt enim.', d,'test5@example.com','Test','User',2, d], ['4','5'] ); + tester( + 'pg-redshift', + 'insert into "accounts" ("about", "created_at", "email", "first_name", "last_name", "logins", "updated_at") values (?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?)', + ['Lorem ipsum Dolore labore incididunt enim.', d,'test4@example.com','Test','User',2, d,'Lorem ipsum Dolore labore incididunt enim.', d,'test5@example.com','Test','User',2, d], + 2 + ); tester( 'sqlite3', 'insert into `accounts` (`about`, `created_at`, `email`, `first_name`, `last_name`, `logins`, `updated_at`) select ? as `about`, ? as `created_at`, ? as `email`, ? as `first_name`, ? as `last_name`, ? as `logins`, ? as `updated_at` union all select ? as `about`, ? as `created_at`, ? as `email`, ? as `first_name`, ? as `last_name`, ? as `logins`, ? as `updated_at`', @@ -222,7 +240,7 @@ module.exports = function(knex) { }); it('will fail when multiple inserts are made into a unique column', function() { - + if(/redshift/i.test(knex.client.dialect)) { return; } return knex('accounts') .where('id', '>', 1) .orWhere('x', 2) @@ -294,6 +312,12 @@ module.exports = function(knex) { ['Lorem ipsum Dolore labore incididunt enim.', d, 'test6@example.com','Test','User',2, d], ['7'] ); + tester( + 'pg-redshift', + 'insert into "accounts" ("about", "created_at", "email", "first_name", "last_name", "logins", "updated_at") values (?, ?, ?, ?, ?, ?, ?)', + ['Lorem ipsum Dolore labore incididunt enim.', d, 'test6@example.com','Test','User',2, d], + 1 + ); tester( 'sqlite3', 'insert into `accounts` (`about`, `created_at`, `email`, `first_name`, `last_name`, `logins`, `updated_at`) values (?, ?, ?, ?, ?, ?, ?)', @@ -331,6 +355,11 @@ module.exports = function(knex) { 'insert into "datatype_test" ("enum_value") values (?)', ['d'] ); + tester( + 'pg-redshift', + 'insert into "datatype_test" ("enum_value") values (?)', + ['d'] + ); tester( 'sqlite3', 'insert into `datatype_test` (`enum_value`) values (?)', @@ -411,6 +440,12 @@ module.exports = function(knex) { [], [1] ); + tester( + 'pg-redshift', + 'insert into "test_default_table" default values', + [], + 1 + ); tester( 'sqlite3', 'insert into `test_default_table` default values', @@ -456,6 +491,12 @@ module.exports = function(knex) { [], [1] ); + tester( + 'pg-redshift', + 'insert into "test_default_table2" default values', + [], + 1 + ); tester( 'sqlite3', 'insert into `test_default_table2` default values', @@ -500,10 +541,16 @@ module.exports = function(knex) { // [1] // ); // tester( - // 'postgresql', - // 'insert into "test_default_table3" ("id") values (default), (default) returning "id"', + // 'postgresql', + // 'insert into "test_default_table3" ("id") values (default), (default) returning "id"', + // [], + // [1, 2] + // ); + // tester( + // 'pg-redshift', + // 'insert into "test_default_table3" ("id") values (default), (default)', // [], - // [1, 2] + // [1, 2] // ); // tester( // 'oracle', @@ -542,10 +589,13 @@ module.exports = function(knex) { 'postgresql', 'insert into "test_table_two" ("account_id", "details", "status") values (?, ?, ?) returning "account_id", "details"', [10,'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.',0], - [{ - account_id: 10, - details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' - }] + [{account_id: 10, details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.'}] + ); + tester( + 'pg-redshift', + 'insert into "test_table_two" ("account_id", "details", "status") values (?, ?, ?)', + [10,'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.',0], + 1 ); tester( 'sqlite3', @@ -556,27 +606,21 @@ module.exports = function(knex) { tester( 'oracle', "insert into \"test_table_two\" (\"account_id\", \"details\", \"status\") values (?, ?, ?) returning ROWID into ?", - [ - 10, - 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', - 0, + [10, 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', 0, function (v) {return v.toString() === '[object ReturningHelper:account_id:details]';} ], - [{ - account_id: 10, - details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' - }] + [{account_id: 10, details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.'}] ); tester( 'mssql', 'insert into [test_table_two] ([account_id], [details], [status]) output inserted.[account_id], inserted.[details] values (?, ?, ?)', [10,'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.',0], - [{ - account_id: 10, - details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' - }] + [{account_id: 10, details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.'}] ); }).then(function(rows) { + if (/redshift/.test(knex.client.dialect)){ + return expect(rows).to.equal(1); + } expect(rows.length).to.equal(1); if (knex.client.dialect === 'postgresql') { expect(_.keys(rows[0]).length).to.equal(2); @@ -587,6 +631,7 @@ module.exports = function(knex) { }); it('should allow a * for returning in postgres and oracle', function() { + if(/redshift/i.test(knex.client.dialect)) { return; } var insertData = { account_id: 10, details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', @@ -675,6 +720,7 @@ module.exports = function(knex) { }); it('#757 - knex.batchInsert(tableName, bulk, chunkSize)', function() { + this.timeout(30000); return knex.batchInsert('BatchInsert', items, 30) .returning(['Col1', 'Col2']) .then(function (result) { @@ -694,6 +740,7 @@ module.exports = function(knex) { }); it('#1880 - Duplicate keys in batchInsert should not throw unhandled exception', function() { + if(/redshift/i.test(knex.client.dialect)) { return; } return new Promise(function(resolve, reject) { return knex.schema.dropTableIfExists('batchInsertDuplicateKey') .then(function() { @@ -779,7 +826,7 @@ module.exports = function(knex) { logins: 2, created_at: new Date(), updated_at: new Date() - }]) + }], '*') .then(function () { return knex('accounts').whereIn('email', [ 'single-test1@example.com', diff --git a/test/integration/builder/joins.js b/test/integration/builder/joins.js index 40e0cad53..0e88ed699 100644 --- a/test/integration/builder/joins.js +++ b/test/integration/builder/joins.js @@ -49,42 +49,89 @@ module.exports = function(knex) { details: '' }] ); - tester( - 'postgresql', - 'select "accounts".*, "test_table_two"."details" from "accounts" inner join "test_table_two" on "accounts"."id" = "test_table_two"."account_id" order by "accounts"."id" asc', [], [{ - id: '1', - first_name: 'Test', - last_name: 'User', - email: 'test@example.com', - logins: 1, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' - }, { - id: '2', - first_name: 'Test', - last_name: 'User', - email: 'test2@example.com', - logins: 1, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' - }, { - id: '3', - first_name: 'Test', - last_name: 'User', - email: 'test3@example.com', - logins: 2, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - details: '' - }] + tester('postgresql', + 'select "accounts".*, "test_table_two"."details" from "accounts" inner join "test_table_two" on "accounts"."id" = "test_table_two"."account_id" order by "accounts"."id" asc', + [], + [ + { + id: '1', + first_name: 'Test', + last_name: 'User', + email: 'test@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' + }, + { + id: '2', + first_name: 'Test', + last_name: 'User', + email: 'test2@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' + }, + { + id: '3', + first_name: 'Test', + last_name: 'User', + email: 'test3@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: '' + } + ] + ); + tester('pg-redshift', + 'select "accounts".*, "test_table_two"."details" from "accounts" inner join "test_table_two" on "accounts"."id" = "test_table_two"."account_id" order by "accounts"."id" asc', + [], + [ + { + id: '1', + first_name: 'Test', + last_name: 'User', + email: 'test@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' + }, + { + id: '2', + first_name: 'Test', + last_name: 'User', + email: 'test2@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' + }, + { + id: '3', + first_name: 'Test', + last_name: 'User', + email: 'test3@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: '' + } + ] ); tester( 'sqlite3', @@ -277,75 +324,161 @@ module.exports = function(knex) { details: null }] ); - tester( - 'postgresql', - 'select "accounts".*, "test_table_two"."details" from "accounts" left join "test_table_two" on "accounts"."id" = "test_table_two"."account_id" order by "accounts"."id" asc', [], [{ - id: '1', - first_name: 'Test', - last_name: 'User', - email: 'test@example.com', - logins: 1, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' - }, { - id: '2', - first_name: 'Test', - last_name: 'User', - email: 'test2@example.com', - logins: 1, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' - }, { - id: '3', - first_name: 'Test', - last_name: 'User', - email: 'test3@example.com', - logins: 2, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - details: '' - }, { - id: '4', - first_name: 'Test', - last_name: 'User', - email: 'test4@example.com', - logins: 2, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - details: null - }, { - id: '5', - first_name: 'Test', - last_name: 'User', - email: 'test5@example.com', - logins: 2, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - details: null - }, { - id: '7', - first_name: 'Test', - last_name: 'User', - email: 'test6@example.com', - logins: 2, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - details: null - }] + tester('postgresql', + 'select "accounts".*, "test_table_two"."details" from "accounts" left join "test_table_two" on "accounts"."id" = "test_table_two"."account_id" order by "accounts"."id" asc', + [], + [ + { + id: '1', + first_name: 'Test', + last_name: 'User', + email: 'test@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' + }, + { + id: '2', + first_name: 'Test', + last_name: 'User', + email: 'test2@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' + }, + { + id: '3', + first_name: 'Test', + last_name: 'User', + email: 'test3@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: '' + }, + { + id: '4', + first_name: 'Test', + last_name: 'User', + email: 'test4@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: null + }, + { + id: '5', + first_name: 'Test', + last_name: 'User', + email: 'test5@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: null + }, + { + id: '7', + first_name: 'Test', + last_name: 'User', + email: 'test6@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: null + } + ] + ); + tester('pg-redshift', + 'select "accounts".*, "test_table_two"."details" from "accounts" left join "test_table_two" on "accounts"."id" = "test_table_two"."account_id" order by "accounts"."id" asc', + [], + [ + { + id: '1', + first_name: 'Test', + last_name: 'User', + email: 'test@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' + }, + { + id: '2', + first_name: 'Test', + last_name: 'User', + email: 'test2@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.' + }, + { + id: '3', + first_name: 'Test', + last_name: 'User', + email: 'test3@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: '' + }, + { + id: '4', + first_name: 'Test', + last_name: 'User', + email: 'test4@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: null + }, + { + id: '5', + first_name: 'Test', + last_name: 'User', + email: 'test5@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: null + }, + { + id: '6', + first_name: 'Test', + last_name: 'User', + email: 'test6@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + details: null + } + ] ); tester( 'sqlite3', @@ -656,93 +789,197 @@ module.exports = function(knex) { json_data: null }] ); - tester( - 'postgresql', - 'select * from "accounts" left join "test_table_two" on "accounts"."id" = "test_table_two"."account_id" or "accounts"."email" = "test_table_two"."details" order by "accounts"."id" asc', [], [{ - id: 1, - first_name: 'Test', - last_name: 'User', - email: 'test@example.com', - logins: 1, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - account_id: 1, - details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', - status: 0, - json_data: null - }, { - id: 2, - first_name: 'Test', - last_name: 'User', - email: 'test2@example.com', - logins: 1, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - account_id: 2, - details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', - status: 1, - json_data: null - }, { - id: 3, - first_name: 'Test', - last_name: 'User', - email: 'test3@example.com', - logins: 2, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - account_id: 3, - details: '', - status: 1, - json_data: null - }, { - id: null, - first_name: 'Test', - last_name: 'User', - email: 'test4@example.com', - logins: 2, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - account_id: null, - details: null, - status: null, - json_data: null - }, { - id: null, - first_name: 'Test', - last_name: 'User', - email: 'test5@example.com', - logins: 2, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - account_id: null, - details: null, - status: null, - json_data: null - }, { - id: null, - first_name: 'Test', - last_name: 'User', - email: 'test6@example.com', - logins: 2, - about: 'Lorem ipsum Dolore labore incididunt enim.', - created_at: d, - updated_at: d, - phone: null, - account_id: null, - details: null, - status: null, - json_data: null - }] + tester('postgresql', + 'select * from "accounts" left join "test_table_two" on "accounts"."id" = "test_table_two"."account_id" or "accounts"."email" = "test_table_two"."details" order by "accounts"."id" asc', + [], + [ + { + id: 1, + first_name: 'Test', + last_name: 'User', + email: 'test@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: 1, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', + status: 0, + json_data: null + }, + { + id: 2, + first_name: 'Test', + last_name: 'User', + email: 'test2@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: 2, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', + status: 1, + json_data: null + }, + { + id: 3, + first_name: 'Test', + last_name: 'User', + email: 'test3@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: 3, + details: '', + status: 1, + json_data: null + }, + { + id: null, + first_name: 'Test', + last_name: 'User', + email: 'test4@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: null, + details: null, + status: null, + json_data: null + }, + { + id: null, + first_name: 'Test', + last_name: 'User', + email: 'test5@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: null, + details: null, + status: null, + json_data: null + }, + { + id: null, + first_name: 'Test', + last_name: 'User', + email: 'test6@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: null, + details: null, + status: null, + json_data: null + } + ] + ); + tester('pg-redshift', + 'select * from "accounts" left join "test_table_two" on "accounts"."id" = "test_table_two"."account_id" or "accounts"."email" = "test_table_two"."details" order by "accounts"."id" asc', + [], + [ + { + id: 1, + first_name: 'Test', + last_name: 'User', + email: 'test@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: 1, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', + status: 0, + json_data: null + }, + { + id: 2, + first_name: 'Test', + last_name: 'User', + email: 'test2@example.com', + logins: 1, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: 2, + details: 'Lorem ipsum Minim nostrud Excepteur consectetur enim ut qui sint in veniam in nulla anim do cillum sunt voluptate Duis non incididunt.', + status: 1, + json_data: null + }, + { + id: 3, + first_name: 'Test', + last_name: 'User', + email: 'test3@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: 3, + details: '', + status: 1, + json_data: null + }, + { + id: null, + first_name: 'Test', + last_name: 'User', + email: 'test4@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: null, + details: null, + status: null, + json_data: null + }, + { + id: null, + first_name: 'Test', + last_name: 'User', + email: 'test5@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: null, + details: null, + status: null, + json_data: null + }, + { + id: null, + first_name: 'Test', + last_name: 'User', + email: 'test6@example.com', + logins: 2, + about: 'Lorem ipsum Dolore labore incididunt enim.', + created_at: d, + updated_at: d, + phone: null, + account_id: null, + details: null, + status: null, + json_data: null + } + ] ); tester( 'sqlite3', @@ -953,26 +1190,57 @@ module.exports = function(knex) { e2: 'test2@example.com' }] ); - tester( - 'postgresql', + tester('postgresql', 'select "accounts"."email" as "e1", "a2"."email" as "e2" from "accounts" inner join "accounts" as "a2" on "a2"."email" <> "accounts"."email" where "a2"."email" = ? order by "e1" asc limit ?', ['test2@example.com', 5], - [{ - e1: 'test3@example.com', - e2: 'test2@example.com' - }, { - e1: 'test4@example.com', - e2: 'test2@example.com' - }, { - e1: 'test5@example.com', - e2: 'test2@example.com' - }, { - e1: 'test6@example.com', - e2: 'test2@example.com' - }, { - e1: 'test@example.com', - e2: 'test2@example.com' - }] + [ + { + e1: 'test3@example.com', + e2: 'test2@example.com' + }, + { + e1: 'test4@example.com', + e2: 'test2@example.com' + }, + { + e1: 'test5@example.com', + e2: 'test2@example.com' + }, + { + e1: 'test6@example.com', + e2: 'test2@example.com' + }, + { + e1: 'test@example.com', + e2: 'test2@example.com' + } + ] + ); + tester('pg-redshift', + 'select "accounts"."email" as "e1", "a2"."email" as "e2" from "accounts" inner join "accounts" as "a2" on "a2"."email" <> "accounts"."email" where "a2"."email" = ? order by "e1" asc limit ?', + ['test2@example.com', 5], + [ + { + e1: 'test3@example.com', + e2: 'test2@example.com' + }, + { + e1: 'test4@example.com', + e2: 'test2@example.com' + }, + { + e1: 'test5@example.com', + e2: 'test2@example.com' + }, + { + e1: 'test6@example.com', + e2: 'test2@example.com' + }, + { + e1: 'test@example.com', + e2: 'test2@example.com' + } + ] ); tester( 'sqlite3', @@ -1073,10 +1341,50 @@ module.exports = function(knex) { e2: 'test2@example.com' }] ); - tester( - 'postgresql', + tester('postgresql', 'select "accounts"."email" as "e1", "a2"."email" as "e2" from "accounts" inner join "accounts" as "a2" on "accounts"."email" <> "a2"."email" or "accounts"."id" = 2 where "a2"."email" = ? order by "e1" asc limit ?', ['test2@example.com', 5], + [{ + e1: 'test2@example.com', + e2: 'test2@example.com' + }, { + e1: 'test3@example.com', + e2: 'test2@example.com' + }, { + e1: 'test4@example.com', + e2: 'test2@example.com' + }, { + e1: 'test5@example.com', + e2: 'test2@example.com' + }, { + e1: 'test6@example.com', + e2: 'test2@example.com' + }] + ); + tester('pg-redshift', + 'select "accounts"."email" as "e1", "a2"."email" as "e2" from "accounts" inner join "accounts" as "a2" on "accounts"."email" <> "a2"."email" or "accounts"."id" = 2 where "a2"."email" = ? order by "e1" asc limit ?', + ['test2@example.com', 5], + [{ + e1: 'test2@example.com', + e2: 'test2@example.com' + }, { + e1: 'test3@example.com', + e2: 'test2@example.com' + }, { + e1: 'test4@example.com', + e2: 'test2@example.com' + }, { + e1: 'test5@example.com', + e2: 'test2@example.com' + }, { + e1: 'test6@example.com', + e2: 'test2@example.com' + }] + ); + tester( + 'sqlite3', + 'select `accounts`.`email` as `e1`, `a2`.`email` as `e2` from `accounts` inner join `accounts` as `a2` on `accounts`.`email` <> `a2`.`email` or `accounts`.`id` = 2 where `a2`.`email` = ? order by `e1` asc limit ?', + ['test2@example.com', 5], [{ e1: 'test2@example.com', e2: 'test2@example.com' @@ -1094,27 +1402,6 @@ module.exports = function(knex) { e2: 'test2@example.com' }] ); - tester( - 'sqlite3', - 'select `accounts`.`email` as `e1`, `a2`.`email` as `e2` from `accounts` inner join `accounts` as `a2` on `accounts`.`email` <> `a2`.`email` or `accounts`.`id` = 2 where `a2`.`email` = ? order by `e1` asc limit ?', - ['test2@example.com', 5], - [{ - e1: 'test2@example.com', - e2: 'test2@example.com' - },{ - e1: 'test3@example.com', - e2: 'test2@example.com' - },{ - e1: 'test4@example.com', - e2: 'test2@example.com' - },{ - e1: 'test5@example.com', - e2: 'test2@example.com' - },{ - e1: 'test6@example.com', - e2: 'test2@example.com' - }] - ); tester( 'oracle', "select * from (select \"accounts\".\"email\" \"e1\", \"a2\".\"email\" \"e2\" from \"accounts\" inner join \"accounts\" \"a2\" on \"accounts\".\"email\" <> \"a2\".\"email\" or \"accounts\".\"id\" = 2 where \"a2\".\"email\" = ? order by \"e1\" asc) where rownum <= ?", @@ -1179,6 +1466,15 @@ module.exports = function(knex) { return res.length === 30; } ); + tester( + 'pg-redshift', + 'select "account_id" from "accounts" cross join "test_table_two" order by "account_id" asc', + [], + function (res) { + // redshift, not supporting insert...returning, had to fake 6 of these in previous tests + return res.length === 24; + } + ); tester( 'oracle', 'select "account_id" from "accounts" cross join "test_table_two" order by "account_id" asc', @@ -1216,6 +1512,7 @@ module.exports = function(knex) { .leftJoin('accounts as a2', function() { this.on('a1.email', '<>', 'a2.email'); }) + .orderBy('a2.id', 'asc') .select(['a1.email', 'a2.email']) .where(knex.raw('a1.id = 1')) .options({ @@ -1226,7 +1523,7 @@ module.exports = function(knex) { .testSql(function(tester) { tester( 'mysql', - 'select `a1`.`email`, `a2`.`email` from `accounts` as `a1` left join `accounts` as `a2` on `a1`.`email` <> `a2`.`email` where a1.id = 1 limit ?', + 'select `a1`.`email`, `a2`.`email` from `accounts` as `a1` left join `accounts` as `a2` on `a1`.`email` <> `a2`.`email` where a1.id = 1 order by `a2`.`id` asc limit ?', [2], [{ a1: { @@ -1246,7 +1543,19 @@ module.exports = function(knex) { ); tester( 'postgres', - 'select "a1"."email", "a2"."email" from "accounts" as "a1" left join "accounts" as "a2" on "a1"."email" <> "a2"."email" where a1.id = 1 limit ?', + 'select "a1"."email", "a2"."email" from "accounts" as "a1" left join "accounts" as "a2" on "a1"."email" <> "a2"."email" where a1.id = 1 order by "a2"."id" asc limit ?', + [2], + [{ + 0: 'test@example.com', + 1: 'test2@example.com' + },{ + 0: 'test@example.com', + 1: 'test3@example.com' + }] + ); + tester( + 'pg-redshift', + 'select "a1"."email", "a2"."email" from "accounts" as "a1" left join "accounts" as "a2" on "a1"."email" <> "a2"."email" where a1.id = 1 order by "a2"."id" asc limit ?', [2], [{ 0: 'test@example.com', @@ -1258,7 +1567,7 @@ module.exports = function(knex) { ); tester( 'sqlite3', - 'select `a1`.`email`, `a2`.`email` from `accounts` as `a1` left join `accounts` as `a2` on `a1`.`email` <> `a2`.`email` where a1.id = 1 limit ?', + 'select `a1`.`email`, `a2`.`email` from `accounts` as `a1` left join `accounts` as `a2` on `a1`.`email` <> `a2`.`email` where a1.id = 1 order by `a2`.`id` asc limit ?', [2], [{ email: 'test2@example.com' @@ -1268,7 +1577,7 @@ module.exports = function(knex) { ); tester( 'mssql', - 'select top (?) [a1].[email], [a2].[email] from [accounts] as [a1] left join [accounts] as [a2] on [a1].[email] <> [a2].[email] where a1.id = 1', + 'select top (?) [a1].[email], [a2].[email] from [accounts] as [a1] left join [accounts] as [a2] on [a1].[email] <> [a2].[email] where a1.id = 1 order by [a2].[id] asc', [2], [{ email: ['test@example.com', 'test2@example.com'] diff --git a/test/integration/builder/selects.js b/test/integration/builder/selects.js index f1dcdc2d2..7e9c63db9 100644 --- a/test/integration/builder/selects.js +++ b/test/integration/builder/selects.js @@ -31,6 +31,12 @@ module.exports = function(knex) { [], ['1', '2', '3', '4', '5', '7'] ); + tester( + 'pg-redshift', + 'select "id" from "accounts" order by "id" asc', + [], + ['1', '2', '3', '4', '5', '6'] + ); tester( 'sqlite3', 'select `id` from `accounts` order by `id` asc', @@ -67,6 +73,12 @@ module.exports = function(knex) { [], ['1', '2', '3', '4', '5', '7'] ); + tester( + 'pg-redshift', + 'select "accounts"."id" from "accounts" order by "accounts"."id" asc', + [], + ['1', '2', '3', '4', '5', '6'] + ); tester( 'sqlite3', 'select `accounts`.`id` from `accounts` order by `accounts`.`id` asc', @@ -103,6 +115,12 @@ module.exports = function(knex) { [2], ['3', '4', '5', '7'] ); + tester( + 'pg-redshift', + 'select "id" from "accounts" order by "id" asc offset ?', + [2], + ['3', '4', '5', '6'] + ); tester( 'sqlite3', 'select `id` from `accounts` order by `id` asc limit ? offset ?', @@ -139,6 +157,12 @@ module.exports = function(knex) { [1], { id: '1', first_name: 'Test' } ); + tester( + 'pg-redshift', + 'select "id", "first_name" from "accounts" order by "id" asc limit ?', + [1], + { id: '1', first_name: 'Test' } + ); tester( 'sqlite3', 'select `id`, `first_name` from `accounts` order by `id` asc limit ?', @@ -161,7 +185,7 @@ module.exports = function(knex) { }); it('allows you to stream', function() { - var count = 0; + let count = 0; return knex('accounts').stream(function(rowStream) { rowStream.on('data', function() { count++; @@ -172,8 +196,8 @@ module.exports = function(knex) { }); it('returns a stream if not passed a function', function(done) { - var count = 0; - var stream = knex('accounts').stream(); + let count = 0; + const stream = knex('accounts').stream(); stream.on('data', function() { count++; if (count === 6) done(); @@ -243,7 +267,7 @@ module.exports = function(knex) { }); it('properly escapes postgres queries on streaming', function() { - var count = 0; + let count = 0; return knex('accounts').where('id', 1).stream(function(rowStream) { rowStream.on('data', function() { count++; @@ -255,13 +279,13 @@ module.exports = function(knex) { it('throws errors on the asCallback if uncaught in the last block', function(ok) { - var listeners = process.listeners('uncaughtException'); + const listeners = process.listeners('uncaughtException'); process.removeAllListeners('uncaughtException'); process.on('uncaughtException', function() { process.removeAllListeners('uncaughtException'); - for (var i = 0, l = listeners.length; i < l; i++) { + for (let i = 0, l = listeners.length; i < l; i++) { process.on('uncaughtException', listeners[i]); } ok(); @@ -318,6 +342,15 @@ module.exports = function(knex) { last_name: 'User' }] ); + tester( + 'pg-redshift', + 'select "first_name", "last_name" from "accounts" where "id" = ?', + [1], + [{ + first_name: 'Test', + last_name: 'User' + }] + ); tester( 'sqlite3', 'select `first_name`, `last_name` from `accounts` where `id` = ?', @@ -372,6 +405,15 @@ module.exports = function(knex) { last_name: 'User' }] ); + tester( + 'pg-redshift', + 'select "first_name", "last_name" from "accounts" where "id" = ?', + [1], + [{ + first_name: 'Test', + last_name: 'User' + }] + ); tester( 'sqlite3', 'select `first_name`, `last_name` from `accounts` where `id` = ?', @@ -418,6 +460,11 @@ module.exports = function(knex) { 'select "email", "logins" from "accounts" where "id" > ?', [1] ); + tester( + 'pg-redshift', + 'select "email", "logins" from "accounts" where "id" > ?', + [1] + ); tester( 'sqlite3', 'select `email`, `logins` from `accounts` where `id` > ?', @@ -474,6 +521,22 @@ module.exports = function(knex) { phone: null }] ); + tester( + 'pg-redshift', + 'select * from "accounts" where "id" = ?', + [1], + [{ + id: '1', + first_name: "Test", + last_name: "User", + email: "test@example.com", + logins: 1, + about: "Lorem ipsum Dolore labore incididunt enim.", + created_at: d, + updated_at: d, + phone: null + }] + ); tester( 'sqlite3', 'select * from `accounts` where `id` = ?', @@ -543,6 +606,12 @@ module.exports = function(knex) { [], [] ); + tester( + 'pg-redshift', + 'select "first_name", "email" from "accounts" where "id" is null', + [], + [] + ); tester( 'sqlite3', 'select `first_name`, `email` from `accounts` where `id` is null', @@ -583,6 +652,12 @@ module.exports = function(knex) { [0], [] ); + tester( + 'pg-redshift', + 'select * from "accounts" where "id" = ?', + [0], + [] + ); tester( 'sqlite3', 'select * from `accounts` where `id` = ?', @@ -647,24 +722,11 @@ module.exports = function(knex) { if (knex.client.dialect !== 'sqlite3' && knex.client.dialect !== 'mssql') { return knex('composite_key_test') .whereIn(['column_a', 'column_b'], [[1, 1], [1, 2]]) + .orderBy('status', 'desc') .select() .testSql(function(tester) { tester('mysql', - 'select * from `composite_key_test` where (`column_a`, `column_b`) in ((?, ?),(?, ?))', - [1,1,1,2], - [{ - column_a: 1, - column_b: 1, - details: 'One, One, One', - status: 1 - },{ - column_a: 1, - column_b: 2, - details: 'One, Two, Zero', - status: 0 - }]); - tester('postgresql', - 'select * from "composite_key_test" where ("column_a","column_b") in ((?, ?),(?, ?))', + 'select * from `composite_key_test` where (`column_a`, `column_b`) in ((?, ?),(?, ?)) order by `status` desc', [1,1,1,2], [{ column_a: 1, @@ -677,8 +739,39 @@ module.exports = function(knex) { details: 'One, Two, Zero', status: 0 }]); + tester('postgresql', + 'select * from "composite_key_test" where ("column_a", "column_b") in ((?, ?),(?, ?)) order by "status" desc', + [1,1,1,2], + [{ + column_a: 1, + column_b: 1, + details: 'One, One, One', + status: 1 + },{ + column_a: 1, + column_b: 2, + details: 'One, Two, Zero', + status: 0 + }]); + tester('pg-redshift', + 'select * from "composite_key_test" where ("column_a", "column_b") in ((?, ?),(?, ?)) order by "status" desc', + [1,1,1,2], + [ + { + column_a: 1, + column_b: 1, + details: 'One, One, One', + status: 1 + }, + { + column_a: 1, + column_b: 2, + details: 'One, Two, Zero', + status: 0 + }, + ]); tester('oracle', - 'select * from "composite_key_test" where ("column_a","column_b") in ((?, ?),(?, ?))', + 'select * from "composite_key_test" where ("column_a","column_b") in ((?, ?),(?, ?)) order by "status" desc', [1,1,1,2], [{ column_a: 1, @@ -720,6 +813,15 @@ module.exports = function(knex) { details: 'One, One, One', status: 1 }]); + tester('pg-redshift', + 'select * from "composite_key_test" where "status" = ? and ("column_a", "column_b") in ((?, ?),(?, ?))', + [1,1,1,1,2], + [{ + column_a: 1, + column_b: 1, + details: 'One, One, One', + status: 1 + }]); tester('oracle', 'select * from "composite_key_test" where "status" = ? and ("column_a", "column_b") in ((?, ?),(?, ?))', [1,1,1,1,2], @@ -792,10 +894,10 @@ module.exports = function(knex) { }); it('Retains array bindings, #228', function() { - var raw = knex.raw('select * from table t where t.id = ANY( ?::int[] )', [[1, 2, 3]]); - var raw2 = knex.raw('select "stored_procedure"(?, ?, ?)', [1, 2, ['a', 'b', 'c']]); - var expected1 = [[1, 2, 3]]; - var expected2 = [1, 2, ['a', 'b', 'c']]; + const raw = knex.raw('select * from table t where t.id = ANY( ?::int[] )', [[1, 2, 3]]); + const raw2 = knex.raw('select "stored_procedure"(?, ?, ?)', [1, 2, ['a', 'b', 'c']]); + const expected1 = [[1, 2, 3]]; + const expected2 = [1, 2, ['a', 'b', 'c']]; expect(raw.toSQL().bindings).to.eql(knex.client.prepBindings(expected1)); expect(raw2.toSQL().bindings).to.eql(knex.client.prepBindings(expected2)); //Also expect raw's bindings to not have been modified by calling .toSQL() (preserving original bindings) @@ -813,7 +915,7 @@ module.exports = function(knex) { it('properly escapes identifiers, #737', function() { if (knex.client.dialect === 'postgresql') { - var query = knex.select('id","name').from('test').toSQL(); + const query = knex.select('id","name').from('test').toSQL(); assert(query.sql === 'select "id"",""name" from "test"'); } }); diff --git a/test/integration/builder/transaction.js b/test/integration/builder/transaction.js index 829229ebb..5e34f1124 100644 --- a/test/integration/builder/transaction.js +++ b/test/integration/builder/transaction.js @@ -9,6 +9,11 @@ var sinon = require('sinon') module.exports = function(knex) { + // Certain dialects do not have proper insert with returning, so if this is true + // then pick an id to use as the "foreign key" just for testing transactions. + const constid = (/redshift/.test(knex.client.dialect)); + let fkid = 1; + describe('Transactions', function() { it('can run with asCallback', function(ok) { @@ -35,7 +40,7 @@ module.exports = function(knex) { updated_at: new Date() }).then(function(resp) { return knex('test_table_two').transacting(t).insert({ - account_id: (id = resp[0]), + account_id: (constid ? ++fkid : id = resp[0]), details: '', status: 1 }); @@ -47,7 +52,9 @@ module.exports = function(knex) { expect(commitMessage).to.equal('Hello world'); return knex('accounts').where('id', id).select('first_name'); }).then(function(resp) { - expect(resp).to.have.length(1); + if (!constid){ + expect(resp).to.have.length(1); + } }); }); @@ -68,7 +75,7 @@ module.exports = function(knex) { updated_at: new Date() }).then(function(resp) { return knex('test_table_two').transacting(t).insert({ - account_id: (id = resp[0]), + account_id: (constid ? ++fkid : id = resp[0]), details: '', status: 1 }); @@ -99,7 +106,7 @@ module.exports = function(knex) { updated_at: new Date() }).then(function(resp) { return trx('test_table_two').insert({ - account_id: (id = resp[0]), + account_id: (constid ? ++fkid : id = resp[0]), details: '', status: 1 }); @@ -110,7 +117,9 @@ module.exports = function(knex) { expect(commitMessage).to.equal('Hello World'); return knex('accounts').where('id', id).select('first_name'); }).then(function(resp) { - expect(resp).to.have.length(1); + if (!constid){ + expect(resp).to.have.length(1); + } }); }); @@ -132,7 +141,7 @@ module.exports = function(knex) { }) .then(function(resp) { return trx.insert({ - account_id: (id = resp[0]), + account_id: (constid ? ++fkid : id = resp[0]), details: '', status: 1 }).into('test_table_two'); @@ -208,7 +217,7 @@ module.exports = function(knex) { updated_at: new Date() }).then(function(resp) { return trx('test_table_two').insert({ - account_id: (id = resp[0]), + account_id: (constid ? ++fkid : id = resp[0]), details: '', status: 1 }); @@ -234,7 +243,9 @@ module.exports = function(knex) { } return knex('accounts').where('id', id).select('first_name'); }).then(function(resp) { - expect(resp).to.have.length(1); + if (!constid){ + expect(resp).to.have.length(1); + } }).finally(function() { return knex.schema.dropTableIfExists('test_schema_transactions'); }); @@ -251,6 +262,7 @@ module.exports = function(knex) { }); it('should allow for nested transactions', function() { + if(/redshift/i.test(knex.client.dialect)) { return Promise.resolve() } return knex.transaction(function(trx) { return trx.select('*').from('accounts').then(function() { return trx.transaction(function() { @@ -275,9 +287,8 @@ module.exports = function(knex) { return knex.transaction(function(trx) { trx.select('*').from('accounts').then(trx.commit).catch(trx.rollback); }) - .then(expectQueryEventToHaveBeenTriggered) - .catch(expectQueryEventToHaveBeenTriggered); - + .then(expectQueryEventToHaveBeenTriggered) + .catch(expectQueryEventToHaveBeenTriggered); }); it('#1040, #1171 - When pool is filled with transaction connections, Non-transaction queries should not hang the application, but instead throw a timeout error', function() { @@ -316,15 +327,15 @@ module.exports = function(knex) { }); it('#1694, #1703 it should return connections to pool if acquireConnectionTimeout is triggered', function() { - var db = Knex({ - client: knex.client.driverName, - pool: { - min: 0, - max: 1 - }, - connection: knex.client.connectionSettings, - acquireConnectionTimeout: 300 - }) + const knexConfig = _.clone(knex.client.config); + knexConfig.pool = { + min: 0, + max: 1, + }; + knexConfig.acquireConnectionTimeout = 300; + + const db = new Knex(knexConfig); + return db.transaction(function() { return db.transaction(function() {}) }).then(function () { diff --git a/test/integration/builder/updates.js b/test/integration/builder/updates.js index 3afa3b667..6b68c351b 100644 --- a/test/integration/builder/updates.js +++ b/test/integration/builder/updates.js @@ -26,6 +26,12 @@ module.exports = function(knex) { ['User','Test','test100@example.com',1], 1 ); + tester( + 'pg-redshift', + 'update "accounts" set "first_name" = ?, "last_name" = ?, "email" = ? where "id" = ?', + ['User','Test','test100@example.com',1], + 1 + ); tester( 'sqlite3', 'update `accounts` set `first_name` = ?, `last_name` = ?, `email` = ? where `id` = ?', @@ -137,6 +143,12 @@ module.exports = function(knex) { phone: null }] ); + tester( + 'pg-redshift', + 'update "accounts" set "email" = ?, "first_name" = ?, "last_name" = ? where "id" = ?', + ['test100@example.com','UpdatedUser','UpdatedTest',1], + 1 + ); tester( 'sqlite3', 'update `accounts` set `email` = ?, `first_name` = ?, `last_name` = ? where `id` = ?', diff --git a/test/integration/migrate/index.js b/test/integration/migrate/index.js index fb60cabca..780c780d1 100644 --- a/test/integration/migrate/index.js +++ b/test/integration/migrate/index.js @@ -34,6 +34,7 @@ module.exports = function(knex) { var tables = ['migration_test_1', 'migration_test_2', 'migration_test_2_1']; describe('knex.migrate.status', function() { + this.timeout(process.env.KNEX_TEST_TIMEOUT || 30000); beforeEach(function() { return knex.migrate.latest({directory: 'test/integration/migrate/test'}); @@ -91,6 +92,11 @@ module.exports = function(knex) { }) .then(function() { // Cleanup the added migrations + if (/redshift/.test(knex.client.dialect)){ + return knex('knex_migrations') + .where('name', 'like', '%foobar%') + .del(); + } return knex('knex_migrations') .where('id', migration1[0]) .orWhere('id', migration2[0]) diff --git a/test/integration/schema/index.js b/test/integration/schema/index.js index 0256980a2..03522278e 100644 --- a/test/integration/schema/index.js +++ b/test/integration/schema/index.js @@ -1,8 +1,8 @@ -/*global describe, it, expect, testPromise*/ +/*global describe, it, expect, testPromise, before, after*/ 'use strict'; -var Promise = testPromise; +const Promise = testPromise; module.exports = function(knex) { @@ -11,9 +11,11 @@ module.exports = function(knex) { describe('dropTable', function() { it('has a dropTableIfExists method', function() { + this.timeout(process.env.KNEX_TEST_TIMEOUT || 30000); return Promise.all([ knex.schema.dropTableIfExists('test_foreign_table_two').testSql(function(tester) { tester(['pg'], ['drop table if exists "test_foreign_table_two"']); + tester(['pg-redshift'], ['drop table if exists "test_foreign_table_two"']); tester(['sqlite3', 'mysql'], ['drop table if exists `test_foreign_table_two`']); tester('oracle', [ "begin execute immediate 'drop table \"test_foreign_table_two\"'; exception when others then if sqlcode != -942 then raise; end if; end;", @@ -37,12 +39,15 @@ module.exports = function(knex) { .dropTableIfExists('test_default_table2') .dropTableIfExists('test_default_table3') .dropTableIfExists('knex_migrations') + .dropTableIfExists('knex_migrations_lock') .dropTableIfExists('bool_test') .dropTableIfExists('10_test_table') .dropTableIfExists('rename_column_foreign_test') .dropTableIfExists('rename_column_test') + .dropTableIfExists('renamecoltest') .dropTableIfExists('should_not_be_run') .dropTableIfExists('invalid_inTable_param_test') + .dropTableIfExists('primarytest') .dropTableIfExists('increments_columns_1_test') .dropTableIfExists('increments_columns_2_test') ]); @@ -226,7 +231,9 @@ module.exports = function(knex) { table.timestamps(); }).testSql(function(tester) { tester('mysql', ['create table `test_table_one` (`id` bigint unsigned not null auto_increment primary key, `first_name` varchar(255), `last_name` varchar(255), `email` varchar(255) null, `logins` int default \'1\', `about` text comment \'A comment.\', `created_at` datetime, `updated_at` datetime) default character set utf8 engine = InnoDB comment = \'A table comment.\'','alter table `test_table_one` add index `test_table_one_first_name_index`(`first_name`)','alter table `test_table_one` add unique `test_table_one_email_unique`(`email`)','alter table `test_table_one` add index `test_table_one_logins_index`(`logins`)']); + tester('redshift', ['create table "test_table_one" FOOBAR']); tester('pg', ['create table "test_table_one" ("id" bigserial primary key, "first_name" varchar(255), "last_name" varchar(255), "email" varchar(255) null, "logins" integer default \'1\', "about" text, "created_at" timestamptz, "updated_at" timestamptz)','comment on table "test_table_one" is \'A table comment.\'',"comment on column \"test_table_one\".\"logins\" is NULL",'comment on column "test_table_one"."about" is \'A comment.\'','create index "test_table_one_first_name_index" on "test_table_one" ("first_name")','alter table "test_table_one" add constraint "test_table_one_email_unique" unique ("email")','create index "test_table_one_logins_index" on "test_table_one" ("logins")']); + tester('pg-redshift', ['create table "test_table_one" ("id" bigint identity(1,1) primary key not null, "first_name" varchar(255), "last_name" varchar(255), "email" varchar(255) null, "logins" integer default \'1\', "about" varchar(max), "created_at" timestamptz, "updated_at" timestamptz)','comment on table "test_table_one" is \'A table comment.\'',"comment on column \"test_table_one\".\"logins\" is NULL",'comment on column "test_table_one"."about" is \'A comment.\'','alter table "test_table_one" add constraint "test_table_one_email_unique" unique ("email")']); tester('sqlite3', ['create table `test_table_one` (`id` integer not null primary key autoincrement, `first_name` varchar(255), `last_name` varchar(255), `email` varchar(255) null, `logins` integer default \'1\', `about` text, `created_at` datetime, `updated_at` datetime)','create index `test_table_one_first_name_index` on `test_table_one` (`first_name`)','create unique index `test_table_one_email_unique` on `test_table_one` (`email`)','create index `test_table_one_logins_index` on `test_table_one` (`logins`)']); tester('oracle', [ 'create table "test_table_one" ("id" number(20, 0) not null primary key, "first_name" varchar2(255), "last_name" varchar2(255), "email" varchar2(255) null, "logins" integer default \'1\', "about" varchar2(4000), "created_at" timestamp with time zone, "updated_at" timestamp with time zone)', @@ -273,6 +280,7 @@ module.exports = function(knex) { }).testSql(function(tester) { tester('mysql', ['create table `test_table_three` (`main` int not null, `paragraph` text) default character set utf8 engine = InnoDB','alter table `test_table_three` add primary key `test_table_three_pkey`(`main`)']); tester('pg', ['create table "test_table_three" ("main" integer not null, "paragraph" text default \'Lorem ipsum Qui quis qui in.\')','alter table "test_table_three" add constraint "test_table_three_pkey" primary key ("main")']); + tester('pg-redshift', ['create table "test_table_three" ("main" integer not null, "paragraph" varchar(max) default \'Lorem ipsum Qui quis qui in.\')','alter table "test_table_three" add constraint "test_table_three_pkey" primary key ("main")']); tester('sqlite3', ['create table `test_table_three` (`main` integer not null, `paragraph` text default \'Lorem ipsum Qui quis qui in.\', primary key (`main`))']); tester('oracle', ['create table "test_table_three" ("main" integer not null, "paragraph" clob default \'Lorem ipsum Qui quis qui in.\')','alter table "test_table_three" add constraint "test_table_three_pkey" primary key ("main")']); tester('mssql', ['CREATE TABLE [test_table_three] ([main] int not null, [paragraph] nvarchar(max), CONSTRAINT [test_table_three_pkey] PRIMARY KEY ([main]))']); @@ -280,6 +288,7 @@ module.exports = function(knex) { }); it('supports the enum and uuid columns', function() { + // NB: redshift does not... return knex.schema .createTable('datatype_test', function(table) { table.enum('enum_value', ['a', 'b', 'c']); @@ -321,6 +330,12 @@ module.exports = function(knex) { 'alter table "test_foreign_table_two" add constraint "fk_fkey_three" foreign key ("fkey_three") references "test_table_two" ("id")', 'alter table "test_foreign_table_two" add constraint "fk_fkey_four" foreign key ("fkey_four") references "test_table_two" ("id")' ]); + tester('pg-redshift', [ + 'create table "test_foreign_table_two" ("id" integer identity(1,1) primary key not null, "fkey_two" integer, "fkey_three" integer, "fkey_four" integer)', + 'alter table "test_foreign_table_two" add constraint "test_foreign_table_two_fkey_two_foreign" foreign key ("fkey_two") references "test_table_two" ("id")', + 'alter table "test_foreign_table_two" add constraint "fk_fkey_three" foreign key ("fkey_three") references "test_table_two" ("id")', + 'alter table "test_foreign_table_two" add constraint "fk_fkey_four" foreign key ("fkey_four") references "test_table_two" ("id")' + ]); tester('sqlite3', [ 'create table `test_foreign_table_two` (`id` integer not null primary key autoincrement, `fkey_two` integer, `fkey_three` integer, `fkey_four` integer, ' + 'foreign key(`fkey_two`) references `test_table_two`(`id`), ' + @@ -346,10 +361,10 @@ module.exports = function(knex) { it('rejects setting foreign key where tableName is not typeof === string', function() { return knex.schema.createTable('invalid_inTable_param_test', function(table) { - var createInvalidUndefinedInTableSchema = function() { + const createInvalidUndefinedInTableSchema = function() { table.increments('id').references('id').inTable() }; - var createInvalidObjectInTableSchema = function () { + const createInvalidObjectInTableSchema = function () { table.integer('another_id').references('id').inTable({tableName: 'this_should_fail'}) }; expect(createInvalidUndefinedInTableSchema).to.throw(TypeError); @@ -369,6 +384,7 @@ module.exports = function(knex) { }).testSql(function(tester) { tester('mysql', ['create table `composite_key_test` (`column_a` int, `column_b` int, `details` text, `status` tinyint) default character set utf8','alter table `composite_key_test` add unique `composite_key_test_column_a_column_b_unique`(`column_a`, `column_b`)']); tester('pg', ['create table "composite_key_test" ("column_a" integer, "column_b" integer, "details" text, "status" smallint)','alter table "composite_key_test" add constraint "composite_key_test_column_a_column_b_unique" unique ("column_a", "column_b")']); + tester('pg-redshift', ['create table "composite_key_test" ("column_a" integer, "column_b" integer, "details" varchar(max), "status" smallint)','alter table "composite_key_test" add constraint "composite_key_test_column_a_column_b_unique" unique ("column_a", "column_b")']); tester('sqlite3', ['create table `composite_key_test` (`column_a` integer, `column_b` integer, `details` text, `status` tinyint)','create unique index `composite_key_test_column_a_column_b_unique` on `composite_key_test` (`column_a`, `column_b`)']); tester('oracle', ['create table "composite_key_test" ("column_a" integer, "column_b" integer, "details" clob, "status" smallint)','alter table "composite_key_test" add constraint "zYmMt0VQwlLZ20XnrMicXZ0ufZk" unique ("column_a", "column_b")']); tester('mssql', ['CREATE TABLE [composite_key_test] ([column_a] int, [column_b] int, [details] nvarchar(max), [status] tinyint, CONSTRAINT [composite_key_test_column_a_column_b_unique] UNIQUE ([column_a], [column_b]))']); @@ -405,6 +421,7 @@ module.exports = function(knex) { }).testSql(function(tester) { tester('mysql', ['create table `charset_collate_test` (`id` int unsigned not null auto_increment primary key, `account_id` int, `details` text, `status` tinyint) default character set latin1 collate latin1_general_ci engine = InnoDB']); tester('pg', ['create table "charset_collate_test" ("id" serial primary key, "account_id" integer, "details" text, "status" smallint)']); + tester('pg-redshift', ['create table "charset_collate_test" ("id" integer identity(1,1) primary key not null, "account_id" integer, "details" varchar(max), "status" smallint)']); tester('sqlite3', ['create table `charset_collate_test` (`id` integer not null primary key autoincrement, `account_id` integer, `details` text, `status` tinyint)']); tester('oracle', [ "create table \"charset_collate_test\" (\"id\" integer not null primary key, \"account_id\" integer, \"details\" clob, \"status\" smallint)", @@ -416,22 +433,23 @@ module.exports = function(knex) { }); it('sets booleans & defaults correctly', function() { - return knex.schema - .createTable('bool_test', function(table) { - table.bool('one'); - table.bool('two').defaultTo(false); - table.bool('three').defaultTo(true); - table.bool('four').defaultTo('true'); - table.bool('five').defaultTo('false'); - }).testSql(function(tester) { - tester('mysql', ['create table `bool_test` (`one` boolean, `two` boolean default \'0\', `three` boolean default \'1\', `four` boolean default \'1\', `five` boolean default \'0\') default character set utf8']); - tester('pg', ['create table "bool_test" ("one" boolean, "two" boolean default \'0\', "three" boolean default \'1\', "four" boolean default \'1\', "five" boolean default \'0\')']); - tester('sqlite3', ['create table `bool_test` (`one` boolean, `two` boolean default \'0\', `three` boolean default \'1\', `four` boolean default \'1\', `five` boolean default \'0\')']); - tester('oracle', ['create table "bool_test" ("one" number(1, 0) check ("one" in (\'0\', \'1\')), "two" number(1, 0) default \'0\' check ("two" in (\'0\', \'1\')), "three" number(1, 0) default \'1\' check ("three" in (\'0\', \'1\')), "four" number(1, 0) default \'1\' check ("four" in (\'0\', \'1\')), "five" number(1, 0) default \'0\' check ("five" in (\'0\', \'1\')))']); - tester('mssql', ['CREATE TABLE [bool_test] ([one] bit, [two] bit default \'0\', [three] bit default \'1\', [four] bit default \'1\', [five] bit default \'0\')']); - }).then(function() { - return knex.insert({one: false}).into('bool_test'); - }); + return knex.schema + .createTable('bool_test', function(table) { + table.bool('one'); + table.bool('two').defaultTo(false); + table.bool('three').defaultTo(true); + table.bool('four').defaultTo('true'); + table.bool('five').defaultTo('false'); + }).testSql(function(tester) { + tester('mysql', ['create table `bool_test` (`one` boolean, `two` boolean default \'0\', `three` boolean default \'1\', `four` boolean default \'1\', `five` boolean default \'0\') default character set utf8']); + tester('pg', ['create table "bool_test" ("one" boolean, "two" boolean default \'0\', "three" boolean default \'1\', "four" boolean default \'1\', "five" boolean default \'0\')']); + tester('pg-redshift', ['create table "bool_test" ("one" boolean, "two" boolean default \'0\', "three" boolean default \'1\', "four" boolean default \'1\', "five" boolean default \'0\')']); + tester('sqlite3', ['create table `bool_test` (`one` boolean, `two` boolean default \'0\', `three` boolean default \'1\', `four` boolean default \'1\', `five` boolean default \'0\')']); + tester('oracle', ['create table "bool_test" ("one" number(1, 0) check ("one" in (\'0\', \'1\')), "two" number(1, 0) default \'0\' check ("two" in (\'0\', \'1\')), "three" number(1, 0) default \'1\' check ("three" in (\'0\', \'1\')), "four" number(1, 0) default \'1\' check ("four" in (\'0\', \'1\')), "five" number(1, 0) default \'0\' check ("five" in (\'0\', \'1\')))']); + tester('mssql', ['CREATE TABLE [bool_test] ([one] bit, [two] bit default \'0\', [three] bit default \'1\', [four] bit default \'1\', [five] bit default \'0\')']); + }).then(function() { + return knex.insert({one: false}).into('bool_test'); + }); }); it('accepts table names starting with numeric values', function() { @@ -495,6 +513,7 @@ module.exports = function(knex) { }); it('allows adding multiple columns at once', function () { + if(/redshift/i.test(knex.client.dialect)) { return; } return knex.schema.table('test_table_two', function(t) { t.string('one'); t.string('two'); @@ -510,6 +529,7 @@ module.exports = function(knex) { it('allows alter column syntax', function () { if (knex.client.dialect.match('sqlite') !== null || + knex.client.dialect.match('redshift') !== null || knex.client.dialect.match('oracle') !== null) { return; } @@ -635,7 +655,10 @@ module.exports = function(knex) { describe('addColumn', function() { describe('mysql only', function() { - if(!knex || !knex.client || (!(/mysql/i.test(knex.client.dialect)) && !(/maria/i.test(knex.client.dialect)))) { + if (!knex || + !knex.client || + (!(/mysql/i.test(knex.client.dialect)) && !(/maria/i.test(knex.client.dialect))) + ) { return Promise.resolve(); } @@ -661,10 +684,11 @@ module.exports = function(knex) { it('should columns order be correctly with after and first', function() { return knex.raw('SHOW CREATE TABLE `add_column_test_mysql`').then(function(schema) { // .columnInfo() keys does not guaranteed fields order. - var fields = schema[0][0]['Create Table'].split('\n') - .filter(function(e) { return e.trim().indexOf('`field_') === 0 }) - .map(function(e) { return e.trim() }) - .map(function(e) { return e.slice(1, e.slice(1).indexOf('`') + 1) }); + const fields = schema[0][0]['Create Table'] + .split('\n') + .filter(function(e) { return e.trim().indexOf('`field_') === 0 }) + .map(function(e) { return e.trim() }) + .map(function(e) { return e.slice(1, e.slice(1).indexOf('`') + 1) }); // Fields order expect(fields[0]).to.equal('field_first'); @@ -674,10 +698,10 @@ module.exports = function(knex) { expect(fields[4]).to.equal('field_nondefault_increments'); // .columnInfo() does not included fields comment. - var comments = schema[0][0]['Create Table'].split('\n') - .filter(function(e) { return e.trim().indexOf('`field_') === 0 }) - .map(function(e) { return e.slice(e.indexOf("'")).trim() }) - .map(function(e) { return e.slice(1, e.slice(1).indexOf("'") + 1) }); + const comments = schema[0][0]['Create Table'].split('\n') + .filter(function(e) { return e.trim().indexOf('`field_') === 0 }) + .map(function(e) { return e.slice(e.indexOf("'")).trim() }) + .map(function(e) { return e.slice(1, e.slice(1).indexOf("'") + 1) }); // Fields comment expect(comments[0]).to.equal('First'); @@ -693,19 +717,27 @@ module.exports = function(knex) { describe('renameColumn', function () { before(function () { return knex.schema.createTable('rename_column_test', function (tbl) { - tbl.increments('id_test').unsigned() + tbl.increments('id_test') + .unsigned() .primary(); - tbl.integer('parent_id_test').unsigned() + tbl.integer('parent_id_test') + .unsigned() .references('id_test') .inTable('rename_column_test'); }) .createTable('rename_column_foreign_test', function(tbl) { - tbl.increments('id').unsigned() + tbl.increments('id') + .unsigned() .primary(); - tbl.integer('foreign_id_test').unsigned() + tbl.integer('foreign_id_test') + .unsigned() .references('id_test') .inTable('rename_column_test'); }) + .createTable('rename_col_test', function(tbl) { + tbl.integer('colnameint').defaultTo(1); + tbl.string('colnamestring').defaultTo('knex').notNullable(); + }) .then(function () { // without data, the column isn't found?? return knex.insert({parent_id_test: 1}).into('rename_column_test'); @@ -713,7 +745,10 @@ module.exports = function(knex) { }); after(function () { - return knex.schema.dropTable('rename_column_foreign_test').dropTable('rename_column_test'); + return knex.schema + .dropTable('rename_column_foreign_test') + .dropTable('rename_column_test') + .dropTable('rename_col_test'); }); it('renames the column', function () { @@ -741,19 +776,17 @@ module.exports = function(knex) { }); it('#933 - .renameColumn should not drop null or default value', function() { + const tableName = 'rename_col_test'; return knex.transaction(function (tr) { - var getColInfo = function() { return tr('renameColTest').columnInfo()}; - return tr.schema.dropTableIfExists('renameColTest') - .createTable('renameColTest', function (table) { - table.integer('colnameint').defaultTo(1); - table.string('colnamestring').defaultTo('knex').notNullable(); - }) - .then(getColInfo) + const getColInfo = () => tr(tableName).columnInfo(); + return getColInfo() .then(function (colInfo) { expect(String(colInfo.colnameint.defaultValue)).to.contain('1'); - expect(colInfo.colnamestring.defaultValue).to.contain('knex'); //Using contain because of different response per dialect. IE mysql 'knex', postgres 'knex::character varying' + // Using contain because of different response per dialect. + // IE mysql 'knex', postgres 'knex::character varying' + expect(colInfo.colnamestring.defaultValue).to.contain('knex'); expect(colInfo.colnamestring.nullable).to.equal(false); - return tr.schema.table('renameColTest', function (table) { + return tr.schema.table(tableName, function (table) { table.renameColumn('colnameint', 'colnameintchanged'); table.renameColumn('colnamestring', 'colnamestringchanged'); }) @@ -769,39 +802,66 @@ module.exports = function(knex) { }); + it('should warn attempting to create primary from nonexistent columns', function() { + // Redshift only + if(!knex || !knex.client || !(/redshift/i.test(knex.client.dialect))) { + return Promise.resolve(); + } + const tableName = 'no_test_column'; + const constraintName = 'testconstraintname'; + return knex.transaction(function(tr) { + return tr.schema.dropTableIfExists(tableName).then(function(){ + return tr.schema.createTable(tableName, function(t) { + t.string('test_zero').notNullable(); + t.string('test_one').notNullable(); + }); + }).then(function() { + return tr.schema.table(tableName, function(u) { + u.primary(['test_one', 'test_two'], constraintName); + }); + }).then(function(){ + throw new Error("should have failed"); + }).catch(function(err){ + expect(err.code).to.equal("42703"); + expect(err.message).to.equal(`alter table "${tableName}" add constraint "${constraintName}" primary key ("test_one", "test_two") - column "test_two" named in key does not exist`); + }).then(function(res){ + return knex.schema.dropTableIfExists(tableName); + }); + }); + }); + //Unit tests checks SQL -- This will test running those queries, no hard assertions here. it('#1430 - .primary() & .dropPrimary() same for all dialects', function() { if(/sqlite/i.test(knex.client.dialect)) { return Promise.resolve(); } - var constraintName = 'testconstraintname'; - var tableName = 'primarytest'; + const constraintName = 'testconstraintname'; + const tableName = 'primarytest'; return knex.transaction(function(tr) { return tr.schema.dropTableIfExists(tableName) .then(function() { - return tr.schema.createTable(tableName, function(table) { - table.string('test').primary(constraintName); - table.string('test2').notNullable(); - }) + return tr.schema.createTable(tableName, function(table) { + table.string('test').primary(constraintName); + table.string('test2').notNullable(); }) - .then(function() { - return tr.schema.table(tableName, function(table) { - table.dropPrimary(constraintName); - }) + }) + .then(function(res) { + return tr.schema.table(tableName, function(table) { + table.dropPrimary(constraintName); }) - .then(function() { - return tr.schema.table(tableName, function(table) { - table.primary(['test', 'test2'], constraintName) - }) - }); + }) + .then(function() { + return tr.schema.table(tableName, function(table) { + table.primary(['test', 'test2'], constraintName) + }) + }); }); }); - describe('invalid field', function() { describe('sqlite3 only', function() { - var tableName = 'invalid_field_test_sqlite3'; - var fieldName = 'field_foo'; + const tableName = 'invalid_field_test_sqlite3'; + const fieldName = 'field_foo'; if(!knex || !knex.client || (!(/sqlite3/i.test(knex.client.dialect)))) { return Promise.resolve(); } @@ -828,10 +888,10 @@ module.exports = function(knex) { return knex(tableName).select().where(fieldName+"foo", "something") .then(function(){ - throw new Error("should have failed"); + throw new Error("should have failed"); }) .catch(function(err){ - expect(err.code).to.equal("SQLITE_ERROR"); + expect(err.code).to.equal("SQLITE_ERROR"); }) }); @@ -840,6 +900,5 @@ module.exports = function(knex) { }); }); - }); }; diff --git a/test/knexfile.js b/test/knexfile.js index b4ffc527c..05665a431 100644 --- a/test/knexfile.js +++ b/test/knexfile.js @@ -5,7 +5,7 @@ var testConfig = process.env.KNEX_TEST && require(process.env.KNEX_TEST) || {}; var _ = require('lodash'); var Promise = require('bluebird'); -// excluding oracle and mssql dialects from default integrations test +// excluding redshift, oracle, and mssql dialects from default integrations test var testIntegrationDialects = (process.env.DB || "maria mysql mysql2 postgres sqlite3").match(/\w+/g); var pool = { @@ -147,6 +147,21 @@ var testConfigs = { } }, + redshift: { + dialect: 'redshift', + connection: testConfig.redshift || { + adapter: 'postgresql', + database: 'knex_test', + user: process.env.REDSHIFT_USER || 'postgres', + password: process.env.REDSHIFT_PASSWORD || '', + port: '5439', + host: process.env.REDSHIFT_HOST || '127.0.0.1', + }, + pool: pool, + migrations: migrations, + seeds: seeds + }, + sqlite3: { dialect: 'sqlite3', connection: testConfig.sqlite3 || { diff --git a/test/unit/query/builder.js b/test/unit/query/builder.js index f75ed9641..6e50accd4 100644 --- a/test/unit/query/builder.js +++ b/test/unit/query/builder.js @@ -4,6 +4,7 @@ var MySQL_Client = require('../../../lib/dialects/mysql') var PG_Client = require('../../../lib/dialects/postgres') +var Redshift_Client = require('../../../lib/dialects/redshift') var Oracle_Client = require('../../../lib/dialects/oracle') var Oracledb_Client = require('../../../lib/dialects/oracledb') var SQLite3_Client = require('../../../lib/dialects/sqlite3') @@ -12,6 +13,7 @@ var MSSQL_Client = require('../../../lib/dialects/mssql') var clients = { mysql: new MySQL_Client({}), postgres: new PG_Client({}), + redshift: new Redshift_Client({}), oracle: new Oracle_Client({}), oracledb: new Oracledb_Client({}), sqlite3: new SQLite3_Client({}), @@ -22,6 +24,7 @@ var useNullAsDefaultConfig = { useNullAsDefault: true }; var clientsWithNullAsDefault = { mysql: new MySQL_Client(useNullAsDefaultConfig), postgres: new PG_Client(useNullAsDefaultConfig), + redshift: new Redshift_Client(useNullAsDefaultConfig), oracle: new Oracle_Client(useNullAsDefaultConfig), oracledb: new Oracledb_Client(useNullAsDefaultConfig), sqlite3: new SQLite3_Client(useNullAsDefaultConfig), @@ -35,7 +38,7 @@ function qb() { } function raw(sql, bindings) { - return clients.postgres.raw(sql, bindings) + return clients.postgres.raw(sql, bindings); } function verifySqlResult(dialect, expectedObj, sqlObj) { @@ -105,6 +108,7 @@ describe("Custom identifier wrapping", function() { var clientsWithCustomIdentifierWrapper = { mysql: new MySQL_Client(customWrapperConfig), postgres: new PG_Client(customWrapperConfig), + redshift: new Redshift_Client(customWrapperConfig), oracle: new Oracle_Client(customWrapperConfig), oracledb: new Oracledb_Client(customWrapperConfig), sqlite3: new SQLite3_Client(customWrapperConfig), @@ -118,6 +122,7 @@ describe("Custom identifier wrapping", function() { mssql: 'select [users_wrapper_was_here].[foo_wrapper_was_here] as [bar_wrapper_was_here] from [schema_wrapper_was_here].[users_wrapper_was_here]', oracledb: 'select "users_wrapper_was_here"."foo_wrapper_was_here" "bar_wrapper_was_here" from "schema_wrapper_was_here"."users_wrapper_was_here"', postgres: 'select "users_wrapper_was_here"."foo_wrapper_was_here" as "bar_wrapper_was_here" from "schema_wrapper_was_here"."users_wrapper_was_here"', + redshift: 'select "users_wrapper_was_here"."foo_wrapper_was_here" as "bar_wrapper_was_here" from "schema_wrapper_was_here"."users_wrapper_was_here"', sqlite3: 'select `users_wrapper_was_here`.`foo_wrapper_was_here` as `bar_wrapper_was_here` from `schema_wrapper_was_here`.`users_wrapper_was_here`' }, clientsWithCustomIdentifierWrapper); }); @@ -184,6 +189,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users`', mssql: 'select * from [users]', postgres: 'select * from "users"', + redshift: 'select * from "users"', }); }); @@ -191,15 +197,25 @@ describe("QueryBuilder", function() { testsql(qb().select('foo').select('bar').select(['baz', 'boom']).from('users'), { mysql: 'select `foo`, `bar`, `baz`, `boom` from `users`', mssql: 'select [foo], [bar], [baz], [boom] from [users]', - postgres: 'select "foo", "bar", "baz", "boom" from "users"' + postgres: 'select "foo", "bar", "baz", "boom" from "users"', + redshift: 'select "foo", "bar", "baz", "boom" from "users"', }); }); it("basic select distinct", function() { testsql(qb().distinct().select('foo', 'bar').from('users'), { - mysql: {sql: 'select distinct `foo`, `bar` from `users`'}, - mssql: {sql: 'select distinct [foo], [bar] from [users]'}, - postgres: {sql: 'select distinct "foo", "bar" from "users"'} + mysql: { + sql: 'select distinct `foo`, `bar` from `users`' + }, + mssql: { + sql: 'select distinct [foo], [bar] from [users]' + }, + postgres: { + sql: 'select distinct "foo", "bar" from "users"' + }, + redshift: { + sql: 'select distinct "foo", "bar" from "users"' + }, }); }); @@ -249,7 +265,8 @@ describe("QueryBuilder", function() { oracle: 'select "foo" "bar" from "users"', mssql: 'select [foo] as [bar] from [users]', oracledb: 'select "foo" "bar" from "users"', - postgres: 'select "foo" as "bar" from "users"' + postgres: 'select "foo" as "bar" from "users"', + redshift: 'select "foo" as "bar" from "users"', }); }); @@ -259,7 +276,8 @@ describe("QueryBuilder", function() { oracle: 'select "foo" "bar" from "users"', mssql: 'select [foo] as [bar] from [users]', oracledb: 'select "foo" "bar" from "users"', - postgres: 'select "foo" as "bar" from "users"' + postgres: 'select "foo" as "bar" from "users"', + redshift: 'select "foo" as "bar" from "users"', }); }); @@ -269,7 +287,8 @@ describe("QueryBuilder", function() { oracle: 'select "foo" "bar" from "users"', mssql: 'select [foo] as [bar] from [users]', oracledb: 'select "foo" "bar" from "users"', - postgres: 'select "foo" as "bar" from "users"' + postgres: 'select "foo" as "bar" from "users"', + redshift: 'select "foo" as "bar" from "users"', }); }); @@ -278,7 +297,8 @@ describe("QueryBuilder", function() { mysql: 'select `foo` as `bar.baz` from `users`', oracle: 'select "foo" "bar.baz" from "users"', mssql: 'select [foo] as [bar.baz] from [users]', - postgres: 'select "foo" as "bar.baz" from "users"' + postgres: 'select "foo" as "bar.baz" from "users"', + redshift: 'select "foo" as "bar.baz" from "users"', }); }); @@ -305,7 +325,8 @@ describe("QueryBuilder", function() { testsql(qb().select('*').from('public.users'), { mysql: 'select * from `public`.`users`', mssql: 'select * from [public].[users]', - postgres: 'select * from "public"."users"' + postgres: 'select * from "public"."users"', + redshift: 'select * from "public"."users"', }); }); @@ -313,6 +334,7 @@ describe("QueryBuilder", function() { testsql(qb().withSchema('myschema').select('*').from('users'), { mysql: 'select * from `myschema`.`users`', postgres: 'select * from "myschema"."users"', + redshift: 'select * from "myschema"."users"', mssql: 'select * from [myschema].[users]', }); }); @@ -333,7 +355,10 @@ describe("QueryBuilder", function() { }, postgres: { sql: 'select * from "users"' - } + }, + redshift: { + sql: 'select * from "users"' + }, }); testsql(qb().select('id').from('users').clearSelect().select('email'), { @@ -345,7 +370,10 @@ describe("QueryBuilder", function() { }, postgres: { sql: 'select "email" from "users"' - } + }, + redshift: { + sql: 'select "email" from "users"' + }, }); }); @@ -359,7 +387,10 @@ describe("QueryBuilder", function() { }, postgres: { sql: 'select "id" from "users"' - } + }, + redshift: { + sql: 'select "id" from "users"' + }, }); testsql(qb().select('id').from('users').where('id', '=', 1).clearWhere().where('id', '=', 2), { @@ -374,7 +405,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select "id" from "users" where "id" = ?', bindings: [2] - } + }, + redshift: { + sql: 'select "id" from "users" where "id" = ?', + bindings: [2] + }, }); }); @@ -391,12 +426,17 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ?', bindings: [1] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ?', + bindings: [1] + }, }); testquery(qb().select('*').from('users').where('id', '=', 1), { mysql: 'select * from `users` where `id` = 1', postgres: 'select * from "users" where "id" = 1', + redshift: 'select * from "users" where "id" = 1', mssql: 'select * from [users] where [id] = 1', }); }); @@ -415,12 +455,17 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where not "id" = ?', bindings: [1] - } + }, + redshift: { + sql: 'select * from "users" where not "id" = ?', + bindings: [1] + }, }); testquery(qb().select('*').from('users').whereNot('id', '=', 1), { mysql: 'select * from `users` where not `id` = 1', postgres: 'select * from "users" where not "id" = 1', + redshift: 'select * from "users" where not "id" = 1', mssql: 'select * from [users] where not [id] = 1', }); }); @@ -438,12 +483,17 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where not ("id" = ? or not "id" = ?)', bindings: [1, 3] - } + }, + redshift: { + sql: 'select * from "users" where not ("id" = ? or not "id" = ?)', + bindings: [1, 3] + }, }); testquery(qb().select('*').from('users').whereNot(function() { this.where('id', '=', 1).orWhereNot('id', '=', 3); }), { mysql: 'select * from `users` where not (`id` = 1 or not `id` = 3)', postgres: 'select * from "users" where not ("id" = 1 or not "id" = 3)', + redshift: 'select * from "users" where not ("id" = 1 or not "id" = 3)', mssql: 'select * from [users] where not ([id] = 1 or not [id] = 3)', }); }); @@ -461,12 +511,17 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where ("id" = ? or not "id" = ?)', bindings: [1, 3] - } + }, + redshift: { + sql: 'select * from "users" where ("id" = ? or not "id" = ?)', + bindings: [1, 3] + }, }); testquery(qb().select('*').from('users').where(function() { this.where('id', '=', 1).orWhereNot('id', '=', 3); }), { mysql: 'select * from `users` where (`id` = 1 or not `id` = 3)', postgres: 'select * from "users" where ("id" = 1 or not "id" = 3)', + redshift: 'select * from "users" where ("id" = 1 or not "id" = 3)', mssql: 'select * from [users] where ([id] = 1 or not [id] = 3)', }); }); @@ -485,12 +540,17 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where not "first_name" = ? and not "last_name" = ?', bindings: ['Test', 'User'] - } + }, + redshift: { + sql: 'select * from "users" where not "first_name" = ? and not "last_name" = ?', + bindings: ['Test', 'User'] + }, }); testquery(qb().select('*').from('users').whereNot({first_name: 'Test', last_name: 'User'}), { mysql: 'select * from `users` where not `first_name` = \'Test\' and not `last_name` = \'User\'', postgres: 'select * from "users" where not "first_name" = \'Test\' and not "last_name" = \'User\'', + redshift: 'select * from "users" where not "first_name" = \'Test\' and not "last_name" = \'User\'', mssql: 'select * from [users] where not [first_name] = \'Test\' and not [last_name] = \'User\'', }); }); @@ -518,7 +578,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" between ? and ?', bindings: [1, 2] - } + }, + redshift: { + sql: 'select * from "users" where "id" between ? and ?', + bindings: [1, 2] + }, }); }); @@ -535,7 +599,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "name" = ? and "id" between ? and ?', bindings: ['user1', 1, 2] - } + }, + redshift: { + sql: 'select * from "users" where "name" = ? and "id" between ? and ?', + bindings: ['user1', 1, 2] + }, }); }); @@ -552,7 +620,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "name" = ? and "id" not between ? and ?', bindings: ['user1', 1, 2] - } + }, + redshift: { + sql: 'select * from "users" where "name" = ? and "id" not between ? and ?', + bindings: ['user1', 1, 2] + }, }); }); @@ -569,7 +641,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" between ? and ?', bindings: [1, 2] - } + }, + redshift: { + sql: 'select * from "users" where "id" between ? and ?', + bindings: [1, 2] + }, }); }); @@ -586,7 +662,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" not between ? and ?', bindings: [1, 2] - } + }, + redshift: { + sql: 'select * from "users" where "id" not between ? and ?', + bindings: [1, 2] + }, }); }); @@ -603,7 +683,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" not between ? and ?', bindings: [1, 2] - } + }, + redshift: { + sql: 'select * from "users" where "id" not between ? and ?', + bindings: [1, 2] + }, }); }); @@ -620,7 +704,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or "email" = ?', bindings: [1, 'foo'] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or "email" = ?', + bindings: [1, 'foo'] + }, }); }); @@ -637,7 +725,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or "email" = ?', bindings: [1, 'foo'] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or "email" = ?', + bindings: [1, 'foo'] + }, }); }); @@ -654,7 +746,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where LCASE("name") = ?', bindings: ['foo'] - } + }, + redshift: { + sql: 'select * from "users" where LCASE("name") = ?', + bindings: ['foo'] + }, }); }); @@ -671,7 +767,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where id = ? or email = ?', bindings: [1, 'foo'] - } + }, + redshift: { + sql: 'select * from "users" where id = ? or email = ?', + bindings: [1, 'foo'] + }, }); }); @@ -688,7 +788,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or email = ?', bindings: [1, 'foo'] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or email = ?', + bindings: [1, 'foo'] + }, }); }); @@ -705,7 +809,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or email = ?', bindings: [1, 'foo'] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or email = ?', + bindings: [1, 'foo'] + }, }); }); @@ -722,7 +830,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" in (?, ?, ?)', bindings: [1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" in (?, ?, ?)', + bindings: [1, 2, 3] + }, }); }); @@ -739,7 +851,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or "id" in (?, ?, ?)', bindings: [1, 1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or "id" in (?, ?, ?)', + bindings: [1, 1, 2, 3] + }, }); }); @@ -756,7 +872,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" not in (?, ?, ?)', bindings: [1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" not in (?, ?, ?)', + bindings: [1, 2, 3] + }, }); }); @@ -773,7 +893,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or "id" not in (?, ?, ?)', bindings: [1, 1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or "id" not in (?, ?, ?)', + bindings: [1, 1, 2, 3] + }, }); }); @@ -790,7 +914,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or "id" in (?, ?, ?)', bindings: [1, 4, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or "id" in (?, ?, ?)', + bindings: [1, 4, 2, 3] + }, }); }); @@ -807,7 +935,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" not in (?, ?, ?)', bindings: [1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" not in (?, ?, ?)', + bindings: [1, 2, 3] + }, }); }); @@ -824,7 +956,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or "id" not in (?, ?, ?)', bindings: [1, 1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or "id" not in (?, ?, ?)', + bindings: [1, 1, 2, 3] + }, }); }); @@ -845,7 +981,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where 1 = ?', bindings: [0] - } + }, + redshift: { + sql: 'select * from "users" where 1 = ?', + bindings: [0] + }, }); }); @@ -866,7 +1006,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where 1 = ?', bindings: [1] - } + }, + redshift: { + sql: 'select * from "users" where 1 = ?', + bindings: [1] + }, }); }); @@ -895,7 +1039,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "test" where "id" = ? and ("id" = ? or "id" = ?)', bindings: [1, 3, 4] - } + }, + redshift: { + sql: 'select * from "test" where "id" = ? and ("id" = ? or "id" = ?)', + bindings: [1, 3, 4] + }, }); }); @@ -919,12 +1067,17 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * where "id" = (select "account_id" from "names" where "names"."id" > ? or ("names"."first_name" like ? and "names"."id" > ?))', bindings: [1, 'Tim%', 10] - } + }, + redshift: { + sql: 'select * where "id" = (select "account_id" from "names" where "names"."id" > ? or ("names"."first_name" like ? and "names"."id" > ?))', + bindings: [1, 'Tim%', 10] + }, }); testquery(chain, { mysql: 'select * where `id` = (select `account_id` from `names` where `names`.`id` > 1 or (`names`.`first_name` like \'Tim%\' and `names`.`id` > 10))', postgres: 'select * where "id" = (select "account_id" from "names" where "names"."id" > 1 or ("names"."first_name" like \'Tim%\' and "names"."id" > 10))', + redshift: 'select * where "id" = (select "account_id" from "names" where "names"."id" > 1 or ("names"."first_name" like \'Tim%\' and "names"."id" > 10))', mssql: 'select * where [id] = (select [account_id] from [names] where [names].[id] > 1 or ([names].[first_name] like \'Tim%\' and [names].[id] > 10))', }); }); @@ -949,7 +1102,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * where "id" = (select "account_id" from "names" where "names"."id" > ? or ("names"."first_name" like ? and "names"."id" > ?))', bindings: [1, 'Tim%', 10] - } + }, + redshift: { + sql: 'select * where "id" = (select "account_id" from "names" where "names"."id" > ? or ("names"."first_name" like ? and "names"."id" > ?))', + bindings: [1, 'Tim%', 10] + }, }); }); @@ -985,7 +1142,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? union select * from "users" where "id" = ?', bindings: [1, 2] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? union select * from "users" where "id" = ?', + bindings: [1, 2] + }, }); var multipleArgumentsChain = qb().select('*').from('users').where({id: 1}).union(function() { @@ -1005,7 +1166,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? union select * from "users" where "id" = ? union select * from "users" where "id" = ?', bindings: [1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? union select * from "users" where "id" = ? union select * from "users" where "id" = ?', + bindings: [1, 2, 3] + }, }); var arrayChain = qb().select('*').from('users').where({id: 1}).union([ @@ -1027,7 +1192,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? union select * from "users" where "id" = ? union select * from "users" where "id" = ?', bindings: [1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? union select * from "users" where "id" = ? union select * from "users" where "id" = ?', + bindings: [1, 2, 3] + }, }); }); @@ -1049,7 +1218,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" in (select max("id") from "users" union (select min("id") from "users"))', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" where "id" in (select max("id") from "users" union (select min("id") from "users"))', + bindings: [] + }, }); // worthwhile since we're playing games with the 'wrap' specification with arguments @@ -1070,7 +1243,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? union (select * from "users" where "id" = ?) union (select * from "users" where "id" = ?)', bindings: [1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? union (select * from "users" where "id" = ?) union (select * from "users" where "id" = ?)', + bindings: [1, 2, 3] + }, }); var arrayWrappedChain = qb().select('*').from('users').where({id: 1}).union([ @@ -1092,7 +1269,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? union (select * from "users" where "id" = ?) union (select * from "users" where "id" = ?)', bindings: [1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? union (select * from "users" where "id" = ?) union (select * from "users" where "id" = ?)', + bindings: [1, 2, 3] + }, }); }); @@ -1121,7 +1302,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? union all select * from "users" where "id" = ?', bindings: [1, 2] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? union all select * from "users" where "id" = ?', + bindings: [1, 2] + }, }); }); @@ -1141,7 +1326,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? union select * from "users" where "id" = ? union select * from "users" where "id" = ?', bindings: [1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? union select * from "users" where "id" = ? union select * from "users" where "id" = ?', + bindings: [1, 2, 3] + }, }); }); @@ -1162,7 +1351,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? union all select * from "users" where "id" = ? union all select * from "users" where "id" = ?', bindings: [1, 2, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? union all select * from "users" where "id" = ? union all select * from "users" where "id" = ?', + bindings: [1, 2, 3] + }, }); }); @@ -1189,7 +1382,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" in (select "id" from "users" where "age" > ? limit ?)', bindings: [25, 3] - } + }, + redshift: { + sql: 'select * from "users" where "id" in (select "id" from "users" where "age" > ? limit ?)', + bindings: [25, 3] + }, }); }); @@ -1208,7 +1405,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" not in (select "id" from "users" where "age" > ?)', bindings: [25] - } + }, + redshift: { + sql: 'select * from "users" where "id" not in (select "id" from "users" where "age" > ?)', + bindings: [25] + }, }); }); @@ -1225,7 +1426,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" is null', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" where "id" is null', + bindings: [] + }, }); }); @@ -1242,7 +1447,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or "id" is null', bindings: [1] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or "id" is null', + bindings: [1] + }, }); }); @@ -1259,7 +1468,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" is not null', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" where "id" is not null', + bindings: [] + }, }); }); @@ -1276,7 +1489,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" > ? or "id" is not null', bindings: [1] - } + }, + redshift: { + sql: 'select * from "users" where "id" > ? or "id" is not null', + bindings: [1] + }, }); }); @@ -1293,7 +1510,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" group by "id", "email"', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" group by "id", "email"', + bindings: [] + }, }); }); @@ -1310,7 +1531,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" order by "email" asc, "age" desc', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" order by "email" asc, "age" desc', + bindings: [] + }, }); }); @@ -1327,7 +1552,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" group by id, email', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" group by id, email', + bindings: [] + }, }); }); @@ -1344,7 +1573,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" order by col NULLS LAST asc', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" order by col NULLS LAST asc', + bindings: [] + }, }); }); @@ -1361,7 +1594,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" order by col NULLS LAST desc', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" order by col NULLS LAST desc', + bindings: [] + }, }); }); @@ -1378,7 +1615,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" order by col NULLS LAST DESC', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" order by col NULLS LAST DESC', + bindings: [] + }, }); }); @@ -1395,7 +1636,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" order by col NULLS LAST ?', bindings: ['dEsc'] - } + }, + redshift: { + sql: 'select * from "users" order by col NULLS LAST ?', + bindings: ['dEsc'] + }, }); }); @@ -1412,7 +1657,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" order by "email" asc, "age" desc', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" order by "email" asc, "age" desc', + bindings: [] + }, }); }); @@ -1421,6 +1670,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `email` > ?', mssql: 'select * from [users] having [email] > ?', postgres: 'select * from "users" having "email" > ?', + redshift: 'select * from "users" having "email" > ?', oracledb: 'select * from "users" having "email" > ?', oracle: 'select * from "users" having "email" > ?' }); @@ -1431,6 +1681,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` > ? or `email` = ?', mssql: 'select * from [users] having [baz] > ? or [email] = ?', postgres: 'select * from "users" having "baz" > ? or "email" = ?', + redshift: 'select * from "users" having "baz" > ? or "email" = ?', oracledb: 'select * from "users" having "baz" > ? or "email" = ?', oracle: 'select * from "users" having "baz" > ? or "email" = ?' }); @@ -1443,6 +1694,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having (`email` > ?)', mssql: 'select * from [users] having ([email] > ?)', postgres: 'select * from "users" having ("email" > ?)', + redshift: 'select * from "users" having ("email" > ?)', oracledb: 'select * from "users" having ("email" > ?)', oracle: 'select * from "users" having ("email" > ?)' }); @@ -1456,6 +1708,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having (`email` > ? or `email` = ?)', mssql: 'select * from [users] having ([email] > ? or [email] = ?)', postgres: 'select * from "users" having ("email" > ? or "email" = ?)', + redshift: 'select * from "users" having ("email" > ? or "email" = ?)', oracledb: 'select * from "users" having ("email" > ? or "email" = ?)', oracle: 'select * from "users" having ("email" > ? or "email" = ?)' }); @@ -1466,6 +1719,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` group by `email` having `email` > ?', mssql: 'select * from [users] group by [email] having [email] > ?', postgres: 'select * from "users" group by "email" having "email" > ?', + redshift: 'select * from "users" group by "email" having "email" > ?', oracledb: 'select * from "users" group by "email" having "email" > ?', oracle: 'select * from "users" group by "email" having "email" > ?' }); @@ -1486,6 +1740,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having user_foo < user_bar', mssql: 'select * from [users] having user_foo < user_bar', postgres: 'select * from "users" having user_foo < user_bar', + redshift: 'select * from "users" having user_foo < user_bar', oracledb: 'select * from "users" having user_foo < user_bar', oracle: 'select * from "users" having user_foo < user_bar' }); @@ -1496,6 +1751,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` = ? or user_foo < user_bar', mssql: 'select * from [users] having [baz] = ? or user_foo < user_bar', postgres: 'select * from "users" having "baz" = ? or user_foo < user_bar', + redshift: 'select * from "users" having "baz" = ? or user_foo < user_bar', oracledb: 'select * from "users" having "baz" = ? or user_foo < user_bar', oracle: 'select * from "users" having "baz" = ? or user_foo < user_bar' }); @@ -1506,6 +1762,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` is null', mssql: 'select * from [users] having [baz] is null', postgres: 'select * from "users" having "baz" is null', + redshift: 'select * from "users" having "baz" is null', oracledb: 'select * from "users" having "baz" is null', oracle: 'select * from "users" having "baz" is null' }); @@ -1516,6 +1773,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` is null or `foo` is null', mssql: 'select * from [users] having [baz] is null or [foo] is null', postgres: 'select * from "users" having "baz" is null or "foo" is null', + redshift: 'select * from "users" having "baz" is null or "foo" is null', oracledb: 'select * from "users" having "baz" is null or "foo" is null', oracle: 'select * from "users" having "baz" is null or "foo" is null' }); @@ -1526,6 +1784,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` is not null', mssql: 'select * from [users] having [baz] is not null', postgres: 'select * from "users" having "baz" is not null', + redshift: 'select * from "users" having "baz" is not null', oracledb: 'select * from "users" having "baz" is not null', oracle: 'select * from "users" having "baz" is not null' }); @@ -1536,6 +1795,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` is not null or `foo` is not null', mssql: 'select * from [users] having [baz] is not null or [foo] is not null', postgres: 'select * from "users" having "baz" is not null or "foo" is not null', + redshift: 'select * from "users" having "baz" is not null or "foo" is not null', oracledb: 'select * from "users" having "baz" is not null or "foo" is not null', oracle: 'select * from "users" having "baz" is not null or "foo" is not null' }); @@ -1548,6 +1808,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having exists (select `baz` from `users`)', mssql: 'select * from [users] having exists (select [baz] from [users])', postgres: 'select * from "users" having exists (select "baz" from "users")', + redshift: 'select * from "users" having exists (select "baz" from "users")', oracledb: 'select * from "users" having exists (select "baz" from "users")', oracle: 'select * from "users" having exists (select "baz" from "users")' }); @@ -1562,6 +1823,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having exists (select `baz` from `users`) or exists (select `foo` from `users`)', mssql: 'select * from [users] having exists (select [baz] from [users]) or exists (select [foo] from [users])', postgres: 'select * from "users" having exists (select "baz" from "users") or exists (select "foo" from "users")', + redshift: 'select * from "users" having exists (select "baz" from "users") or exists (select "foo" from "users")', oracledb: 'select * from "users" having exists (select "baz" from "users") or exists (select "foo" from "users")', oracle: 'select * from "users" having exists (select "baz" from "users") or exists (select "foo" from "users")' }); @@ -1574,6 +1836,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having not exists (select `baz` from `users`)', mssql: 'select * from [users] having not exists (select [baz] from [users])', postgres: 'select * from "users" having not exists (select "baz" from "users")', + redshift: 'select * from "users" having not exists (select "baz" from "users")', oracledb: 'select * from "users" having not exists (select "baz" from "users")', oracle: 'select * from "users" having not exists (select "baz" from "users")' }); @@ -1588,6 +1851,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having not exists (select `baz` from `users`) or not exists (select `foo` from `users`)', mssql: 'select * from [users] having not exists (select [baz] from [users]) or not exists (select [foo] from [users])', postgres: 'select * from "users" having not exists (select "baz" from "users") or not exists (select "foo" from "users")', + redshift: 'select * from "users" having not exists (select "baz" from "users") or not exists (select "foo" from "users")', oracledb: 'select * from "users" having not exists (select "baz" from "users") or not exists (select "foo" from "users")', oracle: 'select * from "users" having not exists (select "baz" from "users") or not exists (select "foo" from "users")' }); @@ -1598,6 +1862,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` between ? and ?', mssql: 'select * from [users] having [baz] between ? and ?', postgres: 'select * from "users" having "baz" between ? and ?', + redshift: 'select * from "users" having "baz" between ? and ?', oracledb: 'select * from "users" having "baz" between ? and ?', oracle: 'select * from "users" having "baz" between ? and ?' }); @@ -1608,6 +1873,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` between ? and ? or `baz` between ? and ?', mssql: 'select * from [users] having [baz] between ? and ? or [baz] between ? and ?', postgres: 'select * from "users" having "baz" between ? and ? or "baz" between ? and ?', + redshift: 'select * from "users" having "baz" between ? and ? or "baz" between ? and ?', oracledb: 'select * from "users" having "baz" between ? and ? or "baz" between ? and ?', oracle: 'select * from "users" having "baz" between ? and ? or "baz" between ? and ?' }); @@ -1618,6 +1884,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` not between ? and ?', mssql: 'select * from [users] having [baz] not between ? and ?', postgres: 'select * from "users" having "baz" not between ? and ?', + redshift: 'select * from "users" having "baz" not between ? and ?', oracledb: 'select * from "users" having "baz" not between ? and ?', oracle: 'select * from "users" having "baz" not between ? and ?' }); @@ -1628,6 +1895,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` not between ? and ? or `baz` not between ? and ?', mssql: 'select * from [users] having [baz] not between ? and ? or [baz] not between ? and ?', postgres: 'select * from "users" having "baz" not between ? and ? or "baz" not between ? and ?', + redshift: 'select * from "users" having "baz" not between ? and ? or "baz" not between ? and ?', oracledb: 'select * from "users" having "baz" not between ? and ? or "baz" not between ? and ?', oracle: 'select * from "users" having "baz" not between ? and ? or "baz" not between ? and ?' }); @@ -1638,6 +1906,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` in (?, ?, ?)', mssql: 'select * from [users] having [baz] in (?, ?, ?)', postgres: 'select * from "users" having "baz" in (?, ?, ?)', + redshift: 'select * from "users" having "baz" in (?, ?, ?)', oracledb: 'select * from "users" having "baz" in (?, ?, ?)', oracle: 'select * from "users" having "baz" in (?, ?, ?)' }); @@ -1648,6 +1917,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` in (?, ?, ?) or `foo` in (?, ?)', mssql: 'select * from [users] having [baz] in (?, ?, ?) or [foo] in (?, ?)', postgres: 'select * from "users" having "baz" in (?, ?, ?) or "foo" in (?, ?)', + redshift: 'select * from "users" having "baz" in (?, ?, ?) or "foo" in (?, ?)', oracledb: 'select * from "users" having "baz" in (?, ?, ?) or "foo" in (?, ?)', oracle: 'select * from "users" having "baz" in (?, ?, ?) or "foo" in (?, ?)' }); @@ -1658,6 +1928,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` not in (?, ?, ?)', mssql: 'select * from [users] having [baz] not in (?, ?, ?)', postgres: 'select * from "users" having "baz" not in (?, ?, ?)', + redshift: 'select * from "users" having "baz" not in (?, ?, ?)', oracledb: 'select * from "users" having "baz" not in (?, ?, ?)', oracle: 'select * from "users" having "baz" not in (?, ?, ?)' }); @@ -1668,6 +1939,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` having `baz` not in (?, ?, ?) or `foo` not in (?, ?)', mssql: 'select * from [users] having [baz] not in (?, ?, ?) or [foo] not in (?, ?)', postgres: 'select * from "users" having "baz" not in (?, ?, ?) or "foo" not in (?, ?)', + redshift: 'select * from "users" having "baz" not in (?, ?, ?) or "foo" not in (?, ?)', oracledb: 'select * from "users" having "baz" not in (?, ?, ?) or "foo" not in (?, ?)', oracle: 'select * from "users" having "baz" not in (?, ?, ?) or "foo" not in (?, ?)' }); @@ -1694,7 +1966,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" limit ?', bindings: [10] - } + }, + redshift: { + sql: 'select * from "users" limit ?', + bindings: [10] + }, }); }); @@ -1719,7 +1995,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" limit ?', bindings: [0] - } + }, + redshift: { + sql: 'select * from "users" limit ?', + bindings: [0] + }, }); }); @@ -1744,7 +2024,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" limit ? offset ?', bindings: [10, 5] - } + }, + redshift: { + sql: 'select * from "users" limit ? offset ?', + bindings: [10, 5] + }, }); }); @@ -1769,7 +2053,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select name = ? as isJohn from "users" limit ?', bindings: ['john', 1] - } + }, + redshift: { + sql: 'select name = ? as isJohn from "users" limit ?', + bindings: ['john', 1] + }, }); }); @@ -1794,7 +2082,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" limit ?', bindings: [1] - } + }, + redshift: { + sql: 'select * from "users" limit ?', + bindings: [1] + }, }); }); @@ -1812,6 +2104,10 @@ describe("QueryBuilder", function() { sql: 'select * from "users" offset ?', bindings: [5] }, + redshift: { + sql: 'select * from "users" offset ?', + bindings: [5] + }, oracle: { sql: 'select * from (select row_.*, ROWNUM rownum_ from (select * from "users") row_ where rownum <= ?) where rownum_ > ?', bindings: [10000000000005, 5] @@ -1840,7 +2136,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or "name" = ?', bindings: [1, 'foo'] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or "name" = ?', + bindings: [1, 'foo'] + }, }); }); @@ -1859,7 +2159,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "email" = ? or ("name" = ? and "age" = ?)', bindings: ['foo', 'bar', 25] - } + }, + redshift: { + sql: 'select * from "users" where "email" = ? or ("name" = ? and "age" = ?)', + bindings: ['foo', 'bar', 25] + }, }); }); @@ -1879,7 +2183,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "email" = ?', bindings: ['foo'] - } + }, + redshift: { + sql: 'select * from "users" where "email" = ?', + bindings: ['foo'] + }, }); }); @@ -1895,7 +2203,10 @@ describe("QueryBuilder", function() { }, postgres: { sql: 'select * from "users"' - } + }, + redshift: { + sql: 'select * from "users"' + }, }); }); @@ -1914,7 +2225,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "email" = ? or "id" = (select max(id) from "users" where "email" = ?)', bindings: ['foo', 'bar'] - } + }, + redshift: { + sql: 'select * from "users" where "email" = ? or "id" = (select max(id) from "users" where "email" = ?)', + bindings: ['foo', 'bar'] + }, }); }); @@ -1933,7 +2248,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select "email" from "users" where "email" = ? or "id" = (select * from "users" where "email" = ?)', bindings: ['foo', 'bar'] - } + }, + redshift: { + sql: 'select "email" from "users" where "email" = ? or "id" = (select * from "users" where "email" = ?)', + bindings: ['foo', 'bar'] + }, }); }); @@ -1952,7 +2271,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "email" = ? or "id" = (select max(id) from "users" where "email" = ?)', bindings: ['foo', 'bar'] - } + }, + redshift: { + sql: 'select * from "users" where "email" = ? or "id" = (select max(id) from "users" where "email" = ?)', + bindings: ['foo', 'bar'] + }, }); }); @@ -1971,7 +2294,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "orders" where exists (select * from "products" where "products"."id" = "orders"."id")', bindings: [] - } + }, + redshift: { + sql: 'select * from "orders" where exists (select * from "products" where "products"."id" = "orders"."id")', + bindings: [] + }, }); }); @@ -1988,7 +2315,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "orders" where exists (select * from "products" where products.id = orders.id)', bindings: [] - } + }, + redshift: { + sql: 'select * from "orders" where exists (select * from "products" where products.id = orders.id)', + bindings: [] + }, }); }); @@ -2007,7 +2338,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "orders" where not exists (select * from "products" where "products"."id" = "orders"."id")', bindings: [] - } + }, + redshift: { + sql: 'select * from "orders" where not exists (select * from "products" where "products"."id" = "orders"."id")', + bindings: [] + }, }); }); @@ -2026,7 +2361,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "orders" where "id" = ? or exists (select * from "products" where "products"."id" = "orders"."id")', bindings: [1] - } + }, + redshift: { + sql: 'select * from "orders" where "id" = ? or exists (select * from "products" where "products"."id" = "orders"."id")', + bindings: [1] + }, }); }); @@ -2045,7 +2384,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "orders" where "id" = ? or not exists (select * from "products" where "products"."id" = "orders"."id")', bindings: [1] - } + }, + redshift: { + sql: 'select * from "orders" where "id" = ? or not exists (select * from "products" where "products"."id" = "orders"."id")', + bindings: [1] + }, }); }); @@ -2063,6 +2406,10 @@ describe("QueryBuilder", function() { sql: 'select * from "users" cross join "contracts" cross join "photos"', bindings: [] }, + redshift: { + sql: 'select * from "users" cross join "contracts" cross join "photos"', + bindings: [] + }, sqlite3: { sql: 'select * from `users` cross join `contracts` cross join `photos`', bindings: [] @@ -2095,7 +2442,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" full outer join "contacts" on "users"."id" = "contacts"."id"', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" full outer join "contacts" on "users"."id" = "contacts"."id"', + bindings: [] + }, }); }); @@ -2125,7 +2476,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" left join "photos" on "users"."id" = "photos"."id"', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" left join "photos" on "users"."id" = "photos"."id"', + bindings: [] + }, }); }); @@ -2150,7 +2505,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" right join "contacts" on "users"."id" = "contacts"."id" right outer join "photos" on "users"."id" = "photos"."id"', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" right join "contacts" on "users"."id" = "contacts"."id" right outer join "photos" on "users"."id" = "photos"."id"', + bindings: [] + }, }); }); @@ -2169,7 +2528,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" or "users"."name" = "contacts"."name"', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" or "users"."name" = "contacts"."name"', + bindings: [] + }, }); }); @@ -2191,7 +2554,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" inner join "contacts" on ("users"."id" = "contacts"."id" or "users"."name" = "contacts"."name")', bindings: [] - } + }, + redshift: { + sql: 'select * from "users" inner join "contacts" on ("users"."id" = "contacts"."id" or "users"."name" = "contacts"."name")', + bindings: [] + }, }); }); @@ -2208,7 +2575,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" inner join "contacts" on "users"."id" = 1 left join "photos" on "photos"."title" = ?', bindings: ['My Photo'] - } + }, + redshift: { + sql: 'select * from "users" inner join "contacts" on "users"."id" = 1 left join "photos" on "photos"."title" = ?', + bindings: ['My Photo'] + }, }); }); @@ -2225,7 +2596,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "myschema"."users" inner join "myschema"."contacts" on "users"."id" = "contacts"."id" left join "myschema"."photos" on "users"."id" = "photos"."id"', bindings: [] - } + }, + redshift: { + sql: 'select * from "myschema"."users" inner join "myschema"."contacts" on "users"."id" = "contacts"."id" left join "myschema"."photos" on "users"."id" = "photos"."id"', + bindings: [] + }, }); }); @@ -2236,6 +2611,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`address` is null', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[address] is null', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is null', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is null', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is null', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is null' }); @@ -2248,6 +2624,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`address` is null or `contacts`.`phone` is null', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[address] is null or [contacts].[phone] is null', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is null or "contacts"."phone" is null', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is null or "contacts"."phone" is null', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is null or "contacts"."phone" is null', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is null or "contacts"."phone" is null' }); @@ -2260,6 +2637,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`address` is not null', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[address] is not null', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is not null', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is not null', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is not null', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is not null' }); @@ -2272,6 +2650,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`address` is not null or `contacts`.`phone` is not null', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[address] is not null or [contacts].[phone] is not null', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is not null or "contacts"."phone" is not null', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is not null or "contacts"."phone" is not null', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is not null or "contacts"."phone" is not null', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."address" is not null or "contacts"."phone" is not null' }); @@ -2284,6 +2663,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and exists (select * from `foo`)', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and exists (select * from [foo])', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and exists (select * from "foo")', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and exists (select * from "foo")', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and exists (select * from "foo")', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and exists (select * from "foo")' }); @@ -2296,6 +2676,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and exists (select * from `foo`) or exists (select * from `bar`)', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and exists (select * from [foo]) or exists (select * from [bar])', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and exists (select * from "foo") or exists (select * from "bar")', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and exists (select * from "foo") or exists (select * from "bar")', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and exists (select * from "foo") or exists (select * from "bar")', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and exists (select * from "foo") or exists (select * from "bar")' }); @@ -2308,6 +2689,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and not exists (select * from `foo`)', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and not exists (select * from [foo])', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and not exists (select * from "foo")', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and not exists (select * from "foo")', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and not exists (select * from "foo")', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and not exists (select * from "foo")' }); @@ -2320,6 +2702,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and not exists (select * from `foo`) or not exists (select * from `bar`)', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and not exists (select * from [foo]) or not exists (select * from [bar])', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and not exists (select * from "foo") or not exists (select * from "bar")', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and not exists (select * from "foo") or not exists (select * from "bar")', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and not exists (select * from "foo") or not exists (select * from "bar")', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and not exists (select * from "foo") or not exists (select * from "bar")' }); @@ -2332,6 +2715,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`id` between ? and ?', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[id] between ? and ?', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" between ? and ?', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" between ? and ?', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" between ? and ?', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" between ? and ?' }); @@ -2344,6 +2728,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`id` between ? and ? or `users`.`id` between ? and ?', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[id] between ? and ? or [users].[id] between ? and ?', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" between ? and ? or "users"."id" between ? and ?', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" between ? and ? or "users"."id" between ? and ?', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" between ? and ? or "users"."id" between ? and ?', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" between ? and ? or "users"."id" between ? and ?' }); @@ -2356,6 +2741,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`id` not between ? and ?', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[id] not between ? and ?', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not between ? and ?', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not between ? and ?', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not between ? and ?', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not between ? and ?' }); @@ -2368,6 +2754,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`id` not between ? and ? or `users`.`id` not between ? and ?', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[id] not between ? and ? or [users].[id] not between ? and ?', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not between ? and ? or "users"."id" not between ? and ?', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not between ? and ? or "users"."id" not between ? and ?', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not between ? and ? or "users"."id" not between ? and ?', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not between ? and ? or "users"."id" not between ? and ?' }); @@ -2380,6 +2767,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`id` in (?, ?, ?, ?)', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[id] in (?, ?, ?, ?)', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" in (?, ?, ?, ?)', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" in (?, ?, ?, ?)', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" in (?, ?, ?, ?)', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" in (?, ?, ?, ?)' }); @@ -2392,6 +2780,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`id` in (?, ?, ?, ?) or `users`.`id` in (?, ?)', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[id] in (?, ?, ?, ?) or [users].[id] in (?, ?)', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" in (?, ?, ?, ?) or "users"."id" in (?, ?)', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" in (?, ?, ?, ?) or "users"."id" in (?, ?)', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" in (?, ?, ?, ?) or "users"."id" in (?, ?)', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" in (?, ?, ?, ?) or "users"."id" in (?, ?)' }); @@ -2404,6 +2793,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`id` not in (?, ?, ?, ?)', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[id] not in (?, ?, ?, ?)', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not in (?, ?, ?, ?)', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not in (?, ?, ?, ?)', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not in (?, ?, ?, ?)', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not in (?, ?, ?, ?)' }); @@ -2416,6 +2806,7 @@ describe("QueryBuilder", function() { mysql: 'select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`id` not in (?, ?, ?, ?) or `users`.`id` not in (?, ?)', mssql: 'select * from [users] inner join [contacts] on [users].[id] = [contacts].[id] and [contacts].[id] not in (?, ?, ?, ?) or [users].[id] not in (?, ?)', postgres: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not in (?, ?, ?, ?) or "users"."id" not in (?, ?)', + redshift: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not in (?, ?, ?, ?) or "users"."id" not in (?, ?)', oracledb: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not in (?, ?, ?, ?) or "users"."id" not in (?, ?)', oracle: 'select * from "users" inner join "contacts" on "users"."id" = "contacts"."id" and "contacts"."id" not in (?, ?, ?, ?) or "users"."id" not in (?, ?)' }); @@ -2434,7 +2825,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select substr(foo, 6) from "users"', bindings: [] - } + }, + redshift: { + sql: 'select substr(foo, 6) from "users"', + bindings: [] + }, }); }); @@ -2451,7 +2846,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select count(*) from "users"', bindings: [] - } + }, + redshift: { + sql: 'select count(*) from "users"', + bindings: [] + }, }); }); @@ -2468,7 +2867,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select count(distinct *) from "users"', bindings: [] - } + }, + redshift: { + sql: 'select count(distinct *) from "users"', + bindings: [] + }, }); }); @@ -2493,7 +2896,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select count(*) as "all" from "users"', bindings: [] - } + }, + redshift: { + sql: 'select count(*) as "all" from "users"', + bindings: [] + }, }); }); @@ -2518,7 +2925,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select count(distinct *) as "all" from "users"', bindings: [] - } + }, + redshift: { + sql: 'select count(distinct *) as "all" from "users"', + bindings: [] + }, }); }); @@ -2569,7 +2980,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select max("id") from "users"', bindings: [] - } + }, + redshift: { + sql: 'select max("id") from "users"', + bindings: [] + }, }); }); @@ -2603,7 +3018,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select max("id") from "users"', bindings: [] - } + }, + redshift: { + sql: 'select max("id") from "users"', + bindings: [] + }, }); }); @@ -2637,7 +3056,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select sum("id") from "users"', bindings: [] - } + }, + redshift: { + sql: 'select sum("id") from "users"', + bindings: [] + }, }); }); @@ -2671,7 +3094,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select sum(distinct "id") from "users"', bindings: [] - } + }, + redshift: { + sql: 'select sum(distinct "id") from "users"', + bindings: [] + }, }); }); @@ -2756,7 +3183,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into "users" ("email") values (?)', bindings: ['foo'] - } + }, + redshift: { + sql: 'insert into "users" ("email") values (?)', + bindings: ['foo'] + }, }); }); @@ -2785,7 +3216,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into "users" ("email", "name") values (?, ?), (?, ?)', bindings: ['foo', 'taylor', 'bar', 'dayle'] - } + }, + redshift: { + sql: 'insert into "users" ("email", "name") values (?, ?), (?, ?)', + bindings: ['foo', 'taylor', 'bar', 'dayle'] + }, }); }); @@ -2796,7 +3231,8 @@ describe("QueryBuilder", function() { oracle: 'begin execute immediate \'insert into "users" ("email", "name") values (:1, :2)\' using \'foo\', \'taylor\'; execute immediate \'insert into "users" ("email", "name") values (:1, :2)\' using NULL, \'dayle\';end;', mssql: "insert into [users] ([email], [name]) values ('foo', 'taylor'), (NULL, 'dayle')", oracledb: 'begin execute immediate \'insert into "users" ("email", "name") values (:1, :2)\' using \'foo\', \'taylor\'; execute immediate \'insert into "users" ("email", "name") values (:1, :2)\' using NULL, \'dayle\';end;', - postgres: 'insert into "users" ("email", "name") values (\'foo\', \'taylor\'), (NULL, \'dayle\')' + postgres: 'insert into "users" ("email", "name") values (\'foo\', \'taylor\'), (NULL, \'dayle\')', + redshift: 'insert into "users" ("email", "name") values (\'foo\', \'taylor\'), (NULL, \'dayle\')', }, clientsWithNullAsDefault); }); @@ -2806,7 +3242,8 @@ describe("QueryBuilder", function() { oracle: 'begin execute immediate \'insert into "users" ("email", "name") values (:1, :2)\' using \'foo\', \'taylor\'; execute immediate \'insert into "users" ("email", "name") values (DEFAULT, :1)\' using \'dayle\';end;', mssql: "insert into [users] ([email], [name]) values ('foo', 'taylor'), (DEFAULT, 'dayle')", oracledb: 'begin execute immediate \'insert into "users" ("email", "name") values (:1, :2)\' using \'foo\', \'taylor\'; execute immediate \'insert into "users" ("email", "name") values (DEFAULT, :1)\' using \'dayle\';end;', - postgres: 'insert into "users" ("email", "name") values (\'foo\', \'taylor\'), (DEFAULT, \'dayle\')' + postgres: 'insert into "users" ("email", "name") values (\'foo\', \'taylor\'), (DEFAULT, \'dayle\')', + redshift: 'insert into "users" ("email", "name") values (\'foo\', \'taylor\'), (DEFAULT, \'dayle\')', }); }); @@ -2833,6 +3270,10 @@ describe("QueryBuilder", function() { sql: "insert into \"users\" (\"email\", \"name\") values (?, ?), (?, ?) returning \"id\"", bindings: ['foo', 'taylor', 'bar', 'dayle'] }, + redshift: { + sql: "insert into \"users\" (\"email\", \"name\") values (?, ?), (?, ?)", + bindings: ['foo', 'taylor', 'bar', 'dayle'] + }, oracle: { sql: "begin execute immediate 'insert into \"users\" (\"email\", \"name\") values (:1, :2) returning ROWID into :3' using ?, ?, out ?; execute immediate 'insert into \"users\" (\"email\", \"name\") values (:1, :2) returning ROWID into :3' using ?, ?, out ?;end;", bindings: function(bindings) { @@ -2878,6 +3319,10 @@ describe("QueryBuilder", function() { sql: 'insert into "users" ("email", "name") values (?, ?), (?, ?) returning "id", "name"', bindings: ['foo', 'taylor', 'bar', 'dayle'] }, + redshift: { + sql: 'insert into "users" ("email", "name") values (?, ?), (?, ?)', + bindings: ['foo', 'taylor', 'bar', 'dayle'] + }, oracle: { sql: "begin execute immediate 'insert into \"users\" (\"email\", \"name\") values (:1, :2) returning ROWID into :3' using ?, ?, out ?; execute immediate 'insert into \"users\" (\"email\", \"name\") values (:1, :2) returning ROWID into :3' using ?, ?, out ?;end;", bindings: function (bindings) { @@ -2924,7 +3369,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into "users" ("email") values (CURRENT TIMESTAMP)', bindings: [] - } + }, + redshift: { + sql: 'insert into "users" ("email") values (CURRENT TIMESTAMP)', + bindings: [] + }, }); }); @@ -2961,7 +3410,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into "table" ("a", "b", "c") values (?, DEFAULT, DEFAULT), (DEFAULT, ?, DEFAULT), (?, DEFAULT, ?)', bindings: [1, 2, 2, 3] - } + }, + redshift: { + sql: 'insert into "table" ("a", "b", "c") values (?, DEFAULT, DEFAULT), (DEFAULT, ?, DEFAULT), (?, DEFAULT, ?)', + bindings: [1, 2, 2, 3] + }, }); clients.sqlite3.valueForUndefined = previousValuesForUndefinedSqlite3; }); @@ -2987,7 +3440,11 @@ describe("QueryBuilder", function() { postgres: { sql: '', bindings: [] - } + }, + redshift: { + sql: '', + bindings: [] + }, }); }); @@ -3012,7 +3469,11 @@ describe("QueryBuilder", function() { postgres: { sql: '', bindings: [] - } + }, + redshift: { + sql: '', + bindings: [] + }, }); }); @@ -3030,6 +3491,10 @@ describe("QueryBuilder", function() { sql: 'insert into "users" default values returning "id"', bindings: [] }, + redshift: { + sql: 'insert into "users" default values', + bindings: [] + }, oracle: { sql: "insert into \"users\" (\"id\") values (default) returning ROWID into ?", bindings: function (bindings) { @@ -3065,6 +3530,10 @@ describe("QueryBuilder", function() { // sql: '', // bindings: [] // }, + // redshift: { + // sql: '', + // bindings: [] + // }, // oracle: { // sql: "", // bindings: [] @@ -3080,7 +3549,11 @@ describe("QueryBuilder", function() { // postgres: { // sql: '', // bindings: [] - // } + // }, + // redshift: { + // sql: '', + // bindings: [] + // }, // }); // }); @@ -3103,17 +3576,25 @@ describe("QueryBuilder", function() { // bindings: [] // }, // postgres: { - // sql: "", - // bindings: [] + // sql: "", + // bindings: [] + // }, + // redshift: { + // sql: "", + // bindings: [] // }, // mssql: { // sql: '', // bindings: [] // }, // postgres: { - // sql: '', - // bindings: [] - // } + // sql: '', + // bindings: [] + // }, + // redshift: { + // sql: '', + // bindings: [] + // }, // }); // }); @@ -3130,7 +3611,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'update "users" set "email" = ?, "name" = ? where "id" = ?', bindings: ['foo', 'bar', 1] - } + }, + redshift: { + sql: 'update "users" set "email" = ?, "name" = ? where "id" = ?', + bindings: ['foo', 'bar', 1] + }, }); }); @@ -3139,7 +3624,7 @@ describe("QueryBuilder", function() { postgres: { sql: 'update only "users" set "email" = ?, "name" = ? where "id" = ?', bindings: ['foo', 'bar', 1] - } + }, }); }); @@ -3152,7 +3637,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'update "users" set "email" = ? where "id" = ?', bindings: ['foo', 1] - } + }, + redshift: { + sql: 'update "users" set "email" = ? where "id" = ?', + bindings: ['foo', 1] + }, }); }); @@ -3169,7 +3658,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'update "users" set "email" = ?, "name" = ? where "id" = ?', bindings: [null, 'bar', 1] - } + }, + redshift: { + sql: 'update "users" set "email" = ?, "name" = ? where "id" = ?', + bindings: [null, 'bar', 1] + }, }); }); @@ -3187,7 +3680,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'update "users" set "email" = ?, "name" = ? where "id" = ?', bindings: ['foo', 'bar', 1] - } + }, + redshift: { + sql: 'update "users" set "email" = ?, "name" = ? where "id" = ?', + bindings: ['foo', 'bar', 1] + }, }); }); @@ -3205,6 +3702,10 @@ describe("QueryBuilder", function() { sql: "update \"users\" set \"email\" = ?, \"name\" = ? where \"users\".\"id\" = ?", bindings: ['foo', 'bar', 1] }, + redshift: { + sql: "update \"users\" set \"email\" = ?, \"name\" = ? where \"users\".\"id\" = ?", + bindings: ['foo', 'bar', 1] + }, }); }); @@ -3222,7 +3723,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'update "users" set "email" = ?, "name" = ? where "users"."id" = ?', bindings: ['foo', 'bar', 1] - } + }, + redshift: { + sql: 'update "users" set "email" = ?, "name" = ? where "users"."id" = ?', + bindings: ['foo', 'bar', 1] + }, }); }); @@ -3239,7 +3744,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'update "users" set "email" = ?, "name" = ? where "id" = ?', bindings: ['foo', 'bar', 1] - } + }, + redshift: { + sql: 'update "users" set "email" = ?, "name" = ? where "id" = ?', + bindings: ['foo', 'bar', 1] + }, }); }); @@ -3278,7 +3787,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'update "users" set "email" = foo, "name" = ? where "id" = ?', bindings: ['bar', 1] - } + }, + redshift: { + sql: 'update "users" set "email" = foo, "name" = ? where "id" = ?', + bindings: ['bar', 1] + }, }); }); @@ -3295,7 +3808,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'delete from "users" where "email" = ?', bindings: ['foo'] - } + }, + redshift: { + sql: 'delete from "users" where "email" = ?', + bindings: ['foo'] + }, }); }); @@ -3304,7 +3821,7 @@ describe("QueryBuilder", function() { postgres: { sql: 'delete from only "users" where "email" = ?', bindings: ['foo'] - } + }, }); }); @@ -3325,6 +3842,10 @@ describe("QueryBuilder", function() { sql: 'truncate "users" restart identity', bindings: [] }, + redshift: { + sql: 'truncate "users"', + bindings: [] + }, oracle: { sql: 'truncate table "users"', bindings: [] @@ -3350,6 +3871,10 @@ describe("QueryBuilder", function() { sql: 'insert into "users" ("email") values (?) returning "id"', bindings: ['foo'] }, + redshift: { + sql: 'insert into "users" ("email") values (?)', + bindings: ['foo'] + }, oracle: { sql: 'insert into "users" ("email") values (?) returning ROWID into ?', bindings: function (bindings) { @@ -3404,6 +3929,10 @@ describe("QueryBuilder", function() { // bindings: ['baz'] // }, // postgres: { + // sql: 'select * from "foo" where "bar" = ? for update', + // bindings: ['baz'] + // }, + // redshift: { // sql: 'select * from "foo" where "bar" = ? for update', // bindings: ['baz'] // }, @@ -3420,9 +3949,13 @@ describe("QueryBuilder", function() { // bindings: ['baz'] // }, // postgres: { + // sql: 'select * from "foo" where "bar" = ?', + // bindings: ['baz'] + // }, + // redshift: { // sql: 'select * from "foo" where "bar" = ?', // bindings: ['baz'] - // } + // }, // }); // }); @@ -3433,6 +3966,10 @@ describe("QueryBuilder", function() { // bindings: ['baz'] // }, // postgres: { + // sql: "select * from \"foo\" where \"bar\" = ? for share", + // bindings: ['baz'] + // }, + // redshift: { // sql: "select * from \"foo\" where \"bar\" = ? for share", // bindings: ['baz'] // }, @@ -3441,9 +3978,13 @@ describe("QueryBuilder", function() { // bindings: ['baz'] // }, // postgres: { + // sql: 'select * from "foo" where "bar" = ?', + // bindings: ['baz'] + // }, + // redshift: { // sql: 'select * from "foo" where "bar" = ?', // bindings: ['baz'] - // } + // }, // }); // }); @@ -3460,7 +4001,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "foo" where "bar" = ?', bindings: ['baz'] - } + }, + redshift: { + sql: 'select * from "foo" where "bar" = ?', + bindings: ['baz'] + }, }); }); @@ -3480,7 +4025,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into "entries" ("secret", "sequence") values (?, (select count(*) from "entries" where "secret" = ?))', bindings: [123, 123] - } + }, + redshift: { + sql: 'insert into "entries" ("secret", "sequence") values (?, (select count(*) from "entries" where "secret" = ?))', + bindings: [123, 123] + }, }); }); @@ -3499,7 +4048,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "student" left outer join "student_languages" on "student"."id" = "student_languages"."student_id" and "student_languages"."code" = ?', bindings: ['en_US'] - } + }, + redshift: { + sql: 'select * from "student" left outer join "student_languages" on "student"."id" = "student_languages"."student_id" and "student_languages"."code" = ?', + bindings: ['en_US'] + }, }); }); @@ -3516,7 +4069,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "test"', bindings: [] - } + }, + redshift: { + sql: 'select * from "test"', + bindings: [] + }, }); }); @@ -3540,7 +4097,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'delete from "word" where "page_id" in (select "id" from "page" where "chapter_id" in (select "id" from "chapter" where "book" = ?))', bindings: [1] - } + }, + redshift: { + sql: 'delete from "word" where "page_id" in (select "id" from "page" where "chapter_id" in (select "id" from "chapter" where "book" = ?))', + bindings: [1] + }, }); testsql(two, { @@ -3555,7 +4116,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'delete from "page" where "chapter_id" in (select "id" from "chapter" where "book" = ?)', bindings: [1] - } + }, + redshift: { + sql: 'delete from "page" where "chapter_id" in (select "id" from "chapter" where "book" = ?)', + bindings: [1] + }, }); testsql(three, { @@ -3570,7 +4135,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'delete from "chapter" where "book" = ?', bindings: [1] - } + }, + redshift: { + sql: 'delete from "chapter" where "book" = ?', + bindings: [1] + }, }); }); @@ -3592,7 +4161,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into recipients (recipient_id, email) select ?, ? where not exists (select 1 from "recipients" where "recipient_id" = ?)', bindings: [1, 'foo@bar.com', 1] - } + }, + redshift: { + sql: 'insert into recipients (recipient_id, email) select ?, ? where not exists (select 1 from "recipients" where "recipient_id" = ?)', + bindings: [1, 'foo@bar.com', 1] + }, }); }); @@ -3615,7 +4188,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'update "tblPerson" set "tblPerson"."City" = ? where "tblPersonData"."DataId" = ? and "tblPerson"."PersonId" = ?', bindings: ['Boonesville', 1, 5] - } + }, + redshift: { + sql: 'update "tblPerson" set "tblPerson"."City" = ? where "tblPersonData"."DataId" = ? and "tblPerson"."PersonId" = ?', + bindings: ['Boonesville', 1, 5] + }, }); }); @@ -3637,7 +4214,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into "recipients" (recipient_id, email) (select \'user\', \'user@foo.com\' where not exists (select 1 from "recipients" where "recipient_id" = ?))', bindings: [1] - } + }, + redshift: { + sql: 'insert into "recipients" (recipient_id, email) (select \'user\', \'user@foo.com\' where not exists (select 1 from "recipients" where "recipient_id" = ?))', + bindings: [1] + }, }); }); @@ -3654,7 +4235,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "name" like ?', bindings: ['%test%'] - } + }, + redshift: { + sql: 'select * from "users" where "name" like ?', + bindings: ['%test%'] + }, }); }); @@ -3663,7 +4248,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "name" ~ ?', bindings: ['.*test.*'] - } + }, + redshift: { + sql: 'select * from "users" where "name" ~ ?', + bindings: ['.*test.*'] + }, }); }); @@ -3672,7 +4261,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "name" not ilike ?', bindings: ['%jeff%'] - } + }, + redshift: { + sql: 'select * from "users" where "name" not ilike ?', + bindings: ['%jeff%'] + }, }); }); @@ -3706,6 +4299,10 @@ describe("QueryBuilder", function() { sql: 'select * from "value" inner join "table" on "table"."array_column"[1] = ?', bindings: [1] }, + redshift: { + sql: 'select * from "value" inner join "table" on "table"."array_column"[1] = ?', + bindings: [1] + }, }); }); @@ -3737,7 +4334,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select "e"."lastname", "e"."salary", (select "avg(salary)" from "employee" where dept_no = e.dept_no) avg_sal_dept from "employee" as "e" where "dept_no" = ?', bindings: ['e.dept_no'] - } + }, + redshift: { + sql: 'select "e"."lastname", "e"."salary", (select "avg(salary)" from "employee" where dept_no = e.dept_no) avg_sal_dept from "employee" as "e" where "dept_no" = ?', + bindings: ['e.dept_no'] + }, }); }); @@ -3769,7 +4370,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select "e"."lastname", "e"."salary", (select "avg(salary)" from "employee" where dept_no = e.dept_no) as "avg_sal_dept" from "employee" as "e" where "dept_no" = ?', bindings: ["e.dept_no"] - } + }, + redshift: { + sql: 'select "e"."lastname", "e"."salary", (select "avg(salary)" from "employee" where dept_no = e.dept_no) as "avg_sal_dept" from "employee" as "e" where "dept_no" = ?', + bindings: ["e.dept_no"] + }, }); }); @@ -3802,7 +4407,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select "e"."lastname", "e"."salary", (select "avg(salary)" from "employee" where dept_no = e.dept_no) as "avg_sal_dept" from "employee" as "e" where "dept_no" = ?', bindings: ["e.dept_no"] - } + }, + redshift: { + sql: 'select "e"."lastname", "e"."salary", (select "avg(salary)" from "employee" where dept_no = e.dept_no) as "avg_sal_dept" from "employee" as "e" where "dept_no" = ?', + bindings: ["e.dept_no"] + }, }); }); @@ -3824,7 +4433,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select "e"."lastname", "e"."salary", (select "salary" from "employee" where dept_no = e.dept_no order by "salary" desc limit ?) as "top_dept_salary" from "employee" as "e" where "dept_no" = ?', bindings: [1, "e.dept_no"] - } + }, + redshift: { + sql: 'select "e"."lastname", "e"."salary", (select "salary" from "employee" where dept_no = e.dept_no order by "salary" desc limit ?) as "top_dept_salary" from "employee" as "e" where "dept_no" = ?', + bindings: [1, "e.dept_no"] + }, }); }); @@ -3856,7 +4469,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "places" where ST_DWithin((places.address).xy, ST_SetSRID(ST_MakePoint(?,?),?), ?) AND ST_Distance((places.address).xy, ST_SetSRID(ST_MakePoint(?,?),?)) > ? AND places.id IN ?', bindings: [-10, 10, 4326, 100000, -5, 5, 4326, 50000, [1,2,3] ] - } + }, + redshift: { + sql: 'select * from "places" where ST_DWithin((places.address).xy, ST_SetSRID(ST_MakePoint(?,?),?), ?) AND ST_Distance((places.address).xy, ST_SetSRID(ST_MakePoint(?,?),?)) > ? AND places.id IN ?', + bindings: [-10, 10, 4326, 100000, -5, 5, 4326, 50000, [1,2,3] ] + }, }); }); @@ -3873,7 +4490,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "accounts" natural full join table1 where "id" = ?', bindings: [1] - } + }, + redshift: { + sql: 'select * from "accounts" natural full join table1 where "id" = ?', + bindings: [1] + }, }); }); @@ -3889,7 +4510,10 @@ describe("QueryBuilder", function() { }, postgres: { sql: 'select * from "accounts" inner join "table1" on ST_Contains(buildings_pluto.geom, ST_Centroid(buildings_building.geom))' - } + }, + redshift: { + sql: 'select * from "accounts" inner join "table1" on ST_Contains(buildings_pluto.geom, ST_Centroid(buildings_building.geom))' + }, }); }); @@ -3906,7 +4530,10 @@ describe("QueryBuilder", function() { }, postgres: { sql: 'select * from "accounts" inner join "table1" using "id"' - } + }, + redshift: { + sql: 'select * from "accounts" inner join "table1" using "id"' + }, }); }); @@ -3925,7 +4552,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into "votes" select * from "votes" where "id" = ?', bindings: [99] - } + }, + redshift: { + sql: 'insert into "votes" select * from "votes" where "id" = ?', + bindings: [99] + }, }); }); @@ -3950,7 +4581,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into "votes" select * from "votes" where "id" = ?', bindings: [99] - } + }, + redshift: { + sql: 'insert into "votes" select * from "votes" where "id" = ?', + bindings: [99] + }, }); }); @@ -3984,7 +4619,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select "A"."nid" as "id" from nidmap2 AS A inner join (SELECT MIN(nid) AS location_id FROM nidmap2) AS B on "A"."x" = "B"."x"', bindings: [] - } + }, + redshift: { + sql: 'select "A"."nid" as "id" from nidmap2 AS A inner join (SELECT MIN(nid) AS location_id FROM nidmap2) AS B on "A"."x" = "B"."x"', + bindings: [] + }, }); }); @@ -4004,7 +4643,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into "entries" ("secret", "sequence") values (?, (select count(*) from "entries" where "secret" = ?))', bindings: [123, 123] - } + }, + redshift: { + sql: 'insert into "entries" ("secret", "sequence") values (?, (select count(*) from "entries" where "secret" = ?))', + bindings: [123, 123] + }, }); }); @@ -4034,7 +4677,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select ?, "g"."f" from (select ? as f) as "g" where "g"."secret" = ?', bindings: ['outer raw select', 'inner raw select', 123] - } + }, + redshift: { + sql: 'select ?, "g"."f" from (select ? as f) as "g" where "g"."secret" = ?', + bindings: ['outer raw select', 'inner raw select', 123] + }, }); }); @@ -4054,7 +4701,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select "id"",""name", "id`name" from "test`"', bindings: [] - } + }, + redshift: { + sql: 'select "id"",""name", "id`name" from "test`"', + bindings: [] + }, }); }); @@ -4078,7 +4729,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "accounts" where "id" = ? and "name" in (?, ?, ?)', bindings: [1, 'a', 'b', 'c'] - } + }, + redshift: { + sql: 'select * from "accounts" where "id" = ? and "name" in (?, ?, ?)', + bindings: [1, 'a', 'b', 'c'] + }, }) }) @@ -4103,7 +4758,10 @@ describe("QueryBuilder", function() { }, postgres: { sql: 'select "foo_id", "bars".* from "foos" left join "bars" on "foos"."bar_id" = "bars"."id"' - } + }, + redshift: { + sql: 'select "foo_id", "bars".* from "foos" left join "bars" on "foos"."bar_id" = "bars"."id"' + }, }) }) @@ -4144,7 +4802,10 @@ describe("QueryBuilder", function() { }, postgres: { sql: 'select * from "users" inner join "photos" on "photos"."id" = 0' - } + }, + redshift: { + sql: 'select * from "users" inner join "photos" on "photos"."id" = 0' + }, }); }); @@ -4158,7 +4819,10 @@ describe("QueryBuilder", function() { }, postgres: { sql: 'select * from "users" inner join "photos" on "photos"."id" > 0' - } + }, + redshift: { + sql: 'select * from "users" inner join "photos" on "photos"."id" > 0' + }, }); }); @@ -4176,7 +4840,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "birthday" >= ?', bindings: [date] - } + }, + redshift: { + sql: 'select * from "users" where "birthday" >= ?', + bindings: [date] + }, }); }); @@ -4194,7 +4862,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where birthday >= ?', bindings: [date] - } + }, + redshift: { + sql: 'select * from "users" where birthday >= ?', + bindings: [date] + }, }); }); @@ -4212,7 +4884,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where ' + fieldName + ' = ?', bindings: expectedBindings - } + }, + redshift: { + sql: 'select * from "users" where ' + fieldName + ' = ?', + bindings: expectedBindings + }, }; }; @@ -4251,7 +4927,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" = ? or ("email" = ? and "id" = ?)', bindings: [1, 'foo', 2] - } + }, + redshift: { + sql: 'select * from "users" where "id" = ? or ("email" = ? and "id" = ?)', + bindings: [1, 'foo', 2] + }, }); }); @@ -4268,7 +4948,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "users" where "id" in (select (?))', bindings: [[1,2,3]] - } + }, + redshift: { + sql: 'select * from "users" where "id" in (select (?))', + bindings: [[1,2,3]] + }, }); @@ -4314,7 +4998,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'insert into "users" ("id", "name", "occupation") values (DEFAULT, ?, DEFAULT), (?, DEFAULT, ?)', bindings: ['test', 1, 'none'] - } + }, + redshift: { + sql: 'insert into "users" ("id", "name", "occupation") values (DEFAULT, ?, DEFAULT), (?, DEFAULT, ?)', + bindings: ['test', 1, 'none'] + }, }); expect(function() { @@ -4349,7 +5037,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'select * from "testtable" where not is_active', bindings: [] - } + }, + redshift: { + sql: 'select * from "testtable" where not is_active', + bindings: [] + }, }) }); @@ -4384,7 +5076,11 @@ describe("QueryBuilder", function() { postgres: { sql: '', bindings: [] - } + }, + redshift: { + sql: '', + bindings: [] + }, }); expect(true).to.equal(false, 'Expected to throw error in compilation about undefined bindings.'); } catch(error) { @@ -4478,6 +5174,7 @@ describe("QueryBuilder", function() { mssql: 'with [withClause] as (select [foo] from [users]) select * from [withClause]', sqlite3: 'with `withClause` as (select `foo` from `users`) select * from `withClause`', postgres: 'with "withClause" as (select "foo" from "users") select * from "withClause"', + redshift: 'with "withClause" as (select "foo" from "users") select * from "withClause"', oracledb: 'with "withClause" as (select "foo" from "users") select * from "withClause"', oracle: 'with "withClause" as (select "foo" from "users") select * from "withClause"' }); @@ -4508,7 +5205,11 @@ describe("QueryBuilder", function() { postgres: { sql: 'with "withClause" as (select "foo" from "users" where "name" = ?) insert into "users" ("email", "name") values (?, ?), (?, ?)', bindings: ['bob', 'thisMail', 'sam', 'thatMail', 'jack'] - } + }, + redshift: { + sql: 'with "withClause" as (select "foo" from "users" where "name" = ?) insert into "users" ("email", "name") values (?, ?), (?, ?)', + bindings: ['bob', 'thisMail', 'sam', 'thatMail', 'jack'] + }, }); }); @@ -4537,6 +5238,7 @@ describe("QueryBuilder", function() { mssql: 'with [withRawClause] as (select "foo" as "baz" from "users") select * from [withRawClause]', sqlite3: 'with `withRawClause` as (select "foo" as "baz" from "users") select * from `withRawClause`', postgres: 'with "withRawClause" as (select "foo" as "baz" from "users") select * from "withRawClause"', + redshift: 'with "withRawClause" as (select "foo" as "baz" from "users") select * from "withRawClause"', oracledb: 'with "withRawClause" as (select "foo" as "baz" from "users") select * from "withRawClause"', oracle: 'with "withRawClause" as (select "foo" as "baz" from "users") select * from "withRawClause"' }); @@ -4551,6 +5253,7 @@ describe("QueryBuilder", function() { mssql: 'with [firstWithClause] as (select [foo] from [users]), [secondWithClause] as (select [bar] from [users]) select * from [secondWithClause]', sqlite3: 'with `firstWithClause` as (select `foo` from `users`), `secondWithClause` as (select `bar` from `users`) select * from `secondWithClause`', postgres: 'with "firstWithClause" as (select "foo" from "users"), "secondWithClause" as (select "bar" from "users") select * from "secondWithClause"', + redshift: 'with "firstWithClause" as (select "foo" from "users"), "secondWithClause" as (select "bar" from "users") select * from "secondWithClause"', oracledb: 'with "firstWithClause" as (select "foo" from "users"), "secondWithClause" as (select "bar" from "users") select * from "secondWithClause"', oracle: 'with "firstWithClause" as (select "foo" from "users"), "secondWithClause" as (select "bar" from "users") select * from "secondWithClause"' }); @@ -4565,6 +5268,7 @@ describe("QueryBuilder", function() { mssql: 'with [withClause] as (with [withSubClause] as ((select [foo] from [users]) as [baz]) select * from [withSubClause]) select * from [withClause]', sqlite3: 'with `withClause` as (with `withSubClause` as ((select `foo` from `users`) as `baz`) select * from `withSubClause`) select * from `withClause`', postgres: 'with "withClause" as (with "withSubClause" as ((select "foo" from "users") as "baz") select * from "withSubClause") select * from "withClause"', + redshift: 'with "withClause" as (with "withSubClause" as ((select "foo" from "users") as "baz") select * from "withSubClause") select * from "withClause"', oracledb: 'with "withClause" as (with "withSubClause" as ((select "foo" from "users") "baz") select * from "withSubClause") select * from "withClause"', oracle: 'with "withClause" as (with "withSubClause" as ((select "foo" from "users") "baz") select * from "withSubClause") select * from "withClause"' }); @@ -4584,9 +5288,13 @@ describe("QueryBuilder", function() { bindings: [1, 20, 10] }, postgres: { - sql: 'with "withClause" as (with "withSubClause" as (select "foo" as "baz" from "users" where "baz" > ? and "baz" < ?) select * from "withSubClause") select * from "withClause" where "id" = ?', - bindings: [1, 20, 10] - }, + sql: 'with "withClause" as (with "withSubClause" as (select "foo" as "baz" from "users" where "baz" > ? and "baz" < ?) select * from "withSubClause") select * from "withClause" where "id" = ?', + bindings: [1, 20, 10] + }, + redshift: { + sql: 'with "withClause" as (with "withSubClause" as (select "foo" as "baz" from "users" where "baz" > ? and "baz" < ?) select * from "withSubClause") select * from "withClause" where "id" = ?', + bindings: [1, 20, 10] + }, oracledb: { sql: 'with "withClause" as (with "withSubClause" as (select "foo" as "baz" from "users" where "baz" > ? and "baz" < ?) select * from "withSubClause") select * from "withClause" where "id" = ?', bindings: [1, 20, 10] @@ -4640,6 +5348,7 @@ describe("QueryBuilder", function() { mssql: 'with [firstWithClause] as (with [firstWithSubClause] as ((select [foo] from [users]) as [foz]) select * from [firstWithSubClause]), [secondWithClause] as (with [secondWithSubClause] as ((select [bar] from [users]) as [baz]) select * from [secondWithSubClause]) select * from [secondWithClause]', sqlite3: 'with `firstWithClause` as (with `firstWithSubClause` as ((select `foo` from `users`) as `foz`) select * from `firstWithSubClause`), `secondWithClause` as (with `secondWithSubClause` as ((select `bar` from `users`) as `baz`) select * from `secondWithSubClause`) select * from `secondWithClause`', postgres: 'with "firstWithClause" as (with "firstWithSubClause" as ((select "foo" from "users") as "foz") select * from "firstWithSubClause"), "secondWithClause" as (with "secondWithSubClause" as ((select "bar" from "users") as "baz") select * from "secondWithSubClause") select * from "secondWithClause"', + redshift: 'with "firstWithClause" as (with "firstWithSubClause" as ((select "foo" from "users") as "foz") select * from "firstWithSubClause"), "secondWithClause" as (with "secondWithSubClause" as ((select "bar" from "users") as "baz") select * from "secondWithSubClause") select * from "secondWithClause"', oracledb: 'with "firstWithClause" as (with "firstWithSubClause" as ((select "foo" from "users") "foz") select * from "firstWithSubClause"), "secondWithClause" as (with "secondWithSubClause" as ((select "bar" from "users") "baz") select * from "secondWithSubClause") select * from "secondWithClause"', oracle: 'with "firstWithClause" as (with "firstWithSubClause" as ((select "foo" from "users") "foz") select * from "firstWithSubClause"), "secondWithClause" as (with "secondWithSubClause" as ((select "bar" from "users") "baz") select * from "secondWithSubClause") select * from "secondWithClause"' }); diff --git a/test/unit/schema/redshift.js b/test/unit/schema/redshift.js new file mode 100644 index 000000000..6d57f3ef7 --- /dev/null +++ b/test/unit/schema/redshift.js @@ -0,0 +1,494 @@ +/*global describe, expect, it*/ + +'use strict'; + +var tableSql; + +const Redshift_Client = require('../../../lib/dialects/redshift'); +const client = new Redshift_Client({}) + +const equal = require('assert').equal; + +describe("Redshift SchemaBuilder", function() { + + it("fixes memoization regression", function() { + tableSql = client.schemaBuilder().createTable('users', function(table) { + table.uuid('key'); + table.increments('id'); + table.string('email'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('create table "users" ("key" char(36), "id" integer identity(1,1) primary key not null, "email" varchar(255))'); + }); + + it("basic alter table", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.increments('id'); + table.string('email'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "id" integer identity(1,1) primary key not null, add column "email" varchar(255)'); + }); + + it("alter table with schema", function() { + tableSql = client.schemaBuilder().withSchema('myschema').table('users', function(table) { + table.increments('id'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "myschema"."users" add column "id" integer identity(1,1) primary key not null'); + }); + + it("drop table", function() { + tableSql = client.schemaBuilder().dropTable('users').toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('drop table "users"'); + }); + + it("drop table with schema", function() { + tableSql = client.schemaBuilder().withSchema('myschema').dropTable('users').toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('drop table "myschema"."users"'); + }); + + it("drop table if exists", function() { + tableSql = client.schemaBuilder().dropTableIfExists('users').toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('drop table if exists "users"'); + }); + + it("drop table if exists with schema", function() { + tableSql = client.schemaBuilder().withSchema('myschema').dropTableIfExists('users').toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('drop table if exists "myschema"."users"'); + }); + + it("drop column", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dropColumn('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" drop column "foo"'); + }); + + it("drop multiple columns", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dropColumn(['foo', 'bar']); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" drop column "foo", drop column "bar"'); + }); + + it("drop multiple columns with arguments", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dropColumn('foo', 'bar'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" drop column "foo", drop column "bar"'); + }); + + it("drop primary", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dropPrimary(); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" drop constraint "users_pkey"'); + }); + + it("drop unique", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dropUnique('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" drop constraint "users_foo_unique"'); + }); + + it("drop unique, custom", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dropUnique(null, 'foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" drop constraint "foo"'); + }); + + it("drop index should be a no-op", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dropIndex('foo'); + }).toSQL(); + equal(0, tableSql.length); + }); + + it("drop foreign", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dropForeign('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" drop constraint "users_foo_foreign"'); + }); + + it("drop foreign", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dropForeign(null, 'foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" drop constraint "foo"'); + }); + + it("drop timestamps", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dropTimestamps(); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" drop column "created_at", drop column "updated_at"'); + }); + + it("rename table", function() { + tableSql = client.schemaBuilder().renameTable('users', 'foo').toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" rename to "foo"'); + }); + + it("adding primary key", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.primary('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add constraint "users_pkey" primary key ("foo")'); + }); + + it("adding primary key fluently", function() { + tableSql = client.schemaBuilder().createTable('users', function(table) { + table.string('name').primary(); + table.string('foo'); + }).toSQL(); + equal(2, tableSql.length); + expect(tableSql[0].sql).to.equal('create table "users" ("name" varchar(255) not null, "foo" varchar(255))'); + expect(tableSql[1].sql).to.equal('alter table "users" add constraint "users_pkey" primary key ("name")'); + }); + + it("adding foreign key", function() { + tableSql = client.schemaBuilder().createTable('accounts', function(table) { + table.integer('account_id').references('users.id'); + }).toSQL(); + expect(tableSql[1].sql).to.equal('alter table "accounts" add constraint "accounts_account_id_foreign" foreign key ("account_id") references "users" ("id")'); + }); + + it("adds foreign key with onUpdate and onDelete", function() { + tableSql = client.schemaBuilder().createTable('person', function(table) { + table.integer('user_id').notNull().references('users.id').onDelete('SET NULL'); + table.integer('account_id').notNull().references('id').inTable('accounts').onUpdate('cascade'); + }).toSQL(); + equal(3, tableSql.length); + expect(tableSql[1].sql).to.equal('alter table "person" add constraint "person_user_id_foreign" foreign key ("user_id") references "users" ("id") on delete SET NULL'); + expect(tableSql[2].sql).to.equal('alter table "person" add constraint "person_account_id_foreign" foreign key ("account_id") references "accounts" ("id") on update cascade'); + }); + + it("adding unique key", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.unique('foo', 'bar'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add constraint "bar" unique ("foo")'); + }); + + it("adding unique key fluently", function() { + tableSql = client.schemaBuilder().createTable('users', function(table) { + table.string('email').unique(); + }).toSQL(); + equal(2, tableSql.length); + expect(tableSql[0].sql).to.equal('create table "users" ("email" varchar(255))'); + expect(tableSql[1].sql).to.equal('alter table "users" add constraint "users_email_unique" unique ("email")'); + }); + + it("adding index should be a no-op", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.index(['foo', 'bar'], 'baz'); + }).toSQL(); + equal(0, tableSql.length); + }); + + it("adding incrementing id", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.increments('id'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "id" integer identity(1,1) primary key not null'); + }); + + it("adding big incrementing id", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.bigIncrements('id'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "id" bigint identity(1,1) primary key not null'); + }); + + it("adding string", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.string('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" varchar(255)'); + }); + + it("adding varchar with length", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.string('foo', 100); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" varchar(100)'); + }); + + it("adding a string with a default", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.string('foo', 100).defaultTo('bar'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" varchar(100) default \'bar\''); + }); + + it("adding text", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.text('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" varchar(max)'); + }); + + it("adding big integer", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.bigInteger('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" bigint'); + }); + + it("tests a big integer as the primary autoincrement key", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.bigIncrements('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" bigint identity(1,1) primary key not null'); + }); + + it("adding integer", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.integer('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" integer'); + }); + + it("adding autoincrement integer", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.increments('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" integer identity(1,1) primary key not null'); + }); + + it("adding medium integer", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.mediumint('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" integer'); + }); + + it("adding tiny integer", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.tinyint('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" smallint'); + }); + + it("adding small integer", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.smallint('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" smallint'); + }); + + it("adding float", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.float('foo', 5, 2); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" real'); + }); + + it("adding double", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.double('foo', 15, 8); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" double precision'); + }); + + it("adding decimal", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.decimal('foo', 5, 2); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" decimal(5, 2)'); + }); + + it("adding boolean", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.boolean('foo').defaultTo(false); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" boolean default \'0\''); + }); + + it("adding enum", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.enum('foo', ['bar', 'baz']); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" varchar(255)'); + }); + + it("adding date", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.date('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" date'); + }); + + it("adding date time", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.dateTime('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" timestamptz'); + }); + + it("adding time", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.time('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" time'); + }); + + it("adding timestamp", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.timestamp('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" timestamptz'); + }); + + it("adding timestamps", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.timestamps(); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "created_at" timestamptz, add column "updated_at" timestamptz'); + }); + + it("adding timestamps with defaults", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.timestamps(false, true); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "created_at" timestamptz not null default CURRENT_TIMESTAMP, add column "updated_at" timestamptz not null default CURRENT_TIMESTAMP'); + }); + + it("adding binary", function() { + tableSql = client.schemaBuilder().table('users', function(table) { + table.binary('foo'); + }).toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "foo" varchar(max)'); + }); + + it('adding jsonb', function() { + tableSql = client.schemaBuilder().table('user', function(t) { + t.jsonb('preferences'); + }).toSQL(); + expect(tableSql[0].sql).to.equal('alter table "user" add column "preferences" varchar(max)'); + }); + + it('allows adding default json objects when the column is json', function() { + tableSql = client.schemaBuilder().table('user', function(t) { + t.json('preferences').defaultTo({}).notNullable(); + }).toSQL(); + expect(tableSql[0].sql).to.equal('alter table "user" add column "preferences" varchar(max) not null {}'); + }); + + it('sets specificType correctly', function() { + tableSql = client.schemaBuilder().table('user', function(t) { + t.specificType('email', 'CITEXT').unique().notNullable(); + }).toSQL(); + expect(tableSql[0].sql).to.equal('alter table "user" add column "email" CITEXT not null'); + }); + + it('allows creating an extension', function() { + var sql = client.schemaBuilder().createExtension('test').toSQL(); + expect(sql[0].sql).to.equal('create extension "test"'); + }); + + it('allows dropping an extension', function() { + var sql = client.schemaBuilder().dropExtension('test').toSQL(); + expect(sql[0].sql).to.equal('drop extension "test"'); + }); + + it('allows creating an extension only if it doesn\'t exist', function() { + var sql = client.schemaBuilder().createExtensionIfNotExists('test').toSQL(); + expect(sql[0].sql).to.equal('create extension if not exists "test"'); + }); + + it('allows dropping an extension only if it exists', function() { + var sql = client.schemaBuilder().dropExtensionIfExists('test').toSQL(); + expect(sql[0].sql).to.equal('drop extension if exists "test"'); + }); + + it('table inherits another table', function() { + tableSql = client.schemaBuilder().createTable('inheriteeTable', function(t) { + t.string('username'); + t.inherits('inheritedTable'); + }).toSQL(); + expect(tableSql[0].sql).to.equal('create table "inheriteeTable" ("username" varchar(255)) like ("inheritedTable")'); + }); + + it('should warn on disallowed method', function() { + tableSql = client.schemaBuilder().createTable('users', function(t) { + t.string('username'); + t.engine('myISAM'); + }).toSQL(); + expect(tableSql[0].sql).to.equal('create table "users" ("username" varchar(255))'); + }); + + it('#1430 - .primary & .dropPrimary takes columns and constraintName', function() { + tableSql = client.schemaBuilder().table('users', function(t) { + // t.string('test1').notNullable(); + t.string('test1'); + t.string('test2').notNullable(); + t.primary(['test1', 'test2'], 'testconstraintname'); + }).toSQL(); + + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal('alter table "users" add column "test1" varchar(255), add column "test2" varchar(255) not null'); + + tableSql = client.schemaBuilder().table('users', function(t) { + t.string('test1').notNullable(); + t.string('test2').notNullable(); + t.primary(['test1', 'test2'], 'testconstraintname'); + }).toSQL(); + + expect(tableSql[0].sql).to.equal('alter table "users" add column "test1" varchar(255) not null, add column "test2" varchar(255) not null'); + expect(tableSql[1].sql).to.equal('alter table "users" add constraint "testconstraintname" primary key ("test1", "test2")'); + + tableSql = client.schemaBuilder().createTable('users', function(t) { + t.string('test').primary('testconstraintname'); + }).toSQL(); + + expect(tableSql[0].sql).to.equal('create table "users" ("test" varchar(255) not null)'); + expect(tableSql[1].sql).to.equal('alter table "users" add constraint "testconstraintname" primary key ("test")'); + }); + +});