diff --git a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java b/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java index 516ab28c80f4e..001d943ca699a 100644 --- a/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java +++ b/x-pack/plugin/sql/qa/single-node/src/test/java/org/elasticsearch/xpack/sql/qa/single_node/RestSqlIT.java @@ -39,4 +39,20 @@ public void testErrorMessageForTranslatingSQLCommandStatement() throws IOExcepti containsString("Cannot generate a query DSL for a special SQL command " + "(e.g.: DESCRIBE, SHOW), sql statement: [SHOW FUNCTIONS]")); } + + public void testErrorMessageForInvalidParamDataType() throws IOException { + expectBadRequest(() -> runTranslateSql( + "{\"query\":\"SELECT null WHERE 0 = ? \", \"mode\": \"odbc\", \"params\":[{\"type\":\"invalid\", \"value\":\"irrelevant\"}]}" + ), + containsString("Cannot cast value [irrelevant] of type [KEYWORD] to parameter type [UNSUPPORTED]") + ); + } + + public void testErrorMessageForInvalidParamSpec() throws IOException { + expectBadRequest(() -> runTranslateSql( + "{\"query\":\"SELECT null WHERE 0 = ? \", \"mode\": \"odbc\", \"params\":[{\"type\":\"SHAPE\", \"value\":false}]}" + ), + containsString("Cannot cast value [false] of type [BOOLEAN] to parameter type [SHAPE]") + ); + } } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/ExpressionBuilder.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/ExpressionBuilder.java index 524d4e8b75a8e..583987d8ab7b5 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/ExpressionBuilder.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/ExpressionBuilder.java @@ -128,6 +128,7 @@ import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; +import static org.elasticsearch.xpack.sql.type.DataTypeConversion.canConvert; import static org.elasticsearch.xpack.sql.type.DataTypeConversion.conversionFor; import static org.elasticsearch.xpack.sql.util.DateUtils.asDateOnly; import static org.elasticsearch.xpack.sql.util.DateUtils.asTimeOnly; @@ -716,6 +717,10 @@ public Literal visitParamLiteral(ParamLiteralContext ctx) { } // otherwise we need to make sure that xcontent-serialized value is converted to the correct type try { + if (canConvert(sourceType, dataType) == false) { + throw new ParsingException(source, "Cannot cast value [{}] of type [{}] to parameter type [{}]", param.value, sourceType, + dataType); + } return new Literal(source, conversionFor(sourceType, dataType).convert(param.value), dataType); } catch (SqlIllegalArgumentException ex) { throw new ParsingException(ex, source, "Unexpected actual parameter type [{}] for type [{}]", sourceType, param.type);