From 6c0506c20d5c8a26f3e5e8452489e5c7948d0817 Mon Sep 17 00:00:00 2001 From: Markus Wendorf Date: Sat, 9 Mar 2024 21:55:29 +0100 Subject: [PATCH] feat: add 'add column if not exists' for postgres --- src/operation-node/column-definition-node.ts | 1 + .../operation-node-transformer.ts | 1 + src/query-compiler/default-query-compiler.ts | 4 ++++ src/schema/column-definition-builder.ts | 10 ++++++++++ test/node/src/schema.test.ts | 20 ++++++++++++++++++- 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/operation-node/column-definition-node.ts b/src/operation-node/column-definition-node.ts index 395d464b4..30897598f 100644 --- a/src/operation-node/column-definition-node.ts +++ b/src/operation-node/column-definition-node.ts @@ -28,6 +28,7 @@ export interface ColumnDefinitionNode extends OperationNode { readonly endModifiers?: ReadonlyArray readonly nullsNotDistinct?: boolean readonly identity?: boolean + readonly ifNotExists?: boolean } /** diff --git a/src/operation-node/operation-node-transformer.ts b/src/operation-node/operation-node-transformer.ts index 3036051b7..063ba46ba 100644 --- a/src/operation-node/operation-node-transformer.ts +++ b/src/operation-node/operation-node-transformer.ts @@ -452,6 +452,7 @@ export class OperationNodeTransformer { endModifiers: this.transformNodeList(node.endModifiers), nullsNotDistinct: node.nullsNotDistinct, identity: node.identity, + ifNotExists: node.ifNotExists, }) } diff --git a/src/query-compiler/default-query-compiler.ts b/src/query-compiler/default-query-compiler.ts index bbdbdb81e..dbec7eaa8 100644 --- a/src/query-compiler/default-query-compiler.ts +++ b/src/query-compiler/default-query-compiler.ts @@ -607,6 +607,10 @@ export class DefaultQueryCompiler } protected override visitColumnDefinition(node: ColumnDefinitionNode): void { + if (node.ifNotExists) { + this.append('if not exists ') + } + this.visitNode(node.column) this.append(' ') diff --git a/src/schema/column-definition-builder.ts b/src/schema/column-definition-builder.ts index 61d4961e1..3f638b765 100644 --- a/src/schema/column-definition-builder.ts +++ b/src/schema/column-definition-builder.ts @@ -376,6 +376,16 @@ export class ColumnDefinitionBuilder implements OperationNodeSource { ) } + /** + * Adds `if not exists` specifier. + * This only works for PostgreSQL. + */ + ifNotExists(): ColumnDefinitionBuilder { + return new ColumnDefinitionBuilder( + ColumnDefinitionNode.cloneWith(this.#node, { ifNotExists: true }), + ) + } + /** * This can be used to add any additional SQL to the end of the column definition. * diff --git a/test/node/src/schema.test.ts b/test/node/src/schema.test.ts index 936f50d46..8cd03929b 100644 --- a/test/node/src/schema.test.ts +++ b/test/node/src/schema.test.ts @@ -299,7 +299,7 @@ for (const dialect of DIALECTS) { const builder = ctx.db.schema .createTable('test') .addColumn('a', 'integer', (col) => - col.identity().notNull().primaryKey() + col.identity().notNull().primaryKey(), ) .addColumn('b', 'integer', (col) => col @@ -2329,6 +2329,24 @@ for (const dialect of DIALECTS) { await builder.execute() }) + + it('should add a column with "if not exists" modifier', async () => { + const builder = ctx.db.schema + .alterTable('test') + .addColumn('desc', 'varchar(20)', (cb) => cb.ifNotExists()) + + testSql(builder, dialect, { + postgres: { + sql: 'alter table "test" add column if not exists "desc" varchar(20)', + parameters: [], + }, + mysql: NOT_SUPPORTED, + mssql: NOT_SUPPORTED, + sqlite: NOT_SUPPORTED, + }) + + await builder.execute() + }) } if (dialect === 'postgres' || dialect === 'mysql') {