@Override protected Object visitBetweenPredicate(BetweenPredicate node, Object context) { Object value = process(node.getValue(), context); if (value == null) { return null; } Object min = process(node.getMin(), context); if (min == null) { return null; } Object max = process(node.getMax(), context); if (max == null) { return null; } if (hasUnresolvedValue(value, min, max)) { return new BetweenPredicate( toExpression(value, expressionTypes.get(node.getValue())), toExpression(min, expressionTypes.get(node.getMin())), toExpression(max, expressionTypes.get(node.getMax()))); } return invokeOperator(OperatorType.BETWEEN, types(node.getValue(), node.getMin(), node.getMax()), ImmutableList.of(value, min, max)); }
protected static Expression processFuncLast(ComparisonExpression node) { System.out.println("Processing last()"); Expression rightNode = node.getRight(); Expression leftNode = node.getLeft(); FunctionCall last = (FunctionCall) rightNode; // # of arguments are already checked outside 1 or 2 String number = last.getArguments().get(0).toString(); String format = "DAY"; // default if (last.getArguments().size() == 2) { format = last.getArguments().get(1).toString().replaceAll("\"", ""); } IntervalLiteral.Sign sign; if (number.startsWith("-")) { sign = IntervalLiteral.Sign.NEGATIVE; number = number.substring(1); } else { sign = IntervalLiteral.Sign.POSITIVE; } CurrentTime cTime = new CurrentTime(CurrentTime.Type.DATE); IntervalLiteral interval = new IntervalLiteral(number, sign, format); ArithmeticExpression arithmOp = new ArithmeticExpression(ArithmeticExpression.Type.SUBTRACT, cTime, interval); BetweenPredicate bPredicate = new BetweenPredicate(leftNode, arithmOp, cTime); return bPredicate; }
@Override protected RowExpression visitBetweenPredicate(BetweenPredicate node, Void context) { RowExpression value = process(node.getValue(), context); RowExpression min = process(node.getMin(), context); RowExpression max = process(node.getMax(), context); return call( betweenSignature(value.getType(), min.getType(), max.getType()), BOOLEAN, value, min, max); }
@Override protected ExtractionResult visitBetweenPredicate(BetweenPredicate node, Boolean complement) { // Re-write as two comparison expressions return process(and( new ComparisonExpression(GREATER_THAN_OR_EQUAL, node.getValue(), node.getMin()), new ComparisonExpression(LESS_THAN_OR_EQUAL, node.getValue(), node.getMax())), complement); }
@Override protected Boolean visitBetweenPredicate(BetweenPredicate node, Void context) { return process(node.getMin(), context) && process(node.getValue(), context) && process(node.getMax(), context); }
@Test public void testBetween() throws Exception { assertExpression("1 BETWEEN 2 AND 3", new BetweenPredicate(new LongLiteral("1"), new LongLiteral("2"), new LongLiteral("3"))); assertExpression("1 NOT BETWEEN 2 AND 3", new NotExpression(new BetweenPredicate(new LongLiteral("1"), new LongLiteral("2"), new LongLiteral("3")))); }
@Override protected String visitBetweenPredicate(BetweenPredicate node, Void context) { return "(" + process(node.getValue(), context) + " BETWEEN " + process(node.getMin(), context) + " AND " + process(node.getMax(), context) + ")"; }
@Override protected String visitBetweenPredicate(BetweenPredicate node, StackableAstVisitorContext<Integer> indent) { return "(" + process(node.getValue(), indent) + " BETWEEN " + process(node.getMin(), indent) + " AND " + process(node.getMax(), indent) + ")"; }
private static List<Expression> extractDisjuncts(Type type, Ranges ranges, QualifiedNameReference reference) { List<Expression> disjuncts = new ArrayList<>(); List<Expression> singleValues = new ArrayList<>(); for (Range range : ranges.getOrderedRanges()) { checkState(!range.isAll()); // Already checked if (range.isSingleValue()) { singleValues.add(toExpression(range.getSingleValue(), type)); } else if (isBetween(range)) { // Specialize the range with BETWEEN expression if possible b/c it is currently more efficient disjuncts.add(new BetweenPredicate(reference, toExpression(range.getLow().getValue(), type), toExpression(range.getHigh().getValue(), type))); } else { List<Expression> rangeConjuncts = new ArrayList<>(); if (!range.getLow().isLowerUnbounded()) { switch (range.getLow().getBound()) { case ABOVE: rangeConjuncts.add(new ComparisonExpression(GREATER_THAN, reference, toExpression(range.getLow().getValue(), type))); break; case EXACTLY: rangeConjuncts.add(new ComparisonExpression(GREATER_THAN_OR_EQUAL, reference, toExpression(range.getLow().getValue(), type))); break; case BELOW: throw new IllegalStateException("Low Marker should never use BELOW bound: " + range); default: throw new AssertionError("Unhandled bound: " + range.getLow().getBound()); } } if (!range.getHigh().isUpperUnbounded()) { switch (range.getHigh().getBound()) { case ABOVE: throw new IllegalStateException("High Marker should never use ABOVE bound: " + range); case EXACTLY: rangeConjuncts.add(new ComparisonExpression(LESS_THAN_OR_EQUAL, reference, toExpression(range.getHigh().getValue(), type))); break; case BELOW: rangeConjuncts.add(new ComparisonExpression(LESS_THAN, reference, toExpression(range.getHigh().getValue(), type))); break; default: throw new AssertionError("Unhandled bound: " + range.getHigh().getBound()); } } // If rangeConjuncts is null, then the range was ALL, which should already have been checked for checkState(!rangeConjuncts.isEmpty()); disjuncts.add(combineConjuncts(rangeConjuncts)); } } // Add back all of the possible single values either as an equality or an IN predicate if (singleValues.size() == 1) { disjuncts.add(new ComparisonExpression(EQUAL, reference, getOnlyElement(singleValues))); } else if (singleValues.size() > 1) { disjuncts.add(new InPredicate(reference, new InListExpression(singleValues))); } return disjuncts; }
@Override protected Type visitBetweenPredicate(BetweenPredicate node, StackableAstVisitorContext<AnalysisContext> context) { return getOperator(context, node, OperatorType.BETWEEN, node.getValue(), node.getMin(), node.getMax()); }
private static BetweenPredicate between(Symbol symbol, Expression min, Expression max) { return new BetweenPredicate(reference(symbol), min, max); }
@Override protected String visitBetweenPredicate(BetweenPredicate node, Boolean unmangleNames) { return "(" + process(node.getValue(), unmangleNames) + " BETWEEN " + process(node.getMin(), unmangleNames) + " AND " + process(node.getMax(), unmangleNames) + ")"; }