Skip to content

Commit a1eb12e

Browse files
committed
Improve INSERT and UPDATE error handling
1 parent ea3a325 commit a1eb12e

File tree

2 files changed

+113
-2
lines changed

2 files changed

+113
-2
lines changed

tests/WP_SQLite_Driver_Tests.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11046,4 +11046,70 @@ public function testCastValuesOnUpdateInNonStrictMode(): void {
1104611046

1104711047
$this->assertQuery( 'DROP TABLE t' );
1104811048
}
11049+
11050+
public function testInsertErrors(): void {
11051+
$this->assertQuery( 'CREATE TABLE t (value INT)' );
11052+
11053+
// Missing table.
11054+
$this->assertQueryError(
11055+
'INSERT INTO missing_table VALUES (1)',
11056+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table 'missing_table' doesn't exists"
11057+
);
11058+
11059+
// Missing column.
11060+
$this->assertQueryError(
11061+
'INSERT INTO t (missing_column) VALUES (1)',
11062+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'missing_column' in 'field list'"
11063+
);
11064+
}
11065+
11066+
public function testInsertErrorsInNonStrictMode(): void {
11067+
$this->assertQuery( "SET SESSION sql_mode = ''" );
11068+
$this->assertQuery( 'CREATE TABLE t (value INT)' );
11069+
11070+
// Missing table.
11071+
$this->assertQueryError(
11072+
'INSERT INTO missing_table VALUES (1)',
11073+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table 'missing_table' doesn't exists"
11074+
);
11075+
11076+
// Missing column.
11077+
$this->assertQueryError(
11078+
'INSERT INTO t (missing_column) VALUES (1)',
11079+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'missing_column' in 'field list'"
11080+
);
11081+
}
11082+
11083+
public function testUpdateErrors(): void {
11084+
$this->assertQuery( 'CREATE TABLE t (value INT)' );
11085+
11086+
// Missing table.
11087+
$this->assertQueryError(
11088+
'UPDATE missing_table SET value = 1',
11089+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table 'missing_table' doesn't exists"
11090+
);
11091+
11092+
// Missing column.
11093+
$this->assertQueryError(
11094+
'UPDATE t SET missing_column = 1',
11095+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'missing_column' in 'field list'"
11096+
);
11097+
}
11098+
11099+
public function testUpdateErrorsInNonStrictMode(): void {
11100+
$this->assertQuery( "SET SESSION sql_mode = ''" );
11101+
$this->assertQuery( 'CREATE TABLE t (value INT)' );
11102+
11103+
// Missing table.
11104+
$this->assertQueryError(
11105+
'UPDATE missing_table SET value = 1',
11106+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table 'missing_table' doesn't exists"
11107+
);
11108+
11109+
// Missing column.
11110+
$this->assertQueryError(
11111+
'UPDATE t SET missing_column = 1',
11112+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'missing_column' in 'field list'"
11113+
);
11114+
}
1104911115
}

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

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4417,6 +4417,17 @@ private function translate_insert_or_replace_body(
44174417
array( $database, $table_name )
44184418
)->fetchAll( PDO::FETCH_ASSOC );
44194419

4420+
// Check if the table exists.
4421+
if ( 0 === count( $columns ) ) {
4422+
throw $this->new_driver_exception(
4423+
sprintf(
4424+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table '%s' doesn't exists",
4425+
$table_name
4426+
),
4427+
'42S02'
4428+
);
4429+
}
4430+
44204431
// Get a list of columns that are targeted by the INSERT or REPLACE query.
44214432
// This is either an explicit column list, or all columns of the table.
44224433
$insert_list = array();
@@ -4442,6 +4453,18 @@ private function translate_insert_or_replace_body(
44424453
}
44434454
}
44444455

4456+
// Check if all listed columns exist.
4457+
$unkwnown_columns = array_diff( $insert_list, array_column( $columns, 'COLUMN_NAME' ) );
4458+
if ( count( $unkwnown_columns ) > 0 ) {
4459+
throw $this->new_driver_exception(
4460+
sprintf(
4461+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column '%s' in 'field list'",
4462+
$unkwnown_columns[0]
4463+
),
4464+
'42S22'
4465+
);
4466+
}
4467+
44454468
// Prepare a helper map of columns that are included in the INSERT list.
44464469
$insert_map = array_combine( $insert_list, $insert_list );
44474470

@@ -4606,7 +4629,19 @@ private function translate_update_list( string $table_name, WP_Parser_Node $node
46064629
',
46074630
array( $database, $table_name )
46084631
)->fetchAll( PDO::FETCH_ASSOC );
4609-
$column_map = array_combine( array_column( $columns, 'COLUMN_NAME' ), $columns );
4632+
4633+
// Check if the table exists.
4634+
if ( 0 === count( $columns ) ) {
4635+
throw $this->new_driver_exception(
4636+
sprintf(
4637+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table '%s' doesn't exists",
4638+
$table_name
4639+
),
4640+
'42S02'
4641+
);
4642+
}
4643+
4644+
$column_map = array_combine( array_column( $columns, 'COLUMN_NAME' ), $columns );
46104645

46114646
// 2. Translate UPDATE list, emulating implicit defaults for NULL values.
46124647
$fragment = '';
@@ -4617,7 +4652,17 @@ private function translate_update_list( string $table_name, WP_Parser_Node $node
46174652

46184653
// Get column info.
46194654
$column_name = $this->unquote_sqlite_identifier( $this->translate( end( $column_ref_parts ) ) );
4620-
$column_info = $column_map[ strtolower( $column_name ) ];
4655+
$column_info = $column_map[ strtolower( $column_name ) ] ?? null;
4656+
if ( ! $column_info ) {
4657+
throw $this->new_driver_exception(
4658+
sprintf(
4659+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column '%s' in 'field list'",
4660+
$column_name
4661+
),
4662+
'42S22'
4663+
);
4664+
}
4665+
46214666
$data_type = $column_info['DATA_TYPE'];
46224667
$is_nullable = 'YES' === $column_info['IS_NULLABLE'];
46234668
$default = $column_info['COLUMN_DEFAULT'];

0 commit comments

Comments
 (0)