Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Checks Constraints Support for CockroachDB #4875

Merged
merged 2 commits into from Jan 1, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 62 additions & 0 deletions lib/dialects/cockroachdb/crdb-tablecompiler.js
Expand Up @@ -7,6 +7,68 @@ class TableCompiler_CRDB extends TableCompiler {
super(client, tableBuilder);
}

addColumns(columns, prefix, colCompilers) {
if (prefix === this.alterColumnsPrefix) {
OlivierCavadenti marked this conversation as resolved.
Show resolved Hide resolved
// alter columns
for (const col of colCompilers) {
const quotedTableName = this.tableName();
const type = col.getColumnType();
// We'd prefer to call this.formatter.wrapAsIdentifier here instead, however the context passed to
// `this` instance is not that of the column, but of the table. Thus, we unfortunately have to call
// `wrapIdentifier` here as well (it is already called once on the initial column operation) to give
// our `alter` operation the correct `queryContext`. Refer to issue #2606 and PR #2612.
const colName = this.client.wrapIdentifier(
col.getColumnName(),
col.columnBuilder.queryContext()
);

// To alter enum columns they must be cast to text first
const isEnum = col.type === 'enu';
this.client.logger.warn(
'Experimental alter column in use, see issue: https://github.com/cockroachdb/cockroach/issues/49329'
);
this.pushQuery({
sql: 'SET enable_experimental_alter_column_type_general = true',
bindings: [],
});
this.pushQuery({
sql: `alter table ${quotedTableName} alter column ${colName} drop default`,
bindings: [],
});
this.pushQuery({
sql: `alter table ${quotedTableName} alter column ${colName} drop not null`,
bindings: [],
});
this.pushQuery({
sql: `alter table ${quotedTableName} alter column ${colName} type ${type} using (${colName}${
isEnum ? '::text::' : '::'
}${type})`,
bindings: [],
});

const defaultTo = col.modified['defaultTo'];
if (defaultTo) {
const modifier = col.defaultTo.apply(col, defaultTo);
this.pushQuery({
sql: `alter table ${quotedTableName} alter column ${colName} set ${modifier}`,
bindings: [],
});
}

const nullable = col.modified['nullable'];
if (nullable && nullable[0] === false) {
this.pushQuery({
sql: `alter table ${quotedTableName} alter column ${colName} set not null`,
bindings: [],
});
}
}
} else {
// base class implementation for normal add
super.addColumns(columns, prefix);
}
}

dropUnique(columns, indexName) {
indexName = indexName
? this.formatter.wrap(indexName)
Expand Down
2 changes: 1 addition & 1 deletion scripts/docker-compose.yml
Expand Up @@ -85,7 +85,7 @@ services:
- 'until /usr/local/bin/psql postgres://testuser:knextest@postgres/knex_test -c "SELECT 1"; do sleep 5; done'

cockroachdb:
image: cockroachdb/cockroach:latest-v21.1
image: cockroachdb/cockroach:latest-v21.2
container_name: crdb
hostname: crdb
command: start-single-node --cluster-name=example-single-node --insecure
Expand Down
11 changes: 8 additions & 3 deletions test/integration2/schema/checks.spec.js
Expand Up @@ -403,7 +403,6 @@ describe.only('Checks', () => {
table.integer('price');
});
expect(await knex('check_test').insert([{ price: -5 }])).to.not.throw;

// Alter table with check constraint fail, we have row that violated the constraint
let error;
try {
Expand All @@ -417,21 +416,27 @@ describe.only('Checks', () => {

// empty the table to add the constraint
await knex('check_test').truncate();

await knex.schema
.table('check_test', (table) => {
table.integer('price').checkPositive().alter();
})
.testSql((tester) => {
tester(
['pg', 'pg-redshift', 'cockroachdb'],
['pg', 'pg-redshift'],
[
'alter table "check_test" alter column "price" drop default',
'alter table "check_test" alter column "price" drop not null',
'alter table "check_test" alter column "price" type integer using ("price"::integer)',
'alter table "check_test" add constraint check_test_price_1 check("price" > 0)',
]
);
tester('cockroachdb', [
'SET enable_experimental_alter_column_type_general = true',
'alter table "check_test" alter column "price" drop default',
'alter table "check_test" alter column "price" drop not null',
'alter table "check_test" alter column "price" type integer using ("price"::integer)',
'alter table "check_test" add constraint check_test_price_1 check("price" > 0)',
]);
tester('oracledb', [
'alter table "check_test" modify "price" integer',
'alter table "check_test" add constraint check_test_price_1 check("price" > 0)',
Expand Down