Fixed issue where the :class:`.array_agg` construct in combination with
:meth:`.FunctionElement.filter` would not produce the correct operator
precedence between the FILTER keyword and the array index operator.
Fixes: #4760
Change-Id: Ic662cd3da3330554ec673bafd80495b3f1506098
(cherry picked from commit
116faee662f618d5ecd13b1e074a27d5e5a40564)
--- /dev/null
+.. change::
+ :tags: bug, sql, postgresql
+ :tickets: 4760
+
+ Fixed issue where the :class:`.array_agg` construct in combination with
+ :meth:`.FunctionElement.filter` would not produce the correct operator
+ precedence in combination with the array index operator.
+
rows=rows,
)
+ def self_group(self, against=None):
+ if operators.is_precedent(operators.filter_op, against):
+ return Grouping(self)
+ else:
+ return self
+
@util.memoized_property
def type(self):
return self.func.type
raise NotImplementedError()
+def filter_op(a, b):
+ raise NotImplementedError()
+
+
def concat_op(a, b):
return a.concat(b)
add: 7,
sub: 7,
concat_op: 6,
+ filter_op: 6,
match_op: 5,
notmatch_op: 5,
ilike_op: 5,
"FROM table1 AS foo",
)
+ def test_array_agg_w_filter_subscript(self):
+ series = func.generate_series(1, 100).alias("series")
+ series_col = column("series")
+ query = select(
+ [func.array_agg(series_col).filter(series_col % 2 == 0)[3]]
+ ).select_from(series)
+ self.assert_compile(
+ query,
+ "SELECT (array_agg(series) FILTER "
+ "(WHERE series %% %(series_1)s = %(param_1)s))[%(param_2)s] "
+ "AS anon_1 FROM "
+ "generate_series(%(generate_series_1)s, %(generate_series_2)s) "
+ "AS series",
+ )
+
def test_delete_extra_froms(self):
t1 = table("t1", column("c1"))
t2 = table("t2", column("c1"))
"mytable.myid > :myid_1)",
)
+ def test_funcfilter_arrayagg_subscript(self):
+ num = column("q")
+ self.assert_compile(
+ func.array_agg(num).filter(num % 2 == 0)[1],
+ "(array_agg(q) FILTER (WHERE q %% %(q_1)s = "
+ "%(param_1)s))[%(param_2)s]",
+ dialect="postgresql",
+ )
+
def test_funcfilter_label(self):
self.assert_compile(
select(