def is_innermost_aggregate(cls, expr): """Return True if the given expression is an innermost aggregate. Only arguments to innermost aggregates actually have access to fields from the original table expression, so we need to detect this case specifically. You might think that repeatedly calling this function while traversing the tree takes quadratic time in the size of the tree, but it actually only takes linear time overall. There's a nice proof of this fact, which this docstring is to small to contain. """ return (isinstance(expr, tq_ast.FunctionCall) and runtime.is_aggregate_func(expr.name) and not any(cls.expression_contains_aggregate(sub_expr) for sub_expr in expr.args))
def is_innermost_aggregate(cls, expr): """Return True if the given expression is an innermost aggregate. Only arguments to innermost aggregates actually have access to fields from the original table expression, so we need to detect this case specifically. You might think that repeatedly calling this function while traversing the tree takes quadratic time in the size of the tree, but it actually only takes linear time overall. There's a nice proof of this fact, which this docstring is to small to contain. """ return (isinstance(expr, tq_ast.FunctionCall) and runtime.is_aggregate_func(expr.name) and not any( cls.expression_contains_aggregate(sub_expr) for sub_expr in expr.args))
def expression_contains_aggregate(cls, expr): """Given a tq_ast expression, check if it does any aggregation. We need to operate on an uncompiled AST here since we use this information to figure out how to compile these expressions. """ if isinstance(expr, tq_ast.UnaryOperator): return cls.expression_contains_aggregate(expr.expr) elif isinstance(expr, tq_ast.BinaryOperator): return (cls.expression_contains_aggregate(expr.left) or cls.expression_contains_aggregate(expr.right)) elif isinstance(expr, tq_ast.FunctionCall): return (runtime.is_aggregate_func(expr.name) or any( cls.expression_contains_aggregate(arg) for arg in expr.args)) elif isinstance(expr, tq_ast.Literal): return False elif isinstance(expr, tq_ast.ColumnId): return False else: assert False, 'Unexpected expression type: %s' % ( expr.__class__.__name__)
def expression_contains_aggregate(cls, expr): """Given a tq_ast expression, check if it does any aggregation. We need to operate on an uncompiled AST here since we use this information to figure out how to compile these expressions. """ if isinstance(expr, tq_ast.UnaryOperator): return cls.expression_contains_aggregate(expr.expr) elif isinstance(expr, tq_ast.BinaryOperator): return (cls.expression_contains_aggregate(expr.left) or cls.expression_contains_aggregate(expr.right)) elif isinstance(expr, tq_ast.FunctionCall): return (runtime.is_aggregate_func(expr.name) or any(cls.expression_contains_aggregate(arg) for arg in expr.args)) elif isinstance(expr, tq_ast.Literal): return False elif isinstance(expr, tq_ast.ColumnId): return False else: assert False, 'Unexpected expression type: %s' % ( expr.__class__.__name__)