[CALCITE-871] In JdbcMeta, register each statement using an id from a generator (Bruno Dumon)
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/00517e7a Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/00517e7a Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/00517e7a Branch: refs/heads/branch-release Commit: 00517e7afa60377214ad4bb84720d12557be1931 Parents: 57e1b4c Author: Bruno Dumon <[email protected]> Authored: Fri Oct 23 12:57:29 2015 -0400 Committer: Julian Hyde <[email protected]> Committed: Mon Oct 26 12:12:10 2015 -0700 ---------------------------------------------------------------------- .../apache/calcite/avatica/jdbc/JdbcMeta.java | 56 ++++++++++++++------ .../calcite/avatica/remote/RemoteMetaTest.java | 17 ++++++ .../calcite/avatica/AvaticaConnection.java | 6 ++- 3 files changed, 61 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/00517e7a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java ---------------------------------------------------------------------- diff --git a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java index 3f00dcb..be885ce 100644 --- a/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java +++ b/avatica-server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java @@ -52,7 +52,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Properties; -import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -64,9 +63,6 @@ public class JdbcMeta implements Meta { private static final String STMT_CACHE_KEY_BASE = "avatica.statementcache"; - private static final String DEFAULT_CONN_ID = - UUID.fromString("00000000-0000-0000-0000-000000000000").toString(); - /** Special value for {@link Statement#getLargeMaxRows()} that means fetch * an unlimited number of rows in a single batch. * @@ -273,19 +269,34 @@ public class JdbcMeta implements Meta { final ResultSet rs = getConnection(ch.id).getMetaData().getTables(catalog, schemaPattern.s, tableNamePattern.s, toArray(typeList)); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } } + /** + * Registers a StatementInfo for the given ResultSet, returning the id under + * which it is registered. This should be used for metadata ResultSets, which + * have an implicit statement created. + */ + private int registerMetaStatement(ResultSet rs) throws SQLException { + final int id = statementIdGenerator.getAndIncrement(); + StatementInfo statementInfo = new StatementInfo(rs.getStatement()); + statementInfo.resultSet = rs; + statementCache.put(id, statementInfo); + return id; + } + public MetaResultSet getColumns(ConnectionHandle ch, String catalog, Pat schemaPattern, Pat tableNamePattern, Pat columnNamePattern) { try { final ResultSet rs = getConnection(ch.id).getMetaData().getColumns(catalog, schemaPattern.s, tableNamePattern.s, columnNamePattern.s); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -295,7 +306,8 @@ public class JdbcMeta implements Meta { try { final ResultSet rs = getConnection(ch.id).getMetaData().getSchemas(catalog, schemaPattern.s); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -304,7 +316,8 @@ public class JdbcMeta implements Meta { public MetaResultSet getCatalogs(ConnectionHandle ch) { try { final ResultSet rs = getConnection(ch.id).getMetaData().getCatalogs(); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -313,7 +326,8 @@ public class JdbcMeta implements Meta { public MetaResultSet getTableTypes(ConnectionHandle ch) { try { final ResultSet rs = getConnection(ch.id).getMetaData().getTableTypes(); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -325,7 +339,8 @@ public class JdbcMeta implements Meta { final ResultSet rs = getConnection(ch.id).getMetaData().getProcedures(catalog, schemaPattern.s, procedureNamePattern.s); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -337,7 +352,8 @@ public class JdbcMeta implements Meta { final ResultSet rs = getConnection(ch.id).getMetaData().getProcedureColumns(catalog, schemaPattern.s, procedureNamePattern.s, columnNamePattern.s); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -349,7 +365,8 @@ public class JdbcMeta implements Meta { final ResultSet rs = getConnection(ch.id).getMetaData().getColumnPrivileges(catalog, schema, table, columnNamePattern.s); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -361,7 +378,8 @@ public class JdbcMeta implements Meta { final ResultSet rs = getConnection(ch.id).getMetaData().getTablePrivileges(catalog, schemaPattern.s, tableNamePattern.s); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -377,7 +395,8 @@ public class JdbcMeta implements Meta { final ResultSet rs = getConnection(ch.id).getMetaData().getBestRowIdentifier(catalog, schema, table, scope, nullable); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -391,7 +410,8 @@ public class JdbcMeta implements Meta { try { final ResultSet rs = getConnection(ch.id).getMetaData().getVersionColumns(catalog, schema, table); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -405,7 +425,8 @@ public class JdbcMeta implements Meta { try { final ResultSet rs = getConnection(ch.id).getMetaData().getPrimaryKeys(catalog, schema, table); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } @@ -430,7 +451,8 @@ public class JdbcMeta implements Meta { public MetaResultSet getTypeInfo(ConnectionHandle ch) { try { final ResultSet rs = getConnection(ch.id).getMetaData().getTypeInfo(); - return JdbcResultSet.create(DEFAULT_CONN_ID, -1, rs, UNLIMITED_COUNT); + int stmtId = registerMetaStatement(rs); + return JdbcResultSet.create(ch.id, stmtId, rs); } catch (SQLException e) { throw new RuntimeException(e); } http://git-wip-us.apache.org/repos/asf/calcite/blob/00517e7a/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java ---------------------------------------------------------------------- diff --git a/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java b/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java index 5e14427..903167e 100644 --- a/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java +++ b/avatica-server/src/test/java/org/apache/calcite/avatica/remote/RemoteMetaTest.java @@ -378,6 +378,23 @@ public class RemoteMetaTest { ConnectionSpec.getDatabaseLock().unlock(); } } + + @Test public void testRemoteColumnsMeta() throws Exception { + // Verify all columns are retrieved, thus that frame-based fetching works correctly for columns + int rowCount = 0; + try (AvaticaConnection conn = (AvaticaConnection) DriverManager.getConnection(url)) { + ResultSet rs = conn.getMetaData().getColumns(null, null, null, null); + while (rs.next()) { + rowCount++; + } + rs.close(); + + // The implicitly created statement should have been closed + assertTrue(rs.getStatement().isClosed()); + } + // default fetch size is 100, we are well beyond it + assertTrue(rowCount > 900); + } } // End RemoteMetaTest.java http://git-wip-us.apache.org/repos/asf/calcite/blob/00517e7a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java ---------------------------------------------------------------------- diff --git a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java index 5386543..a8867c8 100644 --- a/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java +++ b/avatica/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java @@ -551,8 +551,12 @@ public abstract class AvaticaConnection implements Connection { final Meta.StatementHandle h = new Meta.StatementHandle( metaResultSet.connectionId, metaResultSet.statementId, null); final AvaticaStatement statement = lookupStatement(h); - return executeQueryInternal(statement, metaResultSet.signature.sanitize(), + ResultSet resultSet = executeQueryInternal(statement, metaResultSet.signature.sanitize(), metaResultSet.firstFrame); + if (metaResultSet.ownStatement) { + resultSet.getStatement().closeOnCompletion(); + } + return resultSet; } /** Creates a statement wrapper around an existing handle. */
