use of com.facebook.presto.spi.relation.RowExpression in project presto by prestodb.
the class EliminateCrossJoins method buildJoinTree.
public static PlanNode buildJoinTree(List<VariableReferenceExpression> expectedOutputVariables, JoinGraph graph, List<Integer> joinOrder, PlanNodeIdAllocator idAllocator) {
requireNonNull(expectedOutputVariables, "expectedOutputVariables is null");
requireNonNull(idAllocator, "idAllocator is null");
requireNonNull(graph, "graph is null");
joinOrder = ImmutableList.copyOf(requireNonNull(joinOrder, "joinOrder is null"));
checkArgument(joinOrder.size() >= 2);
PlanNode result = graph.getNode(joinOrder.get(0));
Set<PlanNodeId> alreadyJoinedNodes = new HashSet<>();
alreadyJoinedNodes.add(result.getId());
for (int i = 1; i < joinOrder.size(); i++) {
PlanNode rightNode = graph.getNode(joinOrder.get(i));
alreadyJoinedNodes.add(rightNode.getId());
ImmutableList.Builder<JoinNode.EquiJoinClause> criteria = ImmutableList.builder();
for (JoinGraph.Edge edge : graph.getEdges(rightNode)) {
PlanNode targetNode = edge.getTargetNode();
if (alreadyJoinedNodes.contains(targetNode.getId())) {
criteria.add(new JoinNode.EquiJoinClause(edge.getTargetVariable(), edge.getSourceVariable()));
}
}
result = new JoinNode(result.getSourceLocation(), idAllocator.getNextId(), JoinNode.Type.INNER, result, rightNode, criteria.build(), ImmutableList.<VariableReferenceExpression>builder().addAll(result.getOutputVariables()).addAll(rightNode.getOutputVariables()).build(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of());
}
List<RowExpression> filters = graph.getFilters();
for (RowExpression filter : filters) {
result = new FilterNode(result.getSourceLocation(), idAllocator.getNextId(), result, filter);
}
if (graph.getAssignments().isPresent()) {
result = new ProjectNode(idAllocator.getNextId(), result, Assignments.copyOf(graph.getAssignments().get()));
}
// Some nodes are sensitive to what's produced (e.g., DistinctLimit node)
return restrictOutputs(idAllocator, result, ImmutableSet.copyOf(expectedOutputVariables), true).orElse(result);
}
use of com.facebook.presto.spi.relation.RowExpression in project presto by prestodb.
the class ExtractSpatialJoins method addPartitioningNodes.
private static PlanNode addPartitioningNodes(Context context, FunctionAndTypeManager functionAndTypeManager, PlanNode node, VariableReferenceExpression partitionVariable, KdbTree kdbTree, RowExpression geometry, Optional<RowExpression> radius) {
Assignments.Builder projections = Assignments.builder();
for (VariableReferenceExpression outputVariable : node.getOutputVariables()) {
projections.put(outputVariable, outputVariable);
}
FunctionHandle castFunctionHandle = functionAndTypeManager.lookupCast(CAST, VARCHAR.getTypeSignature(), KDB_TREE.getTypeSignature());
ImmutableList.Builder partitioningArgumentsBuilder = ImmutableList.builder().add(new CallExpression(partitionVariable.getSourceLocation(), CAST.name(), castFunctionHandle, KDB_TREE, ImmutableList.of(Expressions.constant(utf8Slice(KdbTreeUtils.toJson(kdbTree)), VARCHAR)))).add(geometry);
radius.map(partitioningArgumentsBuilder::add);
List<RowExpression> partitioningArguments = partitioningArgumentsBuilder.build();
String spatialPartitionsFunctionName = "spatial_partitions";
FunctionHandle functionHandle = functionAndTypeManager.lookupFunction(spatialPartitionsFunctionName, fromTypes(partitioningArguments.stream().map(RowExpression::getType).collect(toImmutableList())));
CallExpression partitioningFunction = new CallExpression(partitionVariable.getSourceLocation(), spatialPartitionsFunctionName, functionHandle, new ArrayType(INTEGER), partitioningArguments);
VariableReferenceExpression partitionsVariable = context.getVariableAllocator().newVariable(partitioningFunction);
projections.put(partitionsVariable, partitioningFunction);
return new UnnestNode(node.getSourceLocation(), context.getIdAllocator().getNextId(), new ProjectNode(node.getSourceLocation(), context.getIdAllocator().getNextId(), node, projections.build(), LOCAL), node.getOutputVariables(), ImmutableMap.of(partitionsVariable, ImmutableList.of(partitionVariable)), Optional.empty());
}
use of com.facebook.presto.spi.relation.RowExpression in project presto by prestodb.
the class PlanRemotePojections method dedupVariables.
private static List<ProjectionContext> dedupVariables(List<ProjectionContext> projectionContexts) {
ImmutableList.Builder<ProjectionContext> deduppedProjectionContexts = ImmutableList.builder();
Set<VariableReferenceExpression> originalVariable = projectionContexts.get(projectionContexts.size() - 1).getProjections().keySet();
SymbolMapper mapper = null;
for (int i = 0; i < projectionContexts.size(); i++) {
Map<VariableReferenceExpression, RowExpression> projections = projectionContexts.get(i).getProjections();
// Apply mapping from previous projection
if (mapper != null) {
ImmutableMap.Builder<VariableReferenceExpression, RowExpression> newProjections = ImmutableMap.builder();
for (Map.Entry<VariableReferenceExpression, RowExpression> entry : projections.entrySet()) {
newProjections.put(entry.getKey(), mapper.map(entry.getValue()));
}
projections = newProjections.build();
}
// Dedup
ImmutableMultimap.Builder<RowExpression, VariableReferenceExpression> reverseProjectionsBuilder = ImmutableMultimap.builder();
projections.forEach((key, value) -> reverseProjectionsBuilder.put(value, key));
ImmutableMultimap<RowExpression, VariableReferenceExpression> reverseProjections = reverseProjectionsBuilder.build();
if (reverseProjections.keySet().size() == projectionContexts.get(i).getProjections().size() && reverseProjections.keySet().stream().noneMatch(VariableReferenceExpression.class::isInstance)) {
// No duplication
deduppedProjectionContexts.add(new ProjectionContext(projections, projectionContexts.get(i).isRemote()));
mapper = null;
} else {
SymbolMapper.Builder mapperBuilder = SymbolMapper.builder();
ImmutableMap.Builder<VariableReferenceExpression, RowExpression> dedupedProjectionsBuilder = ImmutableMap.builder();
for (RowExpression key : reverseProjections.keySet()) {
List<VariableReferenceExpression> values = ImmutableList.copyOf(reverseProjections.get(key));
if (key instanceof VariableReferenceExpression) {
values.forEach(variable -> mapperBuilder.put(variable, (VariableReferenceExpression) key));
dedupedProjectionsBuilder.put((VariableReferenceExpression) key, key);
} else if (values.size() > 1) {
// Consolidate to one variable, prefer variables from original plan
List<VariableReferenceExpression> fromOriginal = originalVariable.stream().filter(values::contains).collect(toImmutableList());
VariableReferenceExpression variable = fromOriginal.isEmpty() ? values.get(0) : getOnlyElement(fromOriginal);
for (int j = 0; j < values.size(); j++) {
if (!values.get(j).equals(variable)) {
mapperBuilder.put(values.get(j), variable);
}
}
dedupedProjectionsBuilder.put(variable, key);
} else {
checkState(values.size() == 1, "Expect only 1 value");
dedupedProjectionsBuilder.put(values.get(0), key);
}
}
deduppedProjectionContexts.add(new ProjectionContext(dedupedProjectionsBuilder.build(), projectionContexts.get(i).isRemote()));
mapper = mapperBuilder.build();
}
}
return deduppedProjectionContexts.build();
}
use of com.facebook.presto.spi.relation.RowExpression in project presto by prestodb.
the class AbstractOperatorBenchmark method createHashProjectOperator.
protected final OperatorFactory createHashProjectOperator(int operatorId, PlanNodeId planNodeId, List<Type> types) {
ImmutableList.Builder<VariableReferenceExpression> variables = ImmutableList.builder();
ImmutableMap.Builder<VariableReferenceExpression, Integer> variableToInputMapping = ImmutableMap.builder();
ImmutableList.Builder<PageProjectionWithOutputs> projections = ImmutableList.builder();
for (int channel = 0; channel < types.size(); channel++) {
VariableReferenceExpression variable = new VariableReferenceExpression(Optional.empty(), "h" + channel, types.get(channel));
variables.add(variable);
variableToInputMapping.put(variable, channel);
projections.add(new PageProjectionWithOutputs(new InputPageProjection(channel), new int[] { channel }));
}
Optional<RowExpression> hashExpression = HashGenerationOptimizer.getHashExpression(localQueryRunner.getMetadata().getFunctionAndTypeManager(), variables.build());
verify(hashExpression.isPresent());
RowExpression translatedHashExpression = translate(hashExpression.get(), variableToInputMapping.build());
PageFunctionCompiler functionCompiler = new PageFunctionCompiler(localQueryRunner.getMetadata(), 0);
projections.add(new PageProjectionWithOutputs(functionCompiler.compileProjection(session.getSqlFunctionProperties(), translatedHashExpression, Optional.empty()).get(), new int[] { types.size() }));
return new FilterAndProjectOperator.FilterAndProjectOperatorFactory(operatorId, planNodeId, () -> new PageProcessor(Optional.empty(), projections.build()), ImmutableList.copyOf(Iterables.concat(types, ImmutableList.of(BIGINT))), getFilterAndProjectMinOutputPageSize(session), getFilterAndProjectMinOutputPageRowCount(session));
}
use of com.facebook.presto.spi.relation.RowExpression in project presto by prestodb.
the class LogicalRowExpressions method extractPredicates.
public static List<RowExpression> extractPredicates(Form form, RowExpression expression) {
if (expression instanceof SpecialFormExpression && ((SpecialFormExpression) expression).getForm() == form) {
SpecialFormExpression specialFormExpression = (SpecialFormExpression) expression;
if (specialFormExpression.getArguments().size() == 2) {
List<RowExpression> predicates = new ArrayList<>();
predicates.addAll(extractPredicates(form, specialFormExpression.getArguments().get(0)));
predicates.addAll(extractPredicates(form, specialFormExpression.getArguments().get(1)));
return unmodifiableList(predicates);
}
if (specialFormExpression.getArguments().size() == 1 && form == IS_NULL) {
return singletonList(expression);
}
throw new IllegalStateException("Unexpected operands:" + expression + " " + form);
}
return singletonList(expression);
}
Aggregations