1818
1919package org .apache .paimon .table .sink ;
2020
21+ import org .apache .paimon .data .BinaryRow ;
2122import org .apache .paimon .data .GenericRow ;
2223import org .apache .paimon .data .InternalRow ;
24+ import org .apache .paimon .data .serializer .InternalRowSerializer ;
2325import org .apache .paimon .schema .TableSchema ;
2426import org .apache .paimon .types .DataField ;
27+ import org .apache .paimon .types .DecimalType ;
2528import org .apache .paimon .types .IntType ;
29+ import org .apache .paimon .types .LocalZonedTimestampType ;
2630import org .apache .paimon .types .RowType ;
31+ import org .apache .paimon .types .TimestampType ;
2732
2833import org .junit .jupiter .api .Test ;
2934
3237import java .util .HashMap ;
3338import java .util .List ;
3439import java .util .Map ;
40+ import java .util .concurrent .ThreadLocalRandom ;
3541
3642import static org .apache .paimon .CoreOptions .BUCKET ;
3743import static org .apache .paimon .CoreOptions .BUCKET_KEY ;
44+ import static org .apache .paimon .table .sink .KeyAndBucketExtractor .bucketKeyHashCode ;
3845import static org .assertj .core .api .Assertions .assertThat ;
3946import static org .assertj .core .api .Assertions .assertThatThrownBy ;
4047
@@ -70,6 +77,30 @@ public void testIllegalBucket() {
7077 assertThatThrownBy (() -> bucket (extractor ("" , "" , "a" , -1 ), row ));
7178 }
7279
80+ @ Test
81+ public void testUnCompactDecimalAndTimestampNullValueBucketNumber () {
82+ GenericRow row = GenericRow .of (null , null , null , 1 );
83+ int bucketNum = ThreadLocalRandom .current ().nextInt (1 , Integer .MAX_VALUE );
84+
85+ RowType rowType =
86+ new RowType (
87+ Arrays .asList (
88+ new DataField (0 , "d" , new DecimalType (38 , 18 )),
89+ new DataField (1 , "ltz" , new LocalZonedTimestampType ()),
90+ new DataField (2 , "ntz" , new TimestampType ()),
91+ new DataField (3 , "k" , new IntType ())));
92+
93+ String [] bucketColsToTest = {"d" , "ltz" , "ntz" };
94+ for (String bucketCol : bucketColsToTest ) {
95+ FixedBucketRowKeyExtractor extractor = extractor (rowType , "" , bucketCol , "" , bucketNum );
96+ BinaryRow binaryRow =
97+ new InternalRowSerializer (rowType .project (bucketCol )).toBinaryRow (row );
98+ assertThat (bucket (extractor , row ))
99+ .isEqualTo (
100+ KeyAndBucketExtractor .bucket (bucketKeyHashCode (binaryRow ), bucketNum ));
101+ }
102+ }
103+
73104 private int bucket (FixedBucketRowKeyExtractor extractor , InternalRow row ) {
74105 extractor .setRecord (row );
75106 return extractor .bucket ();
@@ -91,6 +122,11 @@ private FixedBucketRowKeyExtractor extractor(
91122 new DataField (0 , "a" , new IntType ()),
92123 new DataField (1 , "b" , new IntType ()),
93124 new DataField (2 , "c" , new IntType ())));
125+ return extractor (rowType , partK , bk , pk , numBucket );
126+ }
127+
128+ private FixedBucketRowKeyExtractor extractor (
129+ RowType rowType , String partK , String bk , String pk , int numBucket ) {
94130 List <DataField > fields = TableSchema .newFields (rowType );
95131 Map <String , String > options = new HashMap <>();
96132 options .put (BUCKET_KEY .key (), bk );
0 commit comments