@Override protected String visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, Void context) { return new StringBuilder() .append("(") .append(process(node.getValue(), context)) .append(' ') .append(node.getOperator().getValue()) .append(' ') .append(node.getQuantifier().toString()) .append(' ') .append(process(node.getSubquery(), context)) .append(")") .toString(); }
@Override protected String visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, Void context) { return new StringBuilder() .append("(") .append(process(node.getValue(), context)) .append(' ') .append(node.getOperator().getValue()) .append(' ') .append(node.getQuantifier().toString()) .append(' ') .append(process(node.getSubquery(), context)) .append(")") .toString(); }
@Override protected R visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, C context) { process(node.getValue(), context); process(node.getSubquery(), context); return null; }
@Override protected R visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, C context) { process(node.getValue(), context); process(node.getSubquery(), context); return null; }
private Expression getBoundComparisons(QuantifiedComparisonExpression quantifiedComparison, Symbol minValue, Symbol maxValue) { if (quantifiedComparison.getOperator() == EQUAL && quantifiedComparison.getQuantifier() == ALL) { // A = ALL B <=> min B = max B && A = min B return combineConjuncts( new ComparisonExpression(EQUAL, minValue.toSymbolReference(), maxValue.toSymbolReference()), new ComparisonExpression(EQUAL, quantifiedComparison.getValue(), maxValue.toSymbolReference())); } if (EnumSet.of(LESS_THAN, LESS_THAN_OR_EQUAL, GREATER_THAN, GREATER_THAN_OR_EQUAL).contains(quantifiedComparison.getOperator())) { // A < ALL B <=> A < min B // A > ALL B <=> A > max B // A < ANY B <=> A < max B // A > ANY B <=> A > min B Symbol boundValue = shouldCompareValueWithLowerBound(quantifiedComparison) ? minValue : maxValue; return new ComparisonExpression(quantifiedComparison.getOperator(), quantifiedComparison.getValue(), boundValue.toSymbolReference()); } throw new IllegalArgumentException("Unsupported quantified comparison: " + quantifiedComparison); }
private Expression getBoundComparisons(QuantifiedComparisonExpression quantifiedComparison, Symbol minValue, Symbol maxValue) { if (quantifiedComparison.getOperator() == EQUAL && quantifiedComparison.getQuantifier() == ALL) { // A = ALL B <=> min B = max B && A = min B return combineConjuncts( new ComparisonExpression(EQUAL, minValue.toSymbolReference(), maxValue.toSymbolReference()), new ComparisonExpression(EQUAL, quantifiedComparison.getValue(), maxValue.toSymbolReference())); } if (EnumSet.of(LESS_THAN, LESS_THAN_OR_EQUAL, GREATER_THAN, GREATER_THAN_OR_EQUAL).contains(quantifiedComparison.getOperator())) { // A < ALL B <=> A < min B // A > ALL B <=> A > max B // A < ANY B <=> A < max B // A > ANY B <=> A > min B Symbol boundValue = shouldCompareValueWithLowerBound(quantifiedComparison) ? minValue : maxValue; return new ComparisonExpression(quantifiedComparison.getOperator(), quantifiedComparison.getValue(), boundValue.toSymbolReference()); } throw new IllegalArgumentException("Unsupported quantified comparison: " + quantifiedComparison); }
private PlanBuilder planQuantifiedApplyNode(PlanBuilder subPlan, QuantifiedComparisonExpression quantifiedComparison, boolean correlationAllowed) { subPlan = subPlan.appendProjections(ImmutableList.of(quantifiedComparison.getValue()), symbolAllocator, idAllocator); checkState(quantifiedComparison.getSubquery() instanceof SubqueryExpression); SubqueryExpression quantifiedSubquery = (SubqueryExpression) quantifiedComparison.getSubquery(); SubqueryExpression uncoercedQuantifiedSubquery = uncoercedSubquery(quantifiedSubquery); PlanBuilder subqueryPlan = createPlanBuilder(uncoercedQuantifiedSubquery); subqueryPlan = subqueryPlan.appendProjections(ImmutableList.of(quantifiedSubquery), symbolAllocator, idAllocator); QuantifiedComparisonExpression coercedQuantifiedComparison = new QuantifiedComparisonExpression( quantifiedComparison.getOperator(), quantifiedComparison.getQuantifier(), subPlan.translate(quantifiedComparison.getValue()).toSymbolReference(), subqueryPlan.translate(quantifiedSubquery).toSymbolReference()); Symbol coercedQuantifiedComparisonSymbol = symbolAllocator.newSymbol(coercedQuantifiedComparison, BOOLEAN); subPlan.getTranslations().put(quantifiedComparison, coercedQuantifiedComparisonSymbol); return appendApplyNode( subPlan, quantifiedComparison.getSubquery(), subqueryPlan.getRoot(), Assignments.of(coercedQuantifiedComparisonSymbol, coercedQuantifiedComparison), correlationAllowed); }
private PlanBuilder planQuantifiedApplyNode(PlanBuilder subPlan, QuantifiedComparisonExpression quantifiedComparison, boolean correlationAllowed) { subPlan = subPlan.appendProjections(ImmutableList.of(quantifiedComparison.getValue()), symbolAllocator, idAllocator); checkState(quantifiedComparison.getSubquery() instanceof SubqueryExpression); SubqueryExpression quantifiedSubquery = (SubqueryExpression) quantifiedComparison.getSubquery(); SubqueryExpression uncoercedQuantifiedSubquery = uncoercedSubquery(quantifiedSubquery); PlanBuilder subqueryPlan = createPlanBuilder(uncoercedQuantifiedSubquery); subqueryPlan = subqueryPlan.appendProjections(ImmutableList.of(quantifiedSubquery), symbolAllocator, idAllocator); QuantifiedComparisonExpression coercedQuantifiedComparison = new QuantifiedComparisonExpression( quantifiedComparison.getOperator(), quantifiedComparison.getQuantifier(), subPlan.translate(quantifiedComparison.getValue()).toSymbolReference(), subqueryPlan.translate(quantifiedSubquery).toSymbolReference()); Symbol coercedQuantifiedComparisonSymbol = symbolAllocator.newSymbol(coercedQuantifiedComparison, BOOLEAN); subPlan.getTranslations().put(quantifiedComparison, coercedQuantifiedComparisonSymbol); return appendApplyNode( subPlan, quantifiedComparison.getSubquery(), subqueryPlan.getRoot(), Assignments.of(coercedQuantifiedComparisonSymbol, coercedQuantifiedComparison), correlationAllowed); }
@Override protected Type visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, StackableAstVisitorContext<Context> context) { Expression value = node.getValue(); process(value, context); Expression subquery = node.getSubquery(); process(subquery, context); Type comparisonType = coerceToSingleType(context, node, "Value expression and result of subquery must be of the same type for quantified comparison: %s vs %s", value, subquery); switch (node.getOperator()) { case LESS_THAN: case LESS_THAN_OR_EQUAL: case GREATER_THAN: case GREATER_THAN_OR_EQUAL: if (!comparisonType.isOrderable()) { throw new SemanticException(TYPE_MISMATCH, node, "Type [%s] must be orderable in order to be used in quantified comparison", comparisonType); } break; case EQUAL: case NOT_EQUAL: if (!comparisonType.isComparable()) { throw new SemanticException(TYPE_MISMATCH, node, "Type [%s] must be comparable in order to be used in quantified comparison", comparisonType); } break; default: throw new IllegalStateException(format("Unexpected comparison type: %s", node.getOperator())); } return setExpressionType(node, BOOLEAN); }
@Override protected Type visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, StackableAstVisitorContext<Context> context) { Expression value = node.getValue(); process(value, context); Expression subquery = node.getSubquery(); process(subquery, context); Type comparisonType = coerceToSingleType(context, node, "Value expression and result of subquery must be of the same type for quantified comparison: %s vs %s", value, subquery); switch (node.getOperator()) { case LESS_THAN: case LESS_THAN_OR_EQUAL: case GREATER_THAN: case GREATER_THAN_OR_EQUAL: if (!comparisonType.isOrderable()) { throw new SemanticException(TYPE_MISMATCH, node, "Type [%s] must be orderable in order to be used in quantified comparison", comparisonType); } break; case EQUAL: case NOT_EQUAL: if (!comparisonType.isComparable()) { throw new SemanticException(TYPE_MISMATCH, node, "Type [%s] must be comparable in order to be used in quantified comparison", comparisonType); } break; default: throw new IllegalStateException(format("Unexpected comparison type: %s", node.getOperator())); } return setExpressionType(node, BOOLEAN); }
case SOME: InPredicate inPredicate = new InPredicate(quantifiedComparison.getValue(), quantifiedComparison.getSubquery()); subPlan = appendInPredicateApplyNode(subPlan, inPredicate, correlationAllowed, node); subPlan.getTranslations().put(quantifiedComparison, subPlan.translate(inPredicate)); EQUAL, Quantifier.ANY, quantifiedComparison.getValue(), quantifiedComparison.getSubquery()); Expression notAny = new NotExpression(rewrittenAny); EQUAL, QuantifiedComparisonExpression.Quantifier.ALL, quantifiedComparison.getValue(), quantifiedComparison.getSubquery()); Expression notAll = new NotExpression(rewrittenAll);
case SOME: InPredicate inPredicate = new InPredicate(quantifiedComparison.getValue(), quantifiedComparison.getSubquery()); subPlan = appendInPredicateApplyNode(subPlan, inPredicate, correlationAllowed, node); subPlan.getTranslations().put(quantifiedComparison, subPlan.translate(inPredicate)); EQUAL, Quantifier.ANY, quantifiedComparison.getValue(), quantifiedComparison.getSubquery()); Expression notAny = new NotExpression(rewrittenAny); EQUAL, QuantifiedComparisonExpression.Quantifier.ALL, quantifiedComparison.getValue(), quantifiedComparison.getSubquery()); Expression notAll = new NotExpression(rewrittenAll);