Skip to content

Commit 48b9588

Browse files
committed
Fix column default value handling
1 parent a8fbf9f commit 48b9588

File tree

3 files changed

+66
-19
lines changed

3 files changed

+66
-19
lines changed

tests/WP_SQLite_Driver_Tests.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ public function testShowCreateTableWithCorrectDefaultValues() {
476476
'CREATE TABLE `_tmp__table` (
477477
`ID` bigint NOT NULL AUTO_INCREMENT,
478478
`default_empty_string` varchar(255) DEFAULT \'\',
479-
`null_no_default` varchar(255),
479+
`null_no_default` varchar(255) DEFAULT NULL,
480480
PRIMARY KEY (`ID`)
481481
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci',
482482
$results[0]->{'Create Table'}
@@ -1954,7 +1954,7 @@ public function testAlterTableModifyColumnWithHyphens() {
19541954
'Type' => 'text',
19551955
'Null' => 'YES',
19561956
'Key' => '',
1957-
'Default' => 'NULL',
1957+
'Default' => null,
19581958
'Extra' => '',
19591959
),
19601960
),
@@ -3384,7 +3384,7 @@ public function testUniqueConstraints() {
33843384
public function testDefaultNullValue() {
33853385
$this->assertQuery(
33863386
'CREATE TABLE _tmp_table (
3387-
name varchar(20) NOT NULL default NULL,
3387+
name varchar(20) default NULL,
33883388
no_default varchar(20) NOT NULL
33893389
);'
33903390
);
@@ -3397,9 +3397,9 @@ public function testDefaultNullValue() {
33973397
(object) array(
33983398
'Field' => 'name',
33993399
'Type' => 'varchar(20)',
3400-
'Null' => 'NO',
3400+
'Null' => 'YES',
34013401
'Key' => '',
3402-
'Default' => 'NULL',
3402+
'Default' => null,
34033403
'Extra' => '',
34043404
),
34053405
(object) array(

wp-includes/sqlite-ast/class-wp-sqlite-driver.php

+23-4
Original file line numberDiff line numberDiff line change
@@ -2181,8 +2181,18 @@ private function get_sqlite_create_table_statement( string $table_name, ?string
21812181
$query .= ' PRIMARY KEY AUTOINCREMENT';
21822182
}
21832183
if ( null !== $column['COLUMN_DEFAULT'] ) {
2184-
// @TODO: Correctly quote based on the data type.
2185-
$query .= ' DEFAULT ' . $this->pdo->quote( $column['COLUMN_DEFAULT'] );
2184+
// @TODO: Handle defaults with expression values (DEFAULT_GENERATED).
2185+
2186+
// Handle DEFAULT CURRENT_TIMESTAMP. This works only with timestamp
2187+
// and datetime columns. For other column types, it's just a string.
2188+
if (
2189+
'CURRENT_TIMESTAMP' === $column['COLUMN_DEFAULT']
2190+
&& ( 'timestamp' === $column['DATA_TYPE'] || 'datetime' === $column['DATA_TYPE'] )
2191+
) {
2192+
$query .= ' DEFAULT CURRENT_TIMESTAMP';
2193+
} else {
2194+
$query .= ' DEFAULT ' . $this->pdo->quote( $column['COLUMN_DEFAULT'] );
2195+
}
21862196
}
21872197
$rows[] = $query;
21882198

@@ -2304,9 +2314,18 @@ private function get_mysql_create_table_statement( string $table_name ): ?string
23042314
if ( 'auto_increment' === $column['EXTRA'] ) {
23052315
$sql .= ' AUTO_INCREMENT';
23062316
}
2307-
if ( null !== $column['COLUMN_DEFAULT'] ) {
2308-
// @TODO: Correctly quote based on the data type.
2317+
2318+
// Handle DEFAULT CURRENT_TIMESTAMP. This works only with timestamp
2319+
// and datetime columns. For other column types, it's just a string.
2320+
if (
2321+
'CURRENT_TIMESTAMP' === $column['COLUMN_DEFAULT']
2322+
&& ( 'timestamp' === $column['DATA_TYPE'] || 'datetime' === $column['DATA_TYPE'] )
2323+
) {
2324+
$sql .= ' DEFAULT CURRENT_TIMESTAMP';
2325+
} elseif ( null !== $column['COLUMN_DEFAULT'] ) {
23092326
$sql .= ' DEFAULT ' . $this->pdo->quote( $column['COLUMN_DEFAULT'] );
2327+
} elseif ( 'YES' === $column['IS_NULLABLE'] ) {
2328+
$sql .= ' DEFAULT NULL';
23102329
}
23112330
$rows[] = $sql;
23122331
}

wp-includes/sqlite-ast/class-wp-sqlite-information-schema-builder.php

+38-10
Original file line numberDiff line numberDiff line change
@@ -905,14 +905,31 @@ private function get_table_collation( WP_Parser_Node $node ): string {
905905
}
906906

907907
private function get_column_default( WP_Parser_Node $node ): ?string {
908+
$default_attr = null;
908909
foreach ( $node->get_descendant_nodes( 'columnAttribute' ) as $attr ) {
909910
if ( $attr->has_child_token( WP_MySQL_Lexer::DEFAULT_SYMBOL ) ) {
910-
// @TODO: MySQL seems to normalize default values for numeric
911-
// columns, such as 1.0 to 1, 1e3 to 1000, etc.
912-
return substr( $this->get_value( $attr ), strlen( 'DEFAULT' ) );
911+
$default_attr = $attr;
913912
}
914913
}
915-
return null;
914+
915+
if ( null === $default_attr ) {
916+
return null;
917+
}
918+
919+
if ( $default_attr->has_child_token( WP_MySQL_Lexer::NOW_SYMBOL ) ) {
920+
return 'CURRENT_TIMESTAMP';
921+
}
922+
923+
if (
924+
$default_attr->has_child_node( 'signedLiteral' )
925+
&& null !== $default_attr->get_descendant_node( 'nullLiteral' )
926+
) {
927+
return null;
928+
}
929+
930+
// @TODO: MySQL seems to normalize default values for numeric
931+
// columns, such as 1.0 to 1, 1e3 to 1000, etc.
932+
return $this->get_value( $default_attr->get_child_node() );
916933
}
917934

918935
private function get_column_nullable( WP_Parser_Node $node ): string {
@@ -967,32 +984,43 @@ private function get_column_key( WP_Parser_Node $column_node ): string {
967984
}
968985

969986
private function get_column_extra( WP_Parser_Node $node ): string {
970-
$extra = '';
987+
$extras = array();
988+
$attributes = $node->get_descendant_nodes( 'columnAttribute' );
971989

972990
// SERIAL
973991
$data_type = $node->get_descendant_node( 'dataType' );
974992
if ( null !== $data_type->get_descendant_token( WP_MySQL_Lexer::SERIAL_SYMBOL ) ) {
975993
return 'auto_increment';
976994
}
977995

978-
foreach ( $node->get_descendant_nodes( 'columnAttribute' ) as $attr ) {
996+
// Check whether DEFAULT value is an expression.
997+
foreach ( $attributes as $attr ) {
998+
if (
999+
$attr->has_child_token( WP_MySQL_Lexer::DEFAULT_SYMBOL )
1000+
&& $attr->has_child_node( 'exprWithParentheses' )
1001+
) {
1002+
$extras[] = 'DEFAULT_GENERATED';
1003+
}
1004+
}
1005+
1006+
foreach ( $attributes as $attr ) {
9791007
if ( $attr->has_child_token( WP_MySQL_Lexer::AUTO_INCREMENT_SYMBOL ) ) {
9801008
return 'auto_increment';
9811009
}
9821010
if (
9831011
$attr->has_child_token( WP_MySQL_Lexer::ON_SYMBOL )
9841012
&& $attr->has_child_token( WP_MySQL_Lexer::UPDATE_SYMBOL )
9851013
) {
986-
return 'on update CURRENT_TIMESTAMP';
1014+
$extras[] = 'on update CURRENT_TIMESTAMP';
9871015
}
9881016
}
9891017

9901018
if ( $node->get_descendant_token( WP_MySQL_Lexer::VIRTUAL_SYMBOL ) ) {
991-
$extra = 'VIRTUAL GENERATED';
1019+
$extras[] = 'VIRTUAL GENERATED';
9921020
} elseif ( $node->get_descendant_token( WP_MySQL_Lexer::STORED_SYMBOL ) ) {
993-
$extra = 'STORED GENERATED';
1021+
$extras[] = 'STORED GENERATED';
9941022
}
995-
return $extra;
1023+
return implode( ' ', $extras );
9961024
}
9971025

9981026
private function get_column_comment( WP_Parser_Node $node ): string {

0 commit comments

Comments
 (0)