]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
A :func:`.select` that is made to refer to itself in its FROM clause,
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 9 Oct 2013 00:06:58 +0000 (20:06 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 9 Oct 2013 00:08:35 +0000 (20:08 -0400)
typically via in-place mutation, will raise an informative error
message rather than causing a recursion overflow.
[ticket:2815]

Conflicts:
lib/sqlalchemy/sql/selectable.py

doc/build/changelog/changelog_08.rst
lib/sqlalchemy/sql/expression.py
test/sql/test_selectable.py

index 70521ecbf6c6023fddf4df07209e993cb924b157..0937aaad577bcab2b6c6dba29583949191731cef 100644 (file)
 .. changelog::
     :version: 0.8.3
 
+    .. change::
+        :tags: bug, sql
+        :tickets: 2815
+        :versions: 0.9.0
+
+        A :func:`.select` that is made to refer to itself in its FROM clause,
+        typically via in-place mutation, will raise an informative error
+        message rather than causing a recursion overflow.
+
     .. change::
         :tags: bug, orm
         :tickets: 2813
index b2f957bd02e0f8b2feef48d3adf80bf9d013b36b..5a97c2222b394af1350f66d0195f93fcea05e393 100644 (file)
@@ -5288,6 +5288,9 @@ class Select(HasPrefixes, SelectBase):
 
         def add(items):
             for item in items:
+                if item is self:
+                    raise exc.InvalidRequestError(
+                            "select() construct refers to itself as a FROM")
                 if translate and item in translate:
                     item = translate[item]
                 if not seen.intersection(item._cloned_set):
index 649490ef30ab32b8775b9a4def3cc6532a271115..8289a783d84bb8c169ac2c3196b0c30a20e3c0d2 100644 (file)
@@ -514,6 +514,18 @@ class SelectableTest(fixtures.TestBase, AssertsExecutionResults, AssertsCompiled
             "SELECT c FROM (SELECT (SELECT (SELECT table1.col1 AS a FROM table1) AS b) AS c)"
         )
 
+    def test_self_referential_select_raises(self):
+        t = table('t', column('x'))
+
+        s = select([t])
+
+        s.append_whereclause(s.c.x > 5)
+        assert_raises_message(
+            exc.InvalidRequestError,
+            r"select\(\) construct refers to itself as a FROM",
+            s.compile
+        )
+
     def test_unusual_column_elements_text(self):
         """test that .c excludes text()."""