@@ -9294,13 +9294,13 @@ public function testCheckConstraints(): void {
92949294
92959295 // The of the check expressions below is not 100% matching MySQL,
92969296 // because in MySQL the expressions are parsed and normalized.
9297- ' CONSTRAINT `c1` CHECK ( id < 10 ), ' ,
9298- ' CONSTRAINT `c2` CHECK ( start_timestamp < end_timestamp ), ' ,
9299- ' CONSTRAINT `c3` CHECK ( length ( data ) < 20 ), ' ,
9300- ' CONSTRAINT `t_chk_1` CHECK ( id > 0 ), ' ,
9301- " CONSTRAINT `t_chk_2` CHECK ( name != '' ), " ,
9302- ' CONSTRAINT `t_chk_3` CHECK ( score > 0 AND score < 100 ), ' ,
9303- ' CONSTRAINT `t_chk_4` CHECK ( json_valid ( data ) ) ' ,
9297+ ' CONSTRAINT `c1` CHECK (id < 10), ' ,
9298+ ' CONSTRAINT `c2` CHECK (start_timestamp < end_timestamp), ' ,
9299+ ' CONSTRAINT `c3` CHECK (length( data) < 20), ' ,
9300+ ' CONSTRAINT `t_chk_1` CHECK (id > 0), ' ,
9301+ " CONSTRAINT `t_chk_2` CHECK (name != ''), " ,
9302+ ' CONSTRAINT `t_chk_3` CHECK (score > 0 AND score < 100), ' ,
9303+ ' CONSTRAINT `t_chk_4` CHECK (json_valid( data) ) ' ,
93049304 ') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ' ,
93059305 )
93069306 ),
@@ -9326,8 +9326,8 @@ public function testAlterTableAddCheckConstraint(): void {
93269326 array (
93279327 'CREATE TABLE `t` ( ' ,
93289328 ' `id` int DEFAULT NULL, ' ,
9329- ' CONSTRAINT `c` CHECK ( id > 0 ), ' ,
9330- ' CONSTRAINT `t_chk_1` CHECK ( id < 10 ) ' ,
9329+ ' CONSTRAINT `c` CHECK (id > 0), ' ,
9330+ ' CONSTRAINT `t_chk_1` CHECK (id < 10) ' ,
93319331 ') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ' ,
93329332 )
93339333 ),
@@ -9396,7 +9396,7 @@ public function testCheckConstraintNotEnforced(): void {
93969396 array (
93979397 'CREATE TABLE `t` ( ' ,
93989398 ' `id` int DEFAULT NULL, ' ,
9399- ' CONSTRAINT `c` CHECK ( id > 0 ) /*!80016 NOT ENFORCED */ ' ,
9399+ ' CONSTRAINT `c` CHECK (id > 0) /*!80016 NOT ENFORCED */ ' ,
94009400 ') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ' ,
94019401 )
94029402 ),
@@ -11368,4 +11368,159 @@ public function testSubstringFunction(): void {
1136811368 $ result = $ this ->assertQuery ( "SELECT SUBSTRING('abcdef' FROM 4) AS s " );
1136911369 $ this ->assertSame ( 'def ' , $ result [0 ]->s );
1137011370 }
11371+
11372+ /**
11373+ * Test CREATE TABLE with DEFAULT (now()) - GitHub issue #300
11374+ * Tests that DEFAULT with function calls in parentheses works correctly in AST driver.
11375+ *
11376+ * @see https://github.com/WordPress/sqlite-database-integration/issues/300
11377+ */
11378+ public function testCreateTableWithDefaultNowFunction (): void {
11379+ // Test the exact SQL from the issue
11380+ $ this ->assertQuery (
11381+ 'CREATE TABLE `test_now_default` (
11382+ `id` int NOT NULL,
11383+ `updated` timestamp NOT NULL DEFAULT (now()) ON UPDATE CURRENT_TIMESTAMP
11384+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; '
11385+ );
11386+
11387+ // Insert a row to verify the default value works
11388+ $ this ->assertQuery ( 'INSERT INTO test_now_default (id) VALUES (1) ' );
11389+ $ result = $ this ->assertQuery ( 'SELECT * FROM test_now_default WHERE id = 1 ' );
11390+ $ this ->assertCount ( 1 , $ result );
11391+
11392+ // Verify the updated timestamp was set (should match YYYY-MM-DD HH:MM:SS format)
11393+ $ this ->assertRegExp ( '/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/ ' , $ result [0 ]->updated );
11394+
11395+ // SHOW CREATE TABLE
11396+ $ this ->assertQuery ( 'SHOW CREATE TABLE test_now_default ' );
11397+ $ results = $ this ->engine ->get_query_results ();
11398+ $ this ->assertEquals (
11399+ implode (
11400+ "\n" ,
11401+ array (
11402+ 'CREATE TABLE `test_now_default` ( ' ,
11403+ ' `id` int NOT NULL, ' ,
11404+ ' `updated` timestamp NOT NULL DEFAULT (now()) ON UPDATE CURRENT_TIMESTAMP ' ,
11405+ ') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci ' ,
11406+ )
11407+ ),
11408+ $ results [0 ]->{'Create Table ' }
11409+ );
11410+
11411+ // DESCRIBE
11412+ $ this ->assertQuery ( 'DESCRIBE test_now_default ' );
11413+ $ results = $ this ->engine ->get_query_results ();
11414+ $ this ->assertEquals (
11415+ array (
11416+ (object ) array (
11417+ 'Field ' => 'id ' ,
11418+ 'Type ' => 'int ' ,
11419+ 'Null ' => 'NO ' ,
11420+ 'Key ' => '' ,
11421+ 'Default ' => null ,
11422+ 'Extra ' => '' ,
11423+ ),
11424+ (object ) array (
11425+ 'Field ' => 'updated ' ,
11426+ 'Type ' => 'timestamp ' ,
11427+ 'Null ' => 'NO ' ,
11428+ 'Key ' => '' ,
11429+ 'Default ' => 'now() ' ,
11430+ 'Extra ' => 'DEFAULT_GENERATED on update CURRENT_TIMESTAMP ' ,
11431+ ),
11432+ ),
11433+ $ results
11434+ );
11435+
11436+ // Verify the translated SQLite definition.
11437+ $ result = $ this ->sqlite ->query ( 'PRAGMA table_info(test_now_default) ' )->fetchAll ();
11438+ $ this ->assertSame ( null , $ result [0 ]['dflt_value ' ] );
11439+ $ this ->assertSame ( 'CURRENT_TIMESTAMP ' , $ result [1 ]['dflt_value ' ] );
11440+ }
11441+
11442+ public function testCreateTableWithDefaultExpressions (): void {
11443+ $ this ->assertQuery (
11444+ 'CREATE TABLE t (
11445+ id int NOT NULL,
11446+ col1 int NOT NULL DEFAULT (1 + 2),
11447+ col2 datetime NOT NULL DEFAULT (DATE_ADD(NOW(), INTERVAL 1 YEAR)),
11448+ col3 varchar(255) NOT NULL DEFAULT (CONCAT( \'a \', \'b \'))
11449+ ) '
11450+ );
11451+
11452+ // Insert a row and verify the default values
11453+ $ this ->assertQuery ( 'INSERT INTO t (id) VALUES (1) ' );
11454+ $ this ->assertQuery ( 'SELECT * FROM t WHERE id = 1 ' );
11455+ $ results = $ this ->engine ->get_query_results ();
11456+ $ this ->assertEquals ( 3 , $ results [0 ]->col1 );
11457+ $ this ->assertStringStartsWith ( ( gmdate ( 'Y ' ) + 1 ) . '- ' , $ results [0 ]->col2 );
11458+ $ this ->assertEquals ( 'ab ' , $ results [0 ]->col3 );
11459+
11460+ // SHOW CREATE TABLE
11461+ $ this ->assertQuery ( 'SHOW CREATE TABLE t ' );
11462+ $ results = $ this ->engine ->get_query_results ();
11463+ $ this ->assertEquals (
11464+ implode (
11465+ "\n" ,
11466+ array (
11467+ 'CREATE TABLE `t` ( ' ,
11468+ ' `id` int NOT NULL, ' ,
11469+ ' `col1` int NOT NULL DEFAULT (1 + 2), ' ,
11470+ ' `col2` datetime NOT NULL DEFAULT (DATE_ADD(NOW(), INTERVAL 1 YEAR)), ' ,
11471+ " `col3` varchar(255) NOT NULL DEFAULT (CONCAT('a' , 'b')) " ,
11472+ ') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ' ,
11473+ )
11474+ ),
11475+ $ results [0 ]->{'Create Table ' }
11476+ );
11477+
11478+ // DESCRIBE
11479+ $ this ->assertQuery ( 'DESCRIBE t ' );
11480+ $ results = $ this ->engine ->get_query_results ();
11481+ $ this ->assertEquals (
11482+ array (
11483+ (object ) array (
11484+ 'Field ' => 'id ' ,
11485+ 'Type ' => 'int ' ,
11486+ 'Null ' => 'NO ' ,
11487+ 'Key ' => '' ,
11488+ 'Default ' => null ,
11489+ 'Extra ' => '' ,
11490+ ),
11491+ (object ) array (
11492+ 'Field ' => 'col1 ' ,
11493+ 'Type ' => 'int ' ,
11494+ 'Null ' => 'NO ' ,
11495+ 'Key ' => '' ,
11496+ 'Default ' => '1 + 2 ' ,
11497+ 'Extra ' => 'DEFAULT_GENERATED ' ,
11498+ ),
11499+ (object ) array (
11500+ 'Field ' => 'col2 ' ,
11501+ 'Type ' => 'datetime ' ,
11502+ 'Null ' => 'NO ' ,
11503+ 'Key ' => '' ,
11504+ 'Default ' => 'DATE_ADD(NOW(), INTERVAL 1 YEAR) ' ,
11505+ 'Extra ' => 'DEFAULT_GENERATED ' ,
11506+ ),
11507+ (object ) array (
11508+ 'Field ' => 'col3 ' ,
11509+ 'Type ' => 'varchar(255) ' ,
11510+ 'Null ' => 'NO ' ,
11511+ 'Key ' => '' ,
11512+ 'Default ' => "CONCAT('a' , 'b') " ,
11513+ 'Extra ' => 'DEFAULT_GENERATED ' ,
11514+ ),
11515+ ),
11516+ $ results
11517+ );
11518+
11519+ // Verify the translated SQLite definition.
11520+ $ result = $ this ->sqlite ->query ( 'PRAGMA table_info(t) ' )->fetchAll ();
11521+ $ this ->assertSame ( null , $ result [0 ]['dflt_value ' ] );
11522+ $ this ->assertSame ( '1 + 2 ' , $ result [1 ]['dflt_value ' ] );
11523+ $ this ->assertSame ( "DATETIME(CURRENT_TIMESTAMP, '+' || 1 || ' YEAR') " , $ result [2 ]['dflt_value ' ] );
11524+ $ this ->assertSame ( "('a' || 'b') " , $ result [3 ]['dflt_value ' ] );
11525+ }
1137111526}
0 commit comments