This is an automated email from the ASF dual-hosted git repository.
mbudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new a541ce7a9c [CALCITE-6992] RelJson cannot serialize UUID literals
a541ce7a9c is described below
commit a541ce7a9cb528b1a7870f3b723acda62c4f1828
Author: Mihai Budiu <[email protected]>
AuthorDate: Tue Apr 29 17:46:04 2025 -0700
[CALCITE-6992] RelJson cannot serialize UUID literals
Signed-off-by: Mihai Budiu <[email protected]>
---
.../apache/calcite/rel/externalize/RelJson.java | 5 ++
.../java/org/apache/calcite/rex/RexBuilder.java | 2 +
.../org/apache/calcite/plan/RelWriterTest.java | 67 ++++++++++++++++++++++
3 files changed, 74 insertions(+)
diff --git a/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
b/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
index d619957cdd..a0d09e13a3 100644
--- a/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
+++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelJson.java
@@ -98,6 +98,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
import static org.apache.calcite.rel.RelDistributions.EMPTY;
import static org.apache.calcite.util.Static.RESOURCE;
@@ -495,6 +496,8 @@ public Object toJson(AggregateCall node) {
return toJson((Range) value);
} else if (value instanceof ByteString) {
return toJson(((ByteString) value).toString(16));
+ } else if (value instanceof UUID) {
+ return toJson(value.toString());
} else {
throw new UnsupportedOperationException("type not serializable as JSON: "
+ value + " (type " + value.getClass().getCanonicalName() + ")");
@@ -834,6 +837,8 @@ public RexNode toRex(RelOptCluster cluster, Object o) {
}
} else if (sqlTypeName == SqlTypeName.BINARY || sqlTypeName ==
SqlTypeName.VARBINARY) {
literal = ByteString.of((String) literal, 16);
+ } else if (sqlTypeName == SqlTypeName.UUID) {
+ literal = UUID.fromString((String) literal);
}
return rexBuilder.makeLiteral(literal, type);
}
diff --git a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
index e4317ddbf6..f50abd7b74 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
@@ -2179,6 +2179,8 @@ public RexNode makeLiteral(@Nullable Object value,
RelDataType type,
SqlTypeName.GEOMETRY);
case ANY:
return makeLiteral(value, guessType(value), allowCast);
+ case UUID:
+ return makeUuidLiteral((UUID) value);
default:
throw new IllegalArgumentException(
"Cannot create literal for type '" + sqlTypeName + "'");
diff --git a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
index 94512760b2..8fd02a8c50 100644
--- a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
@@ -99,6 +99,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
@@ -603,6 +604,50 @@ private static Fixture relFn(Function<RelBuilder, RelNode>
relFn) {
.assertThatJson(isLinux(BINARY_LITERAL));
}
+ static final String UUID_LITERAL = "{\n"
+ + " \"rels\": [\n"
+ + " {\n"
+ + " \"id\": \"0\",\n"
+ + " \"relOp\": \"LogicalValues\",\n"
+ + " \"type\": [\n"
+ + " {\n"
+ + " \"type\": \"UUID\",\n"
+ + " \"nullable\": false,\n"
+ + " \"name\": \"$f0\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"tuples\": [\n"
+ + " [\n"
+ + " {\n"
+ + " \"literal\": \"123e4567-e89b-12d3-a456-426655440000\",\n"
+ + " \"type\": {\n"
+ + " \"type\": \"UUID\",\n"
+ + " \"nullable\": false\n"
+ + " }\n"
+ + " }\n"
+ + " ]\n"
+ + " ],\n"
+ + " \"inputs\": []\n"
+ + " }\n"
+ + " ]\n"
+ + "}";
+
+ /** Test case for <a
href="https://issues.apache.org/jira/browse/CALCITE-6992">
+ * [CALCITE 6992] RelJson cannot serialize UUID literals</a>. */
+ @Test void testUuid() {
+ final Function<RelBuilder, RelNode> relFn = b -> {
+ RelDataType rowType = b.getTypeFactory().builder()
+ .add("a", SqlTypeName.INTEGER)
+ .build();
+ return b.values(rowType, 0).project(
+ b.getRexBuilder().makeUuidLiteral(
+ UUID.fromString("123e4567-e89b-12d3-a456-426655440000")))
+ .build();
+ };
+ relFn(relFn)
+ .assertThatJson(isLinux(UUID_LITERAL));
+ }
+
/**
* Unit test for {@link org.apache.calcite.rel.externalize.RelJsonWriter} on
* a simple tree of relational expressions, consisting of a table, a filter
@@ -730,6 +775,28 @@ private static Fixture relFn(Function<RelBuilder, RelNode>
relFn) {
isLinux("LogicalValues(tuples=[[{ X'0a4b' }]])\n"));
}
+ @Test void testReaderUuid() {
+ String s =
+ Frameworks.withPlanner((cluster, relOptSchema, rootSchema) -> {
+ SchemaPlus schema =
+ rootSchema.add("hr",
+ new ReflectiveSchema(new HrSchema()));
+ final RelJsonReader reader =
+ new RelJsonReader(cluster, relOptSchema, schema);
+ RelNode node;
+ try {
+ node = reader.read(UUID_LITERAL);
+ } catch (IOException e) {
+ throw TestUtil.rethrow(e);
+ }
+ return RelOptUtil.dumpPlan("", node, SqlExplainFormat.TEXT,
+ SqlExplainLevel.EXPPLAN_ATTRIBUTES);
+ });
+
+ assertThat(s,
+ isLinux("LogicalValues(tuples=[[{ 123e4567-e89b-12d3-a456-426655440000
}]])\n"));
+ }
+
/**
* Unit test for {@link org.apache.calcite.rel.externalize.RelJsonReader}.
*/