This is an automated email from the ASF dual-hosted git repository.
snuyanzin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git
The following commit(s) were added to refs/heads/master by this push:
new cc633c644e5 [FLINK-40241][table-runtime] Support `VARIANT` as column
type in the 'raw' format
cc633c644e5 is described below
commit cc633c644e510eac74b06ab470e467b43a1987b2
Author: Ramin Gharib <[email protected]>
AuthorDate: Fri Aug 28 16:44:53 2026 +0200
[FLINK-40241][table-runtime] Support `VARIANT` as column type in the 'raw'
format
The 'raw' format now accepts a single VARIANT column, treating the bytes as
a JSON document. On read the bytes are decoded with 'raw.charset' and parsed
like PARSE_JSON with duplicate keys rejected; on write the value is rendered
with Variant#toJson and encoded with the same charset. The round trip is
value-lossless but not byte-lossless: insignificant whitespace is dropped and
object keys are ordered. 'raw.endianness' does not apply to VARIANT.
Combined with 'raw.line-delimiter' this reads and writes newline-delimited
JSON, one row per line.
---
.../docs/connectors/table/formats/raw.md | 11 ++++
docs/content/docs/connectors/table/formats/raw.md | 11 ++++
.../raw/RawFormatDeserializationSchema.java | 36 +++++++++++++
.../apache/flink/formats/raw/RawFormatFactory.java | 3 +-
.../formats/raw/RawFormatSerializationSchema.java | 28 +++++++++-
.../table/formats/raw/RawFormatFactoryTest.java | 42 ++++++++++++---
.../formats/raw/RawFormatLineDelimiterTest.java | 47 +++++++++++++++++
.../formats/raw/RawFormatSerDeSchemaTest.java | 61 +++++++++++++++++++---
8 files changed, 222 insertions(+), 17 deletions(-)
diff --git a/docs/content.zh/docs/connectors/table/formats/raw.md
b/docs/content.zh/docs/connectors/table/formats/raw.md
index 69b4acfa1a0..cb1f2aea4f6 100644
--- a/docs/content.zh/docs/connectors/table/formats/raw.md
+++ b/docs/content.zh/docs/connectors/table/formats/raw.md
@@ -178,6 +178,17 @@ Format 参数
<td><code>RAW</code></td>
<td>通过 RAW 类型的底层 TypeSerializer 序列化的字节序列。</td>
</tr>
+ <tr>
+ <td><code>VARIANT</code></td>
+ <td>A UTF-8 (by default) encoded JSON document.<br>
+ The encoding charset can be configured by 'raw.charset'.<br>
+ On read, the decoded text is parsed like <code>PARSE_JSON</code>, so
duplicate object keys are rejected and
+ malformed JSON fails the job. On write, the value is rendered by
<code>Variant#toJson</code>. The round trip is
+ value-lossless but not byte-lossless: insignificant whitespace is
dropped and object keys are ordered.</td>
+ </tr>
</tbody>
</table>
+Note: combining `VARIANT` with `raw.line-delimiter` gives you
newline-delimited JSON, where each line of a message
+becomes one row.
+
diff --git a/docs/content/docs/connectors/table/formats/raw.md
b/docs/content/docs/connectors/table/formats/raw.md
index 1efdd2b40ee..3e2a2c60e8b 100644
--- a/docs/content/docs/connectors/table/formats/raw.md
+++ b/docs/content/docs/connectors/table/formats/raw.md
@@ -180,6 +180,17 @@ The table below details the SQL types the format supports,
including details of
<td><code>RAW</code></td>
<td>The sequence of bytes serialized by the underlying TypeSerializer of
the RAW type.</td>
</tr>
+ <tr>
+ <td><code>VARIANT</code></td>
+ <td>A UTF-8 (by default) encoded JSON document.<br>
+ The encoding charset can be configured by 'raw.charset'.<br>
+ On read, the decoded text is parsed like <code>PARSE_JSON</code>, so
duplicate object keys are rejected and
+ malformed JSON fails the job. On write, the value is rendered by
<code>Variant#toJson</code>. The round trip is
+ value-lossless but not byte-lossless: insignificant whitespace is
dropped and object keys are ordered.</td>
+ </tr>
</tbody>
</table>
+Note: combining `VARIANT` with `raw.line-delimiter` gives you
newline-delimited JSON, where each line of a message
+becomes one row.
+
diff --git
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatDeserializationSchema.java
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatDeserializationSchema.java
index 4ac4f82f464..870d4d1a429 100644
---
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatDeserializationSchema.java
+++
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatDeserializationSchema.java
@@ -29,6 +29,8 @@ import org.apache.flink.table.data.RowData;
import org.apache.flink.table.data.StringData;
import org.apache.flink.table.types.logical.LogicalType;
import org.apache.flink.types.DeserializationException;
+import org.apache.flink.types.variant.BinaryVariantInternalBuilder;
+import org.apache.flink.types.variant.Variant;
import org.apache.flink.util.Collector;
import javax.annotation.Nullable;
@@ -210,6 +212,9 @@ public class RawFormatDeserializationSchema implements
DeserializationSchema<Row
case RAW:
return RawValueData::fromBytes;
+ case VARIANT:
+ return createVariantConverter(charsetName);
+
case BOOLEAN:
return data -> data[0] != 0;
@@ -278,6 +283,36 @@ public class RawFormatDeserializationSchema implements
DeserializationSchema<Row
};
}
+ /**
+ * Creates a converter that decodes the bytes with the configured charset
and parses the text as
+ * a JSON document into a {@link Variant}. Duplicate object keys are
rejected, matching the
+ * default of {@code PARSE_JSON}.
+ */
+ private static DeserializationRuntimeConverter createVariantConverter(
+ final String charsetName) {
+ return new DeserializationRuntimeConverter() {
+ private static final long serialVersionUID = 1L;
+ private transient Charset charset;
+
+ @Override
+ public void open() {
+ charset = Charset.forName(charsetName);
+ }
+
+ @Override
+ public Object convert(byte[] data) {
+ try {
+ return BinaryVariantInternalBuilder.parseJson(new
String(data, charset), false);
+ } catch (Exception e) {
+ throw new DeserializationException(
+ "Failed to deserialize VARIANT type. "
+ + "The received data is not a valid JSON
document.",
+ e);
+ }
+ }
+ };
+ }
+
private static DeserializationRuntimeConverter
createEndiannessAwareConverter(
final boolean isBigEndian,
final MemorySegmentConverter bigEndianConverter,
@@ -302,6 +337,7 @@ public class RawFormatDeserializationSchema implements
DeserializationSchema<Row
case VARBINARY:
case BINARY:
case RAW:
+ case VARIANT:
return data -> {};
case BOOLEAN:
return createDataLengthValidator(1, "BOOLEAN");
diff --git
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatFactory.java
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatFactory.java
index 05b52cf2c94..61adff04473 100644
---
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatFactory.java
+++
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatFactory.java
@@ -150,7 +150,8 @@ public class RawFormatFactory implements
DeserializationFormatFactory, Serializa
LogicalTypeRoot.INTEGER,
LogicalTypeRoot.BIGINT,
LogicalTypeRoot.FLOAT,
- LogicalTypeRoot.DOUBLE);
+ LogicalTypeRoot.DOUBLE,
+ LogicalTypeRoot.VARIANT);
/** Checks the given field type is supported. */
private static void checkFieldType(LogicalType fieldType) {
diff --git
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatSerializationSchema.java
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatSerializationSchema.java
index 2f16dee5caa..1661b154bbd 100644
---
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatSerializationSchema.java
+++
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/formats/raw/RawFormatSerializationSchema.java
@@ -26,6 +26,8 @@ import org.apache.flink.core.memory.MemorySegmentFactory;
import org.apache.flink.table.data.RowData;
import org.apache.flink.table.types.logical.LogicalType;
import org.apache.flink.table.types.logical.RawType;
+import org.apache.flink.types.variant.Variant;
+import org.apache.flink.types.variant.VariantTypeException;
import javax.annotation.Nullable;
@@ -89,7 +91,7 @@ public class RawFormatSerializationSchema implements
SerializationSchema<RowData
byte[] result = Arrays.copyOf(valueBytes, valueBytes.length +
delimiterBytes.length);
System.arraycopy(delimiterBytes, 0, result, valueBytes.length,
delimiterBytes.length);
return result;
- } catch (IOException e) {
+ } catch (IOException | VariantTypeException e) {
throw new RuntimeException("Could not serialize row '" + row + "'.
", e);
}
}
@@ -164,6 +166,9 @@ public class RawFormatSerializationSchema implements
SerializationSchema<RowData
case RAW:
return createRawValueConverter((RawType<?>) type);
+ case VARIANT:
+ return createVariantConverter(charsetName);
+
case BOOLEAN:
return row -> {
byte b = (byte) (row.getBoolean(0) ? 1 : 0);
@@ -220,6 +225,27 @@ public class RawFormatSerializationSchema implements
SerializationSchema<RowData
};
}
+ /**
+ * Creates a converter that renders the {@link Variant} as a JSON
document. The result is
+ * value-lossless but not byte-lossless: whitespace and object key order
are normalized.
+ */
+ private static SerializationRuntimeConverter createVariantConverter(final
String charsetName) {
+ return new SerializationRuntimeConverter() {
+ private static final long serialVersionUID = 1L;
+ private transient Charset charset;
+
+ @Override
+ public void open() {
+ charset = Charset.forName(charsetName);
+ }
+
+ @Override
+ public byte[] convert(RowData row) {
+ return row.getVariant(0).toJson().getBytes(charset);
+ }
+ };
+ }
+
@SuppressWarnings("unchecked")
private static SerializationRuntimeConverter
createRawValueConverter(RawType<?> rawType) {
final TypeSerializer<Object> serializer =
diff --git
a/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatFactoryTest.java
b/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatFactoryTest.java
index 17ad29f9225..c2e210afd67 100644
---
a/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatFactoryTest.java
+++
b/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatFactoryTest.java
@@ -41,6 +41,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
+import static java.nio.charset.StandardCharsets.UTF_16;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.flink.core.testutils.FlinkAssertions.anyCauseMatches;
import static
org.apache.flink.table.factories.utils.FactoryMocks.createTableSink;
import static
org.apache.flink.table.factories.utils.FactoryMocks.createTableSource;
@@ -63,14 +65,14 @@ class RawFormatFactoryTest {
// test deserialization
final RawFormatDeserializationSchema expectedDeser =
new RawFormatDeserializationSchema(
- ROW_TYPE.getTypeAt(0), InternalTypeInfo.of(ROW_TYPE),
"UTF-8", true);
+ ROW_TYPE.getTypeAt(0), InternalTypeInfo.of(ROW_TYPE),
UTF_8.name(), true);
DeserializationSchema<RowData> actualDeser =
createDeserializationSchema(SCHEMA, tableOptions);
assertThat(actualDeser).isEqualTo(expectedDeser);
// test serialization
final RawFormatSerializationSchema expectedSer =
- new RawFormatSerializationSchema(ROW_TYPE.getTypeAt(0),
"UTF-8", true);
+ new RawFormatSerializationSchema(ROW_TYPE.getTypeAt(0),
UTF_8.name(), true);
SerializationSchema<RowData> actualSer =
createSerializationSchema(SCHEMA, tableOptions);
assertThat(actualSer).isEqualTo(expectedSer);
}
@@ -80,21 +82,21 @@ class RawFormatFactoryTest {
final Map<String, String> tableOptions =
getModifiedOptions(
options -> {
- options.put("raw.charset", "UTF-16");
+ options.put("raw.charset", UTF_16.name());
options.put("raw.endianness", "little-endian");
});
// test deserialization
final RawFormatDeserializationSchema expectedDeser =
new RawFormatDeserializationSchema(
- ROW_TYPE.getTypeAt(0), InternalTypeInfo.of(ROW_TYPE),
"UTF-16", false);
+ ROW_TYPE.getTypeAt(0), InternalTypeInfo.of(ROW_TYPE),
UTF_16.name(), false);
DeserializationSchema<RowData> actualDeser =
createDeserializationSchema(SCHEMA, tableOptions);
assertThat(actualDeser).isEqualTo(expectedDeser);
// test serialization
final RawFormatSerializationSchema expectedSer =
- new RawFormatSerializationSchema(ROW_TYPE.getTypeAt(0),
"UTF-16", false);
+ new RawFormatSerializationSchema(ROW_TYPE.getTypeAt(0),
UTF_16.name(), false);
SerializationSchema<RowData> actualSer =
createSerializationSchema(SCHEMA, tableOptions);
assertThat(actualSer).isEqualTo(expectedSer);
}
@@ -175,6 +177,28 @@ class RawFormatFactoryTest {
.hasMessage("The 'raw' format doesn't supports 'MAP<INT,
STRING>' as column type.");
}
+ @Test
+ void testVariantSeDeSchema() {
+ final ResolvedSchema variantSchema =
+ ResolvedSchema.of(Column.physical("field1",
DataTypes.VARIANT()));
+ final RowType variantRowType =
+ (RowType)
variantSchema.toPhysicalRowDataType().getLogicalType();
+ final Map<String, String> tableOptions = getBasicOptions();
+
+ final RawFormatDeserializationSchema expectedDeser =
+ new RawFormatDeserializationSchema(
+ variantRowType.getTypeAt(0),
+ InternalTypeInfo.of(variantRowType),
+ UTF_8.name(),
+ true);
+ assertThat(createDeserializationSchema(variantSchema, tableOptions))
+ .isEqualTo(expectedDeser);
+
+ final RawFormatSerializationSchema expectedSer =
+ new RawFormatSerializationSchema(variantRowType.getTypeAt(0),
UTF_8.name(), true);
+ assertThat(createSerializationSchema(variantSchema,
tableOptions)).isEqualTo(expectedSer);
+ }
+
@Test
void testLineDelimiterOption() {
final Map<String, String> tableOptions =
@@ -186,14 +210,18 @@ class RawFormatFactoryTest {
// test deserialization schema contains line delimiter
final RawFormatDeserializationSchema expectedDeser =
new RawFormatDeserializationSchema(
- ROW_TYPE.getTypeAt(0), InternalTypeInfo.of(ROW_TYPE),
"UTF-8", true, "\n");
+ ROW_TYPE.getTypeAt(0),
+ InternalTypeInfo.of(ROW_TYPE),
+ UTF_8.name(),
+ true,
+ "\n");
DeserializationSchema<RowData> actualDeser =
createDeserializationSchema(SCHEMA, tableOptions);
assertThat(actualDeser).isEqualTo(expectedDeser);
// test serialization schema contains line delimiter
final RawFormatSerializationSchema expectedSer =
- new RawFormatSerializationSchema(ROW_TYPE.getTypeAt(0),
"UTF-8", true, "\n");
+ new RawFormatSerializationSchema(ROW_TYPE.getTypeAt(0),
UTF_8.name(), true, "\n");
SerializationSchema<RowData> actualSer =
createSerializationSchema(SCHEMA, tableOptions);
assertThat(actualSer).isEqualTo(expectedSer);
}
diff --git
a/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatLineDelimiterTest.java
b/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatLineDelimiterTest.java
index 52652121698..122f1f1d1d2 100644
---
a/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatLineDelimiterTest.java
+++
b/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatLineDelimiterTest.java
@@ -28,14 +28,18 @@ import org.apache.flink.table.data.GenericRowData;
import org.apache.flink.table.data.RowData;
import org.apache.flink.table.data.StringData;
import org.apache.flink.table.types.logical.VarCharType;
+import org.apache.flink.table.types.logical.VariantType;
+import org.apache.flink.types.variant.BinaryVariantInternalBuilder;
import org.apache.flink.util.Collector;
import org.apache.flink.util.UserCodeClassLoader;
import org.junit.jupiter.api.Test;
+import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@@ -48,6 +52,8 @@ class RawFormatLineDelimiterTest {
private static final VarCharType STRING_TYPE = VarCharType.STRING_TYPE;
+ private static final VariantType VARIANT_TYPE = new VariantType();
+
// -----------------------------------------------------------------------
// Deserialization tests
// -----------------------------------------------------------------------
@@ -239,10 +245,45 @@ class RawFormatLineDelimiterTest {
assertThat(rows.get(0).getString(0)).hasToString("hello");
}
+ @Test
+ void testRoundTripNewlineDelimitedJsonAsVariant() throws Exception {
+ RawFormatSerializationSchema ser =
+ new RawFormatSerializationSchema(
+ VARIANT_TYPE, StandardCharsets.UTF_8.name(), true,
"\n");
+ openSer(ser);
+
+ RawFormatDeserializationSchema deser =
+ new RawFormatDeserializationSchema(
+ VARIANT_TYPE,
+ TypeInformation.of(RowData.class),
+ StandardCharsets.UTF_8.name(),
+ true,
+ "\n");
+ openDeser(deser);
+
+ byte[] stream =
+ concat(
+ ser.serialize(buildVariantRow("{\"id\":1}")),
+ ser.serialize(buildVariantRow("{\"id\":2}")));
+ assertThat(new String(stream, StandardCharsets.UTF_8))
+ .isEqualTo("{\"id\":1}\n{\"id\":2}\n");
+
+ List<RowData> rows = collectRows(deser, stream);
+ assertThat(rows).hasSize(2);
+
assertThat(rows.get(0).getVariant(0).getField("id").getByte()).isEqualTo((byte)
1);
+
assertThat(rows.get(1).getVariant(0).getField("id").getByte()).isEqualTo((byte)
2);
+ }
+
// -----------------------------------------------------------------------
// Helpers
// -----------------------------------------------------------------------
+ private static byte[] concat(byte[] first, byte[] second) {
+ byte[] result = Arrays.copyOf(first, first.length + second.length);
+ System.arraycopy(second, 0, result, first.length, second.length);
+ return result;
+ }
+
private void openDeser(RawFormatDeserializationSchema schema) throws
Exception {
schema.open(
new DeserializationSchema.InitializationContext() {
@@ -295,4 +336,10 @@ class RawFormatLineDelimiterTest {
row.setField(0, StringData.fromString(value));
return row;
}
+
+ private RowData buildVariantRow(String json) throws IOException {
+ GenericRowData row = new GenericRowData(1);
+ row.setField(0, BinaryVariantInternalBuilder.parseJson(json, false));
+ return row;
+ }
}
diff --git
a/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatSerDeSchemaTest.java
b/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatSerDeSchemaTest.java
index a4d7a6f67bb..83d0dc328d6 100644
---
a/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatSerDeSchemaTest.java
+++
b/flink-table/flink-table-runtime/src/test/java/org/apache/flink/table/formats/raw/RawFormatSerDeSchemaTest.java
@@ -30,6 +30,9 @@ import
org.apache.flink.table.data.conversion.DataStructureConverter;
import org.apache.flink.table.data.conversion.DataStructureConverters;
import org.apache.flink.table.types.DataType;
import org.apache.flink.types.Row;
+import org.apache.flink.types.variant.BinaryVariantInternalBuilder;
+import org.apache.flink.types.variant.Variant;
+import org.apache.flink.util.InstantiationUtil;
import org.apache.flink.util.StringUtils;
import org.junit.jupiter.params.ParameterizedTest;
@@ -56,6 +59,7 @@ import static org.apache.flink.table.api.DataTypes.SMALLINT;
import static org.apache.flink.table.api.DataTypes.STRING;
import static org.apache.flink.table.api.DataTypes.TINYINT;
import static org.apache.flink.table.api.DataTypes.VARCHAR;
+import static org.apache.flink.table.api.DataTypes.VARIANT;
import static org.apache.flink.util.StringUtils.hexStringToByte;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -63,6 +67,9 @@ import static org.mockito.Mockito.mock;
/** Tests for {@link RawFormatDeserializationSchema} {@link
RawFormatSerializationSchema}. */
class RawFormatSerDeSchemaTest {
+ private static final String JSON_OBJECT =
+ "{\"a\":1,\"b\":\"x\",\"c\":[1,2,3],\"d\":null,\"e\":true}";
+
static List<TestSpec> testData() {
return Arrays.asList(
TestSpec.type(TINYINT()).values(Byte.MAX_VALUE).binary(new
byte[] {Byte.MAX_VALUE}),
@@ -125,6 +132,29 @@ class RawFormatSerDeSchemaTest {
serializeLocalDateTime(
LocalDateTime.parse("2020-11-11T18:08:01.123"))),
+ // test variants, which are represented as JSON documents
+ TestSpec.type(VARIANT())
+ .values(variant(JSON_OBJECT))
+ .binary(JSON_OBJECT.getBytes(StandardCharsets.UTF_8)),
+
TestSpec.type(VARIANT()).values(variant("[1,2,3]")).binary("[1,2,3]".getBytes()),
+ TestSpec.type(VARIANT())
+ .values(variant("\"hello\""))
+ .binary("\"hello\"".getBytes()),
+
TestSpec.type(VARIANT()).values(variant("42")).binary("42".getBytes()),
+
TestSpec.type(VARIANT()).values(variant("3.5")).binary("3.5".getBytes()),
+
TestSpec.type(VARIANT()).values(variant("true")).binary("true".getBytes()),
+
TestSpec.type(VARIANT()).values(variant("null")).binary("null".getBytes()),
+ TestSpec.type(VARIANT())
+ .values(variant("{\"id\":1}"), variant("{\"id\":2}"),
variant("{\"id\":3}"))
+ .binary(
+ "{\"id\":1}".getBytes(),
+ "{\"id\":2}".getBytes(),
+ "{\"id\":3}".getBytes()),
+ TestSpec.type(VARIANT())
+ .values(variant("{\"greeting\":\"你好世界\"}"))
+ .withCharset("UTF-16")
+
.binary("{\"greeting\":\"你好世界\"}".getBytes(StandardCharsets.UTF_16)),
+
// test nulls
TestSpec.type(TINYINT()).values((Object) null).binary((byte[])
null),
TestSpec.type(SMALLINT()).values((Object)
null).binary((byte[]) null),
@@ -137,21 +167,28 @@ class RawFormatSerDeSchemaTest {
TestSpec.type(BYTES()).values((Object) null).binary((byte[])
null),
TestSpec.type(RAW(LocalDateTime.class, new
LocalDateTimeSerializer()))
.values((Object) null)
- .binary((byte[]) null));
+ .binary((byte[]) null),
+ TestSpec.type(VARIANT()).values((Object) null).binary((byte[])
null));
}
@ParameterizedTest
@MethodSource("testData")
void testSerializationAndDeserialization(final TestSpec testSpec) throws
Exception {
+ // Clone through serialization, as Flink does when shipping the schema
to a task manager.
+ // This also guards that the schema stays serializable for every
supported type.
RawFormatDeserializationSchema deserializationSchema =
- new RawFormatDeserializationSchema(
- testSpec.type.getLogicalType(),
- TypeInformation.of(RowData.class),
- testSpec.charsetName,
- testSpec.isBigEndian);
+ InstantiationUtil.clone(
+ new RawFormatDeserializationSchema(
+ testSpec.type.getLogicalType(),
+ TypeInformation.of(RowData.class),
+ testSpec.charsetName,
+ testSpec.isBigEndian));
RawFormatSerializationSchema serializationSchema =
- new RawFormatSerializationSchema(
- testSpec.type.getLogicalType(), testSpec.charsetName,
testSpec.isBigEndian);
+ InstantiationUtil.clone(
+ new RawFormatSerializationSchema(
+ testSpec.type.getLogicalType(),
+ testSpec.charsetName,
+ testSpec.isBigEndian));
deserializationSchema.open(mock(DeserializationSchema.InitializationContext.class));
serializationSchema.open(mock(SerializationSchema.InitializationContext.class));
@@ -186,6 +223,14 @@ class RawFormatSerDeSchemaTest {
}
}
+ private static Variant variant(String json) {
+ try {
+ return BinaryVariantInternalBuilder.parseJson(json, false);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private static byte[] serializeLocalDateTime(LocalDateTime localDateTime) {
DataOutputSerializer dos = new DataOutputSerializer(16);
LocalDateTimeSerializer serializer = new LocalDateTimeSerializer();