Skip to content

Commit

Permalink
Merge pull request #7147 from sclubricants/FixBuilderWhere
Browse files Browse the repository at this point in the history
Bug Fix: [QueryBuilder] where() generates incorrect SQL when using RawSql
  • Loading branch information
kenjis authored Jan 20, 2023
2 parents 3163d3b + 8d0e216 commit 9a71a94
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
12 changes: 9 additions & 3 deletions system/Database/BaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -728,9 +728,15 @@ public function orWhere($key, $value = null, ?bool $escape = null)
*/
protected function whereHaving(string $qbKey, $key, $value = null, string $type = 'AND ', ?bool $escape = null)
{
$rawSqlOnly = false;

if ($key instanceof RawSql) {
$keyValue = [(string) $key => $key];
$escape = false;
if ($value === null) {
$keyValue = [(string) $key => $key];
$rawSqlOnly = true;
} else {
$keyValue = [(string) $key => $value];
}
} elseif (! is_array($key)) {
$keyValue = [$key => $value];
} else {
Expand All @@ -745,7 +751,7 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type
foreach ($keyValue as $k => $v) {
$prefix = empty($this->{$qbKey}) ? $this->groupGetType('') : $this->groupGetType($type);

if ($v instanceof RawSql) {
if ($rawSqlOnly === true) {
$k = '';
$op = '';
} elseif ($v !== null) {
Expand Down
60 changes: 60 additions & 0 deletions tests/system/Database/Builder/WhereTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,66 @@ public function testWhereRawSql()
$this->assertSame($expectedBinds, $builder->getBinds());
}

public function testWhereValueRawSql()
{
$sql = $this->db->table('auth_bearer')
->select('*')
->where('expires', new RawSql('DATE_ADD(NOW(), INTERVAL 2 HOUR)'))
->getCompiledSelect(true);

$expected = <<<'SQL'
SELECT *
FROM "auth_bearer"
WHERE "expires" = DATE_ADD(NOW(), INTERVAL 2 HOUR)
SQL;
$this->assertSame($expected, $sql);
}

public function testWhereKeyOnlyRawSql()
{
$sql = $this->db->table('auth_bearer')
->select('*')
->where(new RawSql('DATE_ADD(NOW(), INTERVAL 2 HOUR)'), '2023-01-01')
->getCompiledSelect(true);

$expected = <<<'SQL'
SELECT *
FROM "auth_bearer"
WHERE DATE_ADD(NOW(), INTERVAL 2 HOUR) = '2023-01-01'
SQL;
$this->assertSame($expected, $sql);
}

public function testWhereKeyAndValueRawSql()
{
$sql = $this->db->table('auth_bearer')
->select('*')
->where(new RawSql('CURRENT_TIMESTAMP()'), new RawSql('DATE_ADD(column, INTERVAL 2 HOUR)'))
->getCompiledSelect(true);

$expected = <<<'SQL'
SELECT *
FROM "auth_bearer"
WHERE CURRENT_TIMESTAMP() = DATE_ADD(column, INTERVAL 2 HOUR)
SQL;
$this->assertSame($expected, $sql);
}

public function testWhereKeyAndValueRawSqlWithOperator()
{
$sql = $this->db->table('auth_bearer')
->select('*')
->where(new RawSql('CURRENT_TIMESTAMP() >='), new RawSql('DATE_ADD(column, INTERVAL 2 HOUR)'))
->getCompiledSelect(true);

$expected = <<<'SQL'
SELECT *
FROM "auth_bearer"
WHERE CURRENT_TIMESTAMP() >= DATE_ADD(column, INTERVAL 2 HOUR)
SQL;
$this->assertSame($expected, $sql);
}

public function testWhereValueSubQuery()
{
$expectedSQL = 'SELECT * FROM "neworder" WHERE "advance_amount" < (SELECT MAX(advance_amount) FROM "orders" WHERE "id" > 2)';
Expand Down

0 comments on commit 9a71a94

Please sign in to comment.