use of com.facebook.presto.sql.tree.SymbolReference in project presto by prestodb.
the class RelationPlanner method addCoercions.
private RelationPlan addCoercions(RelationPlan plan, Type[] targetColumnTypes) {
List<Symbol> oldSymbols = plan.getFieldMappings();
RelationType oldDescriptor = plan.getDescriptor().withOnlyVisibleFields();
verify(targetColumnTypes.length == oldSymbols.size());
ImmutableList.Builder<Symbol> newSymbols = new ImmutableList.Builder<>();
Field[] newFields = new Field[targetColumnTypes.length];
Assignments.Builder assignments = Assignments.builder();
for (int i = 0; i < targetColumnTypes.length; i++) {
Symbol inputSymbol = oldSymbols.get(i);
Type inputType = symbolAllocator.getTypes().get(inputSymbol);
Type outputType = targetColumnTypes[i];
if (outputType != inputType && !metadata.getTypeManager().isTypeOnlyCoercion(inputType, outputType)) {
Expression cast = new Cast(inputSymbol.toSymbolReference(), outputType.getTypeSignature().toString());
Symbol outputSymbol = symbolAllocator.newSymbol(cast, outputType);
assignments.put(outputSymbol, cast);
newSymbols.add(outputSymbol);
} else {
SymbolReference symbolReference = inputSymbol.toSymbolReference();
Symbol outputSymbol = symbolAllocator.newSymbol(symbolReference, outputType);
assignments.put(outputSymbol, symbolReference);
newSymbols.add(outputSymbol);
}
Field oldField = oldDescriptor.getFieldByIndex(i);
newFields[i] = new Field(oldField.getRelationAlias(), oldField.getName(), targetColumnTypes[i], oldField.isHidden(), oldField.getOriginTable(), oldField.isAliased());
}
ProjectNode projectNode = new ProjectNode(idAllocator.getNextId(), plan.getRoot(), assignments.build());
return new RelationPlan(projectNode, Scope.builder().withRelationType(new RelationType(newFields)).build(), newSymbols.build());
}
use of com.facebook.presto.sql.tree.SymbolReference in project presto by prestodb.
the class SubqueryPlanner method appendInPredicateApplyNode.
private PlanBuilder appendInPredicateApplyNode(PlanBuilder subPlan, InPredicate inPredicate, boolean correlationAllowed) {
if (subPlan.canTranslate(inPredicate)) {
// given subquery is already appended
return subPlan;
}
subPlan = subPlan.appendProjections(ImmutableList.of(inPredicate.getValue()), symbolAllocator, idAllocator);
checkState(inPredicate.getValueList() instanceof SubqueryExpression);
SubqueryExpression valueListSubquery = (SubqueryExpression) inPredicate.getValueList();
SubqueryExpression uncoercedValueListSubquery = uncoercedSubquery(valueListSubquery);
PlanBuilder subqueryPlan = createPlanBuilder(uncoercedValueListSubquery);
subqueryPlan = subqueryPlan.appendProjections(ImmutableList.of(valueListSubquery), symbolAllocator, idAllocator);
SymbolReference valueList = subqueryPlan.translate(valueListSubquery).toSymbolReference();
InPredicate parametersReplaced = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(parameters, analysis), inPredicate);
InPredicate inPredicateSubqueryExpression = new InPredicate(subPlan.translate(parametersReplaced.getValue()).toSymbolReference(), valueList);
Symbol inPredicateSubquerySymbol = symbolAllocator.newSymbol(inPredicateSubqueryExpression, BOOLEAN);
subPlan.getTranslations().put(parametersReplaced, inPredicateSubquerySymbol);
subPlan.getTranslations().put(inPredicate, inPredicateSubquerySymbol);
return appendApplyNode(subPlan, inPredicate, subqueryPlan, Assignments.of(inPredicateSubquerySymbol, inPredicateSubqueryExpression), correlationAllowed);
}
use of com.facebook.presto.sql.tree.SymbolReference in project presto by prestodb.
the class QueryPlanner method window.
private PlanBuilder window(PlanBuilder subPlan, QuerySpecification node) {
List<FunctionCall> windowFunctions = ImmutableList.copyOf(analysis.getWindowFunctions(node));
if (windowFunctions.isEmpty()) {
return subPlan;
}
for (FunctionCall windowFunction : windowFunctions) {
Window window = windowFunction.getWindow().get();
// Extract frame
WindowFrame.Type frameType = WindowFrame.Type.RANGE;
FrameBound.Type frameStartType = FrameBound.Type.UNBOUNDED_PRECEDING;
FrameBound.Type frameEndType = FrameBound.Type.CURRENT_ROW;
Expression frameStart = null;
Expression frameEnd = null;
if (window.getFrame().isPresent()) {
WindowFrame frame = window.getFrame().get();
frameType = frame.getType();
frameStartType = frame.getStart().getType();
frameStart = frame.getStart().getValue().orElse(null);
if (frame.getEnd().isPresent()) {
frameEndType = frame.getEnd().get().getType();
frameEnd = frame.getEnd().get().getValue().orElse(null);
}
}
// Pre-project inputs
ImmutableList.Builder<Expression> inputs = ImmutableList.<Expression>builder().addAll(windowFunction.getArguments()).addAll(window.getPartitionBy()).addAll(Iterables.transform(window.getOrderBy(), SortItem::getSortKey));
if (frameStart != null) {
inputs.add(frameStart);
}
if (frameEnd != null) {
inputs.add(frameEnd);
}
subPlan = subPlan.appendProjections(inputs.build(), symbolAllocator, idAllocator);
// Rewrite PARTITION BY in terms of pre-projected inputs
ImmutableList.Builder<Symbol> partitionBySymbols = ImmutableList.builder();
for (Expression expression : window.getPartitionBy()) {
partitionBySymbols.add(subPlan.translate(expression));
}
// Rewrite ORDER BY in terms of pre-projected inputs
Map<Symbol, SortOrder> orderings = new LinkedHashMap<>();
for (SortItem item : window.getOrderBy()) {
Symbol symbol = subPlan.translate(item.getSortKey());
orderings.put(symbol, toSortOrder(item));
}
// Rewrite frame bounds in terms of pre-projected inputs
Optional<Symbol> frameStartSymbol = Optional.empty();
Optional<Symbol> frameEndSymbol = Optional.empty();
if (frameStart != null) {
frameStartSymbol = Optional.of(subPlan.translate(frameStart));
}
if (frameEnd != null) {
frameEndSymbol = Optional.of(subPlan.translate(frameEnd));
}
WindowNode.Frame frame = new WindowNode.Frame(frameType, frameStartType, frameStartSymbol, frameEndType, frameEndSymbol);
TranslationMap outputTranslations = subPlan.copyTranslations();
// Rewrite function call in terms of pre-projected inputs
Expression parametersReplaced = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(analysis.getParameters(), analysis), windowFunction);
outputTranslations.addIntermediateMapping(windowFunction, parametersReplaced);
Expression rewritten = subPlan.rewrite(parametersReplaced);
boolean needCoercion = rewritten instanceof Cast;
// Strip out the cast and add it back as a post-projection
if (rewritten instanceof Cast) {
rewritten = ((Cast) rewritten).getExpression();
}
// If refers to existing symbol, don't create another PlanNode
if (rewritten instanceof SymbolReference) {
if (needCoercion) {
subPlan = explicitCoercionSymbols(subPlan, subPlan.getRoot().getOutputSymbols(), ImmutableList.of(windowFunction));
}
continue;
}
Symbol newSymbol = symbolAllocator.newSymbol(rewritten, analysis.getType(windowFunction));
outputTranslations.put(parametersReplaced, newSymbol);
WindowNode.Function function = new WindowNode.Function((FunctionCall) rewritten, analysis.getFunctionSignature(windowFunction), frame);
List<Symbol> sourceSymbols = subPlan.getRoot().getOutputSymbols();
ImmutableList.Builder<Symbol> orderBySymbols = ImmutableList.builder();
orderBySymbols.addAll(orderings.keySet());
// create window node
subPlan = new PlanBuilder(outputTranslations, new WindowNode(idAllocator.getNextId(), subPlan.getRoot(), new WindowNode.Specification(partitionBySymbols.build(), orderBySymbols.build(), orderings), ImmutableMap.of(newSymbol, function), Optional.empty(), ImmutableSet.of(), 0), analysis.getParameters());
if (needCoercion) {
subPlan = explicitCoercionSymbols(subPlan, sourceSymbols, ImmutableList.of(windowFunction));
}
}
return subPlan;
}
use of com.facebook.presto.sql.tree.SymbolReference in project presto by prestodb.
the class DomainTranslator method toPredicate.
private static Expression toPredicate(Domain domain, SymbolReference reference) {
if (domain.getValues().isNone()) {
return domain.isNullAllowed() ? new IsNullPredicate(reference) : FALSE_LITERAL;
}
if (domain.getValues().isAll()) {
return domain.isNullAllowed() ? TRUE_LITERAL : new NotExpression(new IsNullPredicate(reference));
}
List<Expression> disjuncts = new ArrayList<>();
disjuncts.addAll(domain.getValues().getValuesProcessor().transform(ranges -> extractDisjuncts(domain.getType(), ranges, reference), discreteValues -> extractDisjuncts(domain.getType(), discreteValues, reference), allOrNone -> {
throw new IllegalStateException("Case should not be reachable");
}));
// Add nullability disjuncts
if (domain.isNullAllowed()) {
disjuncts.add(new IsNullPredicate(reference));
}
return combineDisjunctsWithDefault(disjuncts, TRUE_LITERAL);
}
use of com.facebook.presto.sql.tree.SymbolReference in project presto by prestodb.
the class TestEliminateCrossJoins method testGiveUpOnNonIdentityProjections.
@Test
public void testGiveUpOnNonIdentityProjections() {
PlanNode plan = join(project(join(values(symbol("a1")), values(symbol("b"))), symbol("a2"), new ArithmeticUnaryExpression(MINUS, new SymbolReference("a1"))), values(symbol("c")), symbol("a2"), symbol("c"), symbol("c"), symbol("b"));
assertEquals(JoinGraph.buildFrom(plan).size(), 2);
}
Aggregations