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 b5057b7bd5 [CALCITE-7072] Validator should not insert aliases on 
subexpressions
b5057b7bd5 is described below

commit b5057b7bd5192bdb723808af75612e06f55afc4f
Author: Mihai Budiu <[email protected]>
AuthorDate: Tue Jun 24 21:52:32 2025 -0700

    [CALCITE-7072] Validator should not insert aliases on subexpressions
    
    Signed-off-by: Mihai Budiu <[email protected]>
---
 .../validate/implicit/AbstractTypeCoercion.java    |  6 +++-
 .../org/apache/calcite/test/SqlValidatorTest.java  | 32 ++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git 
a/core/src/main/java/org/apache/calcite/sql/validate/implicit/AbstractTypeCoercion.java
 
b/core/src/main/java/org/apache/calcite/sql/validate/implicit/AbstractTypeCoercion.java
index 396044eacf..fe882eac75 100644
--- 
a/core/src/main/java/org/apache/calcite/sql/validate/implicit/AbstractTypeCoercion.java
+++ 
b/core/src/main/java/org/apache/calcite/sql/validate/implicit/AbstractTypeCoercion.java
@@ -40,6 +40,7 @@
 import org.apache.calcite.sql.type.SqlTypeMappingRule;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.type.SqlTypeUtil;
+import org.apache.calcite.sql.validate.SelectScope;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql.validate.SqlValidatorNamespace;
 import org.apache.calcite.sql.validate.SqlValidatorScope;
@@ -213,7 +214,10 @@ protected boolean coerceColumnType(
     }
     RelDataType targetType3 = syncAttributes(validator.deriveType(scope, 
node), targetType);
     SqlNode node3 = castTo(node, targetType3);
-    if (node.getKind() == SqlKind.IDENTIFIER) {
+    // Preserve the original column name as an alias only if 'node' is an item 
in a select list.
+    boolean isSelectItem = (scope instanceof SelectScope)
+        && ((SelectScope) scope).getNode().getSelectList() == nodeList;
+    if (node.getKind() == SqlKind.IDENTIFIER && isSelectItem) {
       SqlIdentifier id = (SqlIdentifier) node;
       String name = id.getComponent(id.names.size() - 1).getSimple();
       node3 = SqlValidatorUtil.addAlias(node3, name);
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 8470bb61d1..ec4cd2b84b 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -25,6 +25,8 @@
 import org.apache.calcite.rel.type.RelDataTypeSystem;
 import org.apache.calcite.rel.type.TimeFrameSet;
 import org.apache.calcite.runtime.CalciteContextException;
+import org.apache.calcite.sql.SqlAsOperator;
+import org.apache.calcite.sql.SqlBasicCall;
 import org.apache.calcite.sql.SqlBasicFunction;
 import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlCollation;
@@ -38,6 +40,7 @@
 import org.apache.calcite.sql.SqlOperatorTable;
 import org.apache.calcite.sql.SqlSelect;
 import org.apache.calcite.sql.SqlSpecialOperator;
+import org.apache.calcite.sql.fun.SqlCase;
 import org.apache.calcite.sql.fun.SqlLibrary;
 import org.apache.calcite.sql.fun.SqlLibraryOperatorTableFactory;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
@@ -5935,6 +5938,35 @@ void testReturnsCorrectRowTypeOnCombinedJoin() {
         .fails("(?s).*Encountered \"\\( true\" at .*");
   }
 
+  /** Test case for <a 
href="https://issues.apache.org/jira/browse/CALCITE-7072";>[CALCITE-7072]
+   * Validator should not insert aliases on subexpressions</a>. */
+  @Test void testCaseCast() throws CalciteContextException, SqlParseException {
+    final String sql = "SELECT CASE WHEN deptno IS NOT NULL THEN empno\n"
+        + "ELSE CAST(deptno AS VARCHAR) END AS ID FROM emp";
+    final SqlParser.Config config = SqlParser.config();
+    final String messagePassingSqlString;
+    final SqlParser sqlParserReader = SqlParser.create(sql, config);
+    final SqlNode node = sqlParserReader.parseQuery();
+    final SqlValidator validator = fixture().factory
+        .withValidatorConfig(c -> c.withIdentifierExpansion(true))
+        .createValidator();
+    final SqlNode x = validator.validate(node);
+    assert x instanceof SqlSelect;
+    SqlSelect select = (SqlSelect) x;
+    SqlNode item = select.getSelectList().get(0);
+    assert item instanceof SqlBasicCall;
+    SqlBasicCall call = (SqlBasicCall) item;
+    assert call.getOperandList().size() == 2;
+    SqlNode op0 = call.getOperandList().get(0);
+    assert op0 instanceof SqlCase;
+    SqlCase caseStat = (SqlCase) op0;
+    assert caseStat.getThenOperands().size() == 1;
+    SqlNode then = caseStat.getThenOperands().get(0);
+    assert then instanceof SqlBasicCall;
+    SqlOperator operator = ((SqlBasicCall) then).getOperator();
+    assert !(operator instanceof SqlAsOperator);
+  }
+
   @Disabled("bug: should fail if sub-query does not have alias")
   @Test void testJoinSubQuery() {
     // Sub-queries require alias

Reply via email to