diff --git a/CHANGELOG.md b/CHANGELOG.md index 48630a5dc..0a25c23a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ Yii Framework 2 Change Log - Bug #20141: Update `ezyang/htmlpurifier` dependency to version `4.17` (@terabytesoftw) - Bug #19817: Add MySQL Query `addCheck()` and `dropCheck()` (@bobonov) - Bug #20165: Adjust pretty name of closures for PHP 8.4 compatibility (@staabm) +- Enh: #20171: Support JSON columns for MariaDB 10.4 or higher (@terabytesoftw) 2.0.49.2 October 12, 2023 ------------------------- diff --git a/db/mysql/JsonExpressionBuilder.php b/db/mysql/JsonExpressionBuilder.php index fe7fc8b78..cb2b35c83 100644 --- a/db/mysql/JsonExpressionBuilder.php +++ b/db/mysql/JsonExpressionBuilder.php @@ -44,6 +44,6 @@ public function build(ExpressionInterface $expression, array &$params = []) $placeholder = static::PARAM_PREFIX . count($params); $params[$placeholder] = Json::encode($value); - return "CAST($placeholder AS JSON)"; + return $placeholder; } } diff --git a/db/mysql/Schema.php b/db/mysql/Schema.php index 7a60c620f..e9678392f 100644 --- a/db/mysql/Schema.php +++ b/db/mysql/Schema.php @@ -380,10 +380,19 @@ protected function findColumns($table) } throw $e; } + + + $jsonColumns = $this->getJsonColumns($table); + foreach ($columns as $info) { if ($this->db->slavePdo->getAttribute(\PDO::ATTR_CASE) !== \PDO::CASE_LOWER) { $info = array_change_key_case($info, CASE_LOWER); } + + if (\in_array($info['field'], $jsonColumns, true)) { + $info['type'] = static::TYPE_JSON; + } + $column = $this->loadColumnSchema($info); $table->columns[$column->name] = $column; if ($column->isPrimaryKey) { @@ -641,4 +650,20 @@ private function loadTableConstraints($tableName, $returnType) return $result[$returnType]; } + + private function getJsonColumns(TableSchema $table): array + { + $sql = $this->getCreateTableSql($table); + $result = []; + + $regexp = '/json_valid\([\`"](.+)[\`"]\s*\)/mi'; + + if (\preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $result[] = $match[1]; + } + } + + return $result; + } }