2929import java .util .Optional ;
3030
3131import static com .fasterxml .jackson .core .JsonToken .END_ARRAY ;
32+ import static com .fasterxml .jackson .core .JsonToken .END_OBJECT ;
33+ import static com .fasterxml .jackson .core .JsonToken .FIELD_NAME ;
3234import static com .fasterxml .jackson .core .JsonToken .START_OBJECT ;
3335import static com .google .common .base .Preconditions .checkArgument ;
3436import static com .google .common .base .Verify .verify ;
@@ -87,16 +89,22 @@ private JsonDecodingUtils() {}
8789 private static final RealDecoder REAL_DECODER = new RealDecoder ();
8890 private static final BooleanDecoder BOOLEAN_DECODER = new BooleanDecoder ();
8991 private static final StringDecoder STRING_DECODER = new StringDecoder ();
90- private static final VariantDecoder VARIANT_DECODER = new VariantDecoder ();
92+ private static final VariantJsonDecoder VARIANT_JSON_DECODER = new VariantJsonDecoder ();
93+ private static final VariantBinaryDecoder VARIANT_BINARY_DECODER = new VariantBinaryDecoder ();
9194 private static final Base64Decoder BASE_64_DECODER = new Base64Decoder ();
9295 private static final ObjectDecoder OBJECT_DECODER = new ObjectDecoder ();
9396
9497 public static TypeDecoder [] createTypeDecoders (List <Column > columns )
98+ {
99+ return createTypeDecoders (columns , false );
100+ }
101+
102+ public static TypeDecoder [] createTypeDecoders (List <Column > columns , boolean supportsVariantBinary )
95103 {
96104 verify (!columns .isEmpty (), "Columns must not be empty" );
97105 TypeDecoder [] decoders = new TypeDecoder [columns .size ()];
98106 for (int i = 0 ; i < columns .size (); i ++) {
99- decoders [i ] = createTypeDecoder (columns .get (i ).getTypeSignature ());
107+ decoders [i ] = createTypeDecoder (columns .get (i ).getTypeSignature (), supportsVariantBinary );
100108 }
101109 return decoders ;
102110 }
@@ -107,7 +115,7 @@ Object decode(JsonParser parser)
107115 throws IOException ;
108116 }
109117
110- private static TypeDecoder createTypeDecoder (ClientTypeSignature signature )
118+ private static TypeDecoder createTypeDecoder (ClientTypeSignature signature , boolean supportsVariantBinary )
111119 {
112120 switch (signature .getRawType ()) {
113121 case BIGINT :
@@ -125,13 +133,13 @@ private static TypeDecoder createTypeDecoder(ClientTypeSignature signature)
125133 case BOOLEAN :
126134 return BOOLEAN_DECODER ;
127135 case VARIANT :
128- return VARIANT_DECODER ;
136+ return supportsVariantBinary ? VARIANT_BINARY_DECODER : VARIANT_JSON_DECODER ;
129137 case ARRAY :
130- return new ArrayDecoder (signature );
138+ return new ArrayDecoder (signature , supportsVariantBinary );
131139 case MAP :
132- return new MapDecoder (signature );
140+ return new MapDecoder (signature , supportsVariantBinary );
133141 case ROW :
134- return new RowDecoder (signature );
142+ return new RowDecoder (signature , supportsVariantBinary );
135143 case VARCHAR :
136144 case JSON :
137145 case TIME :
@@ -296,7 +304,7 @@ public Object decode(JsonParser parser)
296304 }
297305 }
298306
299- private static class VariantDecoder
307+ private static class VariantJsonDecoder
300308 implements TypeDecoder
301309 {
302310 @ Override
@@ -311,6 +319,46 @@ public Object decode(JsonParser parser)
311319 }
312320 }
313321
322+ private static class VariantBinaryDecoder
323+ implements TypeDecoder
324+ {
325+ @ Override
326+ public Object decode (JsonParser parser )
327+ throws IOException
328+ {
329+ if (requireNonNull (parser .currentToken ()) != START_OBJECT ) {
330+ throw illegalToken (parser );
331+ }
332+
333+ byte [] metadataBytes = null ;
334+ byte [] valueBytes = null ;
335+ while (parser .nextToken () != END_OBJECT ) {
336+ if (requireNonNull (parser .currentToken ()) != FIELD_NAME ) {
337+ throw illegalToken (parser );
338+ }
339+
340+ String fieldName = parser .currentName ();
341+ if (parser .nextToken () != JsonToken .VALUE_STRING ) {
342+ throw illegalToken (parser );
343+ }
344+
345+ switch (fieldName ) {
346+ case "metadata" :
347+ metadataBytes = Base64 .getDecoder ().decode (parser .getValueAsString ());
348+ break ;
349+ case "value" :
350+ valueBytes = Base64 .getDecoder ().decode (parser .getValueAsString ());
351+ break ;
352+ }
353+ }
354+
355+ if (metadataBytes == null || valueBytes == null ) {
356+ throw illegalToken (parser );
357+ }
358+ return EncodedVariant .fromBytes (metadataBytes , valueBytes );
359+ }
360+ }
361+
314362 private static class Base64Decoder
315363 implements TypeDecoder
316364 {
@@ -327,11 +375,11 @@ private static class ArrayDecoder
327375 {
328376 private final TypeDecoder typeDecoder ;
329377
330- public ArrayDecoder (ClientTypeSignature signature )
378+ public ArrayDecoder (ClientTypeSignature signature , boolean supportsVariantBinary )
331379 {
332380 requireNonNull (signature , "signature is null" );
333381 checkArgument (signature .getRawType ().equals (ARRAY ), "not an array type signature: %s" , signature );
334- this .typeDecoder = createTypeDecoder (signature .getArgumentsAsTypeSignatures ().get (0 ));
382+ this .typeDecoder = createTypeDecoder (signature .getArgumentsAsTypeSignatures ().get (0 ), supportsVariantBinary );
335383 }
336384
337385 @ Override
@@ -363,12 +411,12 @@ private static class MapDecoder
363411 private final String keyType ;
364412 private final TypeDecoder valueDecoder ;
365413
366- public MapDecoder (ClientTypeSignature signature )
414+ public MapDecoder (ClientTypeSignature signature , boolean supportsVariantBinary )
367415 {
368416 requireNonNull (signature , "signature is null" );
369417 checkArgument (signature .getRawType ().equals (MAP ), "not a map type signature: %s" , signature );
370418 this .keyType = signature .getArgumentsAsTypeSignatures ().get (0 ).getRawType ();
371- this .valueDecoder = createTypeDecoder (signature .getArgumentsAsTypeSignatures ().get (1 ));
419+ this .valueDecoder = createTypeDecoder (signature .getArgumentsAsTypeSignatures ().get (1 ), supportsVariantBinary );
372420 }
373421
374422 @ Override
@@ -446,7 +494,7 @@ private static class RowDecoder
446494 private final TypeDecoder [] fieldDecoders ;
447495 private final List <Optional <String >> fieldNames ;
448496
449- private RowDecoder (ClientTypeSignature signature )
497+ private RowDecoder (ClientTypeSignature signature , boolean supportsVariantBinary )
450498 {
451499 requireNonNull (signature , "signature is null" );
452500 checkArgument (signature .getRawType ().equals (ROW ), "not a row type signature: %s" , signature );
@@ -455,7 +503,7 @@ private RowDecoder(ClientTypeSignature signature)
455503
456504 int index = 0 ;
457505 for (ClientTypeSignatureParameter parameter : signature .getArguments ()) {
458- fieldDecoders [index ] = createTypeDecoder (parameter .getTypeSignature ());
506+ fieldDecoders [index ] = createTypeDecoder (parameter .getTypeSignature (), supportsVariantBinary );
459507 fieldNames .add (parameter .getName ());
460508 index ++;
461509 }
0 commit comments