@@ -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