Creates a RexNode representation a SQL "arg IN (point, ...)" expression. If all of the expressions are literals, creates a call Sarg literal, "SEARCH(arg, SARG([point0..point0], [point1..point1], ...)"; otherwise creates a disjunction, "arg = point0 OR arg = point1 OR ...". I
(RexNode arg, List<? extends RexNode> ranges)
| 1825 | * <p>If there is only a single expression, creates a plain equality |
| 1826 | * {@code arg = point0}. */ |
| 1827 | public RexNode makeIn(RexNode arg, List<? extends RexNode> ranges) { |
| 1828 | if (areAssignable(arg, ranges)) { |
| 1829 | final Sarg sarg = toSarg(Comparable.class, ranges, RexUnknownAs.UNKNOWN); |
| 1830 | if (sarg != null) { |
| 1831 | if (sarg.isPoints() && sarg.pointCount == 1) { |
| 1832 | return makeCall(SqlStdOperatorTable.EQUALS, arg, ranges.get(0)); |
| 1833 | } |
| 1834 | final List<RelDataType> types = ranges.stream() |
| 1835 | .map(RexNode::getType) |
| 1836 | .collect(Collectors.toList()); |
| 1837 | RelDataType sargType = |
| 1838 | requireNonNull(typeFactory.leastRestrictive(types), |
| 1839 | () -> "Can't find leastRestrictive type for SARG among " + types); |
| 1840 | return makeCall(SqlStdOperatorTable.SEARCH, arg, |
| 1841 | makeSearchArgumentLiteral(sarg, sargType)); |
| 1842 | } |
| 1843 | } |
| 1844 | return RexUtil.composeDisjunction(this, ranges.stream() |
| 1845 | .map(r -> makeCall(SqlStdOperatorTable.EQUALS, arg, r)) |
| 1846 | .collect(toImmutableList())); |
| 1847 | } |
| 1848 | |
| 1849 | /** Returns whether and argument and bounds are have types that are |
| 1850 | * sufficiently compatible to be converted to a {@link Sarg}. */ |