Skip to content

Commit 386d168

Browse files
authored
fix(postgres): missing parentheses in whereDate/whereTime for json columns (#55159)
In #12341, the cast to `::date` was added to `whereDate`. This leads to an error with PostgreSQL when passing in json column selectors. For example: `->whereDate('result->created_at', DB::raw('NOW()'))` will throw a syntax error for type date. The same is true for the `whereTime` function with its `::time` cast. To fix this, we need to wrap the column identifier in parentheses, when they are json paths. Current SQL output: ```SQL select * from "users" where "result"->>'created_at'::date = NOW() ``` Correct SQL output with this commit: ```SQL select * from "users" where ("result"->>'created_at')::date = NOW() ```
1 parent 91250d9 commit 386d168

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

src/Illuminate/Database/Query/Grammars/PostgresGrammar.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,13 @@ protected function whereLike(Builder $query, $where)
109109
protected function whereDate(Builder $query, $where)
110110
{
111111
$value = $this->parameter($where['value']);
112+
$column = $this->wrap($where['column']);
112113

113-
return $this->wrap($where['column']).'::date '.$where['operator'].' '.$value;
114+
if ($this->isJsonSelector($where['column'])) {
115+
$column = '('.$column.')';
116+
}
117+
118+
return $column.'::date '.$where['operator'].' '.$value;
114119
}
115120

116121
/**
@@ -123,8 +128,13 @@ protected function whereDate(Builder $query, $where)
123128
protected function whereTime(Builder $query, $where)
124129
{
125130
$value = $this->parameter($where['value']);
131+
$column = $this->wrap($where['column']);
132+
133+
if ($this->isJsonSelector($where['column'])) {
134+
$column = '('.$column.')';
135+
}
126136

127-
return $this->wrap($where['column']).'::time '.$where['operator'].' '.$value;
137+
return $column.'::time '.$where['operator'].' '.$value;
128138
}
129139

130140
/**

tests/Database/DatabaseQueryBuilderTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,10 @@ public function testWhereDatePostgres()
614614
$builder = $this->getPostgresBuilder();
615615
$builder->select('*')->from('users')->whereDate('created_at', new Raw('NOW()'));
616616
$this->assertSame('select * from "users" where "created_at"::date = NOW()', $builder->toSql());
617+
618+
$builder = $this->getPostgresBuilder();
619+
$builder->select('*')->from('users')->whereDate('result->created_at', new Raw('NOW()'));
620+
$this->assertSame('select * from "users" where ("result"->>\'created_at\')::date = NOW()', $builder->toSql());
617621
}
618622

619623
public function testWhereDayPostgres()
@@ -646,6 +650,11 @@ public function testWhereTimePostgres()
646650
$builder->select('*')->from('users')->whereTime('created_at', '>=', '22:00');
647651
$this->assertSame('select * from "users" where "created_at"::time >= ?', $builder->toSql());
648652
$this->assertEquals([0 => '22:00'], $builder->getBindings());
653+
654+
$builder = $this->getPostgresBuilder();
655+
$builder->select('*')->from('users')->whereTime('result->created_at', '>=', '22:00');
656+
$this->assertSame('select * from "users" where ("result"->>\'created_at\')::time >= ?', $builder->toSql());
657+
$this->assertEquals([0 => '22:00'], $builder->getBindings());
649658
}
650659

651660
public function testWherePast()

0 commit comments

Comments
 (0)