diff --git a/src/operation-node/insert-query-node.ts b/src/operation-node/insert-query-node.ts index eb6553b96..7d2ace57f 100644 --- a/src/operation-node/insert-query-node.ts +++ b/src/operation-node/insert-query-node.ts @@ -22,6 +22,7 @@ export interface InsertQueryNode extends OperationNode { readonly ignore?: boolean readonly replace?: boolean readonly explain?: ExplainNode + readonly defaultValues?: boolean } /** diff --git a/src/operation-node/operation-node-transformer.ts b/src/operation-node/operation-node-transformer.ts index b57a79549..f4c6438e8 100644 --- a/src/operation-node/operation-node-transformer.ts +++ b/src/operation-node/operation-node-transformer.ts @@ -378,6 +378,7 @@ export class OperationNodeTransformer { ignore: node.ignore, replace: node.replace, explain: this.transformNode(node.explain), + defaultValues: node.defaultValues, }) } diff --git a/src/query-builder/insert-query-builder.ts b/src/query-builder/insert-query-builder.ts index 6c75ea670..fc160ed14 100644 --- a/src/query-builder/insert-query-builder.ts +++ b/src/query-builder/insert-query-builder.ts @@ -327,6 +327,18 @@ export class InsertQueryBuilder }) } + /** + * Creates an `insert into "person" default values` query. + */ + defaultValues(): InsertQueryBuilder { + return new InsertQueryBuilder({ + ...this.#props, + queryNode: InsertQueryNode.cloneWith(this.#props.queryNode, { + defaultValues: true, + }), + }) + } + /** * Changes an `insert into` query to an `insert ignore into` query. * diff --git a/src/query-compiler/default-query-compiler.ts b/src/query-compiler/default-query-compiler.ts index f8d45287e..4660cc945 100644 --- a/src/query-compiler/default-query-compiler.ts +++ b/src/query-compiler/default-query-compiler.ts @@ -314,6 +314,11 @@ export class DefaultQueryCompiler this.visitNode(node.values) } + if (node.defaultValues) { + this.append(' ') + this.append('default values') + } + if (node.onConflict) { this.append(' ') this.visitNode(node.onConflict) diff --git a/test/node/src/insert.test.ts b/test/node/src/insert.test.ts index ed32f4136..ae1ad472b 100644 --- a/test/node/src/insert.test.ts +++ b/test/node/src/insert.test.ts @@ -77,6 +77,29 @@ for (const dialect of DIALECTS) { }) }) + it('should insert one row with default values', async () => { + const query = ctx.db.insertInto('person').defaultValues() + + testSql(query, dialect, { + postgres: { + sql: 'insert into "person" default values', + parameters: [], + }, + mysql: { + sql: 'insert into `person` default values', + parameters: [], + }, + mssql: { + sql: 'insert into "person" default values', + parameters: [], + }, + sqlite: { + sql: 'insert into "person" default values', + parameters: [], + }, + }) + }) + it('should insert one row with complex values', async () => { const query = ctx.db.insertInto('person').values({ first_name: ctx.db @@ -118,43 +141,42 @@ for (const dialect of DIALECTS) { }) }) - it.skip('should insert one row with expressions', async () => { - const query = ctx.db.insertInto('person').values(({ selectFrom }) => ({ - first_name: selectFrom('pet') - .select('name') - .where('species', '=', 'dog') - .limit(1), - gender: 'female', - })) + if (dialect !== 'mssql') { + it('should insert one row with expressions', async () => { + const query = ctx.db.insertInto('person').values(({ selectFrom }) => ({ + first_name: selectFrom('pet') + .select('name') + .where('species', '=', 'dog') + .limit(1), + gender: 'female', + })) - testSql(query, dialect, { - postgres: { - sql: `insert into "person" ("first_name", "gender") values ((select "first_name" from "person" where "last_name" = $1 limit $2), $3)`, - parameters: ['Aniston', 1, 'female'], - }, - mysql: { - sql: 'insert into `person` (`first_name`, `gender`) values ((select `first_name` from `person` where `last_name` = ? limit ?), ?)', - parameters: ['Aniston', 1, 'female'], - }, - mssql: { - sql: `insert into "person" ("first_name", "gender") values ((select "first_name" from "person" where "last_name" = @1 limit @2), @3)`, - parameters: ['Aniston', 1, 'female'], - }, - sqlite: { - sql: `insert into "person" ("first_name", "gender") values ((select "first_name" from "person" where "last_name" = ? limit ?), ?)`, - parameters: ['Aniston', 1, 'female'], - }, - }) + testSql(query, dialect, { + postgres: { + sql: `insert into "person" ("first_name", "gender") values ((select "name" from "pet" where "species" = $1 limit $2), $3)`, + parameters: ['dog', 1, 'female'], + }, + mysql: { + sql: 'insert into `person` (`first_name`, `gender`) values ((select `name` from `pet` where `species` = ? limit ?), ?)', + parameters: ['dog', 1, 'female'], + }, + sqlite: { + sql: `insert into "person" ("first_name", "gender") values ((select "name" from "pet" where "species" = ? limit ?), ?)`, + parameters: ['dog', 1, 'female'], + }, + mssql: NOT_SUPPORTED, + }) - const result = await query.executeTakeFirst() - expect(result).to.be.instanceOf(InsertResult) - expect(result.numInsertedOrUpdatedRows).to.equal(1n) + const result = await query.executeTakeFirst() + expect(result).to.be.instanceOf(InsertResult) + expect(result.numInsertedOrUpdatedRows).to.equal(1n) - expect(await getNewestPerson(ctx.db)).to.eql({ - first_name: 'Jennifer', - last_name: null, + expect(await getNewestPerson(ctx.db)).to.eql({ + first_name: 'Doggo', + last_name: null, + }) }) - }) + } it('should insert the result of a select query', async () => { const query = ctx.db diff --git a/test/node/src/select.test.ts b/test/node/src/select.test.ts index f0953edd3..7334b798c 100644 --- a/test/node/src/select.test.ts +++ b/test/node/src/select.test.ts @@ -658,7 +658,7 @@ for (const dialect of DIALECTS) { parameters: ['Jennifer'], }, mysql: { - sql: 'select `last_name` from `person` where `first_name` = ? for update of "person"', + sql: 'select `last_name` from `person` where `first_name` = ? for update of `person`', parameters: ['Jennifer'], }, mssql: NOT_SUPPORTED, @@ -712,7 +712,7 @@ for (const dialect of DIALECTS) { parameters: ['Jennifer'], }, mysql: { - sql: 'select `last_name` from `person` where `first_name` = ? for update of "person" skip locked', + sql: 'select `last_name` from `person` where `first_name` = ? for update of `person` skip locked', parameters: ['Jennifer'], }, mssql: NOT_SUPPORTED,