trino的jdbc base的插件提供了直接透传sql到上游数据库的能力table function
然而clickhouse-jdbc却不支持
修改ClickHouseClientModule.java 在configure方法抄一行隔壁mysql module的调用
newSetBinder(binder, ConnectorTableFunction.class).addBinding().toProvider(Query.class).in(Scopes.SINGLETON);
然后开启调试发现报了个
Query not supported: ResultSetMetaData not available for query: ...
然后追查clickhouse plugin testcase的历史提交发现曾经有备注说为啥没有table function
// table function disabled for ClickHouse, because it doesn't provide ResultSetMetaData, so the result relation type cannot be determined
然后搜索一下,发现曾经有过issue提问怎么不执行查询拿到resultset metadata
然后简单粗暴,给clickhouse client加上一个override:
@Override
public JdbcTableHandle getTableHandle(ConnectorSession session, PreparedQuery preparedQuery) {
ImmutableList.Builder<JdbcColumnHandle> columns = ImmutableList.builder();
try (Connection connection = connectionFactory.openConnection(session);
PreparedStatement statement = connection.prepareStatement(preparedQuery.getQuery() + " LIMIT 0")) {
ResultSetMetaData metadata = statement.executeQuery().getMetaData();
if (metadata == null) {
throw new UnsupportedOperationException("Query not supported: ResultSetMetaData not available for query: " + preparedQuery.getQuery());
}
for (int column = 1; column <= metadata.getColumnCount(); column++) {
String name = metadata.getColumnName(column);
JdbcTypeHandle jdbcTypeHandle = new JdbcTypeHandle(
metadata.getColumnType(column),
Optional.ofNullable(metadata.getColumnTypeName(column)),
Optional.of(metadata.getPrecision(column)),
Optional.of(metadata.getScale(column)),
Optional.empty(), // TODO support arrays
Optional.of(metadata.isCaseSensitive(column) ? CASE_SENSITIVE : CASE_INSENSITIVE));
Type type = toColumnMapping(session, connection, jdbcTypeHandle)
.orElseThrow(() -> new UnsupportedOperationException(format("Unsupported type: %s of column: %s", jdbcTypeHandle, name)))
.getType();
columns.add(new JdbcColumnHandle(name, jdbcTypeHandle, type));
}
return new JdbcTableHandle(
new JdbcQueryRelationHandle(preparedQuery),
TupleDomain.all(),
ImmutableList.of(),
Optional.empty(),
OptionalLong.empty(),
Optional.of(columns.build()),
// The query is opaque, so we don't know referenced tables
Optional.empty(),
0);
} catch (SQLException e) {
return super.getTableHandle(session, preparedQuery);
}
}
提交,build镜像,然后就可以使用clickhouse的table function了