[ 
https://issues.apache.org/jira/browse/CALCITE-4347?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17270794#comment-17270794
 ] 

Julian Hyde commented on CALCITE-4347:
--------------------------------------

[~lllouiskuang] wrote:

bq. why was it impossible to infer type of ?. The overload is only for the 
first argument but not the second and the third

You're right, it's not impossible, just a small matter of coding. The two 
possibilities are SUBSTRING(char, int, int) and SUBSTRING(binary, int, int). So 
either way, it has to be an int.

Your fix is just fine, but I suspect that there are several other functions 
that are similar. I wonder whether it is possible for OperandTypeChecker to 
notice that all overloads give the same type to operand i and therefore deduce 
the type of operand i. By which I mean, can we make OperandTypeChecker 
implement OperandTypeInference in some cases?

Your test should check the inferred types of the parameters, not just call 
{{.ok()}}.

Inferring the first operand type from the return type is a clever idea. But you 
should test "{{WHERE deptno = SUBSTRING(? FROM 2 FOR 4)}}" and make sure that 
it gives a useful error. The return type will be inferred to be {{INTEGER}} 
(the type of {{deptno}}), and that is not a valid type for the first operand.

Lastly, rather than {{private static final SqlOperandTypeInference 
OPERAND_TYPE_INFERENCE}} I would have a method {{private static void 
inferOperandTypes(SqlCallBinding callBinding, RelDataType returnType, 
RelDataType[] operandTypes)}} and use a method reference, 
{{SqlSubstringFunction::inferOperandTypes}}. It's just cosmetic, but I prefer 
not to instantiate "function objects" as fields.

> Illegal use of dynamic parameter when use preparestatement
> ----------------------------------------------------------
>
>                 Key: CALCITE-4347
>                 URL: https://issues.apache.org/jira/browse/CALCITE-4347
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>            Reporter: yangzhang
>            Priority: Major
>              Labels: pull-request-available
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> hi , when query with preparestatement, validator throws exception.
> here is 2 sqls:
> 1、select LSTG_FORMAT_NAME
> from kylin_sales
> where LSTG_FORMAT_NAME=substring(?,1,6)
>  
> 2、select LSTG_FORMAT_NAME
> from kylin_sales
> where LSTG_FORMAT_NAME=substring(?,?,6)
>  
> trace is:
> Caused by: org.apache.calcite.runtime.CalciteContextException: At line 4, 
> column 34: Illegal use of dynamic parameter
> at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
> at 
> sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
> at 
> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
> at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
> at org.apache.calcite.runtime.Resources$ExInstWithCause.ex(Resources.java:463)
> at org.apache.calcite.sql.SqlUtil.newContextException(SqlUtil.java:803)
> at org.apache.calcite.sql.SqlUtil.newContextException(SqlUtil.java:788)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.newValidationError(SqlValidatorImpl.java:4708)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.inferUnknownTypes(SqlValidatorImpl.java:1710)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.inferUnknownTypes(SqlValidatorImpl.java:1785)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.inferUnknownTypes(SqlValidatorImpl.java:1785)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateWhereOrOn(SqlValidatorImpl.java:3906)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateWhereClause(SqlValidatorImpl.java:3898)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateSelect(SqlValidatorImpl.java:3224)
> at 
> org.apache.calcite.sql.validate.SelectNamespace.validateImpl(SelectNamespace.java:60)
> at 
> org.apache.calcite.sql.validate.AbstractNamespace.validate(AbstractNamespace.java:84)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateNamespace(SqlValidatorImpl.java:949)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateQuery(SqlValidatorImpl.java:930)
> at org.apache.calcite.sql.SqlSelect.validate(SqlSelect.java:226)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validateScopedExpression(SqlValidatorImpl.java:905)
> at 
> org.apache.calcite.sql.validate.SqlValidatorImpl.validate(SqlValidatorImpl.java:615)
> at 
> org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery(SqlToRelConverter.java:576)
> at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:269)
> at org.apache.calcite.prepare.Prepare.prepareSql(Prepare.java:235)
> at 
> org.apache.calcite.prepare.CalcitePrepareImpl.prepare2_(CalcitePrepareImpl.java:804)
> at 
> org.apache.calcite.prepare.CalcitePrepareImpl.prepare_(CalcitePrepareImpl.java:663)
> at 
> org.apache.calcite.prepare.CalcitePrepareImpl.prepareSql(CalcitePrepareImpl.java:626)
> at 
> org.apache.calcite.jdbc.CalciteConnectionImpl.parseQuery(CalciteConnectionImpl.java:232)
> at 
> org.apache.calcite.jdbc.CalciteConnectionImpl.prepareStatement_(CalciteConnectionImpl.java:214)
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to