Skip to content

Commit 021af14

Browse files
litiliulitiliu
and
litiliu
authored
[Feature] [Postgre CDC]support array type (#8560)
Co-authored-by: litiliu <[email protected]>
1 parent c5751b0 commit 021af14

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/debezium/row/SeaTunnelRowDebeziumDeserializationConverters.java

+41
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
package org.apache.seatunnel.connectors.cdc.debezium.row;
1919

20+
import org.apache.seatunnel.shade.com.google.common.annotations.VisibleForTesting;
21+
22+
import org.apache.seatunnel.api.table.type.ArrayType;
2023
import org.apache.seatunnel.api.table.type.SeaTunnelDataType;
2124
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
2225
import org.apache.seatunnel.api.table.type.SeaTunnelRowType;
@@ -48,6 +51,7 @@
4851
import java.time.LocalTime;
4952
import java.time.ZoneId;
5053
import java.util.Arrays;
54+
import java.util.List;
5155
import java.util.Optional;
5256

5357
/** Deserialization schema from Debezium object to {@link SeaTunnelRow} */
@@ -173,12 +177,49 @@ public Object convert(Object dbzObj, Schema schema) throws Exception {
173177
return createRowConverter(
174178
(SeaTunnelRowType) type, serverTimeZone, userDefinedConverterFactory);
175179
case ARRAY:
180+
return createArrayConverter(type);
176181
case MAP:
177182
default:
178183
throw new UnsupportedOperationException("Unsupported type: " + type);
179184
}
180185
}
181186

187+
@VisibleForTesting
188+
protected static DebeziumDeserializationConverter createArrayConverter(
189+
SeaTunnelDataType<?> type) {
190+
SeaTunnelDataType elementType = ((ArrayType) type).getElementType();
191+
switch (elementType.getSqlType()) {
192+
case BOOLEAN:
193+
return (dbzObj, schema) ->
194+
convertListToArray((List<Boolean>) dbzObj, Boolean.class);
195+
case SMALLINT:
196+
return (dbzObj, schema) -> convertListToArray((List<Short>) dbzObj, Short.class);
197+
case INT:
198+
return (dbzObj, schema) ->
199+
convertListToArray((List<Integer>) dbzObj, Integer.class);
200+
case BIGINT:
201+
return (dbzObj, schema) -> convertListToArray((List<Long>) dbzObj, Long.class);
202+
case FLOAT:
203+
return (dbzObj, schema) -> convertListToArray((List<Float>) dbzObj, Float.class);
204+
case DOUBLE:
205+
return (dbzObj, schema) -> convertListToArray((List<Double>) dbzObj, Double.class);
206+
case STRING:
207+
return (dbzObj, schema) -> convertListToArray((List<String>) dbzObj, String.class);
208+
default:
209+
throw new IllegalArgumentException(
210+
"Unsupported SQL type: " + elementType.getSqlType());
211+
}
212+
}
213+
214+
@SuppressWarnings("unchecked")
215+
private static <T> T[] convertListToArray(List<T> list, Class<T> clazz) {
216+
T[] array = (T[]) java.lang.reflect.Array.newInstance(clazz, list.size());
217+
for (int i = 0; i < list.size(); i++) {
218+
array[i] = list.get(i);
219+
}
220+
return array;
221+
}
222+
182223
private static DebeziumDeserializationConverter convertToBoolean() {
183224
return new DebeziumDeserializationConverter() {
184225
private static final long serialVersionUID = 1L;

seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/test/java/org/apache/seatunnel/connectors/cdc/debezium/row/SeaTunnelRowDebeziumDeserializationConvertersTest.java

+52
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717

1818
package org.apache.seatunnel.connectors.cdc.debezium.row;
1919

20+
import org.apache.seatunnel.api.table.type.ArrayType;
2021
import org.apache.seatunnel.api.table.type.BasicType;
2122
import org.apache.seatunnel.api.table.type.SeaTunnelDataType;
2223
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
2324
import org.apache.seatunnel.api.table.type.SeaTunnelRowType;
25+
import org.apache.seatunnel.connectors.cdc.debezium.DebeziumDeserializationConverter;
2426
import org.apache.seatunnel.connectors.cdc.debezium.DebeziumDeserializationConverterFactory;
2527
import org.apache.seatunnel.connectors.cdc.debezium.MetadataConverter;
2628

@@ -34,6 +36,7 @@
3436

3537
import java.time.ZoneId;
3638
import java.util.ArrayList;
39+
import java.util.Arrays;
3740
import java.util.HashMap;
3841

3942
public class SeaTunnelRowDebeziumDeserializationConvertersTest {
@@ -75,4 +78,53 @@ void testDefaultValueNotUsed() throws Exception {
7578
Assertions.assertEquals(row.getField(0), 1);
7679
Assertions.assertNull(row.getField(1));
7780
}
81+
82+
@Test
83+
void testArrayConverter() throws Exception {
84+
DebeziumDeserializationConverter converter;
85+
// bool array converter
86+
converter =
87+
SeaTunnelRowDebeziumDeserializationConverters.createArrayConverter(
88+
ArrayType.BOOLEAN_ARRAY_TYPE);
89+
Boolean[] booleans = new Boolean[] {false, true};
90+
Assertions.assertTrue(
91+
Arrays.equals(
92+
booleans, (Boolean[]) (converter.convert(Arrays.asList(booleans), null))));
93+
// smallInt array converter
94+
converter =
95+
SeaTunnelRowDebeziumDeserializationConverters.createArrayConverter(
96+
ArrayType.SHORT_ARRAY_TYPE);
97+
Short[] shorts = new Short[] {(short) 1, (short) 2};
98+
Assertions.assertTrue(
99+
Arrays.equals(shorts, (Short[]) (converter.convert(Arrays.asList(shorts), null))));
100+
// int array converter
101+
converter =
102+
SeaTunnelRowDebeziumDeserializationConverters.createArrayConverter(
103+
ArrayType.INT_ARRAY_TYPE);
104+
Integer[] ints = new Integer[] {1, 2};
105+
Assertions.assertTrue(
106+
Arrays.equals(ints, (Integer[]) (converter.convert(Arrays.asList(ints), null))));
107+
// long array converter
108+
converter =
109+
SeaTunnelRowDebeziumDeserializationConverters.createArrayConverter(
110+
ArrayType.LONG_ARRAY_TYPE);
111+
Long[] longs = new Long[] {1L, 2L};
112+
Assertions.assertTrue(
113+
Arrays.equals(longs, (Long[]) (converter.convert(Arrays.asList(longs), null))));
114+
// float array converter
115+
converter =
116+
SeaTunnelRowDebeziumDeserializationConverters.createArrayConverter(
117+
ArrayType.FLOAT_ARRAY_TYPE);
118+
Float[] floats = new Float[] {1.0f, 2.0f};
119+
Assertions.assertTrue(
120+
Arrays.equals(floats, (Float[]) (converter.convert(Arrays.asList(floats), null))));
121+
// double array converter
122+
converter =
123+
SeaTunnelRowDebeziumDeserializationConverters.createArrayConverter(
124+
ArrayType.DOUBLE_ARRAY_TYPE);
125+
Double[] doubles = new Double[] {1.0, 2.0};
126+
Assertions.assertTrue(
127+
Arrays.equals(
128+
doubles, (Double[]) (converter.convert(Arrays.asList(doubles), null))));
129+
}
78130
}

0 commit comments

Comments
 (0)