Search in sources :

Example 36 with SpecialFormExpression

use of com.facebook.presto.spi.relation.SpecialFormExpression in project urban-eureka by errir503.

the class RewriteAggregationIfToFilter method shouldRewriteAggregation.

private boolean shouldRewriteAggregation(Aggregation aggregation, ProjectNode sourceProject) {
    if (functionAndTypeManager.getFunctionMetadata(aggregation.getFunctionHandle()).isCalledOnNullInput()) {
        // This rewrite will filter out the null values. It could change the behavior if the aggregation is also applied on NULLs.
        return false;
    }
    if (!(aggregation.getArguments().size() == 1 && aggregation.getArguments().get(0) instanceof VariableReferenceExpression)) {
        // Currently we only handle aggregation with a single VariableReferenceExpression. The detailed expressions are in a project node below this aggregation.
        return false;
    }
    if (aggregation.getFilter().isPresent() || aggregation.getMask().isPresent()) {
        // Do not rewrite the aggregation if it already has a filter or mask.
        return false;
    }
    RowExpression sourceExpression = sourceProject.getAssignments().get((VariableReferenceExpression) aggregation.getArguments().get(0));
    if (sourceExpression instanceof CallExpression) {
        CallExpression callExpression = (CallExpression) sourceExpression;
        if (callExpression.getArguments().size() == 1 && standardFunctionResolution.isCastFunction(callExpression.getFunctionHandle())) {
            // If the expression is CAST(), check the expression inside.
            sourceExpression = callExpression.getArguments().get(0);
        }
    }
    if (!(sourceExpression instanceof SpecialFormExpression) || !rowExpressionDeterminismEvaluator.isDeterministic(sourceExpression)) {
        return false;
    }
    SpecialFormExpression expression = (SpecialFormExpression) sourceExpression;
    // Only rewrite the aggregation if the else branch is not present or the else result is NULL.
    return expression.getForm() == IF && Expressions.isNull(expression.getArguments().get(2));
}
Also used : VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) CallExpression(com.facebook.presto.spi.relation.CallExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression)

Example 37 with SpecialFormExpression

use of com.facebook.presto.spi.relation.SpecialFormExpression in project urban-eureka by errir503.

the class LogicalRowExpressions method binaryExpression.

public static RowExpression binaryExpression(Form form, Collection<? extends RowExpression> expressions) {
    requireNonNull(form, "operator is null");
    requireNonNull(expressions, "expressions is null");
    if (expressions.isEmpty()) {
        switch(form) {
            case AND:
                return TRUE_CONSTANT;
            case OR:
                return FALSE_CONSTANT;
            default:
                throw new IllegalArgumentException("Unsupported binary expression operator");
        }
    }
    // Build balanced tree for efficient recursive processing that
    // preserves the evaluation order of the input expressions.
    // 
    // The tree is built bottom up by combining pairs of elements into
    // binary AND expressions.
    // 
    // Example:
    // 
    // Initial state:
    // a b c d e
    // 
    // First iteration:
    // 
    // /\    /\   e
    // a  b  c  d
    // 
    // Second iteration:
    // 
    // / \    e
    // /\   /\
    // a  b c  d
    // 
    // 
    // Last iteration:
    // 
    // / \
    // / \  e
    // /\   /\
    // a  b c  d
    Queue<RowExpression> queue = new ArrayDeque<>(expressions);
    while (queue.size() > 1) {
        Queue<RowExpression> buffer = new ArrayDeque<>();
        // combine pairs of elements
        while (queue.size() >= 2) {
            List<RowExpression> arguments = asList(queue.remove(), queue.remove());
            buffer.add(new SpecialFormExpression(form, BOOLEAN, arguments));
        }
        // if there's and odd number of elements, just append the last one
        if (!queue.isEmpty()) {
            buffer.add(queue.remove());
        }
        // continue processing the pairs that were just built
        queue = buffer;
    }
    return queue.remove();
}
Also used : RowExpression(com.facebook.presto.spi.relation.RowExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) ArrayDeque(java.util.ArrayDeque)

Example 38 with SpecialFormExpression

use of com.facebook.presto.spi.relation.SpecialFormExpression in project urban-eureka by errir503.

the class SubfieldExtractor method toRowExpression.

