1515use Yiisoft \Db \Exception \NotSupportedException ;
1616use Yiisoft \Db \Expression \Expression ;
1717use Yiisoft \Db \Helper \DbArrayHelper ;
18- use Yiisoft \Db \Schema \Builder \AbstractColumn ;
1918use Yiisoft \Db \Schema \Builder \ColumnInterface ;
2019use Yiisoft \Db \Schema \ColumnSchemaInterface ;
2120use Yiisoft \Db \Schema \TableSchemaInterface ;
@@ -475,7 +474,7 @@ protected function getCreateTableSql(TableSchemaInterface $table): string
475474 */
476475 protected function loadColumnSchema (array $ info ): ColumnSchemaInterface
477476 {
478- $ dbType = $ info ['type ' ] ?? '' ;
477+ $ dbType = $ info ['type ' ];
479478
480479 $ column = $ this ->createColumnSchema ($ info ['field ' ]);
481480
@@ -488,13 +487,6 @@ protected function loadColumnSchema(array $info): ColumnSchemaInterface
488487 $ column ->unsigned (stripos ($ dbType , 'unsigned ' ) !== false );
489488 $ column ->type (self ::TYPE_STRING );
490489
491- $ extra = $ info ['extra ' ];
492-
493- if (str_starts_with ($ extra , 'DEFAULT_GENERATED ' )) {
494- $ extra = strtoupper (substr ($ extra , 18 ));
495- }
496- $ column ->extra (trim ($ extra ));
497-
498490 if (preg_match ('/^(\w+)(?:\(([^)]+)\))?/ ' , $ dbType , $ matches )) {
499491 $ type = strtolower ($ matches [1 ]);
500492
@@ -533,55 +525,67 @@ protected function loadColumnSchema(array $info): ColumnSchemaInterface
533525 }
534526 }
535527
536- $ column ->phpType ($ this ->getColumnPhpType ($ column ));
528+ // Chapter 2: crutches for MariaDB {@see https://github.com/yiisoft/yii2/issues/19747}
529+ $ extra = $ info ['extra ' ];
530+ if (
531+ empty ($ extra )
532+ && !empty ($ info ['extra_default_value ' ])
533+ && !str_starts_with ($ info ['extra_default_value ' ], '\'' )
534+ && in_array ($ column ->getType (), [
535+ self ::TYPE_CHAR , self ::TYPE_STRING , self ::TYPE_TEXT ,
536+ self ::TYPE_DATETIME , self ::TYPE_TIMESTAMP , self ::TYPE_TIME , self ::TYPE_DATE ,
537+ ], true )
538+ ) {
539+ $ extra = 'DEFAULT_GENERATED ' ;
540+ }
537541
538- if (!$ column ->isPrimaryKey ()) {
539- // Chapter 2: crutches for MariaDB {@see https://github.com/yiisoft/yii2/issues/19747}
540- /** @psalm-var string $columnCategory */
541- $ columnCategory = $ this ->createColumn (
542- $ column ->getType (),
543- $ column ->getSize ()
544- )->getCategoryMap ()[$ column ->getType ()] ?? '' ;
545- $ defaultValue = $ info ['extra_default_value ' ] ?? '' ;
546-
547- if (
548- empty ($ info ['extra ' ]) &&
549- !empty ($ defaultValue ) &&
550- in_array ($ columnCategory , [
551- AbstractColumn::TYPE_CATEGORY_STRING ,
552- AbstractColumn::TYPE_CATEGORY_TIME ,
553- ], true )
554- && !str_starts_with ($ defaultValue , '\'' )
555- ) {
556- $ info ['extra ' ] = 'DEFAULT_GENERATED ' ;
557- }
542+ $ column ->extra ($ extra );
543+ $ column ->phpType ($ this ->getColumnPhpType ($ column ));
544+ $ column ->defaultValue ($ this ->normalizeDefaultValue ($ info ['default ' ], $ column ));
558545
559- /**
560- * When displayed in the INFORMATION_SCHEMA.COLUMNS table, a default CURRENT TIMESTAMP is displayed
561- * as CURRENT_TIMESTAMP up until MariaDB 10.2.2, and as current_timestamp() from MariaDB 10.2.3.
562- *
563- * See details here: https://mariadb.com/kb/en/library/now/#description
564- */
565- if (
566- in_array ($ column ->getType (), [self ::TYPE_TIMESTAMP , self ::TYPE_DATETIME , self ::TYPE_DATE , self ::TYPE_TIME ], true )
567- && preg_match ('/^current_timestamp(?:\((\d*)\))?$/i ' , (string ) $ info ['default ' ], $ matches )
568- ) {
569- $ column ->defaultValue (new Expression ('CURRENT_TIMESTAMP ' . (!empty ($ matches [1 ])
570- ? '( ' . $ matches [1 ] . ') ' : '' )));
571- } elseif (!empty ($ info ['extra ' ]) && !empty ($ info ['default ' ])) {
572- $ column ->defaultValue (new Expression ($ info ['default ' ]));
573- } elseif (isset ($ type ) && $ type === 'bit ' && $ column ->getType () !== self ::TYPE_BOOLEAN ) {
574- $ column ->defaultValue (bindec (trim ((string ) $ info ['default ' ], 'b \'' )));
575- } else {
576- $ column ->defaultValue ($ column ->phpTypecast ($ info ['default ' ]));
577- }
578- } elseif ($ info ['default ' ] !== null ) {
579- $ column ->defaultValue ($ column ->phpTypecast ($ info ['default ' ]));
546+ if (str_starts_with ($ extra , 'DEFAULT_GENERATED ' )) {
547+ $ column ->extra (trim (strtoupper (substr ($ extra , 18 ))));
580548 }
581549
582550 return $ column ;
583551 }
584552
553+ /**
554+ * Converts column's default value according to {@see ColumnSchema::phpType} after retrieval from the database.
555+ *
556+ * @param string|null $defaultValue The default value retrieved from the database.
557+ * @param ColumnSchemaInterface $column The column schema object.
558+ *
559+ * @return mixed The normalized default value.
560+ */
561+ private function normalizeDefaultValue (?string $ defaultValue , ColumnSchemaInterface $ column ): mixed
562+ {
563+ if ($ defaultValue === null ) {
564+ return null ;
565+ }
566+
567+ if ($ column ->isPrimaryKey ()) {
568+ return $ column ->phpTypecast ($ defaultValue );
569+ }
570+
571+ if (
572+ in_array ($ column ->getType (), [self ::TYPE_TIMESTAMP , self ::TYPE_DATETIME , self ::TYPE_DATE , self ::TYPE_TIME ], true )
573+ && preg_match ('/^current_timestamp(?:\((\d*)\))?$/i ' , $ defaultValue , $ matches ) === 1
574+ ) {
575+ return new Expression ('CURRENT_TIMESTAMP ' . (!empty ($ matches [1 ]) ? '( ' . $ matches [1 ] . ') ' : '' ));
576+ }
577+
578+ if (!empty ($ column ->getExtra ()) && !empty ($ defaultValue )) {
579+ return new Expression ($ defaultValue );
580+ }
581+
582+ if (str_starts_with (strtolower ((string ) $ column ->getDbType ()), 'bit ' )) {
583+ return $ column ->phpTypecast (bindec (trim ($ defaultValue , "b' " )));
584+ }
585+
586+ return $ column ->phpTypecast ($ defaultValue );
587+ }
588+
585589 /**
586590 * Loads all check constraints for the given table.
587591 *
0 commit comments