From: Mike Bayer Date: Fri, 28 Mar 2008 15:55:26 +0000 (+0000) Subject: - can now allow selects which correlate all FROM clauses X-Git-Tag: rel_0_4_5~53 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=30020880d90ee2f983b8e6bfb1624349209dd8b0;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - can now allow selects which correlate all FROM clauses and have no FROM themselves. These are typically used in a scalar context, i.e. SELECT x, (SELECT x WHERE y) FROM table. Requires explicit correlate() call. --- diff --git a/CHANGES b/CHANGES index 101edcac0d..261135b9d0 100644 --- a/CHANGES +++ b/CHANGES @@ -54,6 +54,11 @@ CHANGES mapper-config'ed order_by when using select_from() - sql + - can now allow selects which correlate all FROM clauses + and have no FROM themselves. These are typically + used in a scalar context, i.e. SELECT x, (SELECT x WHERE y) + FROM table. Requires explicit correlate() call. + - 'name' is no longer a required constructor argument for Column(). It (and .key) may now be deferred until the column is added to a Table. diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index a3a25f5735..f4611de6da 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -3088,14 +3088,12 @@ class Select(_SelectBaseMixin, FromClause): for f in froms: froms.difference_update(f._hide_froms) - if len(froms) > 1: + if len(froms) > 1 or self.__correlate: if self.__correlate: froms.difference_update(self.__correlate) if self._should_correlate and existing_froms is not None: froms.difference_update(existing_froms) - if not froms: - raise exceptions.InvalidRequestError("Select statement '%s' is overcorrelated; returned no 'from' clauses" % str(self.__dont_correlate())) return froms froms = property(_get_display_froms, doc="""Return a list of all FromClause elements which will be applied to the FROM clause of the resulting statement.""") diff --git a/test/sql/select.py b/test/sql/select.py index 24cff7702e..b8d1f4f68c 100644 --- a/test/sql/select.py +++ b/test/sql/select.py @@ -141,7 +141,16 @@ sq.myothertable_othername AS sq_myothertable_othername FROM (" + sqstring + ") A def test_dont_overcorrelate(self): self.assert_compile(select([table1], from_obj=[table1, table1.select()]), """SELECT mytable.myid, mytable.name, mytable.description FROM mytable, (SELECT mytable.myid AS myid, mytable.name AS name, mytable.description AS description FROM mytable)""") + + def test_intentional_full_correlate(self): + """test a subquery that has no FROM clause.""" + + t = table('t', column('a'), column('b')) + s = select([t.c.a]).where(t.c.a==1).correlate(t).as_scalar() + s2 = select([t.c.a, s]) + self.assert_compile(s2, """SELECT t.a, (SELECT t.a WHERE t.a = :t_a_1) AS anon_1 FROM t""") + def test_exists(self): self.assert_compile(exists([table1.c.myid], table1.c.myid==5).select(), "SELECT EXISTS (SELECT mytable.myid FROM mytable WHERE mytable.myid = :mytable_myid_1)", params={'mytable_myid':5})