use of io.prestosql.sql.tree.SymbolReference in project hetu-core by openlookeng.
the class TransformUnCorrelatedInPredicateSubQuerySelfJoinToAggregate method getAllSymbols.
private static void getAllSymbols(Expression expression, List<SymbolReference> symbols) {
if (expression instanceof LogicalBinaryExpression) {
LogicalBinaryExpression logicalBinaryExpression = (LogicalBinaryExpression) expression;
getAllSymbols(logicalBinaryExpression.getLeft(), symbols);
getAllSymbols(logicalBinaryExpression.getRight(), symbols);
} else if (expression instanceof ComparisonExpression) {
ComparisonExpression comparisonExpression = (ComparisonExpression) expression;
getAllSymbols(comparisonExpression.getLeft(), symbols);
getAllSymbols(comparisonExpression.getRight(), symbols);
} else if (expression instanceof SymbolReference) {
symbols.add((SymbolReference) expression);
}
}
use of io.prestosql.sql.tree.SymbolReference in project hetu-core by openlookeng.
the class TransformUnCorrelatedInPredicateSubQuerySelfJoinToAggregate method isSelfJoin.
private static boolean isSelfJoin(ProjectNode projectNode, Expression predicate, JoinNode joinNode, Lookup lookup) {
PlanNode left = lookup.resolve(joinNode.getLeft());
PlanNode right = lookup.resolve(joinNode.getRight());
// TODO FIX FOR framenwork changes
if (joinNode.getType() == JoinNode.Type.INNER && left instanceof TableScanNode && right instanceof TableScanNode && ((TableScanNode) left).getTable().getFullyQualifiedName().equals(((TableScanNode) right).getTable().getFullyQualifiedName())) {
if (!(predicate instanceof LogicalBinaryExpression && ((LogicalBinaryExpression) predicate).getLeft() instanceof ComparisonExpression && ((LogicalBinaryExpression) predicate).getRight() instanceof ComparisonExpression)) {
return false;
}
SymbolReference projected = SymbolUtils.toSymbolReference(getOnlyElement(projectNode.getOutputSymbols()));
ComparisonExpression leftPredicate = (ComparisonExpression) ((LogicalBinaryExpression) predicate).getLeft();
ComparisonExpression rightPredicate = (ComparisonExpression) ((LogicalBinaryExpression) predicate).getRight();
if (lookup.resolve(projectNode.getSource()) instanceof CTEScanNode) {
CTEScanNode cteScanNode = (CTEScanNode) lookup.resolve(projectNode.getSource());
ProjectNode childProjectOfCte = (ProjectNode) lookup.resolve(cteScanNode.getSource());
RowExpression projectedExpresssion = (childProjectOfCte.getAssignments().get(getOnlyElement(projectNode.getOutputSymbols())));
for (Symbol symbol : lookup.resolve(childProjectOfCte.getSource()).getOutputSymbols()) {
if (symbol.getName().equals(((SymbolReference) OriginalExpressionUtils.castToExpression(projectedExpresssion)).getName())) {
projected = SymbolUtils.toSymbolReference(symbol);
}
}
}
if (leftPredicate.getChildren().contains(projected) && leftPredicate.getOperator() == ComparisonExpression.Operator.EQUAL && rightPredicate.getOperator() == ComparisonExpression.Operator.NOT_EQUAL) {
return true;
} else if (rightPredicate.getChildren().contains(projected) && rightPredicate.getOperator() == ComparisonExpression.Operator.EQUAL && leftPredicate.getOperator() == ComparisonExpression.Operator.NOT_EQUAL) {
return true;
}
}
return false;
}
use of io.prestosql.sql.tree.SymbolReference in project hetu-core by openlookeng.
the class SetOperationNodeTranslator method appendMarkers.
private static PlanNode appendMarkers(PlanNodeIdAllocator idAllocator, PlanSymbolAllocator planSymbolAllocator, PlanNode source, int markerIndex, List<Symbol> markers, Map<Symbol, SymbolReference> projections) {
Assignments.Builder assignments = Assignments.builder();
// add existing intersect symbols to projection
for (Map.Entry<Symbol, SymbolReference> entry : projections.entrySet()) {
Symbol symbol = planSymbolAllocator.newSymbol(entry.getKey().getName(), planSymbolAllocator.getTypes().get(entry.getKey()));
assignments.put(symbol, castToRowExpression(entry.getValue()));
}
// add extra marker fields to the projection
for (int i = 0; i < markers.size(); ++i) {
Expression expression = (i == markerIndex) ? TRUE_LITERAL : new Cast(new NullLiteral(), StandardTypes.BOOLEAN);
assignments.put(planSymbolAllocator.newSymbol(markers.get(i).getName(), BOOLEAN), castToRowExpression(expression));
}
return new ProjectNode(idAllocator.getNextId(), source, assignments.build());
}
use of io.prestosql.sql.tree.SymbolReference in project hetu-core by openlookeng.
the class TablePushdown method getNewIntermediateTreeAfterInnerTableUpdate.
/**
* @param newInnerJoinNode is the recently created join node after the outer table has been pushed into subquery
* @param stack is the stack of nodes from the original captured JoinNode and subquery TableScanNode
* @return the PlanNode after pulling the subquery table's Aggregation and Group By above the join
*/
private PlanNode getNewIntermediateTreeAfterInnerTableUpdate(JoinNode newInnerJoinNode, Stack<NodeWithTreeDirection> stack) {
TableScanNode subqueryTableNode = (TableScanNode) stack.peek().getNode();
/*
* create assignment builder for a new intermediate ProjectNode between the newInnerJoinNode and
* TableScanNode for subquery table
* */
Assignments.Builder assignmentsBuilder = Assignments.builder();
/*
* All symbols from TableScanNode are directly copied over
* */
for (Map.Entry<Symbol, ColumnHandle> tableEntry : subqueryTableNode.getAssignments().entrySet()) {
Symbol s = tableEntry.getKey();
assignmentsBuilder.put(s, castToRowExpression(new SymbolReference(s.getName())));
}
ProjectNode parentOfSubqueryTableNode = new ProjectNode(ruleContext.getIdAllocator().getNextId(), subqueryTableNode, assignmentsBuilder.build());
List<Symbol> parentOfSubqueryTableNodeOutputSymbols = parentOfSubqueryTableNode.getOutputSymbols();
/*
* Recreate the inner joinNode using the new ProjectNode as one of its sources.
* */
PlanNodeStatsEstimate leftSourceStats = ruleContext.getStatsProvider().getStats(newInnerJoinNode.getLeft());
PlanNodeStatsEstimate rightSourceStats = ruleContext.getStatsProvider().getStats(parentOfSubqueryTableNode);
JoinNode newJoinNode;
if (leftSourceStats.isOutputRowCountUnknown()) {
/*
* CAUTION: the stats are not available, so source reordering is not allowed. Query may fail
* */
newJoinNode = new JoinNode(newInnerJoinNode.getId(), newInnerJoinNode.getType(), newInnerJoinNode.getLeft(), parentOfSubqueryTableNode, newInnerJoinNode.getCriteria(), ImmutableList.<Symbol>builder().addAll(parentOfSubqueryTableNodeOutputSymbols).build(), newInnerJoinNode.getFilter(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), newInnerJoinNode.getDynamicFilters());
} else {
double leftSourceRowsCount = leftSourceStats.getOutputRowCount();
double rightSourceRowsCount = rightSourceStats.getOutputRowCount();
if (leftSourceRowsCount <= rightSourceRowsCount) {
// We reorder the children of this new join node such that the table with more rows is on the left
List<JoinNode.EquiJoinClause> newInnerJoinCriteria = newInnerJoinNode.getCriteria().stream().map(JoinNode.EquiJoinClause::flip).collect(toImmutableList());
newJoinNode = new JoinNode(newInnerJoinNode.getId(), newInnerJoinNode.getType(), parentOfSubqueryTableNode, newInnerJoinNode.getLeft(), newInnerJoinCriteria, ImmutableList.<Symbol>builder().addAll(parentOfSubqueryTableNodeOutputSymbols).build(), newInnerJoinNode.getFilter(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), newInnerJoinNode.getDynamicFilters());
} else {
newJoinNode = new JoinNode(newInnerJoinNode.getId(), newInnerJoinNode.getType(), newInnerJoinNode.getLeft(), parentOfSubqueryTableNode, newInnerJoinNode.getCriteria(), ImmutableList.<Symbol>builder().addAll(parentOfSubqueryTableNodeOutputSymbols).build(), newInnerJoinNode.getFilter(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), newInnerJoinNode.getDynamicFilters());
}
}
// Remove the TableScanNode from the stack
stack.pop();
AggregationNode newAggNode = (AggregationNode) stack.peek().getNode().replaceChildren(ImmutableList.of(newJoinNode));
return stack.firstElement().getNode().replaceChildren(ImmutableList.of(newAggNode));
}
use of io.prestosql.sql.tree.SymbolReference in project hetu-core by openlookeng.
the class PushLimitThroughProject method apply.
@Override
public Result apply(LimitNode parent, Captures captures, Context context) {
ProjectNode projectNode = captures.get(CHILD);
// for a LimitNode without ties, simply reorder the nodes
if (!parent.isWithTies()) {
return Result.ofPlanNode(transpose(parent, projectNode));
}
// for a LimitNode with ties, the tiesResolvingScheme must be rewritten in terms of symbols before projection
SymbolMapper.Builder symbolMapper = SymbolMapper.builder();
for (Symbol symbol : parent.getTiesResolvingScheme().get().getOrderBy()) {
Expression expression = castToExpression(projectNode.getAssignments().get(symbol));
// if a symbol results from some computation, the translation fails
if (!(expression instanceof SymbolReference)) {
return Result.empty();
}
symbolMapper.put(symbol, SymbolUtils.from(expression));
}
LimitNode mappedLimitNode = symbolMapper.build().map(parent, projectNode.getSource());
return Result.ofPlanNode(projectNode.replaceChildren(ImmutableList.of(mappedLimitNode)));
}
Aggregations