#35339: Ordering and filtering a Postgres ArrayAgg with parameters inverts SQL
param order
-------------------------------------+-------------------------------------
Reporter: Chris M | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: postgres arrayagg | Triage Stage: Accepted
ordering |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Natalia Bidart):
* cc: Mariusz Felisiak, Simon Charette (added)
* keywords: => postgres arrayagg ordering
* stage: Unreviewed => Accepted
* type: Uncategorized => Bug
* version: 5.0 => dev
Comment:
Hello Chris, thank you for your detailed report.
I can confirm that the provided test fails in current `main` as shown
below. Adding Simon and Mariusz as cc to see if they can provide advice on
the
{{{#!diff
diff --git a/tests/postgres_tests/test_aggregates.py
b/tests/postgres_tests/test_aggregates.py
index 386c55da25..5ab27752d1 100644
--- a/tests/postgres_tests/test_aggregates.py
+++ b/tests/postgres_tests/test_aggregates.py
@@ -12,7 +12,7 @@ from django.db.models import (
Window,
)
from django.db.models.fields.json import KeyTextTransform, KeyTransform
-from django.db.models.functions import Cast, Concat, Substr
+from django.db.models.functions import Cast, Concat, LPad, Substr
from django.test import skipUnlessDBFeature
from django.test.utils import Approximate
from django.utils import timezone
@@ -188,6 +188,16 @@ class TestGeneralAggregate(PostgreSQLTestCase):
)
self.assertEqual(values, {"arrayagg": expected_output})
+ def test_array_agg_filter_and_ordering_params(self):
+ values = AggregateTestModel.objects.aggregate(
+ arrayagg=ArrayAgg(
+ "char_field",
+ filter=Q(json_field__has_key="lang"),
+ ordering=LPad(Cast("integer_field", CharField()), 2,
Value("0")),
+ )
+ )
+ self.assertEqual(values, {"arrayagg": ["Foo2", "Foo4"]})
+
def test_array_agg_integerfield(self):
values = AggregateTestModel.objects.aggregate(
arrayagg=ArrayAgg("integer_field")
}}}
Full trace with `--debug-sql`:
{{{
======================================================================
ERROR: test_array_agg_filter_and_ordering_params
(postgres_tests.test_aggregates.TestGeneralAggregate.test_array_agg_filter_and_ordering_params)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/nessita/fellowship/django/django/db/backends/utils.py", line
105, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/nessita/.virtualenvs/djangodev/lib/python3.11/site-
packages/psycopg/cursor.py", line 732, in execute
raise ex.with_traceback(None)
psycopg.errors.UndefinedFunction: function lpad(character varying,
unknown, integer) does not exist
LINE 1: ...s_tests_aggregatetestmodel"."char_field" ORDER BY LPAD(("pos...
^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
...
File "/home/nessita/.virtualenvs/djangodev/lib/python3.11/site-
packages/psycopg/cursor.py", line 732, in execute
raise ex.with_traceback(None)
django.db.utils.ProgrammingError: function lpad(character varying,
unknown, integer) does not exist
LINE 1: ...s_tests_aggregatetestmodel"."char_field" ORDER BY LPAD(("pos...
^
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.
----------------------------------------------------------------------
(0.000)
SELECT ARRAY_AGG("postgres_tests_aggregatetestmodel"."char_field"
ORDER BY
LPAD(("postgres_tests_aggregatetestmodel"."integer_field")::varchar,
'lang', 2)) FILTER (
WHERE "postgres_tests_aggregatetestmodel"."json_field" ? '0') AS
"arrayagg"
FROM "postgres_tests_aggregatetestmodel";
args=('lang',
Int4(2),
'0');
ALIAS=DEFAULT
}}}
--
Ticket URL: <
https://code.djangoproject.com/ticket/35339#comment:1>