diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index f87f21bf7308..0a720cf33036 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -658,34 +658,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, ]; } @@ -841,7 +842,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); diff --git a/tests/system/Database/Builder/WhereTest.php b/tests/system/Database/Builder/WhereTest.php index 653c837058aa..e58af53cadab 100644 --- a/tests/system/Database/Builder/WhereTest.php +++ b/tests/system/Database/Builder/WhereTest.php @@ -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');