]> 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:06:58 +0000 (20:06 -0400)
typically via in-place mutation, will raise an informative error
message rather than causing a recursion overflow.
[ticket:2815]

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

index 87dbc8f93a54dbed3cd624f13d13f4e942baf5b7..6731fe19a84c327f9481d41738da2b8b2151e9a0 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 e06262c6deb71e9d5f75cd1cff5e19a097ca16a9..43d5a084cdef9e062d4eb2d04c83d1637f1cf2ce 100644 (file)
@@ -1936,6 +1936,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 87a226782566f7bf11abc54401c475646394bcc4..0fc7a0ed0dbc49c3e8205b8ef5f3d5231171f7b3 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()."""