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

[WIP] Check constraints #2364

Closed
wants to merge 1 commit into from
Closed

[WIP] Check constraints #2364

wants to merge 1 commit into from

Conversation

richraid21
Copy link
Contributor

@richraid21 richraid21 commented Dec 1, 2017

Adds check constraint methods to both column and table level APIs

See Postgres Check Constraint Docs

Use case:

await knex.schema.createTable('_test', (t) => {
        t.increments()
        t.text('name').notNullable().check('name != NULL') // Stupid example, but shows chaining
        t.date('created')
        t.date('updated')
        
        t.check('updated >= created')
    })

TODO

Still need to write tests and documentation

Copy link
Member

@elhigu elhigu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this has some bugs which were commented to code rows.

Also this would need implementation for all the supported dialects, because if this is implemented only for 1 dialect it is the same just to use knex.schema.raw (there was a time when I was accepting single db implementations for some features, it was a bad decision).

Lastly tests and documentation is completely missing.

@@ -90,6 +90,11 @@ TableCompiler_PG.prototype.comment = function(comment) {
this.pushQuery(`comment on table ${this.tableName()} is '${this.single.comment}'`);
};

TableCompiler_PG.prototype.check = function(logic) {
const name = this.formatter.wrap(`${this.tableNameRaw}_check`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this naming convention limits number of check constraints per table to be 1.

@@ -90,6 +90,11 @@ TableCompiler_PG.prototype.comment = function(comment) {
this.pushQuery(`comment on table ${this.tableName()} is '${this.single.comment}'`);
};

TableCompiler_PG.prototype.check = function(logic) {
const name = this.formatter.wrap(`${this.tableNameRaw}_check`);
this.pushQuery(`alter table ${this.tableName()} add constraint ${name} check (${logic})`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to support raw() syntax, or otherwise identifier/value bindings cannot be handled properly across the dialects

@elhigu
Copy link
Member

elhigu commented Dec 2, 2017

And there was some indentation error which caused CI to fail :)

@richraid21 richraid21 changed the title [Postgres] Check constraints [WIP] Check constraints Dec 2, 2017
@richraid21
Copy link
Contributor Author

@elhigu
Regarding raw syntax, after some testing, it seems like pg doesn't support this.

The following all fail with assorted errors being thrown in pg:

await knex.raw('alter table _test3 add constraint ? check (length(name) >= 3)', ['name_check'])
// or
await knex.raw('alter table _test3 add constraint name_check check (length(?) >= 3)', ['name'])
// or
await knex.raw('alter table _test3 add constraint name_check check (length(?) >= ?)', ['name', 3])
// or
await knex.raw('alter table _test3 add constraint ? check (length(?) >= ?)', ['name_check', 'name', 3])

@elhigu
Copy link
Member

elhigu commented Dec 6, 2017

Probably all of those examples already throw an error because PG does not use ? for values bindings. Also identifiers are quoted / wrapped by knex, they are not passed as bindings to drivers.

e.g.

raw('?? = ?', ['colName', 'foo'])

will pass string

"colName" = $1` bindings: ['foo']

to the driver.

But it is necessary that knex can do its wrapping to make quotes right (and make use of custom identifier wrapping if it is set in knex configuration).

@GAumala
Copy link
Contributor

GAumala commented Dec 12, 2017

A MySQL implementation should also be included. I'm aware that MySQL parses CHECK statements but ignores them, however, MariaDB doesn't have this limitation as of version 10.2.1. Knex with MySQL driver works seamlessly with MariaDB, so the implementation would still be useful.

I have one question though, is it currently possible to implement the CHECK statement with a raw query without having to do the whole table declaration as a raw query? Something like:

await knex.schema.createTable('_test', (t) => {
        t.increments()
        t.date('created')
        t.date('updated')
        
        t.raw('check updated >= created')
    })

@kibertoad
Copy link
Collaborator

@richraid21 Are you still interested in finishing this?

@OlivierCavadenti
Copy link
Collaborator

Superseded by #4874

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support CHECK
5 participants