17
17
18
18
package org.apache.seatunnel.api.table.catalog;
19
19
20
- import org.apache.seatunnel.shade.com.fasterxml.jackson.databind.node.ObjectNode;
20
+ import org.apache.seatunnel.shade.com.typesafe.config.Config;
21
+ import org.apache.seatunnel.shade.com.typesafe.config.ConfigFactory;
22
+ import org.apache.seatunnel.shade.com.typesafe.config.ConfigObject;
23
+ import org.apache.seatunnel.shade.com.typesafe.config.ConfigValue;
21
24
22
25
import org.apache.seatunnel.api.table.type.ArrayType;
23
26
import org.apache.seatunnel.api.table.type.BasicType;
29
32
import org.apache.seatunnel.api.table.type.SeaTunnelRowType;
30
33
import org.apache.seatunnel.api.table.type.SqlType;
31
34
import org.apache.seatunnel.common.exception.CommonError;
32
- import org.apache.seatunnel.common.utils.JsonUtils;
33
-
34
- import java.util.Map;
35
35
36
36
public class SeaTunnelDataTypeConvertorUtil {
37
37
@@ -87,13 +87,13 @@ public static SeaTunnelDataType<?> deserializeSeaTunnelDataType(
87
87
private static SeaTunnelDataType<?> parseComplexDataType(String field, String columnStr) {
88
88
String column = columnStr.toUpperCase().replace(" ", "");
89
89
if (column.startsWith(SqlType.MAP.name())) {
90
- return parseMapType(field, column );
90
+ return parseMapType(field, columnStr );
91
91
}
92
92
if (column.startsWith(SqlType.ARRAY.name())) {
93
- return parseArrayType(field, column );
93
+ return parseArrayType(field, columnStr );
94
94
}
95
95
if (column.startsWith(SqlType.DECIMAL.name())) {
96
- return parseDecimalType(column );
96
+ return parseDecimalType(columnStr );
97
97
}
98
98
if (column.trim().startsWith("{")) {
99
99
return parseRowType(columnStr);
@@ -102,31 +102,64 @@ private static SeaTunnelDataType<?> parseComplexDataType(String field, String co
102
102
}
103
103
104
104
private static SeaTunnelDataType<?> parseRowType(String columnStr) {
105
- ObjectNode jsonNodes = JsonUtils.parseObject(columnStr);
106
- Map<String, String> fieldsMap = JsonUtils.toStringMap(jsonNodes);
107
- String[] fieldsName = new String[fieldsMap.size()];
108
- SeaTunnelDataType<?>[] seaTunnelDataTypes = new SeaTunnelDataType<?>[fieldsMap.size()];
109
- int i = 0;
110
- for (Map.Entry<String, String> entry : fieldsMap.entrySet()) {
111
- fieldsName[i] = entry.getKey();
112
- seaTunnelDataTypes[i] = deserializeSeaTunnelDataType(entry.getKey(), entry.getValue());
113
- i++;
105
+ String confPayload = "{conf = " + columnStr + "}";
106
+ Config conf;
107
+ try {
108
+ conf = ConfigFactory.parseString(confPayload);
109
+ } catch (RuntimeException e) {
110
+ throw new IllegalArgumentException(
111
+ String.format("HOCON Config parse from %s failed.", confPayload), e);
112
+ }
113
+ return parseRowType(conf.getObject("conf"));
114
+ }
115
+
116
+ private static SeaTunnelDataType<?> parseRowType(ConfigObject conf) {
117
+ String[] fieldNames = new String[conf.size()];
118
+ SeaTunnelDataType<?>[] fieldTypes = new SeaTunnelDataType[conf.size()];
119
+ conf.keySet().toArray(fieldNames);
120
+
121
+ for (int idx = 0; idx < fieldNames.length; idx++) {
122
+ String fieldName = fieldNames[idx];
123
+ ConfigValue typeVal = conf.get(fieldName);
124
+ switch (typeVal.valueType()) {
125
+ case STRING:
126
+ {
127
+ fieldTypes[idx] =
128
+ deserializeSeaTunnelDataType(
129
+ fieldNames[idx], (String) typeVal.unwrapped());
130
+ }
131
+ break;
132
+ case OBJECT:
133
+ {
134
+ fieldTypes[idx] = parseRowType((ConfigObject) typeVal);
135
+ }
136
+ break;
137
+ case LIST:
138
+ case NUMBER:
139
+ case BOOLEAN:
140
+ case NULL:
141
+ default:
142
+ throw new IllegalArgumentException(
143
+ String.format(
144
+ "Unsupported parse SeaTunnel Type from '%s'.",
145
+ typeVal.unwrapped()));
146
+ }
114
147
}
115
- return new SeaTunnelRowType(fieldsName, seaTunnelDataTypes );
148
+ return new SeaTunnelRowType(fieldNames, fieldTypes );
116
149
}
117
150
118
151
private static SeaTunnelDataType<?> parseMapType(String field, String columnStr) {
119
- String genericType = getGenericType(columnStr);
152
+ String genericType = getGenericType(columnStr).trim() ;
120
153
int index =
121
- genericType.startsWith(SqlType.DECIMAL.name())
154
+ genericType.toUpperCase(). startsWith(SqlType.DECIMAL.name())
122
155
?
123
156
// if map key is decimal, we should find the index of second ','
124
157
genericType.indexOf(",", genericType.indexOf(",") + 1)
125
158
:
126
159
// if map key is not decimal, we should find the index of first ','
127
160
genericType.indexOf(",");
128
- String keyGenericType = genericType.substring(0, index);
129
- String valueGenericType = genericType.substring(index + 1);
161
+ String keyGenericType = genericType.substring(0, index).trim() ;
162
+ String valueGenericType = genericType.substring(index + 1).trim() ;
130
163
return new MapType<>(
131
164
deserializeSeaTunnelDataType(field, keyGenericType),
132
165
deserializeSeaTunnelDataType(field, valueGenericType));
@@ -138,7 +171,7 @@ private static String getGenericType(String columnStr) {
138
171
}
139
172
140
173
private static SeaTunnelDataType<?> parseArrayType(String field, String columnStr) {
141
- String genericType = getGenericType(columnStr);
174
+ String genericType = getGenericType(columnStr).trim() ;
142
175
SeaTunnelDataType<?> dataType = deserializeSeaTunnelDataType(field, genericType);
143
176
switch (dataType.getSqlType()) {
144
177
case STRING:
@@ -158,7 +191,7 @@ private static SeaTunnelDataType<?> parseArrayType(String field, String columnSt
158
191
case DOUBLE:
159
192
return ArrayType.DOUBLE_ARRAY_TYPE;
160
193
default:
161
- throw CommonError.unsupportedDataType("SeaTunnel", columnStr , field);
194
+ throw CommonError.unsupportedDataType("SeaTunnel", genericType , field);
162
195
}
163
196
}
164
197
0 commit comments