Skip to content

Commit 9a71a94

Browse files
authored
Merge pull request #7147 from sclubricants/FixBuilderWhere
Bug Fix: [QueryBuilder] where() generates incorrect SQL when using RawSql
2 parents 3163d3b + 8d0e216 commit 9a71a94

2 files changed

Lines changed: 69 additions & 3 deletions

File tree

system/Database/BaseBuilder.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -728,9 +728,15 @@ public function orWhere($key, $value = null, ?bool $escape = null)
728728
*/
729729
protected function whereHaving(string $qbKey, $key, $value = null, string $type = 'AND ', ?bool $escape = null)
730730
{
731+
$rawSqlOnly = false;
732+
731733
if ($key instanceof RawSql) {
732-
$keyValue = [(string) $key => $key];
733-
$escape = false;
734+
if ($value === null) {
735+
$keyValue = [(string) $key => $key];
736+
$rawSqlOnly = true;
737+
} else {
738+
$keyValue = [(string) $key => $value];
739+
}
734740
} elseif (! is_array($key)) {
735741
$keyValue = [$key => $value];
736742
} else {
@@ -745,7 +751,7 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type
745751
foreach ($keyValue as $k => $v) {
746752
$prefix = empty($this->{$qbKey}) ? $this->groupGetType('') : $this->groupGetType($type);
747753

748-
if ($v instanceof RawSql) {
754+
if ($rawSqlOnly === true) {
749755
$k = '';
750756
$op = '';
751757
} elseif ($v !== null) {

tests/system/Database/Builder/WhereTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,66 @@ public function testWhereRawSql()
174174
$this->assertSame($expectedBinds, $builder->getBinds());
175175
}
176176

177+
public function testWhereValueRawSql()
178+
{
179+
$sql = $this->db->table('auth_bearer')
180+
->select('*')
181+
->where('expires', new RawSql('DATE_ADD(NOW(), INTERVAL 2 HOUR)'))
182+
->getCompiledSelect(true);
183+
184+
$expected = <<<'SQL'
185+
SELECT *
186+
FROM "auth_bearer"
187+
WHERE "expires" = DATE_ADD(NOW(), INTERVAL 2 HOUR)
188+
SQL;
189+
$this->assertSame($expected, $sql);
190+
}
191+
192+
public function testWhereKeyOnlyRawSql()
193+
{
194+
$sql = $this->db->table('auth_bearer')
195+
->select('*')
196+
->where(new RawSql('DATE_ADD(NOW(), INTERVAL 2 HOUR)'), '2023-01-01')
197+
->getCompiledSelect(true);
198+
199+
$expected = <<<'SQL'
200+
SELECT *
201+
FROM "auth_bearer"
202+
WHERE DATE_ADD(NOW(), INTERVAL 2 HOUR) = '2023-01-01'
203+
SQL;
204+
$this->assertSame($expected, $sql);
205+
}
206+
207+
public function testWhereKeyAndValueRawSql()
208+
{
209+
$sql = $this->db->table('auth_bearer')
210+
->select('*')
211+
->where(new RawSql('CURRENT_TIMESTAMP()'), new RawSql('DATE_ADD(column, INTERVAL 2 HOUR)'))
212+
->getCompiledSelect(true);
213+
214+
$expected = <<<'SQL'
215+
SELECT *
216+
FROM "auth_bearer"
217+
WHERE CURRENT_TIMESTAMP() = DATE_ADD(column, INTERVAL 2 HOUR)
218+
SQL;
219+
$this->assertSame($expected, $sql);
220+
}
221+
222+
public function testWhereKeyAndValueRawSqlWithOperator()
223+
{
224+
$sql = $this->db->table('auth_bearer')
225+
->select('*')
226+
->where(new RawSql('CURRENT_TIMESTAMP() >='), new RawSql('DATE_ADD(column, INTERVAL 2 HOUR)'))
227+
->getCompiledSelect(true);
228+
229+
$expected = <<<'SQL'
230+
SELECT *
231+
FROM "auth_bearer"
232+
WHERE CURRENT_TIMESTAMP() >= DATE_ADD(column, INTERVAL 2 HOUR)
233+
SQL;
234+
$this->assertSame($expected, $sql);
235+
}
236+
177237
public function testWhereValueSubQuery()
178238
{
179239
$expectedSQL = 'SELECT * FROM "neworder" WHERE "advance_amount" < (SELECT MAX(advance_amount) FROM "orders" WHERE "id" > 2)';

0 commit comments

Comments
 (0)