Skip to content

Commit b3d965f

Browse files
committed
fix: BaseBuilder::getOperator() doesn't recognize LIKE operator in array expression
1 parent f51e8ef commit b3d965f

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

system/Database/BaseBuilder.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type
749749
$k = '';
750750
$op = '';
751751
} elseif ($v !== null) {
752-
$op = $this->getOperator($k, true);
752+
$op = $this->getOperatorFromWhereKey($k);
753753

754754
if (! empty($op)) {
755755
$k = trim($k);
@@ -3387,6 +3387,35 @@ protected function getOperator(string $str, bool $list = false)
33873387
) ? ($list ? $match[0] : $match[0][0]) : false;
33883388
}
33893389

3390+
/**
3391+
* Returns the SQL string operator from where key
3392+
*
3393+
* @return array<int, string>|false
3394+
* @phpstan-return list<string>|false
3395+
*/
3396+
private function getOperatorFromWhereKey(string $whereKey)
3397+
{
3398+
$whereKey = trim($whereKey);
3399+
3400+
if ($this->pregOperators === []) {
3401+
$this->pregOperators = [
3402+
'\s*(?:<|>|!)?=', // =, <=, >=, !=
3403+
'\s*<>?', // <, <>
3404+
'\s*>', // >
3405+
'\s+IS NULL', // IS NULL
3406+
'\s+IS NOT NULL', // IS NOT NULL
3407+
'\s+LIKE', // LIKE
3408+
'\s+NOT LIKE', // NOT LIKE
3409+
];
3410+
}
3411+
3412+
return preg_match_all(
3413+
'/' . implode('|', $this->pregOperators) . '/i',
3414+
$whereKey,
3415+
$match
3416+
) ? $match[0] : false;
3417+
}
3418+
33903419
/**
33913420
* Stores a bind value after ensuring that it's unique.
33923421
* While it might be nicer to have named keys for our binds array

tests/system/Database/Builder/WhereTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,20 @@ public function testWhereAssociateArrayKeyHasEqualValueIsNull()
132132
$this->assertSame($expectedBinds, $builder->getBinds());
133133
}
134134

135+
public function testWhereLikeInAssociateArray()
136+
{
137+
$builder = $this->db->table('user');
138+
139+
$where = [
140+
'id <' => 100,
141+
'col1 LIKE' => '%gmail%',
142+
];
143+
$builder->where($where);
144+
145+
$expectedSQL = 'SELECT * FROM "user" WHERE "id" < 100 AND "col1" LIKE \'%gmail%\'';
146+
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect()));
147+
}
148+
135149
public function testWhereCustomString()
136150
{
137151
$builder = $this->db->table('jobs');

0 commit comments

Comments
 (0)