JDBC 尝试使用准备好的语句占位符作为聚合函数的参数时出现异常
JDBC exception when trying to use a prepared statement placeholder as an argument to an aggregation function
我正在尝试使用 PreparedStatement 占位符作为 sql 聚合函数的参数。如果我将 ?
占位符替换为数值并删除 setDouble
调用,查询将正常工作。
public static String QUERY = """
SELECT DS_GET_QUANTILE(DS_QUANTILES_SKETCH("logins"), ?) as "rank"
FROM (SELECT ip, sum("login-counts") AS "attempts"
FROM "my-datasource"
WHERE __time >= CURRENT_TIMESTAMP - INTERVAL '30' DAY
GROUP BY 1)
""";
void queryFails() throws SQLException {
var connection = jdbcTemplate.getJdbcTemplate().getDataSource().getConnection();
var preparedStatement = connection.prepareStatement(QUERY);
preparedStatement.setDouble(1, .75);
var resultSet = preparedStatement.executeQuery();
}
错误是:
org.apache.calcite.avatica.AvaticaSqlException: Error -1 (00000) : while preparing SQL: SELECT DS_GET_QUANTILE(DS_QUANTILES_SKETCH("attempts"), ?) as "rank"
FROM (SELECT ip, sum("login-login_attempts") AS "attempts"
FROM "metrics-default"
WHERE __time >= CURRENT_TIMESTAMP - INTERVAL '30' DAY
GROUP BY 1)
at org.apache.calcite.avatica.Helper.createException(Helper.java:54)
at org.apache.calcite.avatica.Helper.createException(Helper.java:41)
at org.apache.calcite.avatica.AvaticaConnection.prepareStatement(AvaticaConnection.java:358)
at org.apache.calcite.avatica.AvaticaConnection.prepareStatement(AvaticaConnection.java:175)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
...
java.lang.RuntimeException: org.apache.calcite.tools.ValidationException: org.apache.calcite.runtime.CalciteContextException: From line 1, column 8 to line 1, column 58: Cannot apply 'DS_GET_QUANTILE' to arguments of type 'DS_GET_QUANTILE(<OTHER>, <ANY>)'. Supported form(s): 'DS_GET_QUANTILE(<ANY>, <NUMERIC>)'
at org.apache.druid.sql.avatica.DruidStatement.closeAndPropagateThrowable(DruidStatement.java:377)
at org.apache.druid.sql.avatica.DruidStatement.prepare(DruidStatement.java:181)
at org.apache.druid.sql.avatica.DruidMeta.prepare(DruidMeta.java:158)
它似乎正在将 ?
原封不动地传递给数据库。
这是 avatica 驱动程序中的错误还是查询的某些区域不允许使用占位符?
鉴于根本原因错误消息:
java.lang.RuntimeException:
org.apache.calcite.tools.ValidationException:
org.apache.calcite.runtime.CalciteContextException: From line 1,
column 8 to line 1, column 58: Cannot apply 'DS_GET_QUANTILE' to
arguments of type 'DS_GET_QUANTILE(<OTHER>, <ANY>)'. Supported
form(s): 'DS_GET_QUANTILE(<ANY>, <NUMERIC>)'
这是参数类型推断的问题。尝试将参数显式转换为数字类型,例如cast(? as double)
.
我正在尝试使用 PreparedStatement 占位符作为 sql 聚合函数的参数。如果我将 ?
占位符替换为数值并删除 setDouble
调用,查询将正常工作。
public static String QUERY = """
SELECT DS_GET_QUANTILE(DS_QUANTILES_SKETCH("logins"), ?) as "rank"
FROM (SELECT ip, sum("login-counts") AS "attempts"
FROM "my-datasource"
WHERE __time >= CURRENT_TIMESTAMP - INTERVAL '30' DAY
GROUP BY 1)
""";
void queryFails() throws SQLException {
var connection = jdbcTemplate.getJdbcTemplate().getDataSource().getConnection();
var preparedStatement = connection.prepareStatement(QUERY);
preparedStatement.setDouble(1, .75);
var resultSet = preparedStatement.executeQuery();
}
错误是:
org.apache.calcite.avatica.AvaticaSqlException: Error -1 (00000) : while preparing SQL: SELECT DS_GET_QUANTILE(DS_QUANTILES_SKETCH("attempts"), ?) as "rank"
FROM (SELECT ip, sum("login-login_attempts") AS "attempts"
FROM "metrics-default"
WHERE __time >= CURRENT_TIMESTAMP - INTERVAL '30' DAY
GROUP BY 1)
at org.apache.calcite.avatica.Helper.createException(Helper.java:54)
at org.apache.calcite.avatica.Helper.createException(Helper.java:41)
at org.apache.calcite.avatica.AvaticaConnection.prepareStatement(AvaticaConnection.java:358)
at org.apache.calcite.avatica.AvaticaConnection.prepareStatement(AvaticaConnection.java:175)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
...
java.lang.RuntimeException: org.apache.calcite.tools.ValidationException: org.apache.calcite.runtime.CalciteContextException: From line 1, column 8 to line 1, column 58: Cannot apply 'DS_GET_QUANTILE' to arguments of type 'DS_GET_QUANTILE(<OTHER>, <ANY>)'. Supported form(s): 'DS_GET_QUANTILE(<ANY>, <NUMERIC>)'
at org.apache.druid.sql.avatica.DruidStatement.closeAndPropagateThrowable(DruidStatement.java:377)
at org.apache.druid.sql.avatica.DruidStatement.prepare(DruidStatement.java:181)
at org.apache.druid.sql.avatica.DruidMeta.prepare(DruidMeta.java:158)
它似乎正在将 ?
原封不动地传递给数据库。
这是 avatica 驱动程序中的错误还是查询的某些区域不允许使用占位符?
鉴于根本原因错误消息:
java.lang.RuntimeException: org.apache.calcite.tools.ValidationException: org.apache.calcite.runtime.CalciteContextException: From line 1, column 8 to line 1, column 58: Cannot apply 'DS_GET_QUANTILE' to arguments of type 'DS_GET_QUANTILE(<OTHER>, <ANY>)'. Supported form(s): 'DS_GET_QUANTILE(<ANY>, <NUMERIC>)'
这是参数类型推断的问题。尝试将参数显式转换为数字类型,例如cast(? as double)
.