Skip to content

Commit

Permalink
[CALCITE-6832] Redundant fields/nullable entries in STRUCT serializat…
Browse files Browse the repository at this point in the history
…ion 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.
  • Loading branch information
zabetak committed Feb 21, 2025
1 parent 5f1f2ff commit 0a4f00d
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
17 changes: 7 additions & 10 deletions core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -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));
}

}
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit 0a4f00d

Please sign in to comment.