Feng Zhu created CALCITE-3562: --------------------------------- Summary: Unify function's operands type check logic in validation and behavior in runtime Key: CALCITE-3562 URL: https://issues.apache.org/jira/browse/CALCITE-3562 Project: Calcite Issue Type: Bug Components: core Reporter: Feng Zhu
Current now, there are many issues caused by inconsistency between validator and runtime phase. To summarize: (1)Validation phase allows a wide range of operand types, but the runtime implementation does not cover all cases. For example, _*SqlFunction(MOD)*_ adopts _*OperandTypes.EXACT_NUMERIC_EXACT_NUMERIC*_. {code:java} @Test public void test0() { final String sql = "SELECT mod(12.5, cast(1 as bigint))"; CalciteAssert.that() .query(sql) .returns("EXPR$0=0.5\n"); }{code} We will get: {code:java} java.lang.RuntimeException: while resolving method 'mod[class java.math.BigDecimal, long]' in class class org.apache.calcite.runtime.SqlFunctions at org.apache.calcite.linq4j.tree.Types.lookupMethod(Types.java:323) at org.apache.calcite.linq4j.tree.Expressions.call(Expressions.java:445) at org.apache.calcite.adapter.enumerable.RexImpTable$MethodNameImplementor.implement(RexImpTable.java:2253) at org.apache.calcite.adapter.enumerable.RexImpTable.implementCall(RexImpTable.java:1195){code} (2)Type is assignable conceptually, but in the runtime phase, explicite cast is still required. For example, according to _*SqlTypeAssignmentRules*_, *_ST_MakePoint(Decimal, Decimal)_* also accepts operands with (_Integer_, _Decimal_) types. {code:java} @Test public void test1() { final String sql = "SELECT ST_MakePoint(1, 2.1)"; CalciteAssert.that() .with(CalciteAssert.Config.GEO) .query(sql) .returns("EXPR$0={\"x\":1,\"y\":2.1}\n"); } {code} We will get: {code:java} org.codehaus.commons.compiler.CompileException: Line 22, Column 124: No applicable constructor/method found for actual parameters "int, java.math.BigDecimal"; candidates are: "public static org.apache.calcite.runtime.GeoFunctions$Geom org.apache.calcite.runtime.GeoFunctions.ST_MakePoint(java.math.BigDecimal, java.math.BigDecimal, java.math.BigDecimal)", "public static org.apache.calcite.runtime.GeoFunctions$Geom org.apache.calcite.runtime.GeoFunctions.ST_MakePoint(java.math.BigDecimal, java.math.BigDecimal)" at org.codehaus.janino.UnitCompiler.compileError(UnitCompiler.java:12211) at org.codehaus.janino.UnitCompiler.findMostSpecificIInvocable(UnitCompiler.java:9263) at org.codehaus.janino.UnitCompiler.findIMethod(UnitCompiler.java:9123) at org.codehaus.janino.UnitCompiler.findIMethod(UnitCompiler.java:9025) at org.codehaus.janino.UnitCompiler.compileGet2(UnitCompiler.java:5062) at org.codehaus.janino.UnitCompiler.access$9100(UnitCompiler.java:215){code} (3)For some functions, it is too late to fail the query in runtime phase. For example: _*RAND_INTEGER*_ adopts _*OperandTypes.or(OperandTypes.NUMERIC, OperandTypes.NUMERIC_NUMERIC)*_ {code:java} @Test public void test2() { final String sql = "SELECT rand_integer(1.1, 2)"; CalciteAssert.that() .query(sql) .planContains("xyxyx") .returns("EXPR$0={\"x\":1,\"y\":2.1}\n"); }{code} We will get: {code:java} org.codehaus.commons.compiler.CompileException: Line 22, Column 100: No applicable constructor/method found for actual parameters "java.math.BigDecimal, int"; candidates are: "public int org.apache.calcite.runtime.RandomFunction.randIntegerSeed(int, int)" at org.codehaus.janino.UnitCompiler.compileError(UnitCompiler.java:12211) at org.codehaus.janino.UnitCompiler.findMostSpecificIInvocable(UnitCompiler.java:9263) at org.codehaus.janino.UnitCompiler.findIMethod(UnitCompiler.java:9123){code} -- This message was sent by Atlassian Jira (v8.3.4#803005)