25
25
import org .apache .flink .cdc .common .data .binary .BinaryMapData ;
26
26
import org .apache .flink .cdc .common .data .binary .BinaryRecordData ;
27
27
import org .apache .flink .cdc .common .event .DataChangeEvent ;
28
+ import org .apache .flink .cdc .common .event .TableId ;
28
29
import org .apache .flink .cdc .common .schema .Column ;
29
30
import org .apache .flink .cdc .common .schema .Schema ;
30
31
import org .apache .flink .cdc .common .types .DataType ;
31
32
import org .apache .flink .cdc .common .types .DataTypeChecks ;
32
33
import org .apache .flink .cdc .common .types .DataTypeRoot ;
34
+ import org .apache .flink .cdc .common .types .utils .DataTypeUtils ;
35
+ import org .apache .flink .cdc .connectors .paimon .sink .v2 .bucket .BucketAssignOperator ;
33
36
import org .apache .flink .core .memory .MemorySegment ;
37
+ import org .apache .flink .table .types .utils .TypeConversions ;
34
38
39
+ import org .apache .paimon .catalog .Identifier ;
35
40
import org .apache .paimon .data .BinaryRow ;
36
41
import org .apache .paimon .data .BinaryString ;
37
42
import org .apache .paimon .data .Decimal ;
38
43
import org .apache .paimon .data .GenericRow ;
39
44
import org .apache .paimon .data .InternalRow ;
40
45
import org .apache .paimon .data .Timestamp ;
46
+ import org .apache .paimon .flink .LogicalTypeConversion ;
41
47
import org .apache .paimon .memory .MemorySegmentUtils ;
48
+ import org .apache .paimon .table .Table ;
42
49
import org .apache .paimon .types .RowKind ;
50
+ import org .apache .paimon .types .RowType ;
43
51
44
52
import java .nio .ByteBuffer ;
45
53
import java .time .ZoneId ;
46
54
import java .util .ArrayList ;
47
55
import java .util .List ;
56
+ import java .util .stream .Collectors ;
48
57
49
58
import static org .apache .flink .cdc .common .types .DataTypeChecks .getFieldCount ;
50
59
51
- /** A helper class for {@link PaimonWriter} to create FieldGetter and GenericRow. */
60
+ /**
61
+ * A helper class to deduce Schema of paimon table for {@link BucketAssignOperator}, and create
62
+ * FieldGetter and GenericRow for {@link PaimonWriter}.
63
+ */
52
64
public class PaimonWriterHelper {
53
65
54
66
/** create a list of {@link RecordData.FieldGetter} for {@link PaimonWriter}. */
@@ -61,6 +73,33 @@ public static List<RecordData.FieldGetter> createFieldGetters(Schema schema, Zon
61
73
return fieldGetters ;
62
74
}
63
75
76
+ /**
77
+ * Check if the columns of upstream schema is the same as the physical schema.
78
+ *
79
+ * <p>Note: Default value of column was ignored as it has no influence in {@link
80
+ * #createFieldGetter(DataType, int, ZoneId)}.
81
+ */
82
+ public static Boolean sameColumnsIgnoreCommentAndDefaultValue (
83
+ Schema upstreamSchema , Schema physicalSchema ) {
84
+ List <Column > upstreamColumns = upstreamSchema .getColumns ();
85
+ List <Column > physicalColumns = physicalSchema .getColumns ();
86
+ if (upstreamColumns .size () != physicalColumns .size ()) {
87
+ return false ;
88
+ }
89
+ for (int i = 0 ; i < physicalColumns .size (); i ++) {
90
+ Column upstreamColumn = upstreamColumns .get (i );
91
+ Column physicalColumn = physicalColumns .get (i );
92
+ // Case sensitive.
93
+ if (!upstreamColumn .getName ().equals (physicalColumn .getName ())) {
94
+ return false ;
95
+ }
96
+ if (!upstreamColumn .getType ().equals (physicalColumn .getType ())) {
97
+ return false ;
98
+ }
99
+ }
100
+ return true ;
101
+ }
102
+
64
103
private static RecordData .FieldGetter createFieldGetter (
65
104
DataType fieldType , int fieldPos , ZoneId zoneId ) {
66
105
final RecordData .FieldGetter fieldGetter ;
@@ -215,6 +254,32 @@ public static List<GenericRow> convertEventToFullGenericRows(
215
254
return fullGenericRows ;
216
255
}
217
256
257
+ /**
258
+ * Deduce {@link Schema} for a {@link Table}.
259
+ *
260
+ * <p>Note: default value was not included in the result.
261
+ */
262
+ public static Schema deduceSchemaForPaimonTable (Table table ) {
263
+ RowType rowType = table .rowType ();
264
+ Schema .Builder builder = Schema .newBuilder ();
265
+ builder .setColumns (
266
+ rowType .getFields ().stream ()
267
+ .map (
268
+ column ->
269
+ Column .physicalColumn (
270
+ column .name (),
271
+ DataTypeUtils .fromFlinkDataType (
272
+ TypeConversions .fromLogicalToDataType (
273
+ LogicalTypeConversion .toLogicalType (
274
+ column .type ()))),
275
+ column .description ()))
276
+ .collect (Collectors .toList ()));
277
+ builder .primaryKey (table .primaryKeys ());
278
+ table .comment ().ifPresent (builder ::comment );
279
+ builder .options (table .options ());
280
+ return builder .build ();
281
+ }
282
+
218
283
private static GenericRow convertRecordDataToGenericRow (
219
284
RecordData recordData , List <RecordData .FieldGetter > fieldGetters , RowKind rowKind ) {
220
285
GenericRow genericRow = new GenericRow (rowKind , recordData .getArity ());
@@ -340,4 +405,8 @@ public InternalRow readRowData(
340
405
return row ;
341
406
}
342
407
}
408
+
409
+ public static Identifier identifierFromTableId (TableId tableId ) {
410
+ return Identifier .fromString (tableId .identifier ());
411
+ }
343
412
}
0 commit comments