-
Notifications
You must be signed in to change notification settings - Fork 52
Add support for CHECK constraints
#257
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
Conversation
68992c0 to
7d32ece
Compare
a536e39 to
638bab9
Compare
sejas
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not able to run the create table with check constraint. Maybe I'm doing something wrong during my testing steps.
I tested the PR by applying these changes to an existing Studio site mu-plugin, and when I run a CREATE TABLE, I'm getting the following error:
Next WP_SQLite_Driver_Exception: SQLSTATE[HY000]: General error: 1 no such table: _wp_sqlite_mysql_information_schema_check_constraints in /wordpress/wp-content/mu-plugins/sqlite-database-integration/wp-includes/sqlite-ast/class-wp-sqlite-driver.php:5446
Stack trace:
#0 /wordpress/wp-content/mu-plugins/sqlite-database-integration/wp-includes/sqlite-ast/class-wp-sqlite-driver.php(847): WP_SQLite_Driver->new_driver_exception('SQLSTATE[HY000]...', 'HY000', Object(PDOException))
#1 /tmp/sqlite-command/src/Import.php(54): WP_SQLite_Driver->query('CREATE TABLE `m...')
#2 /tmp/sqlite-command/src/Import.php(38): Automattic\WP_CLI\SQLite\Import->execute_statements('studio-backup-s...')
#3 /tmp/sqlite-command/src/SQLite_Command.php(45): Automattic\WP_CLI\SQLite\Import->run('studio-backup-s...', Array)
#4 [internal function]: Automattic\WP_CLI\SQLite\SQLite_Command->import(Array, Array)
#5 /tmp/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php(100): call_user_func(Array, Array, Array)
#6 [internal function]: WP_CLI\Dispatcher\CommandFactory::WP_CLI\Dispatcher\{closure}(Array, Array)
#7 /tmp/sqlite-command/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php(497): call_user_func(Object(Closure), Array, Array)
#8 phar:///tmp/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(470): WP_CLI\Dispatcher\Subcommand->invoke(Array, Array, Array)
#9 phar:///tmp/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(493): WP_CLI\Runner->run_command(Array, Array)
#10 phar:///tmp/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(136): WP_CLI\Runner->run_command_and_exit()
#11 phar:///tmp/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1349): WP_CLI\Runner->do_early_invoke('after_wp_config...')
#12 phar:///tmp/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1293): WP_CLI\Runner->load_wordpress()
#13 phar:///tmp/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\Runner->start()
#14 phar:///tmp/wp-cli.phar/vendor/wp-cli/wp-cli/php/bootstrap.php(84): WP_CLI\Bootstrap\LaunchRunner->process(Object(WP_CLI\Bootstrap\BootstrapState))
#15 phar:///tmp/wp-cli.phar/vendor/wp-cli/wp-cli/php/wp-cli.php(35): WP_CLI\bootstrap()
#16 phar:///tmp/wp-cli.phar/php/boot-phar.php(20): include('phar:///tmp/wp-...')
#17 /tmp/wp-cli.phar(4): include('phar:///tmp/wp-...')
#18 /tmp/run-cli.php(25): require('/tmp/wp-cli.pha...')
#19 {main}
thrown in /wordpress/wp-content/mu-plugins/sqlite-database-integration/wp-includes/sqlite-ast/class-wp-sqlite-driver.php on line 5446
at SQLImporter.importDatabase (/Users/macbookpro/Documents/projects-m3.nosync/studio/dist/main/index.js:14464:17)
at async SQLImporter.import (/Users/macbookpro/Documents/projects-m3.nosync/studio/dist/main/index.js:14711:7)
at async importBackup (/Users/macbookpro/Documents/projects-m3.nosync/studio/dist/main/index.js:15970:12)
at async importSite (/Users/macbookpro/Documents/projects-m3.nosync/studio/dist/main/index.js:16427:20)
at async Session.<anonymous> (node:electron/js2c/browser_init:2:107024)
Note the difference between the original error vs when I used the code from this PR:
- Next WP_SQLite_Driver_Exception: SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: _wp_sqlite_mysql_information_schema_table_constraints.CONSTRAINT_NAME in /wordpress/wp-content/mu-plugins/sqlite-database-integration/wp-includes/sqlite-ast/class-wp-sqlite-driver.php:5376
+ Next WP_SQLite_Driver_Exception: SQLSTATE[HY000]: General error: 1 no such table: _wp_sqlite_mysql_information_schema_check_constraints in /wordpress/wp-content/mu-plugins/sqlite-database-integration/wp-includes/sqlite-ast/class-wp-sqlite-driver.php:5446| } | ||
|
|
||
| // Translate the check clause from MySQL to SQLite. | ||
| $ast = $this->create_parser( 'SELECT ' . $check_constraint['CHECK_CLAUSE'] )->parse(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Smart! I wonder if we could modify the grammar and replace a check clause terminal with the column definition non-terminal 🤔 Nothing blocking here, though, this is cool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adamziel This actually comes from the information_schema.check_constraints table that stores the full MySQL CHECK expression. So the $check_constraint['CHECK_CLAUSE'] is the CHECK_CLAUSE column. We read it from there, translate it with this "hack" to SQLite, and then apply that to SQLite.
A slight difference is—MySQL normalizes the expression a bit; we keep it as it was written.
|
The code looks great @JanJakes! We just need to create the new table and column on any site upgrading to this plugin version. Is it time to add a simple migrations system that knows which schema version we're using and upgrades us step by step? I know WordPress has one, but I'm not sure we can use it here. |
@adamziel That will happen once we tag the release, and the DB configurator will detect that the version was bumped. The call to @sejas That also explains why you're running into the issue. Try to update the version in these three files, and it should work. And thanks for testing! |
Cool! Now that I've upgraded the plugin version, I confirm that the table is created and works as expected. Great work!. |
Implements support for
CHECKconstraints:This includes support for:
CREATE TABLEwith inlineCHECK (...)for column definitions.CREATE TABLEwithCHECK (...)andCONSTRAINT ... CHECK (...)definitions.ALTER TABLE ... ADD CHECK (...)andALTER TABLE ... ADD CONSTRAINT ... CHECK (...)statements.ALTER TABLE ... DROP CONSTRAINT ...statements.ALTER TABLE ... DROP CHECK ...statements.CHECKconstraints with theNOT ENFORCEDclause.Resolves #251.