This is an automated email from the ASF dual-hosted git repository.

zabetak 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 0a4f00d34d [CALCITE-6832] Redundant fields/nullable entries in STRUCT 
serialization to JSON
0a4f00d34d is described below

commit 0a4f00d34dda2eddc27f56bb1f526db3946ad69e
Author: Stamatis Zampetakis <[email protected]>
AuthorDate: Wed Feb 12 12:52:02 2025 +0100

    [CALCITE-6832] Redundant fields/nullable entries in STRUCT serialization to 
JSON
    
    The JSON serialization of a RelDatatypeField of type STRUCT contains 
redundant fields and nullable entries along with unnecessary nesting.
    
    The redundancy leads to wasted space and convoluted representation that is 
hard to follow especially when there are nested STRUCTS.
---
 .../apache/calcite/rel/externalize/RelJson.java    | 10 +---
 .../org/apache/calcite/plan/RelWriterTest.java     | 17 +++----
 .../calcite/rel/externalize/RelJsonTest.java       | 53 ++++++++++++++++++++++
 .../apache/calcite/rel/externalize/RelJsonTest.xml | 46 +++++++++++++++++++
 4 files changed, 107 insertions(+), 19 deletions(-)

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 c7539a427b..f65adc8962 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
@@ -558,15 +558,7 @@ private Object toJson(RelDataType node) {
   }
 
   private Object toJson(RelDataTypeField node) {
-    final Map<String, @Nullable Object> map;
-    if (node.getType().isStruct()) {
-      map = jsonBuilder().map();
-      map.put("fields", toJson(node.getType()));
-      map.put("nullable", node.getType().isNullable());
-    } else {
-      //noinspection unchecked
-      map = (Map<String, @Nullable Object>) toJson(node.getType());
-    }
+    Map<String, Object> map = (Map<String, Object>) toJson(node.getType());
     map.put("name", node.getName());
     return map;
   }
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 32252f8964..6e06867411 100644
--- a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
@@ -489,16 +489,13 @@ private static Fixture relFn(Function<RelBuilder, 
RelNode> relFn) {
           + "      \"name\": \"v\"\n"
           + "    },\n"
           + "    {\n"
-          + "      \"fields\": {\n"
-          + "        \"fields\": [\n"
-          + "          {\n"
-          + "            \"type\": \"DATE\",\n"
-          + "            \"nullable\": false,\n"
-          + "            \"name\": \"d\"\n"
-          + "          }\n"
-          + "        ],\n"
-          + "        \"nullable\": false\n"
-          + "      },\n"
+          + "      \"fields\": [\n"
+          + "        {\n"
+          + "          \"type\": \"DATE\",\n"
+          + "          \"nullable\": false,\n"
+          + "          \"name\": \"d\"\n"
+          + "        }\n"
+          + "      ],\n"
           + "      \"nullable\": false,\n"
           + "      \"name\": \"r\"\n"
           + "    }\n"
diff --git 
a/core/src/test/java/org/apache/calcite/rel/externalize/RelJsonTest.java 
b/core/src/test/java/org/apache/calcite/rel/externalize/RelJsonTest.java
new file mode 100644
index 0000000000..07d823bac8
--- /dev/null
+++ b/core/src/test/java/org/apache/calcite/rel/externalize/RelJsonTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.rel.externalize;
+
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.type.RelDataTypeField;
+import org.apache.calcite.rel.type.RelDataTypeFieldImpl;
+import org.apache.calcite.rel.type.RelDataTypeSystem;
+import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.test.DiffRepository;
+import org.apache.calcite.util.JsonBuilder;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for @{@link RelJson}.
+ */
+public class RelJsonTest {
+
+  private static final DiffRepository REPO =  
DiffRepository.lookup(RelJsonTest.class);
+
+  @Test void testToJsonWithStructRelDatatypeField() {
+    RelDataTypeFactory typeFactory = new 
SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    RelDataType type = typeFactory.builder()
+        .add("street", SqlTypeName.VARCHAR, 50)
+        .add("number", SqlTypeName.INTEGER)
+        .add("building", SqlTypeName.VARCHAR, 20).nullable(true)
+        .build();
+    RelDataTypeField address =
+        new RelDataTypeFieldImpl("address", 0, type);
+
+    JsonBuilder builder = new JsonBuilder();
+    Object jsonObj = RelJson.create().withJsonBuilder(builder).toJson(address);
+    REPO.assertEquals("content", "${content}", builder.toJsonString(jsonObj));
+  }
+
+}
diff --git 
a/core/src/test/resources/org/apache/calcite/rel/externalize/RelJsonTest.xml 
b/core/src/test/resources/org/apache/calcite/rel/externalize/RelJsonTest.xml
new file mode 100644
index 0000000000..7918106bdc
--- /dev/null
+++ b/core/src/test/resources/org/apache/calcite/rel/externalize/RelJsonTest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" ?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to you under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<Root>
+  <TestCase name="testToJsonWithStructRelDatatypeField">
+    <Resource name="content">
+      <![CDATA[{
+  "fields": [
+    {
+      "type": "VARCHAR",
+      "nullable": false,
+      "precision": 50,
+      "name": "street"
+    },
+    {
+      "type": "INTEGER",
+      "nullable": false,
+      "name": "number"
+    },
+    {
+      "type": "VARCHAR",
+      "nullable": true,
+      "precision": 20,
+      "name": "building"
+    }
+  ],
+  "nullable": false,
+  "name": "address"
+}]]>
+    </Resource>
+  </TestCase>
+</Root>

Reply via email to