def convert_subquery_clause(clause): """Given a clause, if it is a VarsMember clause for an incrementalized subquery, return an equivalent RelMember clause. For any other clause return the clause unchanged. The two forms recognized are: - right-hand side is a Name node - right-hand side is an ImgLookup node on a Name, with a keymask """ if not isinstance(clause, L.VarsMember): return clause if isinstance(clause.iter, L.Name): return L.RelMember(clause.vars, clause.iter.id) elif (isinstance(clause.iter, L.ImgLookup) and isinstance(clause.iter.set, L.Name) and L.is_keymask(clause.iter.mask)): nb, nu = L.break_keymask(clause.iter.mask) assert nb == len(clause.iter.bounds) assert nu == len(clause.vars) return L.RelMember(clause.iter.bounds + clause.vars, clause.iter.set.id) return clause
def rewrite_with_demand(self, query_sym, node): """Given a query symbol and its associated Comp or Aggr node, return the demand-transformed version of that node (not transforming any subqueries). """ symtab = self.symtab demand_params = query_sym.demand_params if not query_sym.uses_demand: return node # Make a demand set or demand query. left_clauses = self.get_left_clauses() if left_clauses is None: dem_sym = make_demand_set(symtab, query_sym) dem_node = L.Name(dem_sym.name) dem_clause = L.RelMember(demand_params, dem_sym.name) self.queries_with_usets.add(query_sym.name) else: dem_sym = make_demand_query(symtab, query_sym, left_clauses) dem_node = dem_sym.make_node() dem_clause = L.VarsMember(demand_params, dem_node) self.demand_queries.add(dem_sym.name) # Determine the rewritten node. if isinstance(node, L.Comp): node = node._replace(clauses=(dem_clause, ) + node.clauses) elif isinstance(node, L.Aggr): node = L.AggrRestr(node.op, node.value, demand_params, dem_node) else: raise AssertionError( 'No rule for handling demand for {} node'.format( node.__class__.__name__)) return node
def visit_Member(self, node): node = self.generic_visit(node) if (isinstance(node.iter, L.Name) and node.iter.id in self.rels and L.is_tuple_of_names(node.target)): return L.RelMember(L.detuplify(node.target), node.iter.id) return node
def process(expr): if not (isinstance(expr, L.Member) and isinstance(expr.iter, L.Name) and expr.iter.id in symtab.get_relations()): return expr, [], [] target = expr.target rel = expr.iter.id if L.is_tuple_of_names(target): cl = L.RelMember(L.detuplify(target), rel) elif isinstance(target, L.Name): cl = L.VarsMember([target.id], L.Wrap(L.Name(rel))) else: raise L.ProgramError('Invalid clause over relation') return cl, [], []
def make_comp(self, struct): """Return the Comp node corresponding to a structure.""" ct = self.symtab.clausetools resname = N.get_resultset_name if isinstance(struct, Filter): filter = struct vars = ct.lhs_vars(filter.clause) pred_clauses = [] for t in filter.preds: tag = self.tags_by_name[t] pred_cl = L.RelMember([tag.tag_var], resname(tag.name)) pred_clauses.append(pred_cl) return L.Comp(L.tuplify(vars), pred_clauses + [filter.clause]) elif isinstance(struct, Tag): tag = struct return L.Comp(L.tuplify([tag.tag_var]), [tag.clause]) else: assert ()
def rename_rhs_rel(self, cl, renamer): # Implementation shared by object-clause subclasses. new_rel = renamer(self.rhs_rel(cl)) return L.RelMember(self.lhs_vars(cl), new_rel)