18 for subquery in rqlst.with_: |
18 for subquery in rqlst.with_: |
19 annotator._annotate_union(subquery.query) |
19 annotator._annotate_union(subquery.query) |
20 #if server.DEBUG: |
20 #if server.DEBUG: |
21 # print '-------- sql annotate', repr(rqlst) |
21 # print '-------- sql annotate', repr(rqlst) |
22 getrschema = annotator.schema.rschema |
22 getrschema = annotator.schema.rschema |
23 has_text_query = need_intersect = False |
23 has_text_query = False |
24 need_distinct = rqlst.distinct |
24 need_distinct = rqlst.distinct |
25 for rel in rqlst.iget_nodes(Relation): |
25 for rel in rqlst.iget_nodes(Relation): |
26 if rel.neged(strict=True): |
26 if rel.neged(strict=True): |
27 if rel.is_types_restriction(): |
27 if rel.is_types_restriction(): |
28 need_distinct = True |
28 need_distinct = True |
29 else: |
29 else: |
30 rschema = getrschema(rel.r_type) |
30 rschema = getrschema(rel.r_type) |
31 if not rschema.is_final(): |
31 if not rschema.is_final(): |
32 # if one of the relation's variable is ambiguous, an intersection |
|
33 # will be necessary |
|
34 for vref in rel.get_nodes(VariableRef): |
|
35 var = vref.variable |
|
36 if not var.stinfo['selected'] and len(var.stinfo['possibletypes']) > 1: |
|
37 need_intersect = True |
|
38 break |
|
39 if rschema.inlined: |
32 if rschema.inlined: |
40 try: |
33 try: |
41 var = rel.children[1].children[0].variable |
34 var = rel.children[1].children[0].variable |
42 except AttributeError: |
35 except AttributeError: |
43 pass # rewritten variable |
36 pass # rewritten variable |
145 try: |
138 try: |
146 stinfo['principal'] = _select_principal(var.sqlscope, joins) |
139 stinfo['principal'] = _select_principal(var.sqlscope, joins) |
147 except CantSelectPrincipal: |
140 except CantSelectPrincipal: |
148 stinfo['invariant'] = False |
141 stinfo['invariant'] = False |
149 rqlst.need_distinct = need_distinct |
142 rqlst.need_distinct = need_distinct |
150 rqlst.need_intersect = need_intersect |
|
151 return has_text_query |
143 return has_text_query |
152 |
144 |
153 |
145 |
154 |
146 |
155 class CantSelectPrincipal(Exception): pass |
147 class CantSelectPrincipal(Exception): pass |
205 return rel |
197 return rel |
206 principal = rel |
198 principal = rel |
207 return principal |
199 return principal |
208 |
200 |
209 |
201 |
210 def set_qdata(union, noinvariant): |
202 def set_qdata(getrschema, union, noinvariant): |
211 """recursive function to set querier data on variables in the syntax tree |
203 """recursive function to set querier data on variables in the syntax tree |
212 """ |
204 """ |
213 for select in union.children: |
205 for select in union.children: |
214 for subquery in select.with_: |
206 for subquery in select.with_: |
215 set_qdata(subquery.query, noinvariant) |
207 set_qdata(getrschema, subquery.query, noinvariant) |
216 for var in select.defined_vars.itervalues(): |
208 for var in select.defined_vars.itervalues(): |
217 if var.stinfo['invariant']: |
209 if var.stinfo['invariant']: |
218 if var in noinvariant and not var.stinfo['principal'].r_type == 'has_text': |
210 if var in noinvariant and not var.stinfo['principal'].r_type == 'has_text': |
219 var._q_invariant = False |
211 var._q_invariant = False |
220 else: |
212 else: |
221 var._q_invariant = True |
213 var._q_invariant = True |
222 else: |
214 else: |
223 var._q_invariant = False |
215 var._q_invariant = False |
|
216 for rel in select.iget_nodes(Relation): |
|
217 if rel.neged(strict=True) and not rel.is_types_restriction(): |
|
218 rschema = getrschema(rel.r_type) |
|
219 if not rschema.is_final(): |
|
220 # if one of the relation's variable is ambiguous but not |
|
221 # invariant, an intersection will be necessary |
|
222 for vref in rel.get_nodes(VariableRef): |
|
223 var = vref.variable |
|
224 if (not var._q_invariant and var.valuable_references() == 1 |
|
225 and len(var.stinfo['possibletypes']) > 1): |
|
226 select.need_intersect = True |
|
227 break |
|
228 else: |
|
229 continue |
|
230 break |
|
231 else: |
|
232 select.need_intersect = False |
224 |
233 |
225 |
234 |
226 class SQLGenAnnotator(object): |
235 class SQLGenAnnotator(object): |
227 def __init__(self, schema): |
236 def __init__(self, schema): |
228 self.schema = schema |
237 self.schema = schema |