﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
36122	Add sanity check against updating non-composite field with composite expression	Jacob Walls	Simon Charette	"Attempting to update a non-composite field via `.update()` with a composite expression fails at the db level with an invalid query:

Rough test:
{{{#!diff
diff --git a/tests/composite_pk/test_update.py b/tests/composite_pk/test_update.py
index ec770230fc..c5deac6d4b 100644
--- a/tests/composite_pk/test_update.py
+++ b/tests/composite_pk/test_update.py
@@ -1,4 +1,5 @@
 from django.db import connection
+from django.db.models import F
 from django.test import TestCase
 
 from .models import Comment, Tenant, TimeStamped, Token, User
@@ -175,3 +176,9 @@ class CompositePKUpdateTests(TestCase):
 
         with self.assertRaisesMessage(ValueError, msg):
             Comment.objects.update(user=User())
+
+    def test_update_lhs_not_composite(self):
+        qs = Comment.objects.filter(user__email=self.user_1.email)
+        msg = ""Composite expressions only work with composite fields.""
+        with self.assertRaisesMessage(ValueError, msg):
+            qs.update(text=F(""pk""))
}}}
----
{{{#!py
======================================================================
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)
}}}"	Bug	closed	Database layer (models, ORM)	5.2	Release blocker	fixed			Ready for checkin	1	0	0	0	0	0
