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 c437a9bbe6 [CALCITE-7094] Using a type alias as a constructor function
causes a validator assertion failure
c437a9bbe6 is described below
commit c437a9bbe6fe858efab146581c24cc89671408ef
Author: Mihai Budiu <[email protected]>
AuthorDate: Tue Jul 15 17:44:02 2025 -0700
[CALCITE-7094] Using a type alias as a constructor function causes a
validator assertion failure
Signed-off-by: Mihai Budiu <[email protected]>
---
.../org/apache/calcite/test/BabelQuidemTest.java | 4 +++
babel/src/test/resources/sql/big-query.iq | 10 +++++++
.../sql/type/ExplicitOperandTypeChecker.java | 32 ++++++++++++++++++++--
3 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/babel/src/test/java/org/apache/calcite/test/BabelQuidemTest.java
b/babel/src/test/java/org/apache/calcite/test/BabelQuidemTest.java
index 12cdadda62..65a4f6c64d 100644
--- a/babel/src/test/java/org/apache/calcite/test/BabelQuidemTest.java
+++ b/babel/src/test/java/org/apache/calcite/test/BabelQuidemTest.java
@@ -110,6 +110,10 @@ public static void main(String[] args) throws Exception {
.with(
ConnectionFactories.addType("DATETIME", typeFactory ->
typeFactory.createSqlType(SqlTypeName.TIMESTAMP)))
+ // More type aliases could be added to emulate Big Query more
precisely
+ .with(
+ ConnectionFactories.addType("INT64", typeFactory ->
+ typeFactory.createSqlType(SqlTypeName.BIGINT)))
.with(
ConnectionFactories.addType("TIMESTAMP", typeFactory ->
typeFactory.createSqlType(
diff --git a/babel/src/test/resources/sql/big-query.iq
b/babel/src/test/resources/sql/big-query.iq
index e587d50267..007e68cb87 100755
--- a/babel/src/test/resources/sql/big-query.iq
+++ b/babel/src/test/resources/sql/big-query.iq
@@ -30,6 +30,16 @@
!use scott-big-query
!set outputformat mysql
+# Two tests for [CALCITE-7094] Using a type alias as a constructor function
+# causes a validator assertion failure
+select int64();
+Cannot apply 'int64' to arguments of type 'int64()'. Supported form(s): int64
+!error
+
+select int64(2);
+Cannot apply 'int64' to arguments of type 'int64(<INTEGER>)'. Supported
form(s): int64
+!error
+
# TODO: create a means to set the current date/time/timestamp for the
# current session CURRENT_TIMESTAMP etc. will return those values.
# Then enable the CURRENT_x tests.
diff --git
a/core/src/main/java/org/apache/calcite/sql/type/ExplicitOperandTypeChecker.java
b/core/src/main/java/org/apache/calcite/sql/type/ExplicitOperandTypeChecker.java
index c4c382659b..ce7b64dbc5 100644
---
a/core/src/main/java/org/apache/calcite/sql/type/ExplicitOperandTypeChecker.java
+++
b/core/src/main/java/org/apache/calcite/sql/type/ExplicitOperandTypeChecker.java
@@ -42,6 +42,14 @@ public ExplicitOperandTypeChecker(RelDataType type) {
@Override public boolean checkOperandTypes(
SqlCallBinding callBinding,
boolean throwOnFailure) {
+ if (!type.isStruct()) {
+ if (throwOnFailure) {
+ throw callBinding.newValidationSignatureError();
+ } else {
+ return false;
+ }
+ }
+
List<SqlTypeFamily> families = new ArrayList<>();
List<RelDataTypeField> fieldList = type.getFieldList();
@@ -62,10 +70,30 @@ public ExplicitOperandTypeChecker(RelDataType type) {
}
@Override public SqlOperandCountRange getOperandCountRange() {
- return SqlOperandCountRanges.of(type.getFieldCount());
+ if (type.isStruct()) {
+ return SqlOperandCountRanges.of(type.getFieldCount());
+ }
+ // This is a type constructor for a scalar type, which is illegal (e.g.
INT64(...))
+ // (the validator will accept this for type aliases).
+ // We pretend here it's OK, but we throw in checkOperandTypes.
+ return SqlOperandCountRanges.between(0, -1);
}
@Override public String getAllowedSignatures(SqlOperator op, String opName) {
- return "<TYPE> " + opName + " <TYPE>";
+ StringBuilder builder = new StringBuilder();
+ builder.append(opName);
+ if (type.isStruct()) {
+ builder.append("(");
+ boolean first = true;
+ for (RelDataTypeField field : type.getFieldList()) {
+ if (!first) {
+ builder.append(", ");
+ }
+ first = false;
+ builder.append(field.getType());
+ }
+ builder.append(")");
+ }
+ return builder.toString();
}
}