private RowExpression toRowExpression(Subfield subfield, List<Type> types) {
    List<Subfield.PathElement> path = subfield.getPath();
    if (path.isEmpty()) {
        return new VariableReferenceExpression(Optional.empty(), subfield.getRootName(), types.get(0));
    }
    RowExpression base = toRowExpression(new Subfield(subfield.getRootName(), path.subList(0, path.size() - 1)), types.subList(0, types.size() - 1));
    Type baseType = types.get(types.size() - 2);
    Subfield.PathElement pathElement = path.get(path.size() - 1);
    if (pathElement instanceof Subfield.LongSubscript) {
        Type indexType = baseType instanceof MapType ? ((MapType) baseType).getKeyType() : BIGINT;
        FunctionHandle functionHandle = functionResolution.subscriptFunction(baseType, indexType);
        ConstantExpression index = new ConstantExpression(base.getSourceLocation(), ((Subfield.LongSubscript) pathElement).getIndex(), indexType);
        return new CallExpression(base.getSourceLocation(), SUBSCRIPT.name(), functionHandle, types.get(types.size() - 1), ImmutableList.of(base, index));
    }
    if (pathElement instanceof Subfield.StringSubscript) {
        Type indexType = ((MapType) baseType).getKeyType();
        FunctionHandle functionHandle = functionResolution.subscriptFunction(baseType, indexType);
        ConstantExpression index = new ConstantExpression(base.getSourceLocation(), Slices.utf8Slice(((Subfield.StringSubscript) pathElement).getIndex()), indexType);
        return new CallExpression(base.getSourceLocation(), SUBSCRIPT.name(), functionHandle, types.get(types.size() - 1), ImmutableList.of(base, index));
    }
    if (pathElement instanceof Subfield.NestedField) {
        Subfield.NestedField nestedField = (Subfield.NestedField) pathElement;
        return new SpecialFormExpression(base.getSourceLocation(), DEREFERENCE, types.get(types.size() - 1), base, new ConstantExpression(base.getSourceLocation(), getFieldIndex((RowType) baseType, nestedField.getName()), INTEGER));
    }
    verify(false, "Unexpected path element: " + pathElement);
    return null;
}
Also used : ConstantExpression(com.facebook.presto.spi.relation.ConstantExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) MapType(com.facebook.presto.common.type.MapType) MapType(com.facebook.presto.common.type.MapType) Varchars.isVarcharType(com.facebook.presto.common.type.Varchars.isVarcharType) ArrayType(com.facebook.presto.common.type.ArrayType) Type(com.facebook.presto.common.type.Type) RowType(com.facebook.presto.common.type.RowType) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) CallExpression(com.facebook.presto.spi.relation.CallExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) Subfield(com.facebook.presto.common.Subfield)

Example 39 with SpecialFormExpression

use of com.facebook.presto.spi.relation.SpecialFormExpression in project urban-eureka by errir503.

the class SubfieldExtractor method toSubfield.

private static Optional<Subfield> toSubfield(RowExpression expression, StandardFunctionResolution functionResolution, ExpressionOptimizer expressionOptimizer, ConnectorSession connectorSession) {
    List<Subfield.PathElement> elements = new ArrayList<>();
    while (true) {
        if (expression instanceof VariableReferenceExpression) {
            Collections.reverse(elements);
            return Optional.of(new Subfield(((VariableReferenceExpression) expression).getName(), unmodifiableList(elements)));
        }
        if (expression instanceof SpecialFormExpression && ((SpecialFormExpression) expression).getForm() == DEREFERENCE) {
            SpecialFormExpression dereferenceExpression = (SpecialFormExpression) expression;
            RowExpression base = dereferenceExpression.getArguments().get(0);
            RowType baseType = (RowType) base.getType();
            RowExpression indexExpression = expressionOptimizer.optimize(dereferenceExpression.getArguments().get(1), ExpressionOptimizer.Level.OPTIMIZED, connectorSession);
            if (indexExpression instanceof ConstantExpression) {
                Object index = ((ConstantExpression) indexExpression).getValue();
                if (index instanceof Number) {
                    Optional<String> fieldName = baseType.getFields().get(((Number) index).intValue()).getName();
                    if (fieldName.isPresent()) {
                        elements.add(new Subfield.NestedField(fieldName.get()));
                        expression = base;
                        continue;
                    }
                }
            }
            return Optional.empty();
        }
        if (expression instanceof CallExpression && functionResolution.isSubscriptFunction(((CallExpression) expression).getFunctionHandle())) {
            List<RowExpression> arguments = ((CallExpression) expression).getArguments();
            RowExpression indexExpression = expressionOptimizer.optimize(arguments.get(1), ExpressionOptimizer.Level.OPTIMIZED, connectorSession);
            if (indexExpression instanceof ConstantExpression) {
                Object index = ((ConstantExpression) indexExpression).getValue();
                if (index instanceof Number) {
                    elements.add(new Subfield.LongSubscript(((Number) index).longValue()));
                    expression = arguments.get(0);
                    continue;
                }
                if (isVarcharType(indexExpression.getType())) {
                    elements.add(new Subfield.StringSubscript(((Slice) index).toStringUtf8()));
                    expression = arguments.get(0);
                    continue;
                }
            }
            return Optional.empty();
        }
        return Optional.empty();
    }
}
Also used : ConstantExpression(com.facebook.presto.spi.relation.ConstantExpression) ArrayList(java.util.ArrayList) RowExpression(com.facebook.presto.spi.relation.RowExpression) RowType(com.facebook.presto.common.type.RowType) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Slice(io.airlift.slice.Slice) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) CallExpression(com.facebook.presto.spi.relation.CallExpression) Subfield(com.facebook.presto.common.Subfield)

