use of com.facebook.presto.spi.relation.RowExpression in project presto by prestodb.
the class LogicalRowExpressions method removeDuplicates.
/**
* Removes duplicate deterministic expressions. Preserves the relative order
* of the expressions in the list.
*/
private List<RowExpression> removeDuplicates(List<RowExpression> expressions) {
Set<RowExpression> seen = new HashSet<>();
List<RowExpression> result = new ArrayList<>();
for (RowExpression expression : expressions) {
if (determinismEvaluator.isDeterministic(expression)) {
if (!seen.contains(expression)) {
result.add(expression);
seen.add(expression);
}
} else {
result.add(expression);
}
}
return unmodifiableList(result);
}
use of com.facebook.presto.spi.relation.RowExpression in project presto by prestodb.
the class LogicalRowExpressions method minimalNormalForm.
public RowExpression minimalNormalForm(RowExpression expression) {
RowExpression conjunctiveNormalForm = convertToConjunctiveNormalForm(expression);
RowExpression disjunctiveNormalForm = convertToDisjunctiveNormalForm(expression);
return numOfClauses(conjunctiveNormalForm) > numOfClauses(disjunctiveNormalForm) ? disjunctiveNormalForm : conjunctiveNormalForm;
}
use of com.facebook.presto.spi.relation.RowExpression in project presto by prestodb.
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();
}
use of com.facebook.presto.spi.relation.RowExpression in project presto by prestodb.
the class DynamicFilters method extractDynamicFilters.
public static DynamicFilterExtractResult extractDynamicFilters(RowExpression expression) {
List<RowExpression> conjuncts = extractConjuncts(expression);
ImmutableList.Builder<RowExpression> staticConjuncts = ImmutableList.builder();
ImmutableList.Builder<DynamicFilterPlaceholder> dynamicConjuncts = ImmutableList.builder();
for (RowExpression conjunct : conjuncts) {
Optional<DynamicFilterPlaceholder> placeholder = getPlaceholder(conjunct);
if (placeholder.isPresent()) {
dynamicConjuncts.add(placeholder.get());
} else {
staticConjuncts.add(conjunct);
}
}
return new DynamicFilterExtractResult(staticConjuncts.build(), dynamicConjuncts.build());
}
use of com.facebook.presto.spi.relation.RowExpression in project presto by prestodb.
the class ExtractSpatialJoins method tryCreateSpatialJoin.
private static Result tryCreateSpatialJoin(Context context, JoinNode joinNode, RowExpression filter, PlanNodeId nodeId, List<VariableReferenceExpression> outputVariables, CallExpression spatialComparison, Metadata metadata, SplitManager splitManager, PageSourceManager pageSourceManager) {
FunctionMetadata spatialComparisonMetadata = metadata.getFunctionAndTypeManager().getFunctionMetadata(spatialComparison.getFunctionHandle());
checkArgument(spatialComparison.getArguments().size() == 2 && spatialComparisonMetadata.getOperatorType().isPresent());
PlanNode leftNode = joinNode.getLeft();
PlanNode rightNode = joinNode.getRight();
List<VariableReferenceExpression> leftVariables = leftNode.getOutputVariables();
List<VariableReferenceExpression> rightVariables = rightNode.getOutputVariables();
RowExpression radius;
Optional<VariableReferenceExpression> newRadiusVariable;
CallExpression newComparison;
if (spatialComparisonMetadata.getOperatorType().get() == OperatorType.LESS_THAN || spatialComparisonMetadata.getOperatorType().get() == OperatorType.LESS_THAN_OR_EQUAL) {
// ST_Distance(a, b) <= r
radius = spatialComparison.getArguments().get(1);
Set<VariableReferenceExpression> radiusVariables = extractUnique(radius);
if (radiusVariables.isEmpty() || (rightVariables.containsAll(radiusVariables) && containsNone(leftVariables, radiusVariables))) {
newRadiusVariable = newRadiusVariable(context, radius);
newComparison = new CallExpression(spatialComparison.getSourceLocation(), spatialComparison.getDisplayName(), spatialComparison.getFunctionHandle(), spatialComparison.getType(), ImmutableList.of(spatialComparison.getArguments().get(0), mapToExpression(newRadiusVariable, radius)));
} else {
return Result.empty();
}
} else {
// r >= ST_Distance(a, b)
radius = spatialComparison.getArguments().get(0);
Set<VariableReferenceExpression> radiusVariables = extractUnique(radius);
if (radiusVariables.isEmpty() || (rightVariables.containsAll(radiusVariables) && containsNone(leftVariables, radiusVariables))) {
newRadiusVariable = newRadiusVariable(context, radius);
OperatorType flippedOperatorType = flip(spatialComparisonMetadata.getOperatorType().get());
FunctionHandle flippedHandle = getFlippedFunctionHandle(spatialComparison, metadata.getFunctionAndTypeManager());
newComparison = new CallExpression(spatialComparison.getSourceLocation(), // TODO verify if this is the correct function displayName
flippedOperatorType.getOperator(), flippedHandle, spatialComparison.getType(), ImmutableList.of(spatialComparison.getArguments().get(1), mapToExpression(newRadiusVariable, radius)));
} else {
return Result.empty();
}
}
RowExpression newFilter = replaceExpression(filter, ImmutableMap.of(spatialComparison, newComparison));
PlanNode newRightNode = newRadiusVariable.map(variable -> addProjection(context, rightNode, variable, radius)).orElse(rightNode);
JoinNode newJoinNode = new JoinNode(joinNode.getSourceLocation(), joinNode.getId(), joinNode.getType(), leftNode, newRightNode, joinNode.getCriteria(), joinNode.getOutputVariables(), Optional.of(newFilter), joinNode.getLeftHashVariable(), joinNode.getRightHashVariable(), joinNode.getDistributionType(), joinNode.getDynamicFilters());
return tryCreateSpatialJoin(context, newJoinNode, newFilter, nodeId, outputVariables, (CallExpression) newComparison.getArguments().get(0), Optional.of(newComparison.getArguments().get(1)), metadata, splitManager, pageSourceManager);
}
Aggregations