Skip to content

Commit 454f008

Browse files
committed
Added check for +Inf/-Inf for every decimal type
1 parent 10219d0 commit 454f008

File tree

2 files changed

+71
-20
lines changed

2 files changed

+71
-20
lines changed

table/src/main/java/tech/ydb/table/values/DecimalType.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,41 @@ public class DecimalType implements Type {
1616

1717
public static final int MAX_PRECISION = 35;
1818

19-
private static final DecimalType YDB_DEFAULT = DecimalType.of(22, 9);
19+
private static final InfValues[] INF_VALUES;
20+
21+
private static final DecimalType YDB_DEFAULT;
22+
23+
static {
24+
INF_VALUES = new InfValues[DecimalType.MAX_PRECISION];
25+
26+
long mask32 = 0xFFFFFFFFL;
27+
long infHigh = 0;
28+
long infLow = 10;
29+
30+
for (int precision = 1; precision <= DecimalType.MAX_PRECISION; precision++) {
31+
INF_VALUES[precision - 1] = new InfValues(infHigh, infLow);
32+
33+
// multiply by 10
34+
long ll = 10 * (infLow & mask32);
35+
long lh = 10 * (infLow >>> 32) + (ll >>> 32);
36+
long hl = 10 * (infHigh & mask32) + (lh >>> 32);
37+
long hh = 10 * (infHigh >>> 32) + (hl >>> 32);
38+
39+
infLow = (lh << 32) + (ll & mask32);
40+
infHigh = (hh << 32) + (hl & mask32);
41+
}
42+
43+
YDB_DEFAULT = DecimalType.of(22, 9);
44+
}
2045

2146
private final int precision;
2247
private final int scale;
48+
private final InfValues inf;
2349

2450
private DecimalType(int precision, int scale) {
2551
this.precision = precision;
2652
this.scale = scale;
53+
this.inf = INF_VALUES[precision - 1];
2754
}
2855

2956
public static DecimalType getDefault() {
@@ -115,4 +142,26 @@ public DecimalValue newValueUnscaled(BigInteger value) {
115142
public DecimalValue newValue(String value) {
116143
return DecimalValue.fromString(this, value);
117144
}
145+
146+
boolean isInf(long high, long low) {
147+
return high > inf.posHigh || (high == inf.posHigh && Long.compareUnsigned(low, inf.posLow) >= 0);
148+
}
149+
150+
boolean isNegInf(long high, long low) {
151+
return high < inf.negHigh || (high == inf.negHigh && Long.compareUnsigned(low, inf.negLow) <= 0);
152+
}
153+
154+
private static class InfValues {
155+
private final long posHigh;
156+
private final long posLow;
157+
private final long negHigh;
158+
private final long negLow;
159+
160+
InfValues(long infHigh, long infLow) {
161+
this.posHigh = infHigh;
162+
this.posLow = infLow;
163+
this.negHigh = 0xFFFFFFFFFFFFFFFFL - infHigh;
164+
this.negLow = 0xFFFFFFFFFFFFFFFFL - infLow + 1;
165+
}
166+
}
118167
}

table/src/main/java/tech/ydb/table/values/DecimalValue.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,6 @@ private static long getLongBe(byte[] buf, int from, int to) {
272272
return r;
273273
}
274274

275-
private static boolean isNan(long high, long low) {
276-
return NAN.high == high && NAN.low == low;
277-
}
278-
279-
private static boolean isInf(long high, long low) {
280-
return high > INF.high || (high == INF.high && Long.compareUnsigned(low, INF.low) >= 0);
281-
}
282-
283-
private static boolean isNegInf(long high, long low) {
284-
return high < NEG_INF.high || (high == NEG_INF.high && Long.compareUnsigned(low, NEG_INF.low) <= 0);
285-
}
286-
287275
private static DecimalValue newNan(DecimalType type) {
288276
return new DecimalValue(type, NAN.high, NAN.low);
289277
}
@@ -295,12 +283,27 @@ private static DecimalValue newInf(DecimalType type) {
295283
private static DecimalValue newNegInf(DecimalType type) {
296284
return new DecimalValue(type, NEG_INF.high, NEG_INF.low);
297285
}
298-
static DecimalValue fromUnscaledLong(DecimalType type, long value) {
299-
if (value == 0) {
286+
287+
private static boolean isNan(long high, long low) {
288+
return NAN.high == high && NAN.low == low;
289+
}
290+
291+
static DecimalValue fromUnscaledLong(DecimalType type, long low) {
292+
if (low == 0) {
300293
return new DecimalValue(type, 0, 0);
301294
}
302-
long high = value > 0 ? 0 : -1;
303-
return new DecimalValue(type, high, value);
295+
296+
long high = low > 0 ? 0 : -1;
297+
298+
if (type.isInf(high, low)) {
299+
return newInf(type);
300+
}
301+
302+
if (type.isNegInf(high, low)) {
303+
return newNegInf(type);
304+
}
305+
306+
return new DecimalValue(type, high, low);
304307
}
305308

306309
static DecimalValue fromBits(DecimalType type, long high, long low) {
@@ -312,11 +315,11 @@ static DecimalValue fromBits(DecimalType type, long high, long low) {
312315
return newNan(type);
313316
}
314317

315-
if (isInf(high, low)) {
318+
if (type.isInf(high, low)) {
316319
return newInf(type);
317320
}
318321

319-
if (isNegInf(high, low)) {
322+
if (type.isNegInf(high, low)) {
320323
return newNegInf(type);
321324
}
322325

@@ -515,5 +518,4 @@ static DecimalValue fromBigDecimal(DecimalType type, BigDecimal value) {
515518

516519
return DecimalValue.fromUnscaledBigInteger(type, rawValue);
517520
}
518-
519521
}

0 commit comments

Comments
 (0)