def __init__(self, table, metrics, by, having, predicates, sort_keys): from ibis.expr.analysis import shares_all_roots, shares_some_roots # All non-scalar refs originate from the input table if not shares_all_roots(metrics + by + having + sort_keys, table): raise com.RelationError( "Selection expressions don't fully originate from " "dependencies of the table expression.") # invariant due to Aggregation and AggregateSelection requiring a valid # Selection assert all( shares_some_roots(predicate, table) for predicate in predicates) if not by: sort_keys = tuple() super().__init__( table=table, metrics=metrics, by=by, having=having, predicates=predicates, sort_keys=sort_keys, ) # Validate schema has no overlapping columns assert self.schema
def is_foreign_expr(self, expr): from ibis.expr.analysis import shares_all_roots # The expression isn't foreign to us. For example, the parent table set # in a correlated WHERE subquery if self.has_ref(expr, parent_contexts=True): return False parents = [self.query.table_set] + self.query.select_set return not shares_all_roots(expr, parents)
def _validate_join_predicates(left, right, predicates): from ibis.expr.analysis import shares_all_roots # Validate join predicates. Each predicate must be valid jointly when # considering the roots of each input table for predicate in predicates: if not shares_all_roots(predicate, [left, right]): raise com.RelationError('The expression {!r} does not fully ' 'originate from dependencies of the table ' 'expression.'.format(predicate))
def _pushdown_exprs(self, exprs): from ibis.expr.analysis import shares_all_roots, sub_for subbed_exprs = [] for expr in util.promote_list(exprs): expr = self.op.table._ensure_expr(expr) subbed = sub_for(expr, [(self.parent, self.op.table)]) subbed_exprs.append(subbed) if subbed_exprs: valid = shares_all_roots(subbed_exprs, self.op.table) else: valid = True return valid, subbed_exprs
def sort_by(self, expr, sort_exprs): from ibis.expr.analysis import shares_all_roots resolved_keys = _maybe_convert_sort_keys([self.table, expr], sort_exprs) if not self.blocks(): if shares_all_roots(resolved_keys, self.table): return Selection( self.table, self.selections, predicates=self.predicates, sort_keys=self.sort_keys + tuple(resolved_keys), ) return Selection(expr, [], sort_keys=resolved_keys)
def sort_by(self, expr, sort_exprs): from ibis.expr.analysis import shares_all_roots resolved_keys = _maybe_convert_sort_keys([self.table, expr], sort_exprs) if shares_all_roots(resolved_keys, self.table): return Aggregation( self.table, self.metrics, by=self.by, having=self.having, predicates=self.predicates, sort_keys=self.sort_keys + tuple(resolved_keys), ) return Selection(expr, [], sort_keys=resolved_keys)
def __init__(self, table, selections, predicates, sort_keys, **kwargs): from ibis.expr.analysis import shares_all_roots, shares_some_roots if not shares_all_roots(selections + sort_keys, table): raise com.RelationError( "Selection expressions don't fully originate from " "dependencies of the table expression.") for predicate in predicates: if not shares_some_roots(predicate, table): raise com.RelationError( "Predicate doesn't share any roots with table") super().__init__( table=table, selections=selections, predicates=predicates, sort_keys=sort_keys, **kwargs, ) # Validate no overlapping columns in schema assert self.schema