Skip to content

Commit 0406780

Browse files
authored
Merge pull request #5247 from vlakoff/db-whereHaving
Do not inappropriately register bind when the value is a closure
2 parents 1e4ff3f + 68ad987 commit 0406780

File tree

2 files changed

+32
-15
lines changed

2 files changed

+32
-15
lines changed

system/Database/BaseBuilder.php

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -672,34 +672,35 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type
672672

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

675-
if (substr($k, -1 * strlen($op)) === $op) {
676-
$k = rtrim(strrev(preg_replace(strrev('/' . $op . '/'), strrev(''), strrev($k), 1)));
675+
if (substr($k, -strlen($op)) === $op) {
676+
$k = rtrim(substr($k, 0, -strlen($op)));
677+
$op = " {$op}";
678+
} else {
679+
$op = '';
677680
}
678-
}
679-
680-
$bind = $this->setBind($k, $v, $escape);
681-
682-
if (empty($op)) {
683-
$k .= ' =';
684681
} else {
685-
$k .= " {$op}";
682+
$op = ' =';
686683
}
687684

688685
if ($v instanceof Closure) {
689686
$builder = $this->cleanClone();
690-
$v = '(' . str_replace("\n", ' ', $v($builder)->getCompiledSelect()) . ')';
687+
$v = ' (' . strtr($v($builder)->getCompiledSelect(), "\n", ' ') . ')';
691688
} else {
692-
$v = " :{$bind}:";
689+
$bind = $this->setBind($k, $v, $escape);
690+
$v = " :{$bind}:";
693691
}
694692
} elseif (! $this->hasOperator($k) && $qbKey !== 'QBHaving') {
695693
// value appears not to have been set, assign the test to IS NULL
696-
$k .= ' IS NULL';
694+
$op = ' IS NULL';
697695
} elseif (preg_match('/\s*(!?=|<>|IS(?:\s+NOT)?)\s*$/i', $k, $match, PREG_OFFSET_CAPTURE)) {
698-
$k = substr($k, 0, $match[0][1]) . ($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL');
696+
$k = substr($k, 0, $match[0][1]);
697+
$op = $match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL';
698+
} else {
699+
$op = '';
699700
}
700701

701702
$this->{$qbKey}[] = [
702-
'condition' => $prefix . $k . $v,
703+
'condition' => $prefix . $k . $op . $v,
703704
'escape' => $escape,
704705
];
705706
}
@@ -855,7 +856,7 @@ protected function _whereIn(?string $key = null, $values = null, bool $not = fal
855856

856857
if ($values instanceof Closure) {
857858
$builder = $this->cleanClone();
858-
$ok = str_replace("\n", ' ', $values($builder)->getCompiledSelect());
859+
$ok = strtr($values($builder)->getCompiledSelect(), "\n", ' ');
859860
} else {
860861
$whereIn = array_values($values);
861862
$ok = $this->setBind($ok, $whereIn, $escape);

tests/system/Database/Builder/WhereTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,22 @@ public function testWhereAssociateArray()
111111
$this->assertSame($expectedBinds, $builder->getBinds());
112112
}
113113

114+
public function testWhereAssociateArrayKeyHasEqualValueIsNull()
115+
{
116+
$builder = $this->db->table('users');
117+
118+
$where = [
119+
'deleted_at =' => null,
120+
];
121+
122+
$expectedSQL = 'SELECT * FROM "users" WHERE "deleted_at" IS NULL';
123+
$expectedBinds = [];
124+
125+
$builder->where($where);
126+
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect()));
127+
$this->assertSame($expectedBinds, $builder->getBinds());
128+
}
129+
114130
public function testWhereCustomString()
115131
{
116132
$builder = $this->db->table('jobs');

0 commit comments

Comments
 (0)