This is an automated email from the ASF dual-hosted git repository.
mihaibudiu 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 ff3cfd17be [CALCITE-7606] ROW field names should be used to infer
column names
ff3cfd17be is described below
commit ff3cfd17be8d095ed2e02e45492e23245ee545be
Author: Mihai Budiu <[email protected]>
AuthorDate: Mon Jun 15 21:53:22 2026 -0700
[CALCITE-7606] ROW field names should be used to infer column names
Signed-off-by: Mihai Budiu <[email protected]>
---
.../calcite/sql/validate/SqlValidatorUtil.java | 4 +++
.../org/apache/calcite/test/SqlValidatorTest.java | 2 +-
.../apache/calcite/test/SqlToRelConverterTest.xml | 12 ++++----
core/src/test/resources/sql/struct.iq | 35 +++++++++++-----------
4 files changed, 29 insertions(+), 24 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
index f05c58a8c7..1c5bfcf9a6 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
@@ -366,6 +366,10 @@ public static String alias(SqlNode node, int ordinal) {
// E.g. "foo.bar" --> "bar"
return Util.last(((SqlIdentifier) node).names);
+ case DOT:
+ // E.g. "row(a as x).x" --> "x"
+ return alias_(((SqlCall) node).operand(1), ordinal);
+
default:
if (ordinal < 0) {
return null;
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index f473cf60db..0fd03a456b 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -14266,7 +14266,7 @@ private static String missingFilters(String... args) {
@Test void testAccessingNestedFieldsOfNullableRecord() {
sql("select ROW_COLUMN_ARRAY[0].NOT_NULL_FIELD from NULLABLEROWS.NR_T1")
.withExtendedCatalog()
- .type("RecordType(BIGINT EXPR$0) NOT NULL");
+ .type("RecordType(BIGINT NOT_NULL_FIELD) NOT NULL");
sql("select ROW_COLUMN_ARRAY[0]['NOT_NULL_FIELD'] from NULLABLEROWS.NR_T1")
.withExtendedCatalog()
.type("RecordType(BIGINT EXPR$0) NOT NULL");
diff --git
a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
index 0bf249f3af..192a0140da 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -553,7 +553,7 @@ LogicalProject(EXPR$0=[ROW(ITEM(ITEM(ITEM(ITEM($3, 0),
'detail'), 'skills'), 0).
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(EXPR$0=[ITEM(ITEM($3, 1).DETAIL.SKILLS, +(2, 3)).DESC])
+LogicalProject(DESC=[ITEM(ITEM($3, 1).DETAIL.SKILLS, +(2, 3)).DESC])
LogicalTableScan(table=[[CATALOG, SALES, DEPT_NESTED]])
]]>
</Resource>
@@ -2030,7 +2030,7 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2],
MGR=[$3], HIREDATE=[$4], SAL=[$
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(EXPR$0=[$1.CITY])
+LogicalProject(CITY=[$1.CITY])
LogicalTableScan(table=[[CATALOG, SALES, EMP_ADDRESS]])
]]>
</Resource>
@@ -2041,7 +2041,7 @@ LogicalProject(EXPR$0=[$1.CITY])
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(EXPR$0=[ROW(ROW(1, 2), ROW(3, 4, 5)).EXPR$1.EXPR$2])
+LogicalProject(EXPR$2=[ROW(ROW(1, 2), ROW(3, 4, 5)).EXPR$1.EXPR$2])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
@@ -2052,7 +2052,7 @@ LogicalProject(EXPR$0=[ROW(ROW(1, 2), ROW(3, 4,
5)).EXPR$1.EXPR$2])
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(EXPR$0=[ROW(1, 2).EXPR$1])
+LogicalProject(EXPR$1=[ROW(1, 2).EXPR$1])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
@@ -4112,7 +4112,7 @@ natural join customer.contact_peek t2]]>
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(EXPR$0=[COALESCE(ROW($4, $5, $6), ROW($14, $15, $16)).X])
+LogicalProject(X=[COALESCE(ROW($4, $5, $6), ROW($14, $15, $16)).X])
LogicalJoin(condition=[AND(=($0, $10), =($1, $11), =($2, $12), =($3, $13),
AND(AND(=($4, $14), =($5, $15)), =($6, $16)), AND(AND(=($7, $17), =($8, $18)),
=($9, $19)))], joinType=[inner])
LogicalProject(CONTACTNO=[$0], FNAME=[$1], LNAME=[$2], EMAIL=[$3],
X=[$4.X], Y=[$4.Y], unit=[$4.unit], M=[$5.M], A=[$5.SUB.A], B=[$5.SUB.B])
LogicalTableScan(table=[[CATALOG, CUSTOMER, CONTACT_PEEK]])
@@ -4532,7 +4532,7 @@ using (coord)]]>
</Resource>
<Resource name="plan">
<![CDATA[
-LogicalProject(EXPR$0=[COALESCE(ROW($4, $5, $6), ROW($14, $15, $16)).X])
+LogicalProject(X=[COALESCE(ROW($4, $5, $6), ROW($14, $15, $16)).X])
LogicalJoin(condition=[AND(AND(=($4, $14), =($5, $15)), =($6, $16))],
joinType=[inner])
LogicalProject(CONTACTNO=[$0], FNAME=[$1], LNAME=[$2], EMAIL=[$3],
X=[$4.X], Y=[$4.Y], unit=[$4.unit], M=[$5.M], A=[$5.SUB.A], B=[$5.SUB.B])
LogicalTableScan(table=[[CATALOG, CUSTOMER, CONTACT_PEEK]])
diff --git a/core/src/test/resources/sql/struct.iq
b/core/src/test/resources/sql/struct.iq
index 198ec492ae..9f2f393937 100644
--- a/core/src/test/resources/sql/struct.iq
+++ b/core/src/test/resources/sql/struct.iq
@@ -249,37 +249,38 @@ select row(1 as a, 'hello' as b);
!ok
+# Test cases for [CALCITE-7606] ROW field names should be used to infer column
names
# Named field access: .field selects a field from a named-field ROW
select row(1 as a, 'hello' as b).a;
-+--------+
-| EXPR$0 |
-+--------+
-| 1 |
-+--------+
++---+
+| A |
++---+
+| 1 |
++---+
(1 row)
!ok
# Named field access on a column expression
select row(empno as eno, ename as en).eno from emp order by empno limit 3;
-+--------+
-| EXPR$0 |
-+--------+
-| 7369 |
-| 7499 |
-| 7521 |
-+--------+
++------+
+| ENO |
++------+
+| 7369 |
+| 7499 |
+| 7521 |
++------+
(3 rows)
!ok
# Nested named-field ROW, and access to inner field
select row(row(1 as x, 2 as y) as inner_row, 'hello' as name).inner_row.x;
-+--------+
-| EXPR$0 |
-+--------+
-| 1 |
-+--------+
++---+
+| X |
++---+
+| 1 |
++---+
(1 row)
!ok