Skip to content

Commit 22f2ab0

Browse files
guojn1githubgxll
authored andcommitted
[fix][dingo-exec] Support json_extract function
1 parent 3f556e3 commit 22f2ab0

File tree

2 files changed

+149
-10
lines changed

2 files changed

+149
-10
lines changed

dingo-common/src/main/java/io/dingodb/common/type/converter/DataConverter.java

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package io.dingodb.common.type.converter;
1818

19+
import io.dingodb.common.log.LogUtils;
1920
import io.dingodb.common.type.DingoType;
2021
import io.dingodb.expr.common.type.Type;
2122
import org.checkerframework.checker.nullness.qual.NonNull;
@@ -94,22 +95,59 @@ default Object convert(@NonNull Map<?, ?> value, @NonNull DingoType keyType, @No
9495
}
9596

9697
default Integer convertIntegerFrom(@NonNull Object value) {
97-
return (Integer) value;
98+
if (value instanceof Integer) {
99+
return (Integer) value;
100+
} else {
101+
try {
102+
return new BigDecimal(value.toString()).intValue();
103+
} catch (Exception e) {
104+
return 0;
105+
}
106+
}
98107
}
99108

100109
default Long convertLongFrom(@NonNull Object value) {
101110
if (value instanceof Integer) {
102111
return ((Integer) value).longValue();
112+
} else if (value instanceof Long) {
113+
return (Long) value;
114+
} else {
115+
try {
116+
return new BigDecimal(value.toString()).longValue();
117+
} catch (Exception e) {
118+
return 0L;
119+
}
103120
}
104-
return (Long) value;
105121
}
106122

107123
default Float convertFloatFrom(@NonNull Object value) {
108-
return (Float) value;
124+
if (value instanceof Float) {
125+
return (Float) value;
126+
} else if (value instanceof Double) {
127+
Double valDouble = (Double) value;
128+
return valDouble.floatValue();
129+
} else {
130+
try {
131+
return new BigDecimal(value.toString()).floatValue();
132+
} catch (Exception e) {
133+
return 0F;
134+
}
135+
}
109136
}
110137

111138
default Double convertDoubleFrom(@NonNull Object value) {
112-
return (Double) value;
139+
if (value instanceof Float) {
140+
Float valFloat = (Float) value;
141+
return valFloat.doubleValue();
142+
} else if (value instanceof Double) {
143+
return (Double) value;
144+
} else {
145+
try {
146+
return new BigDecimal(value.toString()).doubleValue();
147+
} catch (Exception e) {
148+
return 0D;
149+
}
150+
}
113151
}
114152

