def test_undo_node_having(self): qs = u'Any X WHERE X name N' tree = sparse(qs) select = tree.children[0] select.save_state() namevar = select.where.relation().children[-1].children[-1].variable comp = nodes.Comparison('>') maxf = nodes.Function('MAX') maxf.append(nodes.VariableRef(namevar)) comp.append(maxf) comp.append(nodes.Constant(1, 'Int')) select.set_having([comp]) select.recover() self.assertEqual(select.as_string(), qs)
def visit_variableref(self, node): """get the sql name for a variable reference""" stmt = self.current_statement() if node.name in self.revvarmap: selectvar, index = self.revvarmap[node.name] vi = self.varinfos[index] if vi.get('const') is not None: return n.Constant(vi['const'], 'Int') return n.VariableRef(stmt.get_variable(selectvar)) vname_or_term = self._get_varname_or_term(node.name) if isinstance(vname_or_term, str): return n.VariableRef(stmt.get_variable(vname_or_term)) # shared term return vname_or_term.copy(stmt)
def get_etype(self, name): """return the type object for the given entity's type name raise BadRQLQuery on unknown type """ return nodes.Constant(name, 'etype')
def test_replace_node_having(self): tree = sparse(u'Any X WHERE X name "toto tata" HAVING MAX(X) > 1') select = tree.children[0] funcnode = sparse(u'Any X HAVING MAX(X) > 1').children[0].having[0] select.replace(funcnode, nodes.Constant(1.0, 'Float'))
def test_replace_node_groupby(self): tree = sparse(u'Any X GROUPBY X, MAX(X) WHERE X name "toto tata"') select = tree.children[0] funcnode = sparse(u'Any MAX(X)').children[0].selection[0] select.replace(funcnode, nodes.Constant(1.0, 'Float'))
def test_replace_node_orderby(self): tree = sparse(u'Any X ORDERBY MAX(X) WHERE X name "toto tata"') select = tree.children[0] funcnode = sparse(u'Any X ORDERBY MAX(X)').children[0].orderby[0] select.replace(funcnode, nodes.Constant(1.0, 'Float'))
def visit_constant(self, node): """generate filter name for a constant""" return n.Constant(node.value, node.type)
def add_types_restriction(schema, rqlst, newroot=None, solutions=None): if newroot is None: assert solutions is None if hasattr(rqlst, '_types_restr_added'): return solutions = rqlst.solutions newroot = rqlst rqlst._types_restr_added = True else: assert solutions is not None rqlst = rqlst.stmt eschema = schema.eschema allpossibletypes = {} for solution in solutions: for varname, etype in solution.items(): # XXX not considering aliases by design, right ? if varname not in newroot.defined_vars or eschema(etype).final: continue allpossibletypes.setdefault(varname, set()).add(etype) # XXX could be factorized with add_etypes_restriction from rql 0.31 for varname in sorted(allpossibletypes): var = newroot.defined_vars[varname] stinfo = var.stinfo if stinfo.get('uidrel') is not None: continue # eid specified, no need for additional type specification try: typerel = rqlst.defined_vars[varname].stinfo.get('typerel') except KeyError: assert varname in rqlst.aliases continue if newroot is rqlst and typerel is not None: mytyperel = typerel else: for vref in var.references(): rel = vref.relation() if rel and rel.is_types_restriction(): mytyperel = rel break else: mytyperel = None possibletypes = allpossibletypes[varname] if mytyperel is not None: if mytyperel.r_type == 'is_instance_of': # turn is_instance_of relation into a is relation since we've # all possible solutions and don't want to bother with # potential is_instance_of incompatibility mytyperel.r_type = 'is' if len(possibletypes) > 1: node = n.Function('IN') for etype in sorted(possibletypes): node.append(n.Constant(etype, 'etype')) else: etype = next(iter(possibletypes)) node = n.Constant(etype, 'etype') comp = mytyperel.children[1] comp.replace(comp.children[0], node) else: # variable has already some strict types restriction. new # possible types can only be a subset of existing ones, so only # remove no more possible types for cst in mytyperel.get_nodes(n.Constant): if cst.value not in possibletypes: cst.parent.remove(cst) else: # we have to add types restriction if stinfo.get('scope') is not None: rel = var.scope.add_type_restriction(var, possibletypes) else: # tree is not annotated yet, no scope set so add the restriction # to the root rel = newroot.add_type_restriction(var, possibletypes) stinfo['typerel'] = rel stinfo['possibletypes'] = possibletypes
def test_methods_3(self): tree = parse( 'Set X nom "yo" WHERE X is Person', {'Person': nodes.Constant('Person', 'etype')}, ) self.visitor.visit(tree)