use of io.trino.sql.tree.JoinCriteria in project trino by trinodb.
the class RelationPlanner method planJoinUnnest.
private RelationPlan planJoinUnnest(RelationPlan leftPlan, Join joinNode, Unnest node) {
Optional<Expression> filterExpression = Optional.empty();
if (joinNode.getCriteria().isPresent()) {
JoinCriteria criteria = joinNode.getCriteria().get();
if (criteria instanceof NaturalJoin) {
throw semanticException(NOT_SUPPORTED, joinNode, "Natural join involving UNNEST is not supported");
}
if (criteria instanceof JoinUsing) {
throw semanticException(NOT_SUPPORTED, joinNode, "USING for join involving UNNEST is not supported");
}
Expression filter = (Expression) getOnlyElement(criteria.getNodes());
if (filter.equals(TRUE_LITERAL)) {
filterExpression = Optional.of(filter);
} else {
// TODO rewrite filter to support non-trivial join criteria
throw semanticException(NOT_SUPPORTED, joinNode, "JOIN involving UNNEST on condition other than TRUE is not supported");
}
}
return planUnnest(newPlanBuilder(leftPlan, analysis, lambdaDeclarationToSymbolMap), node, leftPlan.getFieldMappings(), filterExpression, joinNode.getType(), analysis.getScope(joinNode));
}
use of io.trino.sql.tree.JoinCriteria in project trino by trinodb.
the class RelationPlanner method planCorrelatedJoin.
private RelationPlan planCorrelatedJoin(Join join, RelationPlan leftPlan, Lateral lateral) {
PlanBuilder leftPlanBuilder = newPlanBuilder(leftPlan, analysis, lambdaDeclarationToSymbolMap);
RelationPlan rightPlan = new RelationPlanner(analysis, symbolAllocator, idAllocator, lambdaDeclarationToSymbolMap, plannerContext, Optional.of(leftPlanBuilder.getTranslations()), session, recursiveSubqueries).process(lateral.getQuery(), null);
PlanBuilder rightPlanBuilder = newPlanBuilder(rightPlan, analysis, lambdaDeclarationToSymbolMap);
Expression filterExpression;
if (join.getCriteria().isEmpty()) {
filterExpression = TRUE_LITERAL;
} else {
JoinCriteria criteria = join.getCriteria().get();
if (criteria instanceof JoinUsing || criteria instanceof NaturalJoin) {
throw semanticException(NOT_SUPPORTED, join, "Correlated join with criteria other than ON is not supported");
}
filterExpression = (Expression) getOnlyElement(criteria.getNodes());
}
List<Symbol> outputSymbols = ImmutableList.<Symbol>builder().addAll(leftPlan.getFieldMappings()).addAll(rightPlan.getFieldMappings()).build();
TranslationMap translationMap = new TranslationMap(outerContext, analysis.getScope(join), analysis, lambdaDeclarationToSymbolMap, outputSymbols).withAdditionalMappings(leftPlanBuilder.getTranslations().getMappings()).withAdditionalMappings(rightPlanBuilder.getTranslations().getMappings());
Expression rewrittenFilterCondition = translationMap.rewrite(filterExpression);
PlanBuilder planBuilder = subqueryPlanner.appendCorrelatedJoin(leftPlanBuilder, rightPlanBuilder.getRoot(), lateral.getQuery(), CorrelatedJoinNode.Type.typeConvert(join.getType()), rewrittenFilterCondition, ImmutableMap.of());
return new RelationPlan(planBuilder.getRoot(), analysis.getScope(join), outputSymbols, outerContext);
}
use of io.trino.sql.tree.JoinCriteria in project trino by trinodb.
the class AstBuilder method visitJoinRelation.
// *************** from clause *****************
@Override
public Node visitJoinRelation(SqlBaseParser.JoinRelationContext context) {
Relation left = (Relation) visit(context.left);
Relation right;
if (context.CROSS() != null) {
right = (Relation) visit(context.right);
return new Join(getLocation(context), Join.Type.CROSS, left, right, Optional.empty());
}
JoinCriteria criteria;
if (context.NATURAL() != null) {
right = (Relation) visit(context.right);
criteria = new NaturalJoin();
} else {
right = (Relation) visit(context.rightRelation);
if (context.joinCriteria().ON() != null) {
criteria = new JoinOn((Expression) visit(context.joinCriteria().booleanExpression()));
} else if (context.joinCriteria().USING() != null) {
criteria = new JoinUsing(visit(context.joinCriteria().identifier(), Identifier.class));
} else {
throw new IllegalArgumentException("Unsupported join criteria");
}
}
Join.Type joinType;
if (context.joinType().LEFT() != null) {
joinType = Join.Type.LEFT;
} else if (context.joinType().RIGHT() != null) {
joinType = Join.Type.RIGHT;
} else if (context.joinType().FULL() != null) {
joinType = Join.Type.FULL;
} else {
joinType = Join.Type.INNER;
}
return new Join(getLocation(context), joinType, left, right, Optional.of(criteria));
}
Aggregations