diff -r 9a50539f01d1 -r e623afd49356 rqlrewrite.py --- a/rqlrewrite.py Mon Mar 15 18:06:32 2010 +0100 +++ b/rqlrewrite.py Mon Mar 15 18:07:54 2010 +0100 @@ -304,21 +304,33 @@ """introduce the given snippet in a subquery""" subselect = stmts.Select() selectvar = varmap[0] - subselect.append_selected(n.VariableRef( - subselect.get_variable(selectvar))) + subselectvar = subselect.get_variable(selectvar) + subselect.append_selected(n.VariableRef(subselectvar)) + snippetrqlst = n.Exists(transformedsnippet.copy(subselect)) aliases = [selectvar] - subselect.add_restriction(transformedsnippet.copy(subselect)) stinfo = self.varinfo['stinfo'] + need_null_test = False for rel in stinfo['relations']: rschema = self.schema.rschema(rel.r_type) if rschema.final or (rschema.inlined and - not rel in stinfo['rhsrelations']): - self.select.remove_node(rel) - rel.children[0].name = selectvar + not rel in stinfo['rhsrelations']): + rel.children[0].name = selectvar # XXX explain why subselect.add_restriction(rel.copy(subselect)) for vref in rel.children[1].iget_nodes(n.VariableRef): subselect.append_selected(vref.copy(subselect)) aliases.append(vref.name) + self.select.remove_node(rel) + # when some inlined relation has to be copied in the subquery, + # we need to test that either value is NULL or that the snippet + # condition is satisfied + if rschema.inlined and rel.optional: + need_null_test = True + if need_null_test: + snippetrqlst = n.Or( + n.make_relation(subselectvar, 'is', (None, None), n.Constant, + operator='IS'), + snippetrqlst) + subselect.add_restriction(snippetrqlst) if self.u_varname: # generate an identifier for the substitution argname = subselect.allocate_varname()