diff --git a/lib/dialects/cockroachdb/crdb-columncompiler.js b/lib/dialects/cockroachdb/crdb-columncompiler.js new file mode 100644 index 0000000000..6a35557ef7 --- /dev/null +++ b/lib/dialects/cockroachdb/crdb-columncompiler.js @@ -0,0 +1,14 @@ +const ColumnCompiler_PG = require('../postgres/schema/pg-columncompiler.js'); + +class ColumnCompiler_CRDB extends ColumnCompiler_PG { + uuid(options = { primaryKey: false }) { + return ( + 'uuid' + + (this.tableCompiler._canBeAddPrimaryKey(options) + ? ' primary key default gen_random_uuid()' + : '') + ); + } +} + +module.exports = ColumnCompiler_CRDB; diff --git a/lib/dialects/cockroachdb/index.js b/lib/dialects/cockroachdb/index.js index a22411a086..63aa8c7895 100644 --- a/lib/dialects/cockroachdb/index.js +++ b/lib/dialects/cockroachdb/index.js @@ -3,6 +3,7 @@ const Client_PostgreSQL = require('../postgres'); const Transaction = require('../postgres/execution/pg-transaction'); const QueryCompiler = require('./crdb-querycompiler'); +const ColumnCompiler = require('./crdb-columncompiler'); const TableCompiler = require('./crdb-tablecompiler'); const ViewCompiler = require('./crdb-viewcompiler'); const QueryBuilder = require('./crdb-querybuilder'); @@ -19,6 +20,10 @@ class Client_CockroachDB extends Client_PostgreSQL { return new QueryCompiler(this, builder, formatter); } + columnCompiler() { + return new ColumnCompiler(this, ...arguments); + } + tableCompiler() { return new TableCompiler(this, ...arguments); } diff --git a/lib/dialects/postgres/schema/pg-columncompiler.js b/lib/dialects/postgres/schema/pg-columncompiler.js index 569c01724e..a7cd3e32bc 100644 --- a/lib/dialects/postgres/schema/pg-columncompiler.js +++ b/lib/dialects/postgres/schema/pg-columncompiler.js @@ -124,6 +124,13 @@ class ColumnCompiler_PG extends ColumnCompiler { (this.tableCompiler._canBeAddPrimaryKey(options) ? ' primary key' : '') ); } + + uuid(options = { primaryKey: false }) { + return ( + 'uuid' + + (this.tableCompiler._canBeAddPrimaryKey(options) ? ' primary key' : '') + ); + } } ColumnCompiler_PG.prototype.bigint = 'bigint'; @@ -133,7 +140,6 @@ ColumnCompiler_PG.prototype.double = 'double precision'; ColumnCompiler_PG.prototype.floating = 'real'; ColumnCompiler_PG.prototype.smallint = 'smallint'; ColumnCompiler_PG.prototype.tinyint = 'smallint'; -ColumnCompiler_PG.prototype.uuid = 'uuid'; function jsonColumn(client, jsonb) { if ( diff --git a/lib/schema/columncompiler.js b/lib/schema/columncompiler.js index c0a7635f0f..e7d495fd7f 100644 --- a/lib/schema/columncompiler.js +++ b/lib/schema/columncompiler.js @@ -277,8 +277,10 @@ ColumnCompiler.prototype.geography = 'geography'; ColumnCompiler.prototype.point = 'point'; ColumnCompiler.prototype.enu = 'varchar'; ColumnCompiler.prototype.bit = ColumnCompiler.prototype.json = 'text'; -ColumnCompiler.prototype.uuid = ({ useBinaryUuid = false } = {}) => - useBinaryUuid ? 'binary(16)' : 'char(36)'; +ColumnCompiler.prototype.uuid = ({ + useBinaryUuid = false, + primaryKey = false, +} = {}) => (useBinaryUuid ? 'binary(16)' : 'char(36)'); ColumnCompiler.prototype.integer = ColumnCompiler.prototype.smallint = ColumnCompiler.prototype.mediumint = diff --git a/test/db-less-test-suite.js b/test/db-less-test-suite.js index 5dd9280708..5a5b400363 100644 --- a/test/db-less-test-suite.js +++ b/test/db-less-test-suite.js @@ -22,6 +22,7 @@ describe('Query Building Tests', function () { require('./unit/schema-builder/mysql')('mysql2'); require('./unit/schema-builder/extensions'); require('./unit/schema-builder/postgres'); + require('./unit/schema-builder/cockroachdb'); require('./unit/schema-builder/redshift'); require('./unit/schema-builder/sqlite3'); require('./unit/schema-builder/oracle'); diff --git a/test/integration2/schema/misc.spec.js b/test/integration2/schema/misc.spec.js index 0a7dfceb35..715bd52869 100644 --- a/test/integration2/schema/misc.spec.js +++ b/test/integration2/schema/misc.spec.js @@ -482,6 +482,43 @@ describe('Schema (misc)', () => { }); }); + describe('uuid types - postgres', () => { + before(async () => { + await knex.schema.createTable('uuid_column_test', (table) => { + table.uuid('id', { primaryKey: true }); + }); + }); + + after(async () => { + await knex.schema.dropTable('uuid_column_test'); + }); + + it('#5211 - creates an uuid column as primary key', async function () { + if (!isPgBased(knex)) { + return this.skip(); + } + + const table_name = 'uuid_column_test'; + const expected_column = 'id'; + const expected_type = 'uuid'; + + const cols = await knex.raw( + `select c.column_name, c.data_type + from INFORMATION_SCHEMA.COLUMNS c + join INFORMATION_SCHEMA.KEY_COLUMN_USAGE cu + on (c.table_name = cu.table_name and c.column_name = cu.column_name) + where c.table_name = ? + and (cu.constraint_name like '%_pkey' or cu.constraint_name = 'primary')`, + table_name + ); + const column_name = cols.rows[0].column_name; + const column_type = cols.rows[0].data_type; + + expect(column_name).to.equal(expected_column); + expect(column_type).to.equal(expected_type); + }); + }); + describe('increments types - mysql', () => { before(() => Promise.all([ diff --git a/test/unit/schema-builder/cockroachdb.js b/test/unit/schema-builder/cockroachdb.js new file mode 100644 index 0000000000..9d0c3de30a --- /dev/null +++ b/test/unit/schema-builder/cockroachdb.js @@ -0,0 +1,23 @@ +const { expect } = require('chai'); + +let tableSql; + +const PG_Client = require('../../../lib/dialects/cockroachdb'); +const client = new PG_Client({ client: 'pg' }); + +const equal = require('chai').assert.equal; + +describe('CockroachDB SchemaBuilder', function () { + it('create table with uuid primary key in one go', function () { + tableSql = client + .schemaBuilder() + .createTable('uuid_primary', function (table) { + table.uuid('id', { primaryKey: true }); + }) + .toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal( + 'create table "uuid_primary" ("id" uuid primary key default gen_random_uuid())' + ); + }); +}); diff --git a/test/unit/schema-builder/postgres.js b/test/unit/schema-builder/postgres.js index 46a0c915bd..f27f041751 100644 --- a/test/unit/schema-builder/postgres.js +++ b/test/unit/schema-builder/postgres.js @@ -137,6 +137,19 @@ describe('PostgreSQL SchemaBuilder', function () { ); }); + it('create table with uuid primary key in one go', function () { + tableSql = client + .schemaBuilder() + .createTable('uuid_primary', function (table) { + table.uuid('id', { primaryKey: true }); + }) + .toSQL(); + equal(1, tableSql.length); + expect(tableSql[0].sql).to.equal( + 'create table "uuid_primary" ("id" uuid primary key)' + ); + }); + it('basic alter table', function () { tableSql = client .schemaBuilder() @@ -446,7 +459,6 @@ describe('PostgreSQL SchemaBuilder', function () { ); }); - it('refresh view concurrently', function () { tableSql = client .schemaBuilder() diff --git a/types/index.d.ts b/types/index.d.ts index 3b8ac2f34f..77dda90515 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -2144,7 +2144,7 @@ export declare namespace Knex { ): ColumnBuilder; json(columnName: string): ColumnBuilder; jsonb(columnName: string): ColumnBuilder; - uuid(columnName: string, options?: Readonly<{useBinaryUuid?: boolean}>): ColumnBuilder; + uuid(columnName: string, options?: Readonly<{useBinaryUuid?: boolean, primaryKey?: boolean}>): ColumnBuilder; comment(val: string): void; specificType(columnName: string, type: string): ColumnBuilder; primary(columnNames: readonly string[], options?: Readonly<{constraintName?: string, deferrable?: deferrableType}>): TableBuilder;