You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pp...@apache.org on 2025/11/13 11:57:47 UTC

(ignite-3) branch ignite-26314 created (now 1f7cba3cdbc)

This is an automated email from the ASF dual-hosted git repository.

ppa pushed a change to branch ignite-26314
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


      at 1f7cba3cdbc IGNITE-26314 Use new ResultSet implementation in JdbcDatabaseMetadata.

This branch includes the following new commits:

     new 1f7cba3cdbc IGNITE-26314 Use new ResultSet implementation in JdbcDatabaseMetadata.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(ignite-3) 01/01: IGNITE-26314 Use new ResultSet implementation in JdbcDatabaseMetadata.

Posted by pp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ppa pushed a commit to branch ignite-26314
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit 1f7cba3cdbc1367a1c0db344df1e506864a7ac1d
Author: Pavel Pereslegin <xx...@gmail.com>
AuthorDate: Thu Nov 13 14:51:21 2025 +0300

    IGNITE-26314 Use new ResultSet implementation in JdbcDatabaseMetadata.
---
 .../internal/jdbc/ItJdbcMetadataSelfTest.java      |  25 +-
 .../ignite/internal/jdbc/JdbcDatabaseMetadata.java | 590 +++++++++++----------
 .../internal/jdbc/JdbcDatabaseMetataUtils.java     | 321 +++++++++++
 .../ignite/internal/jdbc2/ClientSyncResultSet.java |   3 +-
 .../ignite/internal/jdbc2/JdbcResultSet.java       |   3 +-
 .../ignite/internal/jdbc2/JdbcStatement2.java      |  14 +-
 6 files changed, 652 insertions(+), 304 deletions(-)

diff --git a/modules/jdbc/src/integrationTest/java/org/apache/ignite/internal/jdbc/ItJdbcMetadataSelfTest.java b/modules/jdbc/src/integrationTest/java/org/apache/ignite/internal/jdbc/ItJdbcMetadataSelfTest.java
index 2c95ec8e1c7..01c4c75e9c5 100644
--- a/modules/jdbc/src/integrationTest/java/org/apache/ignite/internal/jdbc/ItJdbcMetadataSelfTest.java
+++ b/modules/jdbc/src/integrationTest/java/org/apache/ignite/internal/jdbc/ItJdbcMetadataSelfTest.java
@@ -36,10 +36,15 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.StringJoiner;
 import java.util.UUID;
-import org.apache.ignite.internal.jdbc.proto.event.JdbcColumnMeta;
+import org.apache.ignite.internal.jdbc2.JdbcResultSetMetadata;
+import org.apache.ignite.internal.sql.ColumnMetadataImpl;
+import org.apache.ignite.internal.sql.ColumnMetadataImpl.ColumnOriginImpl;
+import org.apache.ignite.internal.sql.ResultSetMetadataImpl;
 import org.apache.ignite.internal.sql.engine.util.SqlTestUtils;
 import org.apache.ignite.internal.type.NativeType;
 import org.apache.ignite.jdbc.AbstractJdbcSelfTest;
+import org.apache.ignite.sql.ColumnMetadata;
+import org.apache.ignite.sql.ColumnMetadata.ColumnOrigin;
 import org.apache.ignite.sql.ColumnType;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Disabled;
