]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Include DISTINCT in error message for label reference
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 6 Dec 2019 15:24:25 +0000 (10:24 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 6 Dec 2019 15:26:49 +0000 (10:26 -0500)
Needed to add tests to ensure this label reference is handled
correctly, so also modified the exception message to
be more clear if someone has this error within distinct().

Change-Id: I6e685e46ae336596272d14366445ac224c18d92c
(cherry picked from commit 55f66e430d18b8daa51121cbc18537e2dab1ad9f)

doc/build/changelog/unreleased_13/dist_warn.rst [new file with mode: 0644]
lib/sqlalchemy/sql/compiler.py
test/orm/test_query.py
test/sql/test_text.py

diff --git a/doc/build/changelog/unreleased_13/dist_warn.rst b/doc/build/changelog/unreleased_13/dist_warn.rst
new file mode 100644 (file)
index 0000000..b70a9f0
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: bug, sql
+
+    Changed the text of the exception for "Can't resolve label reference" to
+    include other kinds of label coercions, namely that "DISTINCT" is also in
+    this category under the PostgreSQL dialect.
+
index 7a063ab1b5373e79b0e2c21c3db9c1e1e797bc61..4dff9b25b2c4c34518002f6684906be1fae1e91f 100644 (file)
@@ -778,7 +778,8 @@ class SQLCompiler(Compiled):
             elements._no_text_coercion(
                 element.element,
                 exc.CompileError,
-                "Can't resolve label reference for ORDER BY / GROUP BY.",
+                "Can't resolve label reference for ORDER BY / "
+                "GROUP BY / DISTINCT etc.",
             )
         else:
             kwargs["render_label_as_label"] = col
index 2791251bddb3ecceeec86daa8a1e20acb58c067d..2a877015ee858cd9dc7bc62507b9346cf7408d1b 100644 (file)
@@ -3878,6 +3878,45 @@ class DistinctTest(QueryTest, AssertsCompiledSQL):
             dialect="postgresql",
         )
 
+    def test_columns_augmented_sql_three_using_label_reference(self):
+        User, Address = self.classes.User, self.classes.Address
+
+        sess = create_session()
+
+        q = (
+            sess.query(User.id, User.name.label("foo"), Address.id)
+            .distinct("name")
+            .order_by(User.id, User.name, Address.email_address)
+        )
+
+        # no columns are added when DISTINCT ON is used
+        self.assert_compile(
+            q,
+            "SELECT DISTINCT ON (users.name) users.id AS users_id, "
+            "users.name AS foo, addresses.id AS addresses_id FROM users, "
+            "addresses ORDER BY users.id, users.name, addresses.email_address",
+            dialect="postgresql",
+        )
+
+    def test_columns_augmented_sql_illegal_label_reference(self):
+        User, Address = self.classes.User, self.classes.Address
+
+        sess = create_session()
+
+        q = sess.query(User.id, User.name.label("foo"), Address.id).distinct(
+            "not a label"
+        )
+
+        from sqlalchemy.dialects import postgresql
+
+        assert_raises_message(
+            sa_exc.CompileError,
+            "Can't resolve label reference for ORDER BY / "
+            "GROUP BY / DISTINCT etc.",
+            q.with_labels().statement.compile,
+            dialect=postgresql.dialect(),
+        )
+
     def test_columns_augmented_sql_four(self):
         User, Address = self.classes.User, self.classes.Address
 
index 4e1013b00fa689a56c6791421aa277919683c04d..46493cdc1bb647e0daba4180447316b1c5eb77cc 100644 (file)
@@ -629,14 +629,16 @@ class TextErrorsTest(fixtures.TestBase, AssertsCompiledSQL):
 class OrderByLabelResolutionTest(fixtures.TestBase, AssertsCompiledSQL):
     __dialect__ = "default"
 
-    def _test_exception(self, stmt, offending_clause):
+    def _test_exception(self, stmt, offending_clause, dialect=None):
         assert_raises_message(
             exc.CompileError,
-            r"Can't resolve label reference for ORDER BY / GROUP BY. "
+            r"Can't resolve label reference for ORDER BY / GROUP BY / "
+            "DISTINCT etc. "
             "Textual SQL "
             "expression %r should be explicitly "
             r"declared as text\(%r\)" % (offending_clause, offending_clause),
             stmt.compile,
+            dialect=dialect,
         )
 
     def test_order_by_label(self):
@@ -687,6 +689,21 @@ class OrderByLabelResolutionTest(fixtures.TestBase, AssertsCompiledSQL):
         stmt = select([table1.c.myid]).order_by("foobar")
         self._test_exception(stmt, "foobar")
 
+    def test_distinct_label(self):
+
+        stmt = select([table1.c.myid.label("foo")]).distinct("foo")
+        self.assert_compile(
+            stmt,
+            "SELECT DISTINCT ON (foo) mytable.myid AS foo FROM mytable",
+            dialect="postgresql",
+        )
+
+    def test_unresolvable_distinct_label(self):
+        from sqlalchemy.dialects import postgresql
+
+        stmt = select([table1.c.myid.label("foo")]).distinct("not a label")
+        self._test_exception(stmt, "not a label", dialect=postgresql.dialect())
+
     def test_group_by_label(self):
         stmt = select([table1.c.myid.label("foo")]).group_by("foo")
         self.assert_compile(
@@ -840,7 +857,8 @@ class OrderByLabelResolutionTest(fixtures.TestBase, AssertsCompiledSQL):
 
         assert_raises_message(
             exc.CompileError,
-            r"Can't resolve label reference for ORDER BY / GROUP BY. "
+            r"Can't resolve label reference for ORDER BY / GROUP BY / "
+            "DISTINCT etc. "
             "Textual SQL "
             "expression 't1name' should be explicitly "
             r"declared as text\('t1name'\)",