diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 41d19941f42..f95bccff0be 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -8,6 +8,7 @@ Yii Framework 2 Change Log - Bug #15792: Added missing `yii\db\QueryBuilder::conditionClasses` setter (silverfire) - Bug #15822: Fixed `yii\base\Component::off()` not to throw an exception when handler does not exist (silverfire) - Bug #15817: Fixed support of deprecated array format type casting in `yii\db\Command::bindValues()` (silverfire) +- Bug #15804: Fixed `null` values handling for PostgresSQL arrays (silverfire) 2.0.14.1 February 24, 2018 diff --git a/framework/db/ArrayExpression.php b/framework/db/ArrayExpression.php index 19e23c6e1dd..0477cc5a58d 100644 --- a/framework/db/ArrayExpression.php +++ b/framework/db/ArrayExpression.php @@ -182,10 +182,14 @@ public function count() */ public function getIterator() { - if ($this->getValue() instanceof QueryInterface) { + $value = $this->getValue(); + if ($value instanceof QueryInterface) { throw new InvalidConfigException('The ArrayExpression class can not be iterated when the value is a QueryInterface object'); } + if ($value === null) { + $value = []; + } - return new \ArrayIterator($this->getValue()); + return new \ArrayIterator($value); } } diff --git a/framework/db/pgsql/ArrayExpressionBuilder.php b/framework/db/pgsql/ArrayExpressionBuilder.php index 855cfb00c1f..577aacc4ef0 100644 --- a/framework/db/pgsql/ArrayExpressionBuilder.php +++ b/framework/db/pgsql/ArrayExpressionBuilder.php @@ -32,6 +32,9 @@ class ArrayExpressionBuilder implements ExpressionBuilderInterface public function build(ExpressionInterface $expression, array &$params = []) { $value = $expression->getValue(); + if ($value === null) { + return 'NULL'; + } if ($value instanceof Query) { list ($sql, $params) = $this->queryBuilder->build($value, $params); diff --git a/framework/db/pgsql/ArrayParser.php b/framework/db/pgsql/ArrayParser.php index 8ce08b24f5a..fc66789d40e 100644 --- a/framework/db/pgsql/ArrayParser.php +++ b/framework/db/pgsql/ArrayParser.php @@ -102,6 +102,8 @@ private function parseString($value, &$i) if (!$isQuoted && $result === 'NULL') { $result = null; + } elseif ($isQuoted && $result === '{}') { + $result = []; } return $result; diff --git a/framework/db/pgsql/ColumnSchema.php b/framework/db/pgsql/ColumnSchema.php index da2f40ff837..d60cbdbd72d 100644 --- a/framework/db/pgsql/ColumnSchema.php +++ b/framework/db/pgsql/ColumnSchema.php @@ -83,6 +83,8 @@ public function phpTypecast($value) array_walk_recursive($value, function (&$val, $key) { $val = $this->phpTypecastValue($val); }); + } elseif ($value === null) { + return null; } return $this->deserializeArrayColumnToArrayExpression diff --git a/tests/framework/db/pgsql/ActiveRecordTest.php b/tests/framework/db/pgsql/ActiveRecordTest.php index 093907ac806..6bce5d08591 100644 --- a/tests/framework/db/pgsql/ActiveRecordTest.php +++ b/tests/framework/db/pgsql/ActiveRecordTest.php @@ -228,6 +228,27 @@ public function arrayValuesProvider() 'jsonb_col' => [[null, 'a', 'b', '\"', '{"af"}']], 'jsonarray_col' => [new ArrayExpression([[',', 'null', true, 'false', 'f']], 'json')], ]], + 'null arrays values' => [[ + 'intarray_col' => [ + null, + ], + 'textarray2_col' => [ + [null, null], + new ArrayExpression([null, null], 'text', 2), + ], + 'json_col' => [ + null + ], + 'jsonarray_col' => [ + null + ], + ]], + 'empty arrays values' => [[ + 'textarray2_col' => [ + ['', ''], + new ArrayExpression([[], []], 'text', 2), + ], + ]], 'arrays packed in classes' => [[ 'intarray_col' => [ new ArrayExpression([1,-2,null,'42'], 'int', 1), @@ -257,7 +278,7 @@ public function arrayValuesProvider() 'jsonb_col' => [ pi() ], - ]] + ]], ]; } }