]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- small fix to allow successive compiles of the same SELECT object
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 13 Apr 2007 22:22:07 +0000 (22:22 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 13 Apr 2007 22:22:07 +0000 (22:22 +0000)
which features LIMIT/OFFSET.  oracle dialect needs to modify
the object to have ROW_NUMBER OVER and wasn't performing
the full series of steps on successive compiles.

CHANGES
lib/sqlalchemy/databases/oracle.py
test/sql/select.py

diff --git a/CHANGES b/CHANGES
index 53c3349fe68ca95736c6e8cbfa7cd222f776912c..2700536a3c573fbeaeeb8f67c81e214863e11ed0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
 - sqlite:
     - removed silly behavior where sqlite would reflect UNIQUE indexes
       as part of the primary key (?!)
-      
+- oracle:
+    - small fix to allow successive compiles of the same SELECT object
+      which features LIMIT/OFFSET.  oracle dialect needs to modify
+      the object to have ROW_NUMBER OVER and wasn't performing 
+      the full series of steps on successive compiles.
+
 0.3.6
 - sql:
     - bindparam() names are now repeatable!  specify two
index 5377759a2aa61aa019825281e032b1cd586b07b6..fce59a0725a36e4bdb667b04db5758198f03897e 100644 (file)
@@ -418,6 +418,11 @@ class OracleCompiler(ansisql.ANSICompiler):
     the use_ansi flag is False.
     """
 
+    def __init__(self, *args, **kwargs):
+        super(OracleCompiler, self).__init__(*args, **kwargs)
+        # we have to modify SELECT objects a little bit, so store state here
+        self._select_state = {}
+        
     def default_from(self):
         """Called when a ``SELECT`` statement has no froms, and no ``FROM`` clause is to be appended.
 
@@ -523,7 +528,7 @@ class OracleCompiler(ansisql.ANSICompiler):
 
         # TODO: put a real copy-container on Select and copy, or somehow make this
         # not modify the Select statement
-        if getattr(select, '_oracle_visit', False):
+        if self._select_state.get((select, 'visit'), False):
             # cancel out the compiled order_by on the select
             if hasattr(select, "order_by_clause"):
                 self.strings[select.order_by_clause] = ""
@@ -531,14 +536,16 @@ class OracleCompiler(ansisql.ANSICompiler):
             return
 
         if select.limit is not None or select.offset is not None:
-            select._oracle_visit = True
+            self._select_state[(select, 'visit')] = True
             # to use ROW_NUMBER(), an ORDER BY is required.
             orderby = self.strings[select.order_by_clause]
             if not orderby:
                 orderby = select.oid_column
                 self.traverse(orderby)
                 orderby = self.strings[orderby]
-            select.append_column(sql.literal_column("ROW_NUMBER() OVER (ORDER BY %s)" % orderby).label("ora_rn"))
+            if not hasattr(select, '_oracle_visit'):
+                select.append_column(sql.literal_column("ROW_NUMBER() OVER (ORDER BY %s)" % orderby).label("ora_rn"))
+                select._oracle_visit = True
             limitselect = sql.select([c for c in select.c if c.key!='ora_rn'])
             if select.offset is not None:
                 limitselect.append_whereclause("ora_rn>%d" % select.offset)
index 56584e7084dc6c1b36f2c12b50d852efe4a1fe8f..91b293cbe6737730a96075b287896a7794e6e886 100644 (file)
@@ -280,7 +280,9 @@ sq.myothertable_othername AS sq_myothertable_othername FROM (" + sqstring + ") A
     def testoraclelimit(self):
         metadata = MetaData()
         users = Table('users', metadata, Column('name', String(10), key='username'))
-        self.runtest(select([users.c.username], limit=5), "SELECT name FROM (SELECT users.name AS name, ROW_NUMBER() OVER (ORDER BY users.rowid) AS ora_rn FROM users) WHERE ora_rn<=5", dialect=oracle.dialect())
+        s = select([users.c.username], limit=5)
+        self.runtest(s, "SELECT name FROM (SELECT users.name AS name, ROW_NUMBER() OVER (ORDER BY users.rowid) AS ora_rn FROM users) WHERE ora_rn<=5", dialect=oracle.dialect())
+        self.runtest(s, "SELECT name FROM (SELECT users.name AS name, ROW_NUMBER() OVER (ORDER BY users.rowid) AS ora_rn FROM users) WHERE ora_rn<=5", dialect=oracle.dialect())
 
     def testgroupby_and_orderby(self):
         self.runtest(