Opened 12 hours ago
Last modified 12 hours ago
#36122 new Bug
Add sanity check against updating non-composite field with composite expression
Reported by: | Jacob Walls | Owned by: | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 5.2 |
Severity: | Release blocker | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Attempting to update a non-composite field via .update()
with a composite expression fails at the db level with an invalid query:
Rough test:
-
tests/composite_pk/test_update.py
diff --git a/tests/composite_pk/test_update.py b/tests/composite_pk/test_update.py index ec770230fc..c5deac6d4b 100644
a b 1 1 from django.db import connection 2 from django.db.models import F 2 3 from django.test import TestCase 3 4 4 5 from .models import Comment, Tenant, TimeStamped, Token, User … … class CompositePKUpdateTests(TestCase): 175 176 176 177 with self.assertRaisesMessage(ValueError, msg): 177 178 Comment.objects.update(user=User()) 179 180 def test_update_lhs_not_composite(self): 181 qs = Comment.objects.filter(user__email=self.user_1.email) 182 msg = "Composite expressions only work with composite fields." 183 with self.assertRaisesMessage(ValueError, msg): 184 qs.update(text=F("pk"))
====================================================================== ERROR: test_update_lhs_not_composite (composite_pk.test_update.CompositePKUpdateTests.test_update_lhs_not_composite) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/source/django/django/db/backends/utils.py", line 105, in _execute return self.cursor.execute(sql, params) ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ File "/Users/source/django/django/db/backends/sqlite3/base.py", line 360, in execute return super().execute(query, params) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^ sqlite3.OperationalError: near ".": syntax error The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/Users/source/django/tests/composite_pk/test_update.py", line 184, in test_update_lhs_not_composite qs.update(text=F("pk")) ~~~~~~~~~^^^^^^^^^^^^^^ File "/Users/source/django/django/db/models/query.py", line 1254, in update rows = query.get_compiler(self.db).execute_sql(ROW_COUNT) File "/Users/source/django/django/db/models/sql/compiler.py", line 2068, in execute_sql row_count = super().execute_sql(result_type) File "/Users/source/django/django/db/models/sql/compiler.py", line 1623, in execute_sql cursor.execute(sql, params) ~~~~~~~~~~~~~~^^^^^^^^^^^^^ File "/Users/source/django/django/db/backends/utils.py", line 122, in execute return super().execute(sql, params) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^ File "/Users/source/django/django/db/backends/utils.py", line 79, in execute return self._execute_with_wrappers( ~~~~~~~~~~~~~~~~~~~~~~~~~~~^ sql, params, many=False, executor=self._execute ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/Users/source/django/django/db/backends/utils.py", line 92, in _execute_with_wrappers return executor(sql, params, many, context) File "/Users/source/django/django/db/backends/utils.py", line 100, in _execute with self.db.wrap_database_errors: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/source/django/django/db/utils.py", line 91, in __exit__ raise dj_exc_value.with_traceback(traceback) from exc_value File "/Users/source/django/django/db/backends/utils.py", line 105, in _execute return self.cursor.execute(sql, params) ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ File "/Users/source/django/django/db/backends/sqlite3/base.py", line 360, in execute return super().execute(query, params) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^ django.db.utils.OperationalError: near ".": syntax error ---------------------------------------------------------------------- (0.000) UPDATE "composite_pk_comment" SET "text" = "composite_pk_comment"."tenant_id", "composite_pk_comment"."comment_id" WHERE ("composite_pk_comment"."tenant_id", "composite_pk_comment"."comment_id") IN (SELECT U0."tenant_id" AS "tenant", U0."comment_id" AS "id" FROM "composite_pk_comment" U0 INNER JOIN "composite_pk_user" U1 ON (U0."tenant_id" = U1."tenant_id" AND U0."user_id" = U1."id") WHERE U1."email" = 'user0001@example.com'); args=('user0001@example.com',); alias=default ---------------------------------------------------------------------- Ran 1 test in 0.014s FAILED (errors=1)
Note:
See TracTickets
for help on using tickets.
I guess depending on the fix for #36120 this may turn out to be a duplicate (pardon the noise if so)