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 f854ef5ee4 [CALCITE-6382] Type inference for SqlLeadLagAggFunction is
incorrect
f854ef5ee4 is described below
commit f854ef5ee480e0ff893b18d27ec67dc381ee2244
Author: Mihai Budiu <[email protected]>
AuthorDate: Tue Apr 23 17:14:18 2024 -0700
[CALCITE-6382] Type inference for SqlLeadLagAggFunction is incorrect
Signed-off-by: Mihai Budiu <[email protected]>
---
.../calcite/sql/fun/SqlLeadLagAggFunction.java | 27 ++++++++++++++++++++--
.../java/org/apache/calcite/test/JdbcTest.java | 9 --------
.../org/apache/calcite/test/SqlValidatorTest.java | 9 ++++++++
3 files changed, 34 insertions(+), 11 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/sql/fun/SqlLeadLagAggFunction.java
b/core/src/main/java/org/apache/calcite/sql/fun/SqlLeadLagAggFunction.java
index 63b9dc14b1..fb1c24ff0d 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLeadLagAggFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLeadLagAggFunction.java
@@ -22,13 +22,17 @@ import org.apache.calcite.sql.SqlFunctionCategory;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlOperatorBinding;
import org.apache.calcite.sql.type.OperandTypes;
-import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlReturnTypeInference;
import org.apache.calcite.sql.type.SqlSingleOperandTypeChecker;
+import org.apache.calcite.sql.type.SqlTypeFamily;
+import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.type.SqlTypeTransform;
import org.apache.calcite.sql.type.SqlTypeTransforms;
import org.apache.calcite.util.Optionality;
+import java.util.ArrayList;
+import java.util.List;
+
import static com.google.common.base.Preconditions.checkArgument;
/**
@@ -40,10 +44,29 @@ public class SqlLeadLagAggFunction extends SqlAggFunction {
OperandTypes.ANY
.or(OperandTypes.ANY_NUMERIC)
.or(OperandTypes.ANY_NUMERIC_ANY
+ // "same" only checks if two types are comparable
.and(OperandTypes.same(3, 0, 2)));
+ // A version of least restrictive which only looks at operands 0 and 2,
+ // if the latter exists.
+ private static final SqlReturnTypeInference ARG03 = opBinding -> {
+ List<RelDataType> toCheck = new ArrayList<>();
+ toCheck.add(opBinding.getOperandType(0));
+ if (opBinding.getOperandCount() >= 3) {
+ RelDataType op2 = opBinding.getOperandType(2);
+ toCheck.add(op2);
+ }
+ // If any operand is in the CHAR type family, return VARCHAR.
+ for (RelDataType type : toCheck) {
+ if (type.getFamily() == SqlTypeFamily.CHARACTER) {
+ return opBinding.getTypeFactory().createSqlType(SqlTypeName.VARCHAR);
+ }
+ }
+ return opBinding.getTypeFactory().leastRestrictive(toCheck);
+ };
+
private static final SqlReturnTypeInference RETURN_TYPE =
- ReturnTypes.ARG0.andThen(SqlLeadLagAggFunction::transformType);
+ ARG03.andThen(SqlLeadLagAggFunction::transformType);
public SqlLeadLagAggFunction(SqlKind kind) {
super(kind.name(),
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 023a57ef6b..980594a195 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -4631,9 +4631,6 @@ public class JdbcTest {
"RN=8; L=2");
}
- /**
- * Tests expression in offset value of LAG function.
- */
@Disabled("Have no idea how to validate that expression is constant")
@Test void testNtileConstantArgs() {
CalciteAssert.that()
@@ -4652,9 +4649,6 @@ public class JdbcTest {
"RN=8; L=2");
}
- /**
- * Tests expression in offset value of LAG function.
- */
@Test void testNtileNegativeArg() {
CalciteAssert.that()
.query("select rn, ntile(-1) over (order by rn) l\n"
@@ -4663,9 +4657,6 @@ public class JdbcTest {
"Argument to function 'NTILE' must be a positive integer literal");
}
- /**
- * Tests expression in offset value of LAG function.
- */
@Test void testNtileDecimalArg() {
CalciteAssert.that()
.query("select rn, ntile(3.141592653) over (order by rn) l\n"
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 4b5ffd63d1..21d29ebe79 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -3109,6 +3109,15 @@ public class SqlValidatorTest extends
SqlValidatorTestCase {
.fails(RANK_REQUIRES_ORDER_BY);
}
+ /** Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-6382">[CALCITE-6382]
+ * Type inference for SqlLeadLagAggFunction is incorrect</a>. */
+ @Test void testWindowLagInference() {
+ sql("select lead(sal, 4, 0.5) over (w)\n"
+ + " from emp window w as (order by empno)")
+ .type("RecordType(DECIMAL(11, 1) NOT NULL EXPR$0) NOT NULL");
+ }
+
/** Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-883">[CALCITE-883]
* Give error if the aggregate function don't support null treatment</a>. */