|
29
|
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 |