Skip to content

Commit 951fc45

Browse files
committed
Improve INSERT and UPDATE error handling
1 parent a18901b commit 951fc45

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
@@ -11068,4 +11068,70 @@ public function testCastValuesOnUpdateInNonStrictMode(): void {
1106811068

1106911069
$this->assertQuery( 'DROP TABLE t' );
1107011070
}
11071+
11072+
public function testInsertErrors(): void {
11073+
$this->assertQuery( 'CREATE TABLE t (value INT)' );
11074+
11075+
// Missing table.
11076+
$this->assertQueryError(
11077+
'INSERT INTO missing_table VALUES (1)',
11078+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table 'missing_table' doesn't exists"
11079+
);
11080+
11081+
// Missing column.
11082+
$this->assertQueryError(
11083+
'INSERT INTO t (missing_column) VALUES (1)',
11084+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'missing_column' in 'field list'"
11085+
);
11086+
}
11087+
11088+
public function testInsertErrorsInNonStrictMode(): void {
11089+
$this->assertQuery( "SET SESSION sql_mode = ''" );
11090+
$this->assertQuery( 'CREATE TABLE t (value INT)' );
11091+
11092+
// Missing table.
11093+
$this->assertQueryError(
11094+
'INSERT INTO missing_table VALUES (1)',
11095+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table 'missing_table' doesn't exists"
11096+
);
11097+
11098+
// Missing column.
11099+
$this->assertQueryError(
11100+
'INSERT INTO t (missing_column) VALUES (1)',
11101+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'missing_column' in 'field list'"
11102+
);
11103+
}
11104+
11105+
public function testUpdateErrors(): void {
11106+
$this->assertQuery( 'CREATE TABLE t (value INT)' );
11107+
11108+
// Missing table.
11109+
$this->assertQueryError(
11110+
'UPDATE missing_table SET value = 1',
11111+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table 'missing_table' doesn't exists"
11112+
);
11113+
11114+
// Missing column.
11115+
$this->assertQueryError(
11116+
'UPDATE t SET missing_column = 1',
11117+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'missing_column' in 'field list'"
11118+
);
11119+
}
11120+
11121+
public function testUpdateErrorsInNonStrictMode(): void {
11122+
$this->assertQuery( "SET SESSION sql_mode = ''" );
11123+
$this->assertQuery( 'CREATE TABLE t (value INT)' );
11124+
11125+
// Missing table.
11126+
$this->assertQueryError(
11127+
'UPDATE missing_table SET value = 1',
11128+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table 'missing_table' doesn't exists"
11129+
);
11130+
11131+
// Missing column.
11132+
$this->assertQueryError(
11133+
'UPDATE t SET missing_column = 1',
11134+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'missing_column' in 'field list'"
11135+
);
11136+
}
1107111137
}

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

@@ -4617,7 +4640,19 @@ private function translate_update_list( string $table_name, WP_Parser_Node $node
46174640
',
46184641
array( $database, $table_name )
46194642
)->fetchAll( PDO::FETCH_ASSOC );
4620-
$column_map = array_combine( array_column( $columns, 'COLUMN_NAME' ), $columns );
4643+
4644+
// Check if the table exists.
4645+
if ( 0 === count( $columns ) ) {
4646+
throw $this->new_driver_exception(
4647+
sprintf(
4648+
"SQLSTATE[42S02]: Base table or view not found: 1146 Table '%s' doesn't exists",
4649+
$table_name
4650+
),
4651+
'42S02'
4652+
);
4653+
}
4654+
4655+
$column_map = array_combine( array_column( $columns, 'COLUMN_NAME' ), $columns );
46214656

46224657
// Translate the UPDATE list, emulating IMPLICIT DEFAULTs for NULL values.
46234658
$fragment = '';
@@ -4628,7 +4663,17 @@ private function translate_update_list( string $table_name, WP_Parser_Node $node
46284663

46294664
// Get column info.
46304665
$column_name = $this->unquote_sqlite_identifier( $this->translate( end( $column_ref_parts ) ) );
4631-
$column_info = $column_map[ strtolower( $column_name ) ];
4666+
$column_info = $column_map[ strtolower( $column_name ) ] ?? null;
4667+
if ( ! $column_info ) {
4668+
throw $this->new_driver_exception(
4669+
sprintf(
4670+
"SQLSTATE[42S22]: Column not found: 1054 Unknown column '%s' in 'field list'",
4671+
$column_name
4672+
),
4673+
'42S22'
4674+
);
4675+
}
4676+
46324677
$data_type = $column_info['DATA_TYPE'];
46334678
$is_nullable = 'YES' === $column_info['IS_NULLABLE'];
46344679
$default = $column_info['COLUMN_DEFAULT'];

0 commit comments

Comments
 (0)