details:   https://code.tryton.org/python-sql/commit/a59c35753ba7
branch:    default
user:      Cédric Krier <[email protected]>
date:      Mon Nov 24 22:19:12 2025 +0100
description:
        Check the coherence of the aliases of GROUP BY and ORDER BY expressions
diffstat:

 CHANGELOG                |   1 +
 sql/__init__.py          |  14 ++++++++++++++
 sql/tests/test_select.py |  26 ++++++++++++++++++++++----
 3 files changed, 37 insertions(+), 4 deletions(-)

diffs (81 lines):

diff -r c6cb639096fb -r a59c35753ba7 CHANGELOG
--- a/CHANGELOG Mon Nov 24 21:35:33 2025 +0100
+++ b/CHANGELOG Mon Nov 24 22:19:12 2025 +0100
@@ -1,3 +1,4 @@
+* Check the coherence of the aliases of GROUP BY and ORDER BY expressions
 * Do not use parameter for EXTRACT field
 * Remove support for Python older than 3.6
 
diff -r c6cb639096fb -r a59c35753ba7 sql/__init__.py
--- a/sql/__init__.py   Mon Nov 24 21:35:33 2025 +0100
+++ b/sql/__init__.py   Mon Nov 24 22:19:12 2025 +0100
@@ -629,6 +629,20 @@
                 and (self.limit is not None or self.offset is not None)):
             return self._rownum(str)
 
+        for expression in chain(
+                self.group_by or [],
+                self.order_by or []):
+            if not isinstance(expression, As):
+                continue
+            for column in self.columns:
+                if not isinstance(column, As):
+                    continue
+                if column.output_name != expression.output_name:
+                    continue
+                if (str(column.expression) != str(expression.expression)
+                        or column.params != expression.params):
+                    raise ValueError("%r != %r" % (expression, column))
+
         with AliasManager():
             if self.from_ is not None:
                 from_ = ' FROM %s' % self.from_
diff -r c6cb639096fb -r a59c35753ba7 sql/tests/test_select.py
--- a/sql/tests/test_select.py  Mon Nov 24 21:35:33 2025 +0100
+++ b/sql/tests/test_select.py  Mon Nov 24 22:19:12 2025 +0100
@@ -253,6 +253,12 @@
         with self.assertRaises(ValueError):
             self.table.select(group_by=['foo'])
 
+    def test_select_invalid_group_by_alias(self):
+        query = self.table.select(
+            self.table.c1.as_('c'), group_by=self.table.c2.as_('c'))
+        with self.assertRaises(ValueError):
+            str(query)
+
     def test_select_having(self):
         col1 = self.table.col1
         col2 = self.table.col2
@@ -268,16 +274,28 @@
             self.table.select(having='foo')
 
     def test_select_order(self):
-        c = self.table.c
-        query = self.table.select(c, order_by=Literal(1))
+        column = self.table.c
+        query = self.table.select(column, order_by=column)
         self.assertEqual(str(query),
-            'SELECT "a"."c" FROM "t" AS "a" ORDER BY %s')
-        self.assertEqual(tuple(query.params), (1,))
+            'SELECT "a"."c" FROM "t" AS "a" ORDER BY "a"."c"')
+        self.assertEqual(tuple(query.params), ())
+
+        output = column.as_('c1')
+        query = self.table.select(output, order_by=output)
+        self.assertEqual(str(query),
+            'SELECT "a"."c" AS "c1" FROM "t" AS "a" ORDER BY "c1"')
+        self.assertEqual(tuple(query.params), ())
 
     def test_select_invalid_order(self):
         with self.assertRaises(ValueError):
             self.table.select(order_by='foo')
 
+    def test_select_invalid_order_alias(self):
+        query = self.table.select(
+            self.table.c1.as_('c'), order_by=self.table.c2.as_('c'))
+        with self.assertRaises(ValueError):
+            str(query)
+
     def test_select_limit_offset(self):
         try:
             Flavor.set(Flavor(limitstyle='limit'))

Reply via email to