Skip to content

Commit 8896592

Browse files
committed
wip
1 parent 413a72d commit 8896592

File tree

2 files changed

+74
-14
lines changed

2 files changed

+74
-14
lines changed

tests/WP_SQLite_Driver_Tests.php

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5861,7 +5861,7 @@ public function testDropIndex(): void {
58615861
}
58625862

58635863
public function testColumnInfo(): void {
5864-
$this->assertQuery( 'CREATE TABLE t (id INT, name TEXT, score FLOAT, data BLOB)' );
5864+
$this->assertQuery( 'CREATE TABLE t (id INT, name TEXT, score DOUBLE, data BLOB)' );
58655865
$this->assertQuery( 'SELECT * FROM t' );
58665866

58675867
$this->assertEquals( 4, $this->engine->get_last_column_count() );
@@ -5876,8 +5876,7 @@ public function testColumnInfo(): void {
58765876
'flags' => array(),
58775877
'table' => 't',
58785878
'name' => 'id',
5879-
//'len' => 11,
5880-
'len' => -1,
5879+
'len' => 11,
58815880
'precision' => 0,
58825881
'sqlite:decl_type' => 'INTEGER',
58835882
),
@@ -5891,8 +5890,7 @@ public function testColumnInfo(): void {
58915890
'flags' => array( 'blob' ),
58925891
'table' => 't',
58935892
'name' => 'name',
5894-
//'len' => 262140,
5895-
'len' => -1,
5893+
'len' => 262140,
58965894
'precision' => 0,
58975895
'sqlite:decl_type' => 'TEXT',
58985896
),
@@ -5906,10 +5904,8 @@ public function testColumnInfo(): void {
59065904
'flags' => array(),
59075905
'table' => 't',
59085906
'name' => 'score',
5909-
//'len' => 22,
5910-
'len' => -1,
5911-
//'precision' => 31,
5912-
'precision' => 0,
5907+
'len' => 22,
5908+
'precision' => 31,
59135909
'sqlite:decl_type' => 'REAL',
59145910
),
59155911
$column_info[2]
@@ -5922,8 +5918,7 @@ public function testColumnInfo(): void {
59225918
'flags' => array( 'blob' ),
59235919
'table' => 't',
59245920
'name' => 'data',
5925-
//'len' => 65535,
5926-
'len' => -1,
5921+
'len' => 65535,
59275922
'precision' => 0,
59285923
'sqlite:decl_type' => 'BLOB',
59295924
),

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

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -768,12 +768,77 @@ public function get_last_column_meta(): array {
768768
// Build the column metadata as per "PDOStatement::getColumnMeta()".
769769
$column_meta = array();
770770
for ( $i = 0; $i < $this->last_column_meta_statement->columnCount(); $i++ ) {
771-
$meta = $this->last_column_meta_statement->getColumnMeta( $i );
771+
$meta = $this->last_column_meta_statement->getColumnMeta( $i );
772+
$table = $meta['table'];
773+
$name = $meta['name'];
772774

775+
// Types.
773776
$sqlite_type = $meta['sqlite:decl_type'];
774777
$native_type = $native_types[ $sqlite_type ] ?? null;
775778
$pdo_type = $pdo_types[ $sqlite_type ] ?? PDO::PARAM_NULL;
776779

780+
// Length and precision.
781+
$len = $meta['len'];
782+
$precision = $meta['precision'];
783+
784+
// When table is known, we can get data from the information schema.
785+
if ( strlen( $table ) > 0 ) {
786+
$table_is_temporary = $this->information_schema_builder->temporary_table_exists( $table );
787+
$columns_table = $this->information_schema_builder->get_table_name( $table_is_temporary, 'columns' );
788+
$column_info = $this->execute_sqlite_query(
789+
sprintf(
790+
'
791+
SELECT
792+
DATA_TYPE,
793+
COLUMN_TYPE,
794+
CHARACTER_MAXIMUM_LENGTH,
795+
NUMERIC_PRECISION
796+
FROM %s
797+
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND COLUMN_NAME = ?
798+
',
799+
$this->quote_sqlite_identifier( $columns_table )
800+
),
801+
array( $this->db_name, $table, $name )
802+
)->fetch( PDO::FETCH_ASSOC );
803+
804+
// If set, lenght can be taken from the information schema.
805+
if ( isset( $column_info['CHARACTER_MAXIMUM_LENGTH'] ) ) {
806+
$len = (int) $column_info['CHARACTER_MAXIMUM_LENGTH'];
807+
}
808+
809+
// For string types, the length is multiplied by the maximum number
810+
// of bytes per character for the used connection encoding. In our
811+
// case, it's always "utf8mb4" and therefore 4 bytes per character.
812+
if (
813+
str_contains( $column_info['DATA_TYPE'], 'text' )
814+
|| str_contains( $column_info['DATA_TYPE'], 'char' )
815+
) {
816+
$len = 4 * $len;
817+
}
818+
819+
// For integer and real types, the length is the number of digits.
820+
if ( 'INTEGER' === $sqlite_type || 'REAL' === $sqlite_type ) {
821+
$len = (int) $column_info['NUMERIC_PRECISION'];
822+
}
823+
824+
// Signed "int" and "bigint" numbers are 1 byte longer than unsigned.
825+
if (
826+
( 'int' === $column_info['DATA_TYPE'] || 'bigint' === $column_info['DATA_TYPE'] )
827+
&& ! str_contains( $column_info['COLUMN_TYPE'], 'unsigned' )
828+
) {
829+
$len += 1;
830+
}
831+
}
832+
833+
// Precision.
834+
if ( 'REAL' === $sqlite_type ) {
835+
//$precision = (int) ( $column_info['precision'] ?? $meta['precision'] );
836+
//$precision = 31;
837+
} else {
838+
//$precision = 0;
839+
}
840+
841+
// Flags.
777842
$flags = array();
778843
if ( 'BLOB' === $native_type ) {
779844
$flags[] = 'blob';
@@ -785,8 +850,8 @@ public function get_last_column_meta(): array {
785850
'flags' => $flags,
786851
'table' => $meta['table'],
787852
'name' => $meta['name'],
788-
'len' => $meta['len'],
789-
'precision' => $meta['precision'],
853+
'len' => $len,
854+
'precision' => $precision,
790855
'sqlite:decl_type' => $meta['sqlite:decl_type'],
791856
);
792857
}

0 commit comments

Comments
 (0)