3030import java .util .ArrayDeque ;
3131import java .util .Arrays ;
3232import java .util .Deque ;
33+ import java .util .Optional ;
3334import org .apache .parquet .io .api .Binary ;
3435import org .apache .parquet .io .api .RecordConsumer ;
36+ import org .apache .parquet .schema .LogicalTypeAnnotation ;
3537import org .apache .parquet .schema .MessageType ;
3638import org .apache .parquet .schema .PrimitiveType .PrimitiveTypeName ;
3739import org .apache .parquet .schema .Type ;
@@ -202,6 +204,7 @@ private void validate(PrimitiveTypeName... ptypes) {
202204 @ Override
203205 public void addInteger (int value ) {
204206 validate (INT32 );
207+ validateUnsignedInteger (value );
205208 delegate .addInteger (value );
206209 }
207210
@@ -211,6 +214,7 @@ public void addInteger(int value) {
211214 @ Override
212215 public void addLong (long value ) {
213216 validate (INT64 );
217+ validateUnsignedLong (value );
214218 delegate .addLong (value );
215219 }
216220
@@ -249,4 +253,66 @@ public void addDouble(double value) {
249253 validate (DOUBLE );
250254 delegate .addDouble (value );
251255 }
256+
257+ private void validateUnsignedInteger (int value ) {
258+ Type currentType = types .peek ().asGroupType ().getType (fields .peek ());
259+ if (currentType != null && currentType .isPrimitive ()) {
260+ LogicalTypeAnnotation logicalType = currentType .asPrimitiveType ().getLogicalTypeAnnotation ();
261+ if (logicalType != null ) {
262+ logicalType .accept (new LogicalTypeAnnotation .LogicalTypeAnnotationVisitor <Void >() {
263+ @ Override
264+ public Optional <Void > visit (LogicalTypeAnnotation .IntLogicalTypeAnnotation intType ) {
265+ if (!intType .isSigned ()) {
266+ switch (intType .getBitWidth ()) {
267+ case 8 :
268+ if (value < 0 || value > 255 ) {
269+ throw new InvalidRecordException ("Value " + value
270+ + " is out of range for UINT_8 (0-255) in field "
271+ + currentType .getName ());
272+ }
273+ break ;
274+ case 16 :
275+ if (value < 0 || value > 65535 ) {
276+ throw new InvalidRecordException ("Value " + value
277+ + " is out of range for UINT_16 (0-65535) in field "
278+ + currentType .getName ());
279+ }
280+ break ;
281+ case 32 :
282+ case 64 :
283+ if (value < 0 ) {
284+ throw new InvalidRecordException ("Negative value " + value
285+ + " is not allowed for unsigned integer type "
286+ + currentType .getName ());
287+ }
288+ break ;
289+ }
290+ }
291+ return Optional .empty ();
292+ }
293+ });
294+ }
295+ }
296+ }
297+
298+ private void validateUnsignedLong (long value ) {
299+ Type currentType = types .peek ().asGroupType ().getType (fields .peek ());
300+ if (currentType != null && currentType .isPrimitive ()) {
301+ LogicalTypeAnnotation logicalType = currentType .asPrimitiveType ().getLogicalTypeAnnotation ();
302+ if (logicalType != null ) {
303+ logicalType .accept (new LogicalTypeAnnotation .LogicalTypeAnnotationVisitor <Void >() {
304+ @ Override
305+ public Optional <Void > visit (LogicalTypeAnnotation .IntLogicalTypeAnnotation intType ) {
306+ if (!intType .isSigned ()) {
307+ if (value < 0 ) {
308+ throw new InvalidRecordException ("Negative value " + value
309+ + " is not allowed for unsigned integer type " + currentType .getName ());
310+ }
311+ }
312+ return Optional .empty ();
313+ }
314+ });
315+ }
316+ }
317+ }
252318}
0 commit comments