web/lib/django/db/backends/oracle/compiler.py
changeset 29 cc9b7e14412b
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
       
     1 from django.db.models.sql import compiler
       
     2 
       
     3 
       
     4 class SQLCompiler(compiler.SQLCompiler):
       
     5     def resolve_columns(self, row, fields=()):
       
     6         # If this query has limit/offset information, then we expect the
       
     7         # first column to be an extra "_RN" column that we need to throw
       
     8         # away.
       
     9         if self.query.high_mark is not None or self.query.low_mark:
       
    10             rn_offset = 1
       
    11         else:
       
    12             rn_offset = 0
       
    13         index_start = rn_offset + len(self.query.extra_select.keys())
       
    14         values = [self.query.convert_values(v, None, connection=self.connection)
       
    15                   for v in row[rn_offset:index_start]]
       
    16         for value, field in map(None, row[index_start:], fields):
       
    17             values.append(self.query.convert_values(value, field, connection=self.connection))
       
    18         return tuple(values)
       
    19 
       
    20     def as_sql(self, with_limits=True, with_col_aliases=False):
       
    21         """
       
    22         Creates the SQL for this query. Returns the SQL string and list
       
    23         of parameters.  This is overriden from the original Query class
       
    24         to handle the additional SQL Oracle requires to emulate LIMIT
       
    25         and OFFSET.
       
    26 
       
    27         If 'with_limits' is False, any limit/offset information is not
       
    28         included in the query.
       
    29         """
       
    30 
       
    31         # The `do_offset` flag indicates whether we need to construct
       
    32         # the SQL needed to use limit/offset with Oracle.
       
    33         do_offset = with_limits and (self.query.high_mark is not None
       
    34                                      or self.query.low_mark)
       
    35         if not do_offset:
       
    36             sql, params = super(SQLCompiler, self).as_sql(with_limits=False,
       
    37                     with_col_aliases=with_col_aliases)
       
    38         else:
       
    39             sql, params = super(SQLCompiler, self).as_sql(with_limits=False,
       
    40                                                     with_col_aliases=True)
       
    41 
       
    42             # Wrap the base query in an outer SELECT * with boundaries on
       
    43             # the "_RN" column.  This is the canonical way to emulate LIMIT
       
    44             # and OFFSET on Oracle.
       
    45             high_where = ''
       
    46             if self.query.high_mark is not None:
       
    47                 high_where = 'WHERE ROWNUM <= %d' % (self.query.high_mark,)
       
    48             sql = 'SELECT * FROM (SELECT ROWNUM AS "_RN", "_SUB".* FROM (%s) "_SUB" %s) WHERE "_RN" > %d' % (sql, high_where, self.query.low_mark)
       
    49 
       
    50         return sql, params
       
    51 
       
    52 
       
    53 class SQLInsertCompiler(compiler.SQLInsertCompiler, SQLCompiler):
       
    54     pass
       
    55 
       
    56 class SQLDeleteCompiler(compiler.SQLDeleteCompiler, SQLCompiler):
       
    57     pass
       
    58 
       
    59 class SQLUpdateCompiler(compiler.SQLUpdateCompiler, SQLCompiler):
       
    60     pass
       
    61 
       
    62 class SQLAggregateCompiler(compiler.SQLAggregateCompiler, SQLCompiler):
       
    63     pass
       
    64 
       
    65 class SQLDateCompiler(compiler.SQLDateCompiler, SQLCompiler):
       
    66     pass