#32096 closed Bug (fixed)
Using KeyTransform for JSONField produces invalid SQL in various places.
| Reported by: | Igor Jerosimić | Owned by: | Mariusz Felisiak |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 3.1 |
| Severity: | Release blocker | Keywords: | KeyTransform, ArrayAgg |
| Cc: | Sage Abdullah | Triage Stage: | Ready for checkin |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Using KeyTransform in ordering attribute of ArrayAgg function produces invalid SQL. I don't know if it matters but I'm using Postgres for DB.
# sample model from django.db import models class Parent(models.Model): name = models.CharField(default='test') class Child(models.Model): parent = models.ForeignKey( Parent, on_delete=models.SET_NULL, related_name='children', ) data = models.JSONField(default=dict) # sample data parent = Parent.objects.create() Child.objects.create(parent=parent, data={'en': 'English', 'fr': 'French'}) # error Parent.objects.annotate( children_array=ArrayAgg( KeyTextTransform('en', 'children__data'), distinct=True, ordering=[KeyTransform('en', 'children__data')], ), ).all()
Produces invalid SQL in the ORDER BY section:
ARRAY_AGG(DISTINCT ("children"."data" ->> 'default') ORDER BY None("children"."data"))
NOTE: This was working fine before Django 3.1.
Change History (21)
comment:1 by , 5 years ago
| Description: | modified (diff) |
|---|---|
| Keywords: | KeyTransform ArrayAgg added |
comment:2 by , 5 years ago
| Severity: | Normal → Release blocker |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
comment:3 by , 5 years ago
From a quick grep I identified the following as_sql calls that suffered from the same class of isssue
ExpressionWrapper.as_sqlFieldGetDbPrepValueIterableMixin.resolve_expression_parameterWindow.as_sqlforself.partitionbut it would need to allowcompiler.completo proxy**kwargspassing or simply create a copy ofself.partitionto assign it the template at__init__time instead. The latter seems like the less intrusive method.
I identified these by going through all instances of [^)]\.as_sql so I might have missed a few.
Version 0, edited 5 years ago by (next)
comment:4 by , 5 years ago
| Cc: | added |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
comment:5 by , 5 years ago
| Has patch: | set |
|---|---|
| Summary: | Using KeyTransform in ArrayAgg function produces invalid SQL → Using KeyTransform for JSONField produces invalid SQL in various places. |
comment:6 by , 5 years ago
| Triage Stage: | Accepted → Ready for checkin |
|---|
comment:18 by , 5 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
Note:
See TracTickets
for help on using tickets.
It's due to
OrderableAggMixin.as_sqlcalling its ordering expression as_sql method directly instead of doingcompiler.compile(expr)since the latter properly handles the vendor logic.This wasn't an issue when
KeyTransformwas only implemented forcontrib.postgresas it's implementation was not vendored but now it does.There might other instances of this problem lying around in
django.db.models.expressionsand friends since it's the first time I've seen this issue manifest itself and I don't remember this is something we kept an eye for during code reviews.