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了

