Skip to content

Commit 04b9708

Browse files
committed
Add support JSON columns MariaDb.
1 parent c6145cb commit 04b9708

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

framework/db/mysql/JsonExpressionBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ public function build(ExpressionInterface $expression, array &$params = [])
4444
$placeholder = static::PARAM_PREFIX . count($params);
4545
$params[$placeholder] = Json::encode($value);
4646

47-
return "CAST($placeholder AS JSON)";
47+
return $placeholder;
4848
}
4949
}

framework/db/mysql/Schema.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,19 @@ protected function findColumns($table)
380380
}
381381
throw $e;
382382
}
383+
384+
385+
$jsonColumns = $this->getJsonColumns($table);
386+
383387
foreach ($columns as $info) {
384388
if ($this->db->slavePdo->getAttribute(\PDO::ATTR_CASE) !== \PDO::CASE_LOWER) {
385389
$info = array_change_key_case($info, CASE_LOWER);
386390
}
391+
392+
if (\in_array($info['field'], $jsonColumns, true)) {
393+
$info['type'] = static::TYPE_JSON;
394+
}
395+
387396
$column = $this->loadColumnSchema($info);
388397
$table->columns[$column->name] = $column;
389398
if ($column->isPrimaryKey) {
@@ -641,4 +650,20 @@ private function loadTableConstraints($tableName, $returnType)
641650

642651
return $result[$returnType];
643652
}
653+
654+
private function getJsonColumns(TableSchema $table): array
655+
{
656+
$sql = $this->getCreateTableSql($table);
657+
$result = [];
658+
659+
$regexp = '/json_valid\([\`"](.+)[\`"]\s*\)/mi';
660+
661+
if (\preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) {
662+
foreach ($matches as $match) {
663+
$result[] = $match[1];
664+
}
665+
}
666+
667+
return $result;
668+
}
644669
}

tests/framework/db/mysql/QueryBuilderTest.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -267,35 +267,35 @@ public function conditionProvider()
267267
// json conditions
268268
[
269269
['=', 'jsoncol', new JsonExpression(['lang' => 'uk', 'country' => 'UA'])],
270-
'[[jsoncol]] = CAST(:qp0 AS JSON)', [':qp0' => '{"lang":"uk","country":"UA"}'],
270+
'[[jsoncol]] = :qp0', [':qp0' => '{"lang":"uk","country":"UA"}'],
271271
],
272272
[
273273
['=', 'jsoncol', new JsonExpression([false])],
274-
'[[jsoncol]] = CAST(:qp0 AS JSON)', [':qp0' => '[false]']
274+
'[[jsoncol]] = :qp0', [':qp0' => '[false]']
275275
],
276276
'object with type. Type is ignored for MySQL' => [
277277
['=', 'prices', new JsonExpression(['seeds' => 15, 'apples' => 25], 'jsonb')],
278-
'[[prices]] = CAST(:qp0 AS JSON)', [':qp0' => '{"seeds":15,"apples":25}'],
278+
'[[prices]] = :qp0', [':qp0' => '{"seeds":15,"apples":25}'],
279279
],
280280
'nested json' => [
281281
['=', 'data', new JsonExpression(['user' => ['login' => 'silverfire', 'password' => 'c4ny0ur34d17?'], 'props' => ['mood' => 'good']])],
282-
'[[data]] = CAST(:qp0 AS JSON)', [':qp0' => '{"user":{"login":"silverfire","password":"c4ny0ur34d17?"},"props":{"mood":"good"}}']
282+
'[[data]] = :qp0', [':qp0' => '{"user":{"login":"silverfire","password":"c4ny0ur34d17?"},"props":{"mood":"good"}}']
283283
],
284284
'null value' => [
285285
['=', 'jsoncol', new JsonExpression(null)],
286-
'[[jsoncol]] = CAST(:qp0 AS JSON)', [':qp0' => 'null']
286+
'[[jsoncol]] = :qp0', [':qp0' => 'null']
287287
],
288288
'null as array value' => [
289289
['=', 'jsoncol', new JsonExpression([null])],
290-
'[[jsoncol]] = CAST(:qp0 AS JSON)', [':qp0' => '[null]']
290+
'[[jsoncol]] = :qp0', [':qp0' => '[null]']
291291
],
292292
'null as object value' => [
293293
['=', 'jsoncol', new JsonExpression(['nil' => null])],
294-
'[[jsoncol]] = CAST(:qp0 AS JSON)', [':qp0' => '{"nil":null}']
294+
'[[jsoncol]] = :qp0', [':qp0' => '{"nil":null}']
295295
],
296296
'with object as value' => [
297297
['=', 'jsoncol', new JsonExpression(new DynamicModel(['a' => 1, 'b' => 2]))],
298-
'[[jsoncol]] = CAST(:qp0 AS JSON)', [':qp0' => '{"a":1,"b":2}']
298+
'[[jsoncol]] = :qp0', [':qp0' => '{"a":1,"b":2}']
299299
],
300300
'query' => [
301301
['=', 'jsoncol', new JsonExpression((new Query())->select('params')->from('user')->where(['id' => 1]))],
@@ -307,7 +307,7 @@ public function conditionProvider()
307307
],
308308
'nested and combined json expression' => [
309309
['=', 'jsoncol', new JsonExpression(new JsonExpression(['a' => 1, 'b' => 2, 'd' => new JsonExpression(['e' => 3])]))],
310-
"[[jsoncol]] = CAST(:qp0 AS JSON)", [':qp0' => '{"a":1,"b":2,"d":{"e":3}}']
310+
"[[jsoncol]] = :qp0", [':qp0' => '{"a":1,"b":2,"d":{"e":3}}']
311311
],
312312
'search by property in JSON column (issue #15838)' => [
313313
['=', new Expression("(jsoncol->>'$.someKey')"), '42'],
@@ -328,7 +328,7 @@ public function updateProvider()
328328
[
329329
'id' => 1,
330330
],
331-
$this->replaceQuotes('UPDATE [[profile]] SET [[description]]=CAST(:qp0 AS JSON) WHERE [[id]]=:qp1'),
331+
$this->replaceQuotes('UPDATE [[profile]] SET [[description]]=:qp0 WHERE [[id]]=:qp1'),
332332
[
333333
':qp0' => '{"abc":"def","0":123,"1":null}',
334334
':qp1' => 1,

0 commit comments

Comments
 (0)