From 67afbfd8af1e57bdd26996f7c0e6b837d489929f Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 23 Mar 2006 06:17:29 +0000 Subject: [PATCH] some adjustments to oracle non-ansi join concatenation, 'row number over' syntax --- lib/sqlalchemy/databases/oracle.py | 14 ++++++++++---- test/select.py | 4 ++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/sqlalchemy/databases/oracle.py b/lib/sqlalchemy/databases/oracle.py index 1a02448e08..c36f4546e6 100644 --- a/lib/sqlalchemy/databases/oracle.py +++ b/lib/sqlalchemy/databases/oracle.py @@ -227,9 +227,9 @@ class OracleCompiler(ansisql.ANSICompiler): def visit_join(self, join): if self._use_ansi: return ansisql.ANSICompiler.visit_join(self, join) - + self.froms[join] = self.get_from_text(join.left) + ", " + self.get_from_text(join.right) - self.wheres[join] = join.onclause + self.wheres[join] = sql.and_(self.wheres.get(join.left, None), join.onclause) if join.isouter: # if outer join, push on the right side table as the current "outertable" @@ -241,6 +241,8 @@ class OracleCompiler(ansisql.ANSICompiler): join.onclause.accept_visitor(self) self._outertable = outertable + + self.visit_compound(self.wheres[join]) def visit_alias(self, alias): """oracle doesnt like 'FROM table AS alias'. is the AS standard SQL??""" @@ -250,7 +252,7 @@ class OracleCompiler(ansisql.ANSICompiler): def visit_column(self, column): if self._use_ansi: return ansisql.ANSICompiler.visit_column(self, column) - + if column.table is self._outertable: self.strings[column] = "%s.%s(+)" % (column.table.name, column.name) else: @@ -285,7 +287,11 @@ class OracleCompiler(ansisql.ANSICompiler): # to use ROW_NUMBER(), an ORDER BY is required. so here we dig in # as best we can to find some column we can order by # TODO: try to get "oid_column" to be used here - orderby = "%s.rowid ASC" % select.primary_key[0].original.table.name + if len(select.primary_key): + col = select.primary_key[0].original.table.name + else: + col = select.froms[0].name + orderby = "%s.rowid ASC" % col select.append_column(sql.ColumnClause("ROW_NUMBER() OVER (ORDER BY %s)" % orderby).label("ora_rn")) limitselect = sql.select([c for c in select.c if c.key!='ora_rn']) if select.offset is not None: diff --git a/test/select.py b/test/select.py index 081cd83bee..2f4aa47b36 100644 --- a/test/select.py +++ b/test/select.py @@ -463,6 +463,10 @@ mytable.name = :mytable_name AND mytable.myid = :mytable_myid AND \ myothertable.othername != :myothertable_othername AND EXISTS (select yay from foo where boo = lar)", engine = oracle.engine({}, use_ansi = False)) + query = table1.outerjoin(table2, table1.c.myid==table2.c.otherid).outerjoin(table3, table3.c.userid==table2.c.otherid) + self.runtest(query.select(), "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, myothertable.othername, thirdtable.userid, thirdtable.otherstuff FROM mytable LEFT OUTER JOIN myothertable ON mytable.myid = myothertable.otherid LEFT OUTER JOIN thirdtable ON thirdtable.userid = myothertable.otherid") + self.runtest(query.select(), "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, myothertable.othername, thirdtable.userid, thirdtable.otherstuff FROM mytable, myothertable, thirdtable WHERE mytable.myid = myothertable.otherid(+) AND thirdtable.userid(+) = myothertable.otherid", engine=oracle.engine({}, use_ansi=False)) + def testbindparam(self): self.runtest(select( [table1, table2], -- 2.47.2