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
@@ -71,6 +78,30 @@ public void testIllegalBucket() {
7178 .hasMessageContaining ("Num bucket is illegal" );
7279 }
7380
81+ @ Test
82+ public void testUnCompactDecimalAndTimestampNullValueBucketNumber () {
83+ GenericRow row = GenericRow .of (null , null , null , 1 );
84+ int bucketNum = ThreadLocalRandom .current ().nextInt (1 , Integer .MAX_VALUE );
85+
86+ RowType rowType =
87+ new RowType (
88+ Arrays .asList (
89+ new DataField (0 , "d" , new DecimalType (38 , 18 )),
90+ new DataField (1 , "ltz" , new LocalZonedTimestampType ()),
91+ new DataField (2 , "ntz" , new TimestampType ()),
92+ new DataField (3 , "k" , new IntType ())));
93+
94+ String [] bucketColsToTest = {"d" , "ltz" , "ntz" };
95+ for (String bucketCol : bucketColsToTest ) {
96+ FixedBucketRowKeyExtractor extractor = extractor (rowType , "" , bucketCol , "" , bucketNum );
97+ BinaryRow binaryRow =
98+ new InternalRowSerializer (rowType .project (bucketCol )).toBinaryRow (row );
99+ assertThat (bucket (extractor , row ))
100+ .isEqualTo (
101+ KeyAndBucketExtractor .bucket (bucketKeyHashCode (binaryRow ), bucketNum ));
102+ }
103+ }
104+
74105 private int bucket (FixedBucketRowKeyExtractor extractor , InternalRow row ) {
75106 extractor .setRecord (row );
76107 return extractor .bucket ();
@@ -92,6 +123,11 @@ private FixedBucketRowKeyExtractor extractor(
92123 new DataField (0 , "a" , new IntType ()),
93124 new DataField (1 , "b" , new IntType ()),
94125 new DataField (2 , "c" , new IntType ())));
126+ return extractor (rowType , partK , bk , pk , numBucket );
127+ }
128+
129+ private FixedBucketRowKeyExtractor extractor (
130+ RowType rowType , String partK , String bk , String pk , int numBucket ) {
95131 List <DataField > fields = TableSchema .newFields (rowType );
96132 Map <String , String > options = new HashMap <>();
97133 options .put (BUCKET_KEY .key (), bk );
0 commit comments