tkalkirill commented on code in PR #5004:
URL: https://github.com/apache/calcite/pull/5004#discussion_r3451378150
##########
core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableLimit.java:
##########
@@ -133,4 +141,147 @@ static Expression getExpression(RexNode rexNode) {
return Expressions.constant(RexLiteral.intValue(rexNode));
}
}
+
+ static Expression getExpressionForFetch(RexNode rexNode,
+ EnumerableRelImplementor implementor, BlockBuilder builder) {
+ if (rexNode instanceof RexDynamicParam) {
+ final RexDynamicParam param = (RexDynamicParam) rexNode;
+ return Expressions.call(EnumerableLimit.class, "toIntFetch",
+ Expressions.convert_(
+ Expressions.call(DataContext.ROOT,
+ BuiltInMethod.DATA_CONTEXT_GET.method,
+ Expressions.constant("?" + param.getIndex())),
+ Number.class));
+ } else if (rexNode instanceof RexLiteral) {
+ return Expressions.constant(
+ toIntFetch(((RexLiteral) rexNode).getValueAs(Number.class)));
+ } else {
+ final Expression expression =
+ RexToLixTranslator.forAggregation(implementor.getTypeFactory(),
+ builder, null, implementor.getConformance())
+ .translate(rexNode);
+ return Expressions.call(EnumerableLimit.class, "toIntFetch",
+ Expressions.convert_(Expressions.box(expression), Number.class));
+ }
+ }
+
+ /** Converts a FETCH expression result to the range supported by Enumerable.
*/
+ public static int toIntFetch(@Nullable Number value) {
+ final BigDecimal decimal = validateFetchValue(value);
+ final int result;
+ try {
+ result = decimal.intValueExact();
+ } catch (ArithmeticException e) {
+ throw new IllegalArgumentException("FETCH value " + value
+ + " is out of range; expected a value between 0 and "
+ + Integer.MAX_VALUE, e);
+ }
+ if (result < 0) {
+ throw new IllegalArgumentException("FETCH value " + value
+ + " is out of range; expected a value between 0 and "
+ + Integer.MAX_VALUE);
+ }
+ return result;
+ }
+
+ /** Converts a FETCH expression result to the range supported by a long. */
+ public static long toLongFetch(@Nullable Number value) {
+ final BigDecimal decimal = validateFetchValue(value);
+ final long result;
+ try {
+ result = decimal.longValueExact();
+ } catch (ArithmeticException e) {
+ throw new IllegalArgumentException("FETCH value " + value
Review Comment:
Yes, these bounds come from the execution APIs rather than from the logical
FETCH representation. Enumerable and Bindable use int because
ExtendedEnumerable.take accepts an int; Cassandra and Druid also expose integer
limits. Elasticsearch and Geode use long. The logical Rex value and the generic
reduction path remain BigDecimal, and MongoDB/JDBC do not apply these bounds. I
can clarify this in the Javadocs.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]