@@ -77,24 +82,27 @@ public class ItJdbcMetadataSelfTest extends AbstractJdbcSelfTest {
         try {
             DatabaseMetaData dbMeta = conn.getMetaData();
 
-            List<JdbcColumnMeta> columnsMeta = new ArrayList<>();
+            List<ColumnMetadata> columnsMeta = new ArrayList<>();
             try (ResultSet rs = dbMeta.getColumns(null, "META", "TEST", null)) {
                 while (rs.next()) {
-                    JdbcColumnMeta meta = new JdbcColumnMeta(
-                            rs.getString("COLUMN_NAME"),
+                    ColumnOrigin origin = new ColumnOriginImpl(
                             rs.getString("TABLE_SCHEM"),
                             rs.getString("TABLE_NAME"),
+                            rs.getString("COLUMN_NAME")
+                    );
+                    ColumnMetadata meta = new ColumnMetadataImpl(
                             rs.getString("COLUMN_NAME"),
                             dataTypeToColumnType(rs.getInt("DATA_TYPE"), rs.getString("TYPE_NAME")),
-                            rs.getShort("COLUMN_SIZE"),
-                            rs.getShort("DECIMAL_DIGITS"),
-                            "YES".equals(rs.getString("IS_NULLABLE"))
+                            rs.getInt("COLUMN_SIZE"),
+                            rs.getInt("DECIMAL_DIGITS"),
+                            "YES".equals(rs.getString("IS_NULLABLE")),
+                            origin
                     );
                     columnsMeta.add(meta);
                 }
             }
 
-            ResultSetMetaData rsMeta = new JdbcResultSetMetadata(columnsMeta);
+            ResultSetMetaData rsMeta = new JdbcResultSetMetadata(new ResultSetMetadataImpl(columnsMeta));
             checkMeta(rsMeta);
         } finally {
             stmt.execute("DROP TABLE META.TEST;");
@@ -161,7 +169,6 @@ public class ItJdbcMetadataSelfTest extends AbstractJdbcSelfTest {
     }
 
     @Test
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26145")
     public void testResultSetMetaDataColumns() throws Exception {
         createMetaTable();
 
diff --git a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadata.java b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadata.java
index 8a7baea022b..97e99e0bb63 100644
--- a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadata.java
+++ b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadata.java
@@ -24,6 +24,7 @@ import static java.sql.ResultSet.TYPE_FORWARD_ONLY;
 import static java.sql.RowIdLifetime.ROWID_UNSUPPORTED;
 import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
+import static org.apache.ignite.internal.jdbc.JdbcDatabaseMetataUtils.createObjectListResultSet;
 import static org.apache.ignite.internal.jdbc.proto.SqlStateCode.CONNECTION_CLOSED;
 
 import java.sql.Connection;
@@ -54,6 +55,7 @@ import org.apache.ignite.internal.jdbc.proto.event.JdbcMetaTablesResult;
 import org.apache.ignite.internal.jdbc.proto.event.JdbcPrimaryKeyMeta;
 import org.apache.ignite.internal.jdbc.proto.event.JdbcTableMeta;
 import org.apache.ignite.internal.properties.IgniteProductVersion;
+import org.apache.ignite.internal.sql.ColumnMetadataImpl;
 import org.apache.ignite.sql.ColumnMetadata;
 import org.apache.ignite.sql.ColumnType;
 
@@ -813,22 +815,28 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
         return false;
     }
 
+    private static ColumnMetadata columnMeta(String name, ColumnType type) {
+        return new ColumnMetadataImpl(name, type, -1, -1, true, null);
+    }
+
+
+
     /** {@inheritDoc} */
     @Override
     public ResultSet getProcedures(String catalog, String schemaPtrn,
             String procedureNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("PROCEDURE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("PROCEDURE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("PROCEDURE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("", ColumnType.NULL),
-                new JdbcColumnMeta("", ColumnType.NULL),
-                new JdbcColumnMeta("", ColumnType.NULL),
-                new JdbcColumnMeta("REMARKS", ColumnType.STRING),
-                new JdbcColumnMeta("PROCEDURE_TYPE", ColumnType.INT16),
-                new JdbcColumnMeta("SPECIFIC_NAME", ColumnType.STRING)
+        return createObjectListResultSet(asList(
+                columnMeta("PROCEDURE_CAT", ColumnType.STRING),
+                columnMeta("PROCEDURE_SCHEM", ColumnType.STRING),
+                columnMeta("PROCEDURE_NAME", ColumnType.STRING),
+                columnMeta("", ColumnType.NULL),
+                columnMeta("", ColumnType.NULL),
+                columnMeta("", ColumnType.NULL),
+                columnMeta("REMARKS", ColumnType.STRING),
+                columnMeta("PROCEDURE_TYPE", ColumnType.INT16),
+                columnMeta("SPECIFIC_NAME", ColumnType.STRING)
         ));
     }
 
@@ -838,27 +846,27 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             String colNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("PROCEDURE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("PROCEDURE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("PROCEDURE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("COLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("COLUMN_TYPE", ColumnType.INT16),
-                new JdbcColumnMeta("DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("PRECISION", ColumnType.INT32),
-                new JdbcColumnMeta("LENGTH", ColumnType.INT32),
-                new JdbcColumnMeta("SCALE", ColumnType.INT16),
-                new JdbcColumnMeta("RADIX", ColumnType.INT16),
-                new JdbcColumnMeta("NULLABLE", ColumnType.INT16),
-                new JdbcColumnMeta("REMARKS", ColumnType.STRING),
-                new JdbcColumnMeta("COLUMN_DEF", ColumnType.STRING),
-                new JdbcColumnMeta("SQL_DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("SQL_DATETIME_SUB", ColumnType.INT32),
-                new JdbcColumnMeta("CHAR_OCTET_LENGTH", ColumnType.INT32),
-                new JdbcColumnMeta("ORDINAL_POSITION", ColumnType.INT32),
-                new JdbcColumnMeta("IS_NULLABLE", ColumnType.STRING),
-                new JdbcColumnMeta("SPECIFIC_NAME", ColumnType.STRING)
+        return createObjectListResultSet(asList(
+                columnMeta("PROCEDURE_CAT", ColumnType.STRING),
+                columnMeta("PROCEDURE_SCHEM", ColumnType.STRING),
+                columnMeta("PROCEDURE_NAME", ColumnType.STRING),
+                columnMeta("COLUMN_NAME", ColumnType.STRING),
+                columnMeta("COLUMN_TYPE", ColumnType.INT16),
+                columnMeta("DATA_TYPE", ColumnType.INT32),
+                columnMeta("TYPE_NAME", ColumnType.STRING),
+                columnMeta("PRECISION", ColumnType.INT32),
+                columnMeta("LENGTH", ColumnType.INT32),
+                columnMeta("SCALE", ColumnType.INT16),
+                columnMeta("RADIX", ColumnType.INT16),
+                columnMeta("NULLABLE", ColumnType.INT16),
+                columnMeta("REMARKS", ColumnType.STRING),
+                columnMeta("COLUMN_DEF", ColumnType.STRING),
+                columnMeta("SQL_DATA_TYPE", ColumnType.INT32),
+                columnMeta("SQL_DATETIME_SUB", ColumnType.INT32),
+                columnMeta("CHAR_OCTET_LENGTH", ColumnType.INT32),
+                columnMeta("ORDINAL_POSITION", ColumnType.INT32),
+                columnMeta("IS_NULLABLE", ColumnType.STRING),
+                columnMeta("SPECIFIC_NAME", ColumnType.STRING)
         ));
     }
 
@@ -868,17 +876,17 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             throws SQLException {
         ensureNotClosed();
 
-        final List<JdbcColumnMeta> meta = asList(
-                new JdbcColumnMeta("TABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_TYPE", ColumnType.STRING),
-                new JdbcColumnMeta("REMARKS", ColumnType.STRING),
-                new JdbcColumnMeta("TYPE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TYPE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("SELF_REFERENCING_COL_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("REF_GENERATION", ColumnType.STRING));
+        List<ColumnMetadata> meta = asList(
+                columnMeta("TABLE_CAT", ColumnType.STRING),
+                columnMeta("TABLE_SCHEM", ColumnType.STRING),
+                columnMeta("TABLE_NAME", ColumnType.STRING),
+                columnMeta("TABLE_TYPE", ColumnType.STRING),
+                columnMeta("REMARKS", ColumnType.STRING),
+                columnMeta("TYPE_CAT", ColumnType.STRING),
+                columnMeta("TYPE_SCHEM", ColumnType.STRING),
+                columnMeta("TYPE_NAME", ColumnType.STRING),
+                columnMeta("SELF_REFERENCING_COL_NAME", ColumnType.STRING),
+                columnMeta("REF_GENERATION", ColumnType.STRING));
 
         boolean tblTypeMatch = false;
 
@@ -895,7 +903,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
         }
 
         if (!isValidCatalog(catalog) || !tblTypeMatch) {
-            return new JdbcResultSet(Collections.emptyList(), meta);
+            return createObjectListResultSet(meta);
         }
 
         try {
@@ -912,7 +920,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
                 rows.add(tableRow(tblMeta));
             }
 
-            return new JdbcResultSet(rows, meta);
+            return createObjectListResultSet(rows, meta);
         } catch (InterruptedException e) {
             throw new SQLException("Thread was interrupted.", e);
         } catch (ExecutionException e) {
@@ -933,13 +941,13 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     public ResultSet getSchemas(String catalog, String schemaPtrn) throws SQLException {
         ensureNotClosed();
 
-        List<JdbcColumnMeta> meta = asList(
-                new JdbcColumnMeta("TABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_CATALOG", ColumnType.STRING)
+        List<ColumnMetadata> meta = asList(
+                columnMeta("TABLE_SCHEM", ColumnType.STRING),
+                columnMeta("TABLE_CATALOG", ColumnType.STRING)
         );
 
         if (!isValidCatalog(catalog)) {
-            return new JdbcResultSet(Collections.emptyList(), meta);
+            return createObjectListResultSet(meta);
         }
 
         try {
@@ -960,7 +968,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
                 rows.add(row);
             }
 
-            return new JdbcResultSet(rows, meta);
+            return createObjectListResultSet(rows, meta);
         } catch (InterruptedException e) {
             throw new SQLException("Thread was interrupted.", e);
         } catch (ExecutionException e) {
@@ -976,8 +984,8 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     public ResultSet getCatalogs() throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(singletonList(singletonList(CATALOG_NAME)),
-                asList(new JdbcColumnMeta("TABLE_CAT", ColumnType.STRING)));
+        return createObjectListResultSet(singletonList(singletonList(CATALOG_NAME)),
+                asList(columnMeta("TABLE_CAT", ColumnType.STRING)));
     }
 
     /** {@inheritDoc} */
@@ -986,9 +994,9 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     public ResultSet getTableTypes() throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(
+        return createObjectListResultSet(
                 asList(List.of(TYPE_TABLE, TYPE_VIEW)),
-                asList(new JdbcColumnMeta("TABLE_TYPE", ColumnType.STRING)));
+                asList(columnMeta("TABLE_TYPE", ColumnType.STRING)));
     }
 
     /** {@inheritDoc} */
@@ -996,35 +1004,35 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     public ResultSet getColumns(String catalog, String schemaPtrn, String tblNamePtrn, String colNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        final List<JdbcColumnMeta> meta = asList(
-                new JdbcColumnMeta("TABLE_CAT", ColumnType.STRING),      // 1
-                new JdbcColumnMeta("TABLE_SCHEM", ColumnType.STRING),    // 2
-                new JdbcColumnMeta("TABLE_NAME", ColumnType.STRING),     // 3
-                new JdbcColumnMeta("COLUMN_NAME", ColumnType.STRING),    // 4
-                new JdbcColumnMeta("DATA_TYPE", ColumnType.INT16),       // 5
-                new JdbcColumnMeta("TYPE_NAME", ColumnType.STRING),      // 6
-                new JdbcColumnMeta("COLUMN_SIZE", ColumnType.INT32),   // 7
-                new JdbcColumnMeta("BUFFER_LENGTH", ColumnType.INT32), // 8
-                new JdbcColumnMeta("DECIMAL_DIGITS", ColumnType.INT32), // 9
-                new JdbcColumnMeta("NUM_PREC_RADIX", ColumnType.INT16),  // 10
-                new JdbcColumnMeta("NULLABLE", ColumnType.INT16),        // 11
-                new JdbcColumnMeta("REMARKS", ColumnType.STRING),        // 12
-                new JdbcColumnMeta("COLUMN_DEF", ColumnType.STRING),     // 13
-                new JdbcColumnMeta("SQL_DATA_TYPE", ColumnType.INT32), // 14
-                new JdbcColumnMeta("SQL_DATETIME_SUB", ColumnType.INT32), // 15
-                new JdbcColumnMeta("CHAR_OCTET_LENGTH", ColumnType.INT32), // 16
-                new JdbcColumnMeta("ORDINAL_POSITION", ColumnType.INT32), // 17
-                new JdbcColumnMeta("IS_NULLABLE", ColumnType.STRING),    // 18
-                new JdbcColumnMeta("SCOPE_CATLOG", ColumnType.STRING),   // 19
-                new JdbcColumnMeta("SCOPE_SCHEMA", ColumnType.STRING),   // 20
-                new JdbcColumnMeta("SCOPE_TABLE", ColumnType.STRING),    // 21
-                new JdbcColumnMeta("SOURCE_DATA_TYPE", ColumnType.INT16), // 22
-                new JdbcColumnMeta("IS_AUTOINCREMENT", ColumnType.STRING), // 23
-                new JdbcColumnMeta("IS_GENERATEDCOLUMN", ColumnType.STRING) // 24
+        List<ColumnMetadata> meta = asList(
+                columnMeta("TABLE_CAT", ColumnType.STRING),      // 1
+                columnMeta("TABLE_SCHEM", ColumnType.STRING),    // 2
+                columnMeta("TABLE_NAME", ColumnType.STRING),     // 3
+                columnMeta("COLUMN_NAME", ColumnType.STRING),    // 4
+                columnMeta("DATA_TYPE", ColumnType.INT16),       // 5
+                columnMeta("TYPE_NAME", ColumnType.STRING),      // 6
+                columnMeta("COLUMN_SIZE", ColumnType.INT32),   // 7
+                columnMeta("BUFFER_LENGTH", ColumnType.INT32), // 8
+                columnMeta("DECIMAL_DIGITS", ColumnType.INT32), // 9
+                columnMeta("NUM_PREC_RADIX", ColumnType.INT16),  // 10
+                columnMeta("NULLABLE", ColumnType.INT16),        // 11
+                columnMeta("REMARKS", ColumnType.STRING),        // 12
+                columnMeta("COLUMN_DEF", ColumnType.STRING),     // 13
+                columnMeta("SQL_DATA_TYPE", ColumnType.INT32), // 14
+                columnMeta("SQL_DATETIME_SUB", ColumnType.INT32), // 15
+                columnMeta("CHAR_OCTET_LENGTH", ColumnType.INT32), // 16
+                columnMeta("ORDINAL_POSITION", ColumnType.INT32), // 17
+                columnMeta("IS_NULLABLE", ColumnType.STRING),    // 18
+                columnMeta("SCOPE_CATLOG", ColumnType.STRING),   // 19
+                columnMeta("SCOPE_SCHEMA", ColumnType.STRING),   // 20
+                columnMeta("SCOPE_TABLE", ColumnType.STRING),    // 21
+                columnMeta("SOURCE_DATA_TYPE", ColumnType.INT16), // 22
+                columnMeta("IS_AUTOINCREMENT", ColumnType.STRING), // 23
+                columnMeta("IS_GENERATEDCOLUMN", ColumnType.STRING) // 24
         );
 
         if (!isValidCatalog(catalog)) {
-            return new JdbcResultSet(Collections.emptyList(), meta);
+            return createObjectListResultSet(meta);
         }
 
         try {
@@ -1041,7 +1049,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
                 rows.add(columnRow(res.meta().get(i), i + 1));
             }
 
-            return new JdbcResultSet(rows, meta);
+            return createObjectListResultSet(rows, meta);
         } catch (InterruptedException e) {
             throw new SQLException("Thread was interrupted.", e);
         } catch (ExecutionException e) {
@@ -1057,15 +1065,15 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             String colNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("TABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("COLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("GRANTOR", ColumnType.STRING),
-                new JdbcColumnMeta("GRANTEE", ColumnType.STRING),
-                new JdbcColumnMeta("PRIVILEGE", ColumnType.STRING),
-                new JdbcColumnMeta("IS_GRANTABLE", ColumnType.STRING)
+        return createObjectListResultSet(asList(
+                columnMeta("TABLE_CAT", ColumnType.STRING),
+                columnMeta("TABLE_SCHEM", ColumnType.STRING),
+                columnMeta("TABLE_NAME", ColumnType.STRING),
+                columnMeta("COLUMN_NAME", ColumnType.STRING),
+                columnMeta("GRANTOR", ColumnType.STRING),
+                columnMeta("GRANTEE", ColumnType.STRING),
+                columnMeta("PRIVILEGE", ColumnType.STRING),
+                columnMeta("IS_GRANTABLE", ColumnType.STRING)
         ));
     }
 
@@ -1075,14 +1083,14 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             String tblNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("TABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("GRANTOR", ColumnType.STRING),
-                new JdbcColumnMeta("GRANTEE", ColumnType.STRING),
-                new JdbcColumnMeta("PRIVILEGE", ColumnType.STRING),
-                new JdbcColumnMeta("IS_GRANTABLE", ColumnType.STRING)
+        return createObjectListResultSet(asList(
+                columnMeta("TABLE_CAT", ColumnType.STRING),
+                columnMeta("TABLE_SCHEM", ColumnType.STRING),
+                columnMeta("TABLE_NAME", ColumnType.STRING),
+                columnMeta("GRANTOR", ColumnType.STRING),
+                columnMeta("GRANTEE", ColumnType.STRING),
+                columnMeta("PRIVILEGE", ColumnType.STRING),
+                columnMeta("IS_GRANTABLE", ColumnType.STRING)
         ));
     }
 
@@ -1090,15 +1098,15 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     @Override
     public ResultSet getBestRowIdentifier(String catalog, String schema, String tbl, int scope,
             boolean nullable) throws SQLException {
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("SCOPE", ColumnType.INT16),
-                new JdbcColumnMeta("COLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("COLUMN_SIZE", ColumnType.INT32),
-                new JdbcColumnMeta("BUFFER_LENGTH", ColumnType.INT32),
-                new JdbcColumnMeta("DECIMAL_DIGITS", ColumnType.INT16),
-                new JdbcColumnMeta("PSEUDO_COLUMN", ColumnType.INT16)
+        return createObjectListResultSet(asList(
+                columnMeta("SCOPE", ColumnType.INT16),
+                columnMeta("COLUMN_NAME", ColumnType.STRING),
+                columnMeta("DATA_TYPE", ColumnType.INT32),
+                columnMeta("TYPE_NAME", ColumnType.STRING),
+                columnMeta("COLUMN_SIZE", ColumnType.INT32),
+                columnMeta("BUFFER_LENGTH", ColumnType.INT32),
+                columnMeta("DECIMAL_DIGITS", ColumnType.INT16),
+                columnMeta("PSEUDO_COLUMN", ColumnType.INT16)
         ));
     }
 
@@ -1107,15 +1115,15 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     public ResultSet getVersionColumns(String catalog, String schema, String tbl) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("SCOPE", ColumnType.INT16),
-                new JdbcColumnMeta("COLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("COLUMN_SIZE", ColumnType.INT32),
-                new JdbcColumnMeta("BUFFER_LENGTH", ColumnType.INT32),
-                new JdbcColumnMeta("DECIMAL_DIGITS", ColumnType.INT16),
-                new JdbcColumnMeta("PSEUDO_COLUMN", ColumnType.INT16)
+        return createObjectListResultSet(asList(
+                columnMeta("SCOPE", ColumnType.INT16),
+                columnMeta("COLUMN_NAME", ColumnType.STRING),
+                columnMeta("DATA_TYPE", ColumnType.INT32),
+                columnMeta("TYPE_NAME", ColumnType.STRING),
+                columnMeta("COLUMN_SIZE", ColumnType.INT32),
+                columnMeta("BUFFER_LENGTH", ColumnType.INT32),
+                columnMeta("DECIMAL_DIGITS", ColumnType.INT16),
+                columnMeta("PSEUDO_COLUMN", ColumnType.INT16)
         ));
     }
 
@@ -1124,16 +1132,16 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     public ResultSet getPrimaryKeys(String catalog, String schema, String tbl) throws SQLException {
         ensureNotClosed();
 
-        final List<JdbcColumnMeta> meta = asList(
-                new JdbcColumnMeta("TABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("COLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("KEY_SEQ", ColumnType.INT16),
-                new JdbcColumnMeta("PK_NAME", ColumnType.STRING));
+        List<ColumnMetadata> meta = asList(
+                columnMeta("TABLE_CAT", ColumnType.STRING),
+                columnMeta("TABLE_SCHEM", ColumnType.STRING),
+                columnMeta("TABLE_NAME", ColumnType.STRING),
+                columnMeta("COLUMN_NAME", ColumnType.STRING),
+                columnMeta("KEY_SEQ", ColumnType.INT16),
+                columnMeta("PK_NAME", ColumnType.STRING));
 
         if (!isValidCatalog(catalog)) {
-            return new JdbcResultSet(Collections.emptyList(), meta);
+            return createObjectListResultSet(meta);
         }
 
         try {
@@ -1149,7 +1157,7 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
                 rows.addAll(primaryKeyRows(pkMeta));
             }
 
-            return new JdbcResultSet(rows, meta);
+            return createObjectListResultSet(rows, meta);
         } catch (InterruptedException e) {
             throw new SQLException("Thread was interrupted.", e);
         } catch (ExecutionException e) {
@@ -1164,21 +1172,21 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     public ResultSet getImportedKeys(String catalog, String schema, String tbl) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("PKTABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("PKTABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("PKTABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("PKCOLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("FKTABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("FKTABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("FKTABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("FKCOLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("KEY_SEQ", ColumnType.INT16),
-                new JdbcColumnMeta("UPDATE_RULE", ColumnType.INT16),
-                new JdbcColumnMeta("DELETE_RULE", ColumnType.INT16),
-                new JdbcColumnMeta("FK_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("PK_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("DEFERRABILITY", ColumnType.INT16)
+        return createObjectListResultSet(asList(
+                columnMeta("PKTABLE_CAT", ColumnType.STRING),
+                columnMeta("PKTABLE_SCHEM", ColumnType.STRING),
+                columnMeta("PKTABLE_NAME", ColumnType.STRING),
+                columnMeta("PKCOLUMN_NAME", ColumnType.STRING),
+                columnMeta("FKTABLE_CAT", ColumnType.STRING),
+                columnMeta("FKTABLE_SCHEM", ColumnType.STRING),
+                columnMeta("FKTABLE_NAME", ColumnType.STRING),
+                columnMeta("FKCOLUMN_NAME", ColumnType.STRING),
+                columnMeta("KEY_SEQ", ColumnType.INT16),
+                columnMeta("UPDATE_RULE", ColumnType.INT16),
+                columnMeta("DELETE_RULE", ColumnType.INT16),
+                columnMeta("FK_NAME", ColumnType.STRING),
+                columnMeta("PK_NAME", ColumnType.STRING),
+                columnMeta("DEFERRABILITY", ColumnType.INT16)
         ));
     }
 
@@ -1187,21 +1195,21 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     public ResultSet getExportedKeys(String catalog, String schema, String tbl) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("PKTABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("PKTABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("PKTABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("PKCOLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("FKTABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("FKTABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("FKTABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("FKCOLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("KEY_SEQ", ColumnType.INT16),
-                new JdbcColumnMeta("UPDATE_RULE", ColumnType.INT16),
-                new JdbcColumnMeta("DELETE_RULE", ColumnType.INT16),
-                new JdbcColumnMeta("FK_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("PK_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("DEFERRABILITY", ColumnType.INT16)
+        return createObjectListResultSet(asList(
+                columnMeta("PKTABLE_CAT", ColumnType.STRING),
+                columnMeta("PKTABLE_SCHEM", ColumnType.STRING),
+                columnMeta("PKTABLE_NAME", ColumnType.STRING),
+                columnMeta("PKCOLUMN_NAME", ColumnType.STRING),
+                columnMeta("FKTABLE_CAT", ColumnType.STRING),
+                columnMeta("FKTABLE_SCHEM", ColumnType.STRING),
+                columnMeta("FKTABLE_NAME", ColumnType.STRING),
+                columnMeta("FKCOLUMN_NAME", ColumnType.STRING),
+                columnMeta("KEY_SEQ", ColumnType.INT16),
+                columnMeta("UPDATE_RULE", ColumnType.INT16),
+                columnMeta("DELETE_RULE", ColumnType.INT16),
+                columnMeta("FK_NAME", ColumnType.STRING),
+                columnMeta("PK_NAME", ColumnType.STRING),
+                columnMeta("DEFERRABILITY", ColumnType.INT16)
         ));
     }
 
@@ -1211,21 +1219,21 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             String foreignCatalog, String foreignSchema, String foreignTbl) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("PKTABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("PKTABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("PKTABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("PKCOLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("FKTABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("FKTABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("FKTABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("FKCOLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("KEY_SEQ", ColumnType.INT16),
-                new JdbcColumnMeta("UPDATE_RULE", ColumnType.INT16),
-                new JdbcColumnMeta("DELETE_RULE", ColumnType.INT16),
-                new JdbcColumnMeta("FK_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("PK_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("DEFERRABILITY", ColumnType.INT16)
+        return createObjectListResultSet(asList(
+                columnMeta("PKTABLE_CAT", ColumnType.STRING),
+                columnMeta("PKTABLE_SCHEM", ColumnType.STRING),
+                columnMeta("PKTABLE_NAME", ColumnType.STRING),
+                columnMeta("PKCOLUMN_NAME", ColumnType.STRING),
+                columnMeta("FKTABLE_CAT", ColumnType.STRING),
+                columnMeta("FKTABLE_SCHEM", ColumnType.STRING),
+                columnMeta("FKTABLE_NAME", ColumnType.STRING),
+                columnMeta("FKCOLUMN_NAME", ColumnType.STRING),
+                columnMeta("KEY_SEQ", ColumnType.INT16),
+                columnMeta("UPDATE_RULE", ColumnType.INT16),
+                columnMeta("DELETE_RULE", ColumnType.INT16),
+                columnMeta("FK_NAME", ColumnType.STRING),
+                columnMeta("PK_NAME", ColumnType.STRING),
+                columnMeta("DEFERRABILITY", ColumnType.INT16)
         ));
     }
 
@@ -1326,25 +1334,25 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
                 (short) typeNullable, false, (short) typeSearchable, false, false, false, "ARRAY", 0, 0,
                 Types.ARRAY, 0, null));
 
-        return new JdbcResultSet(types, asList(
-                new JdbcColumnMeta("TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("PRECISION", ColumnType.INT32),
-                new JdbcColumnMeta("LITERAL_PREFIX", ColumnType.STRING),
-                new JdbcColumnMeta("LITERAL_SUFFIX", ColumnType.STRING),
-                new JdbcColumnMeta("CREATE_PARAMS", ColumnType.STRING),
-                new JdbcColumnMeta("NULLABLE", ColumnType.INT16),
-                new JdbcColumnMeta("CASE_SENSITIVE", ColumnType.BOOLEAN),
-                new JdbcColumnMeta("SEARCHABLE", ColumnType.INT16),
-                new JdbcColumnMeta("UNSIGNED_ATTRIBUTE", ColumnType.BOOLEAN),
-                new JdbcColumnMeta("FIXED_PREC_SCALE", ColumnType.BOOLEAN),
-                new JdbcColumnMeta("AUTO_INCREMENT", ColumnType.BOOLEAN),
-                new JdbcColumnMeta("LOCAL_TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("MINIMUM_SCALE", ColumnType.INT16),
-                new JdbcColumnMeta("MAXIMUM_SCALE", ColumnType.INT16),
-                new JdbcColumnMeta("SQL_DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("SQL_DATETIME_SUB", ColumnType.INT32),
-                new JdbcColumnMeta("NUM_PREC_RADIX", ColumnType.INT32)
+        return createObjectListResultSet(types, asList(
+                columnMeta("TYPE_NAME", ColumnType.STRING),
+                columnMeta("DATA_TYPE", ColumnType.INT32),
+                columnMeta("PRECISION", ColumnType.INT32),
+                columnMeta("LITERAL_PREFIX", ColumnType.STRING),
+                columnMeta("LITERAL_SUFFIX", ColumnType.STRING),
+                columnMeta("CREATE_PARAMS", ColumnType.STRING),
+                columnMeta("NULLABLE", ColumnType.INT16),
+                columnMeta("CASE_SENSITIVE", ColumnType.BOOLEAN),
+                columnMeta("SEARCHABLE", ColumnType.INT16),
+                columnMeta("UNSIGNED_ATTRIBUTE", ColumnType.BOOLEAN),
+                columnMeta("FIXED_PREC_SCALE", ColumnType.BOOLEAN),
+                columnMeta("AUTO_INCREMENT", ColumnType.BOOLEAN),
+                columnMeta("LOCAL_TYPE_NAME", ColumnType.STRING),
+                columnMeta("MINIMUM_SCALE", ColumnType.INT16),
+                columnMeta("MAXIMUM_SCALE", ColumnType.INT16),
+                columnMeta("SQL_DATA_TYPE", ColumnType.INT32),
+                columnMeta("SQL_DATETIME_SUB", ColumnType.INT32),
+                columnMeta("NUM_PREC_RADIX", ColumnType.INT32)
         ));
     }
 
@@ -1354,23 +1362,23 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             boolean approximate) throws SQLException {
         ensureNotClosed();
 
-        final List<JdbcColumnMeta> meta = asList(
-                new JdbcColumnMeta("TABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("NON_UNIQUE", ColumnType.BOOLEAN),
-                new JdbcColumnMeta("INDEX_QUALIFIER", ColumnType.STRING),
-                new JdbcColumnMeta("INDEX_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("TYPE", ColumnType.INT16),
-                new JdbcColumnMeta("ORDINAL_POSITION", ColumnType.INT16),
-                new JdbcColumnMeta("COLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("ASC_OR_DESC", ColumnType.STRING),
-                new JdbcColumnMeta("CARDINALITY", ColumnType.INT32),
-                new JdbcColumnMeta("PAGES", ColumnType.INT32),
-                new JdbcColumnMeta("FILTER_CONDITION", ColumnType.STRING));
+        List<ColumnMetadata> meta = asList(
+                columnMeta("TABLE_CAT", ColumnType.STRING),
+                columnMeta("TABLE_SCHEM", ColumnType.STRING),
+                columnMeta("TABLE_NAME", ColumnType.STRING),
+                columnMeta("NON_UNIQUE", ColumnType.BOOLEAN),
+                columnMeta("INDEX_QUALIFIER", ColumnType.STRING),
+                columnMeta("INDEX_NAME", ColumnType.STRING),
+                columnMeta("TYPE", ColumnType.INT16),
+                columnMeta("ORDINAL_POSITION", ColumnType.INT16),
+                columnMeta("COLUMN_NAME", ColumnType.STRING),
+                columnMeta("ASC_OR_DESC", ColumnType.STRING),
+                columnMeta("CARDINALITY", ColumnType.INT32),
+                columnMeta("PAGES", ColumnType.INT32),
+                columnMeta("FILTER_CONDITION", ColumnType.STRING));
 
         if (!isValidCatalog(catalog)) {
-            return new JdbcResultSet(Collections.emptyList(), meta);
+            return createObjectListResultSet(Collections.emptyList(), meta);
         }
 
         throw new UnsupportedOperationException("Index info is not supported yet.");
@@ -1454,14 +1462,14 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             int[] types) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("TYPE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TYPE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("CLASS_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("REMARKS", ColumnType.STRING),
-                new JdbcColumnMeta("BASE_TYPE", ColumnType.INT16)
+        return createObjectListResultSet(asList(
+                columnMeta("TYPE_CAT", ColumnType.STRING),
+                columnMeta("TYPE_SCHEM", ColumnType.STRING),
+                columnMeta("TYPE_NAME", ColumnType.STRING),
+                columnMeta("CLASS_NAME", ColumnType.STRING),
+                columnMeta("DATA_TYPE", ColumnType.INT32),
+                columnMeta("REMARKS", ColumnType.STRING),
+                columnMeta("BASE_TYPE", ColumnType.INT16)
         ));
     }
 
@@ -1501,13 +1509,13 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             String typeNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("TYPE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TYPE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("SUPERTYPE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("SUPERTYPE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("SUPERTYPE_NAME", ColumnType.STRING)
+        return createObjectListResultSet(asList(
+                columnMeta("TYPE_CAT", ColumnType.STRING),
+                columnMeta("TYPE_SCHEM", ColumnType.STRING),
+                columnMeta("TYPE_NAME", ColumnType.STRING),
+                columnMeta("SUPERTYPE_CAT", ColumnType.STRING),
+                columnMeta("SUPERTYPE_SCHEM", ColumnType.STRING),
+                columnMeta("SUPERTYPE_NAME", ColumnType.STRING)
         ));
     }
 
@@ -1517,11 +1525,11 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             String tblNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("TABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("SUPERTABLE_NAME", ColumnType.STRING)
+        return createObjectListResultSet(asList(
+                columnMeta("TABLE_CAT", ColumnType.STRING),
+                columnMeta("TABLE_SCHEM", ColumnType.STRING),
+                columnMeta("TABLE_NAME", ColumnType.STRING),
+                columnMeta("SUPERTABLE_NAME", ColumnType.STRING)
         ));
     }
 
@@ -1531,28 +1539,28 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             String attributeNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("TYPE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TYPE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("ATTR_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("ATTR_TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("ATTR_SIZE", ColumnType.INT32),
-                new JdbcColumnMeta("DECIMAL_DIGITS", ColumnType.INT32),
-                new JdbcColumnMeta("NUM_PREC_RADIX", ColumnType.INT32),
-                new JdbcColumnMeta("NULLABLE", ColumnType.INT32),
-                new JdbcColumnMeta("REMARKS", ColumnType.STRING),
-                new JdbcColumnMeta("ATTR_DEF", ColumnType.STRING),
-                new JdbcColumnMeta("SQL_DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("SQL_DATETIME_SUB", ColumnType.INT32),
-                new JdbcColumnMeta("CHAR_OCTET_LENGTH", ColumnType.INT32),
-                new JdbcColumnMeta("ORDINAL_POSITION", ColumnType.INT32),
-                new JdbcColumnMeta("IS_NULLABLE", ColumnType.STRING),
-                new JdbcColumnMeta("SCOPE_CATALOG", ColumnType.STRING),
-                new JdbcColumnMeta("SCOPE_SCHEMA", ColumnType.STRING),
-                new JdbcColumnMeta("SCOPE_TABLE", ColumnType.STRING),
-                new JdbcColumnMeta("SOURCE_DATA_TYPE", ColumnType.INT16)
+        return createObjectListResultSet(asList(
+                columnMeta("TYPE_CAT", ColumnType.STRING),
+                columnMeta("TYPE_SCHEM", ColumnType.STRING),
+                columnMeta("TYPE_NAME", ColumnType.STRING),
+                columnMeta("ATTR_NAME", ColumnType.STRING),
+                columnMeta("DATA_TYPE", ColumnType.INT32),
+                columnMeta("ATTR_TYPE_NAME", ColumnType.STRING),
+                columnMeta("ATTR_SIZE", ColumnType.INT32),
+                columnMeta("DECIMAL_DIGITS", ColumnType.INT32),
+                columnMeta("NUM_PREC_RADIX", ColumnType.INT32),
+                columnMeta("NULLABLE", ColumnType.INT32),
+                columnMeta("REMARKS", ColumnType.STRING),
+                columnMeta("ATTR_DEF", ColumnType.STRING),
+                columnMeta("SQL_DATA_TYPE", ColumnType.INT32),
+                columnMeta("SQL_DATETIME_SUB", ColumnType.INT32),
+                columnMeta("CHAR_OCTET_LENGTH", ColumnType.INT32),
+                columnMeta("ORDINAL_POSITION", ColumnType.INT32),
+                columnMeta("IS_NULLABLE", ColumnType.STRING),
+                columnMeta("SCOPE_CATALOG", ColumnType.STRING),
+                columnMeta("SCOPE_SCHEMA", ColumnType.STRING),
+                columnMeta("SCOPE_TABLE", ColumnType.STRING),
+                columnMeta("SOURCE_DATA_TYPE", ColumnType.INT16)
         ));
     }
 
@@ -1633,11 +1641,11 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
     public ResultSet getClientInfoProperties() throws SQLException {
         // We do not check whether connection is closed as 
         // this operation is not expected to do any server calls.  
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("NAME", ColumnType.STRING),
-                new JdbcColumnMeta("MAX_LEN", ColumnType.INT32),
-                new JdbcColumnMeta("DEFAULT_VALUE", ColumnType.STRING),
-                new JdbcColumnMeta("DESCRIPTION", ColumnType.STRING)
+        return createObjectListResultSet(asList(
+                columnMeta("NAME", ColumnType.STRING),
+                columnMeta("MAX_LEN", ColumnType.INT32),
+                columnMeta("DEFAULT_VALUE", ColumnType.STRING),
+                columnMeta("DESCRIPTION", ColumnType.STRING)
         ));
     }
 
@@ -1649,13 +1657,13 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             String functionNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("FUNCTION_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("FUNCTION_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("FUNCTION_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("REMARKS", ColumnType.STRING),
-                new JdbcColumnMeta("FUNCTION_TYPE", ColumnType.STRING),
-                new JdbcColumnMeta("SPECIFIC_NAME", ColumnType.STRING)
+        return createObjectListResultSet(asList(
+                columnMeta("FUNCTION_CAT", ColumnType.STRING),
+                columnMeta("FUNCTION_SCHEM", ColumnType.STRING),
+                columnMeta("FUNCTION_NAME", ColumnType.STRING),
+                columnMeta("REMARKS", ColumnType.STRING),
+                columnMeta("FUNCTION_TYPE", ColumnType.STRING),
+                columnMeta("SPECIFIC_NAME", ColumnType.STRING)
         ));
     }
 
@@ -1665,24 +1673,24 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             String colNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("FUNCTION_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("FUNCTION_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("FUNCTION_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("COLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("COLUMN_TYPE", ColumnType.INT16),
-                new JdbcColumnMeta("DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("TYPE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("PRECISION", ColumnType.INT32),
-                new JdbcColumnMeta("LENGTH", ColumnType.INT32),
-                new JdbcColumnMeta("SCALE", ColumnType.INT16),
-                new JdbcColumnMeta("RADIX", ColumnType.INT16),
-                new JdbcColumnMeta("NULLABLE", ColumnType.INT16),
-                new JdbcColumnMeta("REMARKS", ColumnType.STRING),
-                new JdbcColumnMeta("CHAR_OCTET_LENGTH", ColumnType.INT32),
-                new JdbcColumnMeta("ORDINAL_POSITION", ColumnType.INT32),
-                new JdbcColumnMeta("IS_NULLABLE", ColumnType.STRING),
-                new JdbcColumnMeta("SPECIFIC_NAME", ColumnType.STRING)
+        return createObjectListResultSet(asList(
+                columnMeta("FUNCTION_CAT", ColumnType.STRING),
+                columnMeta("FUNCTION_SCHEM", ColumnType.STRING),
+                columnMeta("FUNCTION_NAME", ColumnType.STRING),
+                columnMeta("COLUMN_NAME", ColumnType.STRING),
+                columnMeta("COLUMN_TYPE", ColumnType.INT16),
+                columnMeta("DATA_TYPE", ColumnType.INT32),
+                columnMeta("TYPE_NAME", ColumnType.STRING),
+                columnMeta("PRECISION", ColumnType.INT32),
+                columnMeta("LENGTH", ColumnType.INT32),
+                columnMeta("SCALE", ColumnType.INT16),
+                columnMeta("RADIX", ColumnType.INT16),
+                columnMeta("NULLABLE", ColumnType.INT16),
+                columnMeta("REMARKS", ColumnType.STRING),
+                columnMeta("CHAR_OCTET_LENGTH", ColumnType.INT32),
+                columnMeta("ORDINAL_POSITION", ColumnType.INT32),
+                columnMeta("IS_NULLABLE", ColumnType.STRING),
+                columnMeta("SPECIFIC_NAME", ColumnType.STRING)
         ));
     }
 
@@ -1708,19 +1716,19 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
             String colNamePtrn) throws SQLException {
         ensureNotClosed();
 
-        return new JdbcResultSet(Collections.emptyList(), asList(
-                new JdbcColumnMeta("TABLE_CAT", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_SCHEM", ColumnType.STRING),
-                new JdbcColumnMeta("TABLE_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("COLUMN_NAME", ColumnType.STRING),
-                new JdbcColumnMeta("DATA_TYPE", ColumnType.INT32),
-                new JdbcColumnMeta("COLUMN_SIZE", ColumnType.INT32),
-                new JdbcColumnMeta("DECIMAL_DIGITS", ColumnType.INT32),
-                new JdbcColumnMeta("NUM_PREC_RADIX", ColumnType.INT32),
-                new JdbcColumnMeta("COLUMN_USAGE", ColumnType.INT32),
-                new JdbcColumnMeta("REMARKS", ColumnType.STRING),
-                new JdbcColumnMeta("CHAR_OCTET_LENGTH", ColumnType.INT32),
-                new JdbcColumnMeta("IS_NULLABLE", ColumnType.STRING)
+        return createObjectListResultSet(asList(
+                columnMeta("TABLE_CAT", ColumnType.STRING),
+                columnMeta("TABLE_SCHEM", ColumnType.STRING),
+                columnMeta("TABLE_NAME", ColumnType.STRING),
+                columnMeta("COLUMN_NAME", ColumnType.STRING),
+                columnMeta("DATA_TYPE", ColumnType.INT32),
+                columnMeta("COLUMN_SIZE", ColumnType.INT32),
+                columnMeta("DECIMAL_DIGITS", ColumnType.INT32),
+                columnMeta("NUM_PREC_RADIX", ColumnType.INT32),
+                columnMeta("COLUMN_USAGE", ColumnType.INT32),
+                columnMeta("REMARKS", ColumnType.STRING),
+                columnMeta("CHAR_OCTET_LENGTH", ColumnType.INT32),
+                columnMeta("IS_NULLABLE", ColumnType.STRING)
         ));
     }
 
@@ -1777,14 +1785,14 @@ public class JdbcDatabaseMetadata implements DatabaseMetaData {
         row.add(CATALOG_NAME);                  // 1. TABLE_CAT
         row.add(colMeta.schemaName());          // 2. TABLE_SCHEM
         row.add(colMeta.tableName());           // 3. TABLE_NAME
-        row.add(colMeta.columnLabel());          // 4. COLUMN_NAME
-        row.add(colMeta.dataType());            // 5. DATA_TYPE
+        row.add(colMeta.columnLabel());         // 4. COLUMN_NAME
+        row.add((short) colMeta.dataType());    // 5. DATA_TYPE
         row.add(colMeta.dataTypeName());        // 6. TYPE_NAME
         row.add(colMeta.precision() == -1 ? null : colMeta.precision()); // 7. COLUMN_SIZE
         row.add((Integer) null);                 // 8. BUFFER_LENGTH
         row.add(colMeta.scale() == -1 ? null : colMeta.scale());           // 9. DECIMAL_DIGITS
         row.add(10);                            // 10. NUM_PREC_RADIX
-        row.add(colMeta.isNullable() ? columnNullable : columnNoNulls);  // 11. NULLABLE
+        row.add(colMeta.isNullable() ? (short) columnNullable : (short) columnNoNulls);  // 11. NULLABLE
         row.add((String) null);                  // 12. REMARKS
         row.add(colMeta.defaultValue());        // 13. COLUMN_DEF
         row.add(colMeta.dataType());            // 14. SQL_DATA_TYPE
diff --git a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetataUtils.java b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetataUtils.java
new file mode 100644
index 00000000000..8f94df1e87f
--- /dev/null
+++ b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetataUtils.java
@@ -0,0 +1,321 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import org.apache.ignite.internal.jdbc2.ClientSyncResultSet;
+import org.apache.ignite.internal.jdbc2.JdbcResultSet;
+import org.apache.ignite.internal.sql.ResultSetMetadataImpl;
+import org.apache.ignite.internal.util.TransformingIterator;
+import org.apache.ignite.sql.ColumnMetadata;
+import org.apache.ignite.sql.NoRowSetExpectedException;
+import org.apache.ignite.sql.ResultSetMetadata;
+import org.apache.ignite.sql.SqlRow;
+import org.apache.ignite.table.Tuple;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Helper methods for creating a {@link ResultSet} set using a list of objects.
+ */
+public class JdbcDatabaseMetataUtils {
+    static ResultSet createObjectListResultSet(List<ColumnMetadata> columnsMeta) {
+        return createObjectListResultSet(List.of(), columnsMeta);
+    }
+
+    static ResultSet createObjectListResultSet(List<List<Object>> rows, List<ColumnMetadata> columnsMeta) {
+        ResultSetMetadata meta = new ResultSetMetadataImpl(columnsMeta);
+
+        TransformingIterator<List<Object>, SqlRow> transformer = new TransformingIterator<>(rows.iterator(),
+                ObjectListToSqlRowAdapter::new);
+
+        return new JdbcResultSet(
+                new IteratorBasedClientSyncResultSet(transformer, meta),
+                null,
+                ZoneId::systemDefault,
+                false,
+                0
+        );
+    }
+
+    private static class IteratorBasedClientSyncResultSet implements ClientSyncResultSet {
+        private final ResultSetMetadata metadata;
+        private final Iterator<SqlRow> rowsIterator;
+
+        IteratorBasedClientSyncResultSet(Iterator<SqlRow> rowsIterator, ResultSetMetadata metadata) {
+            this.rowsIterator = rowsIterator;
+            this.metadata = metadata;
+        }
+
+        @Override
+        public ResultSetMetadata metadata() {
+            return metadata;
+        }
+
+        @Override
+        public boolean hasRowSet() {
+            return true;
+        }
+
+        @Override
+        public long affectedRows() {
+            return -1;
+        }
+
+        @Override
+        public boolean wasApplied() {
+            return false;
+        }
+
+        @Override
+        public boolean hasNextResultSet() {
+            return false;
+        }
+
+        @Override
+        public ClientSyncResultSet nextResultSet() {
+            throw new NoSuchElementException("Query has no more results");
+        }
+
+        @Override
+        public void close() {
+            // No-op.
+        }
+
+        @Override
+        public boolean hasNext() {
+            return rowsIterator.hasNext();
+        }
+
+        @Override
+        public SqlRow next() {
+            if (!rowsIterator.hasNext()) {
+                throw new NoRowSetExpectedException();
+            }
+
+            return rowsIterator.next();
+        }
+    }
+
+    private static class ObjectListToSqlRowAdapter implements SqlRow {
+        private final List<Object> row;
+
+        ObjectListToSqlRowAdapter(List<Object> row) {
+            this.row = row;
+        }
+
+        @Override
+        public <T> @Nullable T value(int columnIndex) {
+            return (T) row.get(columnIndex);
+        }
+
+        @Override
+        public <T> @Nullable T value(String columnName) throws IllegalArgumentException {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public ResultSetMetadata metadata() {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public int columnCount() {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public String columnName(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public int columnIndex(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public <T> @Nullable T valueOrDefault(String columnName, @Nullable T defaultValue) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public Tuple set(String columnName, @Nullable Object value) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public boolean booleanValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public boolean booleanValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public byte byteValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public byte byteValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public short shortValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public short shortValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public int intValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public int intValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public long longValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public long longValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public float floatValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public float floatValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public double doubleValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public double doubleValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public BigDecimal decimalValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public BigDecimal decimalValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public String stringValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public String stringValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public byte[] bytesValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public byte[] bytesValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public UUID uuidValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public UUID uuidValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public LocalDate dateValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public LocalDate dateValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public LocalTime timeValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public LocalTime timeValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public LocalDateTime datetimeValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public LocalDateTime datetimeValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public Instant timestampValue(String columnName) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+
+        @Override
+        public Instant timestampValue(int columnIndex) {
+            throw new UnsupportedOperationException("This method should not be called.");
+        }
+    }
+}
diff --git a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/ClientSyncResultSet.java b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/ClientSyncResultSet.java
index a565e073947..231bba83a5c 100644
--- a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/ClientSyncResultSet.java
+++ b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/ClientSyncResultSet.java
@@ -26,7 +26,8 @@ import org.apache.ignite.sql.SqlRow;
 /**
  * Sync result set.
  */
-interface ClientSyncResultSet extends Iterator<SqlRow> {
+// TODO https://issues.apache.org/jira/browse/IGNITE-26145 Remove "public" modifier
+public interface ClientSyncResultSet extends Iterator<SqlRow> {
 
     ResultSetMetadata EMPTY_METADATA = new ResultSetMetadataImpl(List.of());
 
diff --git a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
index 6863ffc40c3..da9948c0709 100644
--- a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
+++ b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
@@ -105,7 +105,8 @@ public class JdbcResultSet implements ResultSet {
     /**
      * Constructor.
      */
-    JdbcResultSet(
+    // TODO https://issues.apache.org/jira/browse/IGNITE-26145 Remove "public" modifier
+    public JdbcResultSet(
             ClientSyncResultSet rs,
             Statement statement,
             Supplier<ZoneId> zoneIdSupplier,
diff --git a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement2.java b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement2.java
index 79efecb640d..4a46f0ef647 100644
--- a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement2.java
+++ b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement2.java
@@ -510,12 +510,22 @@ public class JdbcStatement2 implements Statement {
         return FETCH_FORWARD;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * Gives the JDBC driver a hint as to the number of rows that should
+     * be fetched from the database.
+     *
+     * <p>Note: in the current driver implementation, this method does nothing.
+     *
+     * @param fetchSize the number of rows to fetch
+     * @exception SQLException if the condition {@code rows >= 0} is not satisfied.
+     * @since 1.2
+     * @see #getFetchSize
+     */
     @Override
     public void setFetchSize(int fetchSize) throws SQLException {
         ensureNotClosed();
 
-        if (fetchSize <= 0) {
+        if (fetchSize < 0) {
             throw new SQLException("Invalid fetch size.");
         }