Skip to content

Commit abf0430

Browse files
committed
[CALCITE-7349] Upgrade the types of FETCH and OFFSET in SORT to BigDecimal
1 parent c274aac commit abf0430

File tree

7 files changed

+28
-16
lines changed

7 files changed

+28
-16
lines changed

core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableMergeUnionRule.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ public EnumerableMergeUnionRule(Config config) {
9292
inputFetch = sort.fetch;
9393
} else if (sort.fetch instanceof RexLiteral && sort.offset instanceof RexLiteral) {
9494
inputFetch =
95-
call.builder().literal(RexLiteral.longValue(sort.fetch)
96-
+ RexLiteral.longValue(sort.offset));
95+
call.builder().literal(RexLiteral.bigDecimalValue(sort.fetch)
96+
.add(RexLiteral.bigDecimalValue(sort.offset)));
9797
}
9898
}
9999

core/src/main/java/org/apache/calcite/rel/metadata/RelMdUtil.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,9 +1048,14 @@ private static boolean alreadySmaller(RelMetadataQuery mq, RelNode input,
10481048
// Cannot be determined
10491049
return false;
10501050
}
1051-
final long offsetVal = offset == null ? 0 : RexLiteral.longValue(offset);
1052-
final long limit = RexLiteral.longValue(fetch);
1053-
return (double) offsetVal + (double) limit >= rowCount;
1051+
final BigDecimal offsetVal = offset == null
1052+
? BigDecimal.ZERO
1053+
: RexLiteral.bigDecimalValue(offset);
1054+
final BigDecimal limit = RexLiteral.bigDecimalValue(fetch);
1055+
if (!Double.isFinite(rowCount)) {
1056+
return false;
1057+
}
1058+
return offsetVal.add(limit).compareTo(BigDecimal.valueOf(rowCount)) >= 0;
10541059
}
10551060

10561061
/**

core/src/main/java/org/apache/calcite/rel/rules/PruneEmptyRules.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
import org.immutables.value.Value;
4949

50+
import java.math.BigDecimal;
5051
import java.util.Collections;
5152
import java.util.List;
5253
import java.util.function.Predicate;
@@ -500,9 +501,8 @@ public interface SortFetchZeroRuleConfig extends PruneEmptyRule.Config {
500501
Sort sort = call.rel(0);
501502
return sort.fetch != null
502503
&& !(sort.fetch instanceof RexDynamicParam)
503-
&& RexLiteral.longValue(sort.fetch) == 0;
504+
&& RexLiteral.bigDecimalValue(sort.fetch).equals(BigDecimal.ZERO);
504505
}
505-
506506
};
507507
}
508508
}

core/src/main/java/org/apache/calcite/rel/rules/SortJoinTransposeRule.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,12 @@ public SortJoinTransposeRule(Class<? extends Sort> sortClass,
202202
if (sort.fetch == null) {
203203
return null;
204204
}
205-
final long outerFetch = RexLiteral.longValue(sort.fetch);
206-
final long outerOffset = sort.offset != null ? RexLiteral.longValue(sort.offset) : 0;
207-
final long totalFetch = outerOffset + outerFetch;
208-
return rexBuilder.makeExactLiteral(BigDecimal.valueOf(totalFetch));
205+
final BigDecimal outerFetch = RexLiteral.bigDecimalValue(sort.fetch);
206+
final BigDecimal outerOffset = sort.offset != null
207+
? RexLiteral.bigDecimalValue(sort.offset)
208+
: BigDecimal.ZERO;
209+
final BigDecimal totalFetch = outerOffset.add(outerFetch);
210+
return rexBuilder.makeExactLiteral(totalFetch);
209211
}
210212

211213
/** Rule configuration. */

core/src/main/java/org/apache/calcite/rel/rules/SortRemoveRedundantRule.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,17 @@ protected SortRemoveRedundantRule(final SortRemoveRedundantRule.Config config) {
125125
// then we could remove the redundant sort.
126126
if (inputMaxRowCount != null
127127
&& Double.isFinite(inputMaxRowCount)
128-
&& new BigDecimal(inputMaxRowCount).compareTo(rowCountThreshold.get()) <= 0) {
128+
&& BigDecimal.valueOf(inputMaxRowCount).compareTo(rowCountThreshold.get()) <= 0) {
129129
call.transformTo(sort.getInput());
130130
}
131131
}
132132

133133
private static Optional<BigDecimal> getRowCountThreshold(Sort sort) {
134134
if (RelOptUtil.isLimit(sort)) {
135135
assert sort.fetch != null;
136-
final BigDecimal fetch = ((RexLiteral) sort.fetch).getValueAs(BigDecimal.class);
136+
final BigDecimal fetch = RexLiteral.bigDecimalValue(sort.fetch);
137137

138138
// We don't need to deal with fetch is 0.
139-
assert fetch != null;
140139
if (fetch.equals(BigDecimal.ZERO)) {
141140
return Optional.empty();
142141
}

core/src/main/java/org/apache/calcite/rex/RexLiteral.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,12 @@ public static long longValue(RexNode node) {
12901290
return number.longValue();
12911291
}
12921292

1293+
/** Returns the value of a literal, cast, or unary minus, as a BigDecimal;
1294+
* never null. */
1295+
public static BigDecimal bigDecimalValue(RexNode node) {
1296+
return (BigDecimal) numberValue(node);
1297+
}
1298+
12931299
public static @Nullable String stringValue(RexNode node) {
12941300
final Comparable value = findValue(node);
12951301
return (value == null) ? null : ((NlsString) value).getValue();

core/src/main/java/org/apache/calcite/tools/RelBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
import org.apache.calcite.util.ImmutableNullableList;
118118
import org.apache.calcite.util.Litmus;
119119
import org.apache.calcite.util.NlsString;
120+
import org.apache.calcite.util.NumberUtil;
120121
import org.apache.calcite.util.Optionality;
121122
import org.apache.calcite.util.Pair;
122123
import org.apache.calcite.util.Util;
@@ -494,8 +495,7 @@ public RexLiteral literal(@Nullable Object value) {
494495
return rexBuilder.makeApproxLiteral(
495496
((Number) value).doubleValue(), getTypeFactory().createSqlType(SqlTypeName.DOUBLE));
496497
} else if (value instanceof Number) {
497-
return rexBuilder.makeExactLiteral(
498-
BigDecimal.valueOf(((Number) value).longValue()));
498+
return rexBuilder.makeExactLiteral(NumberUtil.toBigDecimal((Number) value));
499499
} else if (value instanceof String) {
500500
return rexBuilder.makeLiteral((String) value);
501501
} else if (value instanceof Enum) {

0 commit comments

Comments
 (0)