1 from django.core.exceptions import FieldError |
1 from django.core.exceptions import FieldError |
2 from django.db import connection |
|
3 from django.db.models.fields import FieldDoesNotExist |
2 from django.db.models.fields import FieldDoesNotExist |
4 from django.db.models.sql.constants import LOOKUP_SEP |
3 from django.db.models.sql.constants import LOOKUP_SEP |
5 |
4 |
6 class SQLEvaluator(object): |
5 class SQLEvaluator(object): |
7 def __init__(self, expression, query, allow_joins=True): |
6 def __init__(self, expression, query, allow_joins=True): |
10 self.cols = {} |
9 self.cols = {} |
11 |
10 |
12 self.contains_aggregate = False |
11 self.contains_aggregate = False |
13 self.expression.prepare(self, query, allow_joins) |
12 self.expression.prepare(self, query, allow_joins) |
14 |
13 |
15 def as_sql(self, qn=None): |
14 def prepare(self): |
16 return self.expression.evaluate(self, qn) |
15 return self |
|
16 |
|
17 def as_sql(self, qn, connection): |
|
18 return self.expression.evaluate(self, qn, connection) |
17 |
19 |
18 def relabel_aliases(self, change_map): |
20 def relabel_aliases(self, change_map): |
19 for node, col in self.cols.items(): |
21 for node, col in self.cols.items(): |
20 self.cols[node] = (change_map.get(col[0], col[0]), col[1]) |
22 self.cols[node] = (change_map.get(col[0], col[0]), col[1]) |
21 |
23 |
52 |
54 |
53 ################################################## |
55 ################################################## |
54 # Vistor methods for final expression evaluation # |
56 # Vistor methods for final expression evaluation # |
55 ################################################## |
57 ################################################## |
56 |
58 |
57 def evaluate_node(self, node, qn): |
59 def evaluate_node(self, node, qn, connection): |
58 if not qn: |
|
59 qn = connection.ops.quote_name |
|
60 |
|
61 expressions = [] |
60 expressions = [] |
62 expression_params = [] |
61 expression_params = [] |
63 for child in node.children: |
62 for child in node.children: |
64 if hasattr(child, 'evaluate'): |
63 if hasattr(child, 'evaluate'): |
65 sql, params = child.evaluate(self, qn) |
64 sql, params = child.evaluate(self, qn, connection) |
66 else: |
65 else: |
67 sql, params = '%s', (child,) |
66 sql, params = '%s', (child,) |
68 |
67 |
69 if len(getattr(child, 'children', [])) > 1: |
68 if len(getattr(child, 'children', [])) > 1: |
70 format = '(%s)' |
69 format = '(%s)' |
75 expressions.append(format % sql) |
74 expressions.append(format % sql) |
76 expression_params.extend(params) |
75 expression_params.extend(params) |
77 |
76 |
78 return connection.ops.combine_expression(node.connector, expressions), expression_params |
77 return connection.ops.combine_expression(node.connector, expressions), expression_params |
79 |
78 |
80 def evaluate_leaf(self, node, qn): |
79 def evaluate_leaf(self, node, qn, connection): |
81 if not qn: |
|
82 qn = connection.ops.quote_name |
|
83 |
|
84 col = self.cols[node] |
80 col = self.cols[node] |
85 if hasattr(col, 'as_sql'): |
81 if hasattr(col, 'as_sql'): |
86 return col.as_sql(qn), () |
82 return col.as_sql(qn, connection), () |
87 else: |
83 else: |
88 return '%s.%s' % (qn(col[0]), qn(col[1])), () |
84 return '%s.%s' % (qn(col[0]), qn(col[1])), () |