Skip to content

Commit 845dfba

Browse files
authored
Fix number typing used in maps (#7676)
We are automatically widening numbers from Integer to Long and Float to Double to be able to compare them. But used as key for maps it does not work because the type needs to be exact. For fixing this we are moving to widening then numbers only at comparison time. Otherwise we keep the original typing.
1 parent c0adef9 commit 845dfba

File tree

13 files changed

+50
-42
lines changed

13 files changed

+50
-42
lines changed

dd-java-agent/agent-debugger/debugger-el/src/main/java/com/datadog/debugger/el/PrettyPrintVisitor.java

+4-9
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
import com.datadog.debugger.el.values.SetValue;
3434
import com.datadog.debugger.el.values.StringValue;
3535
import datadog.trace.bootstrap.debugger.el.Values;
36-
import java.math.BigDecimal;
37-
import java.math.BigInteger;
3836
import java.util.List;
3937
import java.util.Map;
4038
import java.util.Set;
@@ -226,13 +224,10 @@ public String visit(ObjectValue objectValue) {
226224
@Override
227225
public String visit(NumericValue numericValue) {
228226
Number value = numericValue.value;
229-
if (value instanceof Double) {
230-
return String.valueOf(value.doubleValue());
231-
}
232-
if (value instanceof Long) {
233-
return String.valueOf(value.longValue());
234-
}
235-
if (value instanceof BigDecimal || value instanceof BigInteger) {
227+
if (value != null) {
228+
if (value instanceof Double || value instanceof Float) {
229+
return String.valueOf(value.doubleValue());
230+
}
236231
return value.toString();
237232
}
238233
return "null";

dd-java-agent/agent-debugger/debugger-el/src/main/java/com/datadog/debugger/el/expressions/ComparisonOperator.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ public enum ComparisonOperator {
1414
@Override
1515
public Boolean apply(Value<?> left, Value<?> right) {
1616
if (left instanceof NumericValue && right instanceof NumericValue) {
17-
Number leftNumber = (Number) left.getValue();
18-
Number rightNumber = (Number) right.getValue();
17+
Number leftNumber = ((NumericValue) left).getWidenValue();
18+
Number rightNumber = ((NumericValue) right).getWidenValue();
1919
if (isNan(leftNumber, rightNumber)) {
2020
return Boolean.FALSE;
2121
}
@@ -152,8 +152,8 @@ protected static boolean isNan(Number... numbers) {
152152

153153
protected static Integer compare(Value<?> left, Value<?> right) {
154154
if (left instanceof NumericValue && right instanceof NumericValue) {
155-
Number leftNumber = (Number) left.getValue();
156-
Number rightNumber = (Number) right.getValue();
155+
Number leftNumber = ((NumericValue) left).getWidenValue();
156+
Number rightNumber = ((NumericValue) right).getWidenValue();
157157
if (isNan(leftNumber, rightNumber)) {
158158
return null;
159159
}

dd-java-agent/agent-debugger/debugger-el/src/main/java/com/datadog/debugger/el/values/ListValue.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public boolean contains(Value<?> val) {
178178
}
179179
}
180180
} else if (arrayType == long.class) {
181-
long longValue = (Long) val.getValue();
181+
long longValue = ((Number) val.getValue()).longValue();
182182
for (int i = 0; i < count; i++) {
183183
if (Array.getLong(arrayHolder, i) == longValue) {
184184
return true;

dd-java-agent/agent-debugger/debugger-el/src/main/java/com/datadog/debugger/el/values/NumericValue.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/** A numeric {@linkplain com.datadog.debugger.el.Value} */
77
public final class NumericValue extends Literal<Number> {
88
public NumericValue(Number value) {
9-
super(widen(value));
9+
super(value);
1010
}
1111

1212
private static Number widen(Number value) {
@@ -19,6 +19,10 @@ private static Number widen(Number value) {
1919
return value;
2020
}
2121

22+
public Number getWidenValue() {
23+
return widen(getValue());
24+
}
25+
2226
@Override
2327
public String toString() {
2428
return "NumericLiteral{" + "value=" + value + '}';

dd-java-agent/agent-debugger/debugger-el/src/test/java/com/datadog/debugger/el/ValueScriptTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ public void topLevelPrimitives() {
5151
new Object[] {
5252
"hello",
5353
"hello",
54-
10L,
54+
10,
5555
100_000_000_000L,
56-
2.5D,
56+
2.5F,
5757
3.14D,
5858
"a",
5959
"b",
60-
5L,
61-
3L,
60+
5,
61+
3,
6262
"el",
6363
Values.NULL_OBJECT,
6464
Boolean.TRUE,

dd-java-agent/agent-debugger/debugger-el/src/test/java/com/datadog/debugger/el/expressions/ComparisonExpressionTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,10 @@ private static Stream<Arguments> expressions() {
156156
"null instanceof \"java.lang.String\""),
157157
Arguments.of(
158158
new NumericValue(1),
159-
new StringValue("java.lang.Long"),
159+
new StringValue("java.lang.Integer"),
160160
INSTANCEOF,
161161
true,
162-
"1 instanceof \"java.lang.Long\""),
162+
"1 instanceof \"java.lang.Integer\""),
163163
Arguments.of(
164164
new NumericValue(1.0),
165165
new StringValue("java.lang.Double"),

dd-java-agent/agent-debugger/debugger-el/src/test/java/com/datadog/debugger/el/expressions/LenExpressionTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,24 @@ void undefinedExpression() {
3737
@Test
3838
void stringExpression() {
3939
LenExpression expression = new LenExpression(DSL.value("a"));
40-
assertEquals(1L, expression.evaluate(resolver).getValue());
40+
assertEquals(1, expression.evaluate(resolver).getValue());
4141
assertEquals("len(\"a\")", print(expression));
4242
}
4343

4444
@Test
4545
void collectionExpression() {
4646
LenExpression expression = new LenExpression(DSL.value(Arrays.asList("a", "b")));
47-
assertEquals(2L, expression.evaluate(resolver).getValue());
47+
assertEquals(2, expression.evaluate(resolver).getValue());
4848
assertEquals("len(List)", print(expression));
4949
expression = new LenExpression(DSL.value(new HashSet<>(Arrays.asList("a", "b"))));
50-
assertEquals(2L, expression.evaluate(resolver).getValue());
50+
assertEquals(2, expression.evaluate(resolver).getValue());
5151
assertEquals("len(Set)", print(expression));
5252
}
5353

5454
@Test
5555
void mapExpression() {
5656
LenExpression expression = new LenExpression(DSL.value(Collections.singletonMap("a", "b")));
57-
assertEquals(1L, expression.evaluate(resolver).getValue());
57+
assertEquals(1, expression.evaluate(resolver).getValue());
5858
assertEquals("len(Map)", print(expression));
5959
}
6060
}

dd-java-agent/agent-debugger/debugger-el/src/test/java/com/datadog/debugger/el/expressions/ValueRefExpressionTest.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ class Obj {
9292
assertEquals("Hello there", expression.evaluate(resolver).getValue());
9393
assertEquals("msg", print(expression));
9494
expression = DSL.ref("i");
95-
assertEquals(
96-
(long) 6, expression.evaluate(resolver).getValue()); // int value is widened to long
95+
assertEquals(6, expression.evaluate(resolver).getValue()); // int value is widened to long
9796
assertEquals("i", print(expression));
9897
ValueRefExpression invalidExpression = ref(ValueReferences.synthetic("invalid"));
9998
RuntimeException runtimeException =

dd-java-agent/agent-debugger/debugger-el/src/test/java/com/datadog/debugger/el/values/ListValueTest.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ void testFromArray() {
5353
Value<?> v = listValue.get(i);
5454
assertNotNull(v);
5555
if (expected != null) {
56-
assertEquals(
57-
((Integer) array[i]).longValue(), v.getValue()); // int is automatically widened to long
56+
assertEquals(array[i], v.getValue());
5857
} else {
5958
assertEquals(Value.nullValue(), v);
6059
}
@@ -78,7 +77,7 @@ void testFromArrayOfArrays() {
7877
ListValue collection = (ListValue) v;
7978
for (int j = 0; j < collection.count(); j++) {
8079
Value<?> v1 = collection.get(j);
81-
assertEquals((long) intArray[i][j], v1.getValue()); // int is automatically widened to long
80+
assertEquals(intArray[i][j], v1.getValue()); // int is automatically widened to long
8281
}
8382
}
8483
assertThrows(IllegalArgumentException.class, () -> listValue.get(-1));

dd-java-agent/agent-debugger/debugger-el/src/test/java/com/datadog/debugger/el/values/MapValueTest.java

+13
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,17 @@ void get() {
4747
assertEquals(Value.undefinedValue(), instance.get(Values.UNDEFINED_OBJECT));
4848
assertEquals(Value.undefinedValue(), instance.get(Value.undefinedValue()));
4949
}
50+
51+
@Test
52+
void intMap() {
53+
Map<Integer, Integer> map = new HashMap<>();
54+
map.put(1, 1);
55+
map.put(2, 2);
56+
instance = new MapValue(map);
57+
assertEquals(2, instance.count());
58+
assertEquals(Value.of(1), instance.get(1));
59+
assertEquals(Value.of(2), instance.get(2));
60+
Value<?> key = Value.of(1);
61+
assertEquals(Value.of(1), instance.get(key));
62+
}
5063
}

dd-java-agent/agent-debugger/debugger-el/src/test/java/com/datadog/debugger/el/values/NumericValueTest.java

+4-7
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ void testByteLiteral() {
2323
NumericValue instance = new NumericValue(expected);
2424
assertFalse(instance.isNull());
2525
assertFalse(instance.isUndefined());
26-
assertNotEquals(expected, instance.getValue());
27-
assertEquals((long) expected, instance.getValue());
26+
assertEquals(expected, instance.getValue());
2827
assertEquals("1", print(instance));
2928
}
3029

@@ -34,8 +33,7 @@ void testShortLiteral() {
3433
NumericValue instance = new NumericValue(expected);
3534
assertFalse(instance.isNull());
3635
assertFalse(instance.isUndefined());
37-
assertNotEquals(expected, instance.getValue());
38-
assertEquals((long) expected, instance.getValue());
36+
assertEquals(expected, instance.getValue());
3937
assertEquals("1", print(instance));
4038
}
4139

@@ -45,8 +43,7 @@ void testIntLiteral() {
4543
NumericValue instance = new NumericValue(expected);
4644
assertFalse(instance.isNull());
4745
assertFalse(instance.isUndefined());
48-
assertNotEquals(expected, instance.getValue());
49-
assertEquals((long) expected, instance.getValue());
46+
assertEquals(expected, instance.getValue());
5047
assertEquals("1", print(instance));
5148
}
5249

@@ -66,7 +63,7 @@ void testFloatLiteral() {
6663
NumericValue instance = new NumericValue(expected);
6764
assertFalse(instance.isNull());
6865
assertFalse(instance.isUndefined());
69-
assertEquals((double) expected, instance.getValue());
66+
assertEquals(expected, instance.getValue());
7067
assertEquals("1.0", print(instance));
7168
}
7269

dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/instrumentation/MetricInstrumentor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ public VisitorResult visit(StringValue stringValue) {
637637

638638
@Override
639639
public VisitorResult visit(NumericValue numericValue) {
640-
Number number = numericValue.getValue();
640+
Number number = numericValue.getWidenValue();
641641
InsnList insnList = new InsnList();
642642
if (number instanceof Long) {
643643
ldc(insnList, number.longValue());

dd-smoke-tests/debugger-integration-tests/src/test/java/datadog/smoketest/MoshiConfigTestHelper.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,11 @@ public Void visit(StringValue stringValue) {
296296
@Override
297297
public Void visit(NumericValue numericValue) {
298298
try {
299-
if (numericValue.getValue() instanceof Long) {
300-
jsonWriter.value(numericValue.getValue().longValue());
301-
} else if (numericValue.getValue() instanceof Double) {
302-
jsonWriter.value(numericValue.getValue().doubleValue());
299+
Number widenValue = numericValue.getWidenValue();
300+
if (widenValue instanceof Long) {
301+
jsonWriter.value(widenValue.longValue());
302+
} else if (widenValue instanceof Double) {
303+
jsonWriter.value(widenValue.doubleValue());
303304
} else {
304305
throw new UnsupportedOperationException(
305306
"numeric value unsupported:" + numericValue.getValue().getClass());

0 commit comments

Comments
 (0)