Skip to content

Commit

Permalink
Merge pull request #5247 from vlakoff/db-whereHaving
Browse files Browse the repository at this point in the history
Do not inappropriately register bind when the value is a closure
  • Loading branch information
kenjis authored Nov 16, 2021
2 parents 1e4ff3f + 68ad987 commit 0406780
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
31 changes: 16 additions & 15 deletions system/Database/BaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -672,34 +672,35 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type

$op = trim(current($op));

if (substr($k, -1 * strlen($op)) === $op) {
$k = rtrim(strrev(preg_replace(strrev('/' . $op . '/'), strrev(''), strrev($k), 1)));
if (substr($k, -strlen($op)) === $op) {
$k = rtrim(substr($k, 0, -strlen($op)));
$op = " {$op}";
} else {
$op = '';
}
}

$bind = $this->setBind($k, $v, $escape);

if (empty($op)) {
$k .= ' =';
} else {
$k .= " {$op}";
$op = ' =';
}

if ($v instanceof Closure) {
$builder = $this->cleanClone();
$v = '(' . str_replace("\n", ' ', $v($builder)->getCompiledSelect()) . ')';
$v = ' (' . strtr($v($builder)->getCompiledSelect(), "\n", ' ') . ')';
} else {
$v = " :{$bind}:";
$bind = $this->setBind($k, $v, $escape);
$v = " :{$bind}:";
}
} elseif (! $this->hasOperator($k) && $qbKey !== 'QBHaving') {
// value appears not to have been set, assign the test to IS NULL
$k .= ' IS NULL';
$op = ' IS NULL';
} elseif (preg_match('/\s*(!?=|<>|IS(?:\s+NOT)?)\s*$/i', $k, $match, PREG_OFFSET_CAPTURE)) {
$k = substr($k, 0, $match[0][1]) . ($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL');
$k = substr($k, 0, $match[0][1]);
$op = $match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL';
} else {
$op = '';
}

$this->{$qbKey}[] = [
'condition' => $prefix . $k . $v,
'condition' => $prefix . $k . $op . $v,
'escape' => $escape,
];
}
Expand Down Expand Up @@ -855,7 +856,7 @@ protected function _whereIn(?string $key = null, $values = null, bool $not = fal

if ($values instanceof Closure) {
$builder = $this->cleanClone();
$ok = str_replace("\n", ' ', $values($builder)->getCompiledSelect());
$ok = strtr($values($builder)->getCompiledSelect(), "\n", ' ');
} else {
$whereIn = array_values($values);
$ok = $this->setBind($ok, $whereIn, $escape);
Expand Down
16 changes: 16 additions & 0 deletions tests/system/Database/Builder/WhereTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,22 @@ public function testWhereAssociateArray()
$this->assertSame($expectedBinds, $builder->getBinds());
}

public function testWhereAssociateArrayKeyHasEqualValueIsNull()
{
$builder = $this->db->table('users');

$where = [
'deleted_at =' => null,
];

$expectedSQL = 'SELECT * FROM "users" WHERE "deleted_at" IS NULL';
$expectedBinds = [];

$builder->where($where);
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect()));
$this->assertSame($expectedBinds, $builder->getBinds());
}

public function testWhereCustomString()
{
$builder = $this->db->table('jobs');
Expand Down

0 comments on commit 0406780

Please sign in to comment.