From 9aadcf9f1b91f2586c64a94e7d949e400503b812 Mon Sep 17 00:00:00 2001 From: Olivier Cavadenti Date: Wed, 10 Nov 2021 20:21:25 +0100 Subject: [PATCH 1/4] Add columns in create table like #4820 --- .../mssql/schema/mssql-tablecompiler.js | 3 + .../mysql/schema/mysql-tablecompiler.js | 3 + .../oracle/schema/oracle-tablecompiler.js | 3 + .../postgres/schema/pg-tablecompiler.js | 6 +- .../redshift/schema/redshift-tablecompiler.js | 3 + .../sqlite3/schema/sqlite-tablecompiler.js | 4 ++ test/integration2/schema/misc.spec.js | 55 +++++++++++++++++++ test/unit/schema-builder/mssql.js | 17 ++++++ test/unit/schema-builder/mysql.js | 17 ++++++ test/unit/schema-builder/oracledb.js | 17 ++++++ test/unit/schema-builder/postgres.js | 14 +++++ test/unit/schema-builder/redshift.js | 20 +++++++ test/unit/schema-builder/sqlite3.js | 20 +++++++ 13 files changed, 181 insertions(+), 1 deletion(-) diff --git a/lib/dialects/mssql/schema/mssql-tablecompiler.js b/lib/dialects/mssql/schema/mssql-tablecompiler.js index 3714ede333..3c5bc9db0f 100644 --- a/lib/dialects/mssql/schema/mssql-tablecompiler.js +++ b/lib/dialects/mssql/schema/mssql-tablecompiler.js @@ -36,6 +36,9 @@ class TableCompiler_MSSQL extends TableCompiler { if (this.single.comment) { this.comment(this.single.comment); } + if (like) { + this.addColumns(columns, this.addColumnsPrefix); + } } comment(/** @type {string} */ comment) { diff --git a/lib/dialects/mysql/schema/mysql-tablecompiler.js b/lib/dialects/mysql/schema/mysql-tablecompiler.js index 3e66057e1b..9765b17ec4 100644 --- a/lib/dialects/mysql/schema/mysql-tablecompiler.js +++ b/lib/dialects/mysql/schema/mysql-tablecompiler.js @@ -50,6 +50,9 @@ class TableCompiler_MySQL extends TableCompiler { } this.pushQuery(sql); + if (like) { + this.addColumns(columns, this.addColumnsPrefix); + } } // Compiles the comment on the table. diff --git a/lib/dialects/oracle/schema/oracle-tablecompiler.js b/lib/dialects/oracle/schema/oracle-tablecompiler.js index eb33d8229f..2dbe6944e5 100644 --- a/lib/dialects/oracle/schema/oracle-tablecompiler.js +++ b/lib/dialects/oracle/schema/oracle-tablecompiler.js @@ -66,6 +66,9 @@ class TableCompiler_Oracle extends TableCompiler { bindings: columns.bindings, }); if (this.single.comment) this.comment(this.single.comment); + if (like) { + this.addColumns(columns, this.addColumnsPrefix); + } } // Compiles the comment on the table. diff --git a/lib/dialects/postgres/schema/pg-tablecompiler.js b/lib/dialects/postgres/schema/pg-tablecompiler.js index dae03938c0..d9223bde58 100644 --- a/lib/dialects/postgres/schema/pg-tablecompiler.js +++ b/lib/dialects/postgres/schema/pg-tablecompiler.js @@ -49,7 +49,11 @@ class TableCompiler_PG extends TableCompiler { createStatement + this.tableName() + (like && this.tableNameLike() - ? ' (like ' + this.tableNameLike() + ' including all)' + ? ' (like ' + + this.tableNameLike() + + ' including all' + + (columns.sql.length ? ', ' + columns.sql.join(', ') : '') + + ')' : columnsSql); if (this.single.inherits) sql += ` inherits (${this.formatter.wrap(this.single.inherits)})`; diff --git a/lib/dialects/redshift/schema/redshift-tablecompiler.js b/lib/dialects/redshift/schema/redshift-tablecompiler.js index 94c0b98d61..67308b6b05 100644 --- a/lib/dialects/redshift/schema/redshift-tablecompiler.js +++ b/lib/dialects/redshift/schema/redshift-tablecompiler.js @@ -45,6 +45,9 @@ class TableCompiler_Redshift extends TableCompiler_PG { }); const hasComment = has(this.single, 'comment'); if (hasComment) this.comment(this.single.comment); + if (like) { + this.addColumns(columns, this.addColumnsPrefix); + } } primary(columns, constraintName) { diff --git a/lib/dialects/sqlite3/schema/sqlite-tablecompiler.js b/lib/dialects/sqlite3/schema/sqlite-tablecompiler.js index 4331fbb490..0ff6f5382e 100644 --- a/lib/dialects/sqlite3/schema/sqlite-tablecompiler.js +++ b/lib/dialects/sqlite3/schema/sqlite-tablecompiler.js @@ -30,6 +30,10 @@ class TableCompiler_SQLite3 extends TableCompiler { sql += ')'; } this.pushQuery(sql); + + if (like) { + this.addColumns(columns, this.addColumnsPrefix); + } } addColumns(columns, prefix, colCompilers) { diff --git a/test/integration2/schema/misc.spec.js b/test/integration2/schema/misc.spec.js index 6a871b2cbe..14dae21939 100644 --- a/test/integration2/schema/misc.spec.js +++ b/test/integration2/schema/misc.spec.js @@ -321,6 +321,61 @@ describe('Schema (misc)', () => { expect(Object.keys(res)).to.have.all.members(['id', 'data']); }); }); + + it('copy table with additionnal column', async () => { + await knex.schema + .createTableLike( + 'table_copied', + 'table_to_copy', + function (table) { + table.text('add_col'); + table.integer('add_num_col'); + } + ) + .testSql((tester) => { + tester('mysql', [ + 'create table `table_copied` like `table_to_copy`', + 'alter table `table_copied` add `add_col` text, add `numeric_col` int', + ]); + tester( + ['pg', 'cockroachdb'], + [ + 'create table "table_copied" (like "users" including all, "add_col" text, "numeric_col" integer)', + ] + ); + tester('pg-redshift', [ + 'create table "table_copied" (like "table_to_copy")', + 'alter table "table_copied" add column "add_col" varchar(max)', + 'alter table "table_copied" add column "add_num_col" integer', + ]); + tester('sqlite3', [ + 'create table `table_copied` as select * from `table_to_copy` where 0=1', + 'alter table `table_copied` add column `add_col` text', + 'alter table `users_like` add column `add_num_col` integer', + ]); + tester('oracledb', [ + 'create table "table_copied" as (select * from "table_to_copy" where 0=1)', + 'alter table "table_copied" add ("add_col" clob, "add_num_col" integer)', + ]); + tester('mssql', [ + 'SELECT * INTO [table_copied] FROM [table_to_copy] WHERE 0=1', + 'ALTER TABLE [table_copied] ADD [add_col] nvarchar(max), [numeric_col] int', + ]); + }); + + expect(await knex.schema.hasTable('table_copied')).to.equal(true); + + await knex('table_copied') + .columnInfo() + .then((res) => { + expect(Object.keys(res)).to.have.all.members([ + 'id', + 'data', + 'add_col', + 'add_num_col', + ]); + }); + }); }); describe('increments types - postgres', () => { diff --git a/test/unit/schema-builder/mssql.js b/test/unit/schema-builder/mssql.js index b146f17b8f..e07fc86be3 100644 --- a/test/unit/schema-builder/mssql.js +++ b/test/unit/schema-builder/mssql.js @@ -50,6 +50,23 @@ describe('MSSQL SchemaBuilder', function () { ); }); + it('create table like another with additionnal columns', function () { + tableSql = client + .schemaBuilder() + .createTableLike('users_like', 'users', function (table) { + table.text('add_col'); + table.integer('numeric_col'); + }) + .toSQL(); + expect(tableSql.length).to.equal(2); + expect(tableSql[0].sql).to.equal( + 'SELECT * INTO [users_like] FROM [users] WHERE 0=1' + ); + expect(tableSql[1].sql).to.equal( + 'ALTER TABLE [users_like] ADD [add_col] nvarchar(max), [numeric_col] int' + ); + }); + describe('views', function () { let knexMssql; diff --git a/test/unit/schema-builder/mysql.js b/test/unit/schema-builder/mysql.js index a641179e62..2af5944892 100644 --- a/test/unit/schema-builder/mysql.js +++ b/test/unit/schema-builder/mysql.js @@ -46,6 +46,23 @@ module.exports = function (dialect) { ); }); + it('create table like another with additionnal columns', function () { + tableSql = client + .schemaBuilder() + .createTableLike('users_like', 'users', function (table) { + table.text('add_col'); + table.integer('numeric_col'); + }) + .toSQL(); + expect(tableSql.length).to.equal(2); + expect(tableSql[0].sql).to.equal( + 'create table `users_like` like `users`' + ); + expect(tableSql[1].sql).to.equal( + 'alter table `users_like` add `add_col` text, add `numeric_col` int' + ); + }); + it('test basic create table with incrementing without primary key', function () { tableSql = client .schemaBuilder() diff --git a/test/unit/schema-builder/oracledb.js b/test/unit/schema-builder/oracledb.js index 1cbde61dd1..fb52e47206 100644 --- a/test/unit/schema-builder/oracledb.js +++ b/test/unit/schema-builder/oracledb.js @@ -35,6 +35,23 @@ describe('OracleDb SchemaBuilder', function () { ); }); + it('test create table like with additionnal columns', function () { + tableSql = client + .schemaBuilder() + .createTableLike('users_like', 'users', function (table) { + table.text('add_col'); + table.integer('add_num_col'); + }); + + expect(tableSql.toSQL().length).to.equal(2); + expect(tableSql.toSQL()[0].sql).to.equal( + 'create table "users_like" as (select * from "users" where 0=1)' + ); + expect(tableSql.toSQL()[1].sql).to.equal( + 'alter table "users_like" add ("add_col" clob, "add_num_col" integer)' + ); + }); + describe('views', function () { let knexOracleDb; diff --git a/test/unit/schema-builder/postgres.js b/test/unit/schema-builder/postgres.js index 2caee2ac6f..e9ef958d08 100644 --- a/test/unit/schema-builder/postgres.js +++ b/test/unit/schema-builder/postgres.js @@ -123,6 +123,20 @@ describe('PostgreSQL SchemaBuilder', function () { ); }); + it('create table like another with additionnal columns', function () { + tableSql = client + .schemaBuilder() + .createTableLike('users_like', 'users', function (table) { + table.text('add_col'); + table.integer('numeric_col'); + }) + .toSQL(); + expect(tableSql.length).to.equal(1); + expect(tableSql[0].sql).to.equal( + 'create table "users_like" (like "users" including all, "add_col" text, "numeric_col" integer)' + ); + }); + it('basic alter table', function () { tableSql = client .schemaBuilder() diff --git a/test/unit/schema-builder/redshift.js b/test/unit/schema-builder/redshift.js index 1beb76d87e..c385794742 100644 --- a/test/unit/schema-builder/redshift.js +++ b/test/unit/schema-builder/redshift.js @@ -38,6 +38,26 @@ describe('Redshift SchemaBuilder', function () { ); }); + it('create table like another with additional columns', function () { + tableSql = client + .schemaBuilder() + .createTableLike('users_like', 'users', function (table) { + table.text('add_col'); + table.integer('add_num_col'); + }) + .toSQL(); + expect(tableSql.length).to.equal(3); + expect(tableSql[0].sql).to.equal( + 'create table "users_like" (like "users")' + ); + expect(tableSql[1].sql).to.equal( + 'alter table "users_like" add column "add_col" varchar(max)' + ); + expect(tableSql[2].sql).to.equal( + 'alter table "users_like" add column "add_num_col" integer' + ); + }); + it('basic alter table', function () { tableSql = client .schemaBuilder() diff --git a/test/unit/schema-builder/sqlite3.js b/test/unit/schema-builder/sqlite3.js index e18cae0c65..454db5672f 100644 --- a/test/unit/schema-builder/sqlite3.js +++ b/test/unit/schema-builder/sqlite3.js @@ -50,6 +50,26 @@ describe('SQLite SchemaBuilder', function () { ); }); + it('test create table like with additionnal columns', function () { + tableSql = client + .schemaBuilder() + .createTableLike('users_like', 'users', function (table) { + table.text('add_col'); + table.integer('add_num_col'); + }); + + expect(tableSql.toSQL().length).to.equal(3); + expect(tableSql.toSQL()[0].sql).to.equal( + 'create table `users_like` as select * from `users` where 0=1' + ); + expect(tableSql.toSQL()[1].sql).to.equal( + 'alter table `users_like` add column `add_col` text' + ); + expect(tableSql.toSQL()[2].sql).to.equal( + 'alter table `users_like` add column `add_num_col` integer' + ); + }); + describe('views', function () { let knexSqlite3; From 02d64c5ab5d5ab51c493831689a6e5abf46f63db Mon Sep 17 00:00:00 2001 From: Olivier Cavadenti Date: Wed, 10 Nov 2021 20:34:27 +0100 Subject: [PATCH 2/4] fix misc test --- test/integration2/schema/misc.spec.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/integration2/schema/misc.spec.js b/test/integration2/schema/misc.spec.js index 14dae21939..072773bc7c 100644 --- a/test/integration2/schema/misc.spec.js +++ b/test/integration2/schema/misc.spec.js @@ -323,6 +323,8 @@ describe('Schema (misc)', () => { }); it('copy table with additionnal column', async () => { + await knex.schema.dropTableIfExists('table_copied'); + await knex.schema.dropTableIfExists('table_to_copy'); await knex.schema .createTableLike( 'table_copied', @@ -335,12 +337,12 @@ describe('Schema (misc)', () => { .testSql((tester) => { tester('mysql', [ 'create table `table_copied` like `table_to_copy`', - 'alter table `table_copied` add `add_col` text, add `numeric_col` int', + 'alter table `table_copied` add `add_col` text, add `add_num_col` int', ]); tester( ['pg', 'cockroachdb'], [ - 'create table "table_copied" (like "users" including all, "add_col" text, "numeric_col" integer)', + 'create table "table_copied" (like "users" including all, "add_col" text, "add_num_col" integer)', ] ); tester('pg-redshift', [ @@ -351,7 +353,7 @@ describe('Schema (misc)', () => { tester('sqlite3', [ 'create table `table_copied` as select * from `table_to_copy` where 0=1', 'alter table `table_copied` add column `add_col` text', - 'alter table `users_like` add column `add_num_col` integer', + 'alter table `table_copied` add column `add_num_col` integer', ]); tester('oracledb', [ 'create table "table_copied" as (select * from "table_to_copy" where 0=1)', @@ -359,7 +361,7 @@ describe('Schema (misc)', () => { ]); tester('mssql', [ 'SELECT * INTO [table_copied] FROM [table_to_copy] WHERE 0=1', - 'ALTER TABLE [table_copied] ADD [add_col] nvarchar(max), [numeric_col] int', + 'ALTER TABLE [table_copied] ADD [add_col] nvarchar(max), [add_num_col] int"', ]); }); From fb0dca17822e097b6953612f83ec3f979cefc924 Mon Sep 17 00:00:00 2001 From: Olivier Cavadenti Date: Wed, 10 Nov 2021 20:38:14 +0100 Subject: [PATCH 3/4] remove drop --- test/integration2/schema/misc.spec.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/integration2/schema/misc.spec.js b/test/integration2/schema/misc.spec.js index 072773bc7c..183a37ee74 100644 --- a/test/integration2/schema/misc.spec.js +++ b/test/integration2/schema/misc.spec.js @@ -324,7 +324,6 @@ describe('Schema (misc)', () => { it('copy table with additionnal column', async () => { await knex.schema.dropTableIfExists('table_copied'); - await knex.schema.dropTableIfExists('table_to_copy'); await knex.schema .createTableLike( 'table_copied', @@ -361,7 +360,7 @@ describe('Schema (misc)', () => { ]); tester('mssql', [ 'SELECT * INTO [table_copied] FROM [table_to_copy] WHERE 0=1', - 'ALTER TABLE [table_copied] ADD [add_col] nvarchar(max), [add_num_col] int"', + 'ALTER TABLE [table_copied] ADD [add_col] nvarchar(max), [add_num_col] int', ]); }); From 202865336059b744bc6b0c0eb5220001246f8881 Mon Sep 17 00:00:00 2001 From: Olivier Cavadenti Date: Wed, 10 Nov 2021 20:44:15 +0100 Subject: [PATCH 4/4] fix typo --- test/integration2/schema/misc.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration2/schema/misc.spec.js b/test/integration2/schema/misc.spec.js index 183a37ee74..65c4cc77c9 100644 --- a/test/integration2/schema/misc.spec.js +++ b/test/integration2/schema/misc.spec.js @@ -341,7 +341,7 @@ describe('Schema (misc)', () => { tester( ['pg', 'cockroachdb'], [ - 'create table "table_copied" (like "users" including all, "add_col" text, "add_num_col" integer)', + 'create table "table_copied" (like "table_to_copy" including all, "add_col" text, "add_num_col" integer)', ] ); tester('pg-redshift', [