Skip to content

Commit

Permalink
IGNITE-24378 SQL Calcite: Fix query validation failure with a dynamic…
Browse files Browse the repository at this point in the history
… parameter - Fixes #11846.

Signed-off-by: Aleksey Plekhanov <[email protected]>
  • Loading branch information
Vladsz83 authored and alex-plekhanov committed Feb 11, 2025
1 parent c56d532 commit 8346282
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ public class IgniteSqlValidator extends SqlValidatorImpl {
/** Dynamic parameters. */
@Nullable private final Object[] parameters;

/** */
private final RelDataType nullType;

/**
* Creates a validator.
*
Expand All @@ -124,6 +127,8 @@ public IgniteSqlValidator(
super(opTab, catalogReader, typeFactory, cfg);

this.parameters = parameters;

nullType = typeFactory.createSqlType(SqlTypeName.NULL);
}

/** {@inheritDoc} */
Expand Down Expand Up @@ -543,7 +548,7 @@ private boolean isSystemFieldName(String alias) {
/** {@inheritDoc} */
@Override public RelDataType deriveType(SqlValidatorScope scope, SqlNode expr) {
if (expr instanceof SqlDynamicParam) {
RelDataType type = deriveDynamicParameterType((SqlDynamicParam)expr);
RelDataType type = deriveDynamicParameterType((SqlDynamicParam)expr, nullType);

if (type != null)
return type;
Expand All @@ -553,7 +558,7 @@ private boolean isSystemFieldName(String alias) {
}

/** @return A derived type or {@code null} if unable to determine. */
@Nullable private RelDataType deriveDynamicParameterType(SqlDynamicParam node) {
@Nullable private RelDataType deriveDynamicParameterType(SqlDynamicParam node, RelDataType nullValType) {
RelDataType type = getValidatedNodeTypeIfKnown(node);

// Do not clarify the widest type for any value.
Expand All @@ -569,7 +574,7 @@ private boolean isSystemFieldName(String alias) {
return type;

type = val == null
? typeFactory.createSqlType(SqlTypeName.NULL)
? typeFactory().createTypeWithNullability(nullValType, true)
: typeFactory().createTypeWithNullability(typeFactory().toSql(typeFactory().createType(val.getClass())), true);

setValidatedNodeType(node, type);
Expand All @@ -579,8 +584,8 @@ private boolean isSystemFieldName(String alias) {

/** {@inheritDoc} */
@Override protected void inferUnknownTypes(RelDataType inferredType, SqlValidatorScope scope, SqlNode node) {
if (node instanceof SqlDynamicParam && unknownType.equals(inferredType)
&& deriveDynamicParameterType((SqlDynamicParam)node) != null)
if (node instanceof SqlDynamicParam && !(inferredType instanceof OtherType)
&& deriveDynamicParameterType((SqlDynamicParam)node, unknownType.equals(inferredType) ? nullType : inferredType) != null)
return;

if (node instanceof SqlCall) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ public void testCasts() {
/** */
@Test
public void testDynamicParameters() {
assertQuery("select 1 + ?").withParams(1).returns(2).check();
assertQuery("select ? + 1").withParams(1).returns(2).check();
assertQuery("select 1 + CAST(? AS INTEGER)").withParams(2L).returns(3).check();
assertQuery("select CAST(? AS INTEGER) + 1").withParams(2L).returns(3).check();
assertQuery("select 1 + ?").withParams(1L).returns(2L).check();
assertQuery("select ? + 1").withParams(1L).returns(2L).check();
assertQuery("select 1 + ?").withParams(new BigDecimal("2")).returns(new BigDecimal(3)).check();
assertQuery("select ? + 1").withParams(new BigDecimal("2")).returns(new BigDecimal(3)).check();

assertQuery("SELECT COALESCE(?, ?)").withParams("a", 10).returns("a").check();
assertQuery("SELECT COALESCE(null, ?)").withParams(13).returns(13).check();
assertQuery("SELECT LOWER(?)").withParams("ASD").returns("asd").check();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ public void testParseSelectAndUnion() throws Exception {
checkQuery("select (select 1)");
checkQuery("select (select 1, select ?)");
checkQuery("select ((select 1), select ? + ?)");
checkQuery("select 1 + ?");
checkQuery("select ? + 1");
checkQuery("select ? + ?");
checkQuery("select CURRENT_DATE");
checkQuery("select CURRENT_DATE()");

Expand Down

0 comments on commit 8346282

Please sign in to comment.