Example 40 with SpecialFormExpression

use of com.facebook.presto.spi.relation.SpecialFormExpression in project urban-eureka by errir503.

the class Partitioning method translateToCoalesce.

// Maps VariableReferenceExpression in both partitions to an COALESCE expression, keeps constant arguments unchanged.
public Optional<Partitioning> translateToCoalesce(Partitioning other, Metadata metadata, Session session) {
    checkArgument(arePartitionHandlesCompatibleForCoalesce(this.handle, other.handle, metadata, session), "incompatible partitioning handles: cannot coalesce %s and %s", this.handle, other.handle);
    checkArgument(this.arguments.size() == other.arguments.size(), "incompatible number of partitioning arguments: %s != %s", this.arguments.size(), other.arguments.size());
    ImmutableList.Builder<RowExpression> arguments = ImmutableList.builder();
    for (int i = 0; i < this.arguments.size(); i++) {
        RowExpression leftArgument = this.arguments.get(i);
        RowExpression rightArgument = other.arguments.get(i);
        if (leftArgument instanceof ConstantExpression) {
            arguments.add(leftArgument);
        } else if (rightArgument instanceof ConstantExpression) {
            arguments.add(rightArgument);
        } else if (leftArgument instanceof VariableReferenceExpression && rightArgument instanceof VariableReferenceExpression) {
            VariableReferenceExpression leftVariable = (VariableReferenceExpression) leftArgument;
            VariableReferenceExpression rightVariable = (VariableReferenceExpression) rightArgument;
            checkArgument(leftVariable.getType().equals(rightVariable.getType()), "incompatible types: %s != %s", leftVariable.getType(), rightVariable.getType());
            arguments.add(new SpecialFormExpression(COALESCE, leftVariable.getType(), ImmutableList.of(leftVariable, rightVariable)));
        } else {
            return Optional.empty();
        }
    }
    return Optional.of(new Partitioning(metadata.isRefinedPartitioningOver(session, other.handle, this.handle) ? this.handle : other.handle, arguments.build()));
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ConstantExpression(com.facebook.presto.spi.relation.ConstantExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression)

Aggregations

SpecialFormExpression (com.facebook.presto.spi.relation.SpecialFormExpression)46 RowExpression (com.facebook.presto.spi.relation.RowExpression)38 ConstantExpression (com.facebook.presto.spi.relation.ConstantExpression)18 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)18 CallExpression (com.facebook.presto.spi.relation.CallExpression)16 ImmutableList (com.google.common.collect.ImmutableList)14 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)12 Test (org.testng.annotations.Test)12 Variable (com.facebook.presto.bytecode.Variable)10 Type (com.facebook.presto.common.type.Type)10 IfStatement (com.facebook.presto.bytecode.control.IfStatement)8 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)8 Page (com.facebook.presto.common.Page)8 RowType (com.facebook.presto.common.type.RowType)8 Scope (com.facebook.presto.bytecode.Scope)6 Subfield (com.facebook.presto.common.Subfield)6 ArrayDeque (java.util.ArrayDeque)6 ArrayList (java.util.ArrayList)6 Map (java.util.Map)6 LambdaDefinitionExpression (com.facebook.presto.spi.relation.LambdaDefinitionExpression)5