115153
default Boolean convertBooleanFrom(@NonNull Object value) {
@@ -128,28 +166,60 @@ default Boolean convertBooleanFrom(@NonNull Object value) {
128166
}
129167

130168
default String convertStringFrom(@NonNull Object value) {
131-
return (String) value;
169+
if (value instanceof String) {
170+
return (String) value;
171+
} else {
172+
return value.toString();
173+
}
132174
}
133175

134176
default BigDecimal convertDecimalFrom(@NonNull Object value) {
135-
return (BigDecimal) value;
177+
if (value instanceof BigDecimal) {
178+
return (BigDecimal) value;
179+
} else {
180+
try {
181+
return new BigDecimal(value.toString());
182+
} catch (Exception e) {
183+
return new BigDecimal(0);
184+
}
185+
}
136186
}
137187

138188
default Date convertDateFrom(@NonNull Object value) {
139189
if (value instanceof Timestamp) {
140190
Timestamp timestamp = (Timestamp) value;
141191
LocalDateTime localDateTime = timestamp.toLocalDateTime();
142192
return new Date(localDateTime.atZone(ZoneId.of("UTC")).toInstant().toEpochMilli());
193+
} else if (value instanceof Date) {
194+
return (Date) value;
195+
} else {
196+
return new Date(System.currentTimeMillis());
143197
}
144-
return (Date) value;
145198
}
146199

147200
default Time convertTimeFrom(@NonNull Object value) {
148-
return (Time) value;
201+
if (value instanceof Time) {
202+
return (Time) value;
203+
} else if (value instanceof Date) {
204+
Date date = (Date) value;
205+
return new Time(date.getTime());
206+
} else if (value instanceof Timestamp) {
207+
Timestamp timestamp = (Timestamp) value;
208+
return new Time(timestamp.getTime());
209+
} else {
210+
return new Time(System.currentTimeMillis());
211+
}
149212
}
150213

151214
default Timestamp convertTimestampFrom(@NonNull Object value) {
152-
return (Timestamp) value;
215+
if (value instanceof Timestamp) {
216+
return (Timestamp) value;
217+
} else if (value instanceof Date) {
218+
Date date = (Date) value;
219+
return new Timestamp(date.getTime());
220+
} else {
221+
return new Timestamp(System.currentTimeMillis());
222+
}
153223
}
154224

155225
default byte[] convertBinaryFrom(@NonNull Object value) {

dingo-exec/src/main/java/io/dingodb/exec/fun/mysql/JsonExtractFun.java

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@
1616

1717
package io.dingodb.exec.fun.mysql;
1818

19+
import com.fasterxml.jackson.core.JsonProcessingException;
20+
import com.fasterxml.jackson.databind.JsonNode;
21+
import com.fasterxml.jackson.databind.ObjectMapper;
22+
import com.fasterxml.jackson.databind.node.ArrayNode;
1923
import io.dingodb.expr.common.type.Type;
2024
import io.dingodb.expr.common.type.Types;
2125
import io.dingodb.expr.runtime.ExprConfig;
2226
import io.dingodb.expr.runtime.op.BinaryOp;
2327
import org.checkerframework.checker.nullness.qual.NonNull;
2428

29+
import java.util.Arrays;
30+
import java.util.List;
31+
2532
public class JsonExtractFun extends BinaryOp {
2633
private static final long serialVersionUID = -8343792468386621027L;
2734

@@ -41,6 +48,68 @@ public Type getType() {
4148

4249
@Override
4350
public Object evalValue(Object value0, Object value1, ExprConfig config) {
44-
return "";
51+
if (value0 == null) {
52+
return null;
53+
}
54+
if (value1 == null) {
55+
return value0;
56+
}
57+
String path = value1.toString();
58+
String[] paths = path.split("\\.");
59+
if (!paths[0].startsWith("$")) {
60+
return null;
61+
}
62+
if (paths.length == 1 && paths[0].equals("$")) {
63+
return value0;
64+
}
65+
List<String> pathList = Arrays.asList(paths);
66+
ObjectMapper mapper = new ObjectMapper();
67+
try {
68+
JsonNode rootNode = mapper.readTree(value0.toString());
69+
JsonNode node = rootNode;
70+
for (int i = 0; i < pathList.size(); i ++) {
71+
String pathItem = pathList.get(i);
72+
if (i == 0) {
73+
if (pathItem.contains("[") && pathItem.contains("]")) {
74+
int start = pathItem.indexOf("[");
75+
int end = pathItem.indexOf("]");
76+
if (end >= start + 1) {
77+
int item = Integer.parseInt(pathItem.substring(start + 1, end));
78+
node = rootNode.get(item);
79+
if (node == null && !(rootNode instanceof ArrayNode) && item == 0) {
80+
node = rootNode;
81+
}
82+
} else {
83+
return null;
84+
}
85+
} else {
86+
node = rootNode;
87+
}
88+
} else {
89+
if (pathItem.contains("[") && pathItem.contains("]")) {
90+
int start = pathItem.indexOf("[");
91+
int end = pathItem.indexOf("]");
92+
if (end >= start + 1) {
93+
int item = Integer.parseInt(pathItem.substring(start + 1, end));
94+
pathItem = pathItem.substring(0, start);
95+
node = node.get(pathItem).get(item);
96+
}
97+
} else {
98+
node = node.get(pathItem);
99+
}
100+
}
101+
102+
}
103+
if (node != null) {
104+
String res = node.toString();
105+
if (res.startsWith("\"") && res.endsWith("\"")) {
106+
return res.substring(1, res.length() - 1);
107+
}
108+
return node.toString();
109+
}
110+
return null;
111+
} catch (JsonProcessingException e) {
112+
return null;
113+
}
45114
}
46115
}

0 commit comments

Comments
 (0)