示例#1
0
 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)
示例#2
0
 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)
示例#3
0
    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')
示例#4
0
 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'))
示例#5
0
 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'))
示例#6
0
 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'))
示例#7
0
 def visit_constant(self, node):
     """generate filter name for a constant"""
     return n.Constant(node.value, node.type)
示例#8
0
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
示例#9
0
 def test_methods_3(self):
     tree = parse(
         'Set X nom "yo" WHERE X is Person',
         {'Person': nodes.Constant('Person', 'etype')},
     )
     self.visitor.visit(tree)