This is an automated email from the ASF dual-hosted git repository.
zhenchen 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 570c412f2d [CALCITE-5199] The leastRestrictiveStructuredType method
should reserve the StructKind instead of override it to FULLY_QUALIFIED
570c412f2d is described below
commit 570c412f2dbf114b56fb92220f6af670a559809a
Author: Zhen Chen <[email protected]>
AuthorDate: Thu Oct 23 07:16:15 2025 +0800
[CALCITE-5199] The leastRestrictiveStructuredType method should reserve the
StructKind instead of override it to FULLY_QUALIFIED
---
.../calcite/rel/type/RelDataTypeFactoryImpl.java | 3 +-
.../calcite/sql/type/SqlTypeFactoryTest.java | 38 ++++++++++++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git
a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java
b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java
index 7a7dc6eb2a..b5d901ec37 100644
--- a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java
+++ b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeFactoryImpl.java
@@ -237,7 +237,8 @@ private RelDataType createStructType(
}
// recursively compute column-wise least restrictive
- final Builder builder = builder();
+ // preserve the struct kind from type0
+ final Builder builder = builder().kind(type0.getStructKind());
for (int j = 0; j < fieldCount; ++j) {
// REVIEW jvs 22-Jan-2004: Always use the field name from the
// first type?
diff --git
a/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFactoryTest.java
b/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFactoryTest.java
index a85fff1bf0..09731bf3a5 100644
--- a/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFactoryTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/type/SqlTypeFactoryTest.java
@@ -20,6 +20,7 @@
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rel.type.RelDataTypeFieldImpl;
import org.apache.calcite.rel.type.RelRecordType;
+import org.apache.calcite.rel.type.StructKind;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
@@ -346,4 +347,41 @@ private void checkCreateSqlTypeWithPrecision(
assertFalse(unknownType2.isNullable());
assertThat(unknownType2.getFullTypeString(), is("UNKNOWN NOT NULL"));
}
+
+ /** Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-5199">[CALCITE-5199]
+ * The leastRestrictiveStructuredType method should reserve the StructKind
instead of
+ * override it to FULLY_QUALIFIED</a>. */
+ @Test void testLeastRestrictiveStructurePreservesStructKind() {
+ SqlTypeFixture f = new SqlTypeFixture();
+ RelDataTypeFactory typeFactory = f.typeFactory;
+
+ // Test with PEEK_FIELDS
+ testStructKindPreservation(typeFactory, f, StructKind.PEEK_FIELDS);
+ // Test with PEEK_FIELDS_DEFAULT
+ testStructKindPreservation(typeFactory, f, StructKind.PEEK_FIELDS_DEFAULT);
+ }
+
+ private void testStructKindPreservation(
+ RelDataTypeFactory typeFactory, SqlTypeFixture f, StructKind kind) {
+ // Create two struct types with the specified kind
+ RelDataType struct1 =
+ typeFactory.createStructType(kind,
+ ImmutableList.of(f.sqlInt, f.sqlInt),
+ ImmutableList.of("i", "j"));
+ RelDataType struct2 =
+ typeFactory.createStructType(kind,
+ ImmutableList.of(f.sqlBigInt, f.sqlBigInt),
+ ImmutableList.of("i", "j"));
+
+ // Compute least restrictive type
+ RelDataType leastRestrictive =
+ typeFactory.leastRestrictive(ImmutableList.of(struct1, struct2));
+
+ // Verify the result is a struct type
+ assertThat(leastRestrictive.getSqlTypeName(), is(SqlTypeName.ROW));
+
+ // Verify the struct kind is preserved, not overridden to FULLY_QUALIFIED
+ assertThat(leastRestrictive.getStructKind(), is(kind));
+ }
}