You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/08/21 08:40:29 UTC

[20/50] [abbrv] ignite git commit: IGNITE-5233: JDBC thind driver: implemented metadata methods. This closes #2079.

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinParameterMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinParameterMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinParameterMetadata.java
new file mode 100644
index 0000000..8647258
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinParameterMetadata.java
@@ -0,0 +1,115 @@
+/*
+ * 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.thin;
+
+import java.sql.ParameterMetaData;
+import java.sql.SQLException;
+import java.util.List;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcParameterMeta;
+
+/**
+ * JDBC SQL query's parameters metadata.
+ */
+public class JdbcThinParameterMetadata implements ParameterMetaData {
+    /** Parameters metadata. */
+    private final List<JdbcParameterMeta> meta;
+
+    /**
+     * @param meta Parameters metadata.
+     */
+    public JdbcThinParameterMetadata(List<JdbcParameterMeta> meta) {
+        assert meta != null;
+
+        this.meta = meta;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int getParameterCount() throws SQLException {
+        return meta.size();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("MagicConstant")
+    @Override public int isNullable(int param) throws SQLException {
+        return parameter(param).isNullable();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isSigned(int param) throws SQLException {
+        return parameter(param).isSigned();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int getPrecision(int param) throws SQLException {
+        return parameter(param).precision();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int getScale(int param) throws SQLException {
+        return parameter(param).scale();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int getParameterType(int param) throws SQLException {
+        return parameter(param).type();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getParameterTypeName(int param) throws SQLException {
+        return parameter(param).typeName();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getParameterClassName(int param) throws SQLException {
+        return parameter(param).typeClass();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("MagicConstant")
+    @Override public int getParameterMode(int param) throws SQLException {
+        return parameter(param).mode();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override public <T> T unwrap(Class<T> iface) throws SQLException {
+        if (!isWrapperFor(iface))
+            throw new SQLException("Parameters metadata is not a wrapper for " + iface.getName());
+
+        return (T)this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return iface != null && iface.isAssignableFrom(JdbcThinParameterMetadata.class);
+    }
+
+    /**
+     * Bounds checks the parameter index.
+     *
+     * @param param Parameter index.
+     * @return Parameter.
+     * @throws SQLException If failed.
+     */
+    private JdbcParameterMeta parameter(int param) throws SQLException {
+        if (param <= 0 || param > meta.size())
+            throw new SQLException("Invalid parameter number");
+
+        return meta.get(param - 1);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
index 455c80f..e6dfa59 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.jdbc.thin;
 
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.Reader;
 import java.math.BigDecimal;
@@ -39,7 +40,9 @@ import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Calendar;
+import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.processors.odbc.SqlListenerUtils;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaParamsResult;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery;
 
 /**
@@ -52,6 +55,9 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep
     /** Query arguments. */
     protected ArrayList<Object> args;
 
+    /** Parameters metadata. */
+    private JdbcThinParameterMetadata metaData;
+
     /**
      * Creates new prepared statement.
      *
@@ -322,8 +328,27 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep
     /** {@inheritDoc} */
     @Override public ParameterMetaData getParameterMetaData() throws SQLException {
         ensureNotClosed();
+        try {
+            if (conn.isClosed())
+                throw new SQLException("Connection is closed.");
 
-        throw new SQLFeatureNotSupportedException("Meta data for prepared statement is not supported.");
+            if (metaData != null)
+                return metaData;
+
+            JdbcMetaParamsResult res = conn.io().parametersMeta(conn.getSchema(), sql);
+
+            metaData = new JdbcThinParameterMetadata(res.meta());
+
+            return metaData;
+        }
+        catch (IOException e) {
+            conn.close();
+
+            throw new SQLException("Failed to query Ignite.", e);
+        }
+        catch (IgniteCheckedException e) {
+            throw new SQLException("Failed to query Ignite.", e);
+        }
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java
index 5c61e23..c4be5bc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java
@@ -100,6 +100,34 @@ public class JdbcThinResultSet implements ResultSet {
     /** Update count. */
     private long updCnt;
 
+    /** Jdbc metadata. Cache the JDBC object on the first access */
+    private JdbcThinResultSetMetadata jdbcMeta;
+
+    /**
+     * Constructs static result set.
+     *
+     * @param fields Fields.
+     * @param meta Columns metadata.
+     */
+    JdbcThinResultSet(List<List<Object>> fields, List<JdbcColumnMeta> meta) {
+        stmt = null;
+        fetchSize = 0;
+        qryId = -1L;
+        finished = true;
+        isQuery = true;
+        updCnt = -1;
+
+        this.rows = fields;
+
+        rowsIter = fields.iterator();
+
+        this.meta = meta;
+
+        metaInit = true;
+
+        initColumnOrder();
+    }
+
     /**
      * Creates new result set.
      *
@@ -180,7 +208,7 @@ public class JdbcThinResultSet implements ResultSet {
 
     /** {@inheritDoc} */
     @Override public void close() throws SQLException {
-        if (closed || stmt.connection().isClosed())
+        if (closed || stmt == null || stmt.connection().isClosed())
             return;
 
         try {
@@ -497,7 +525,10 @@ public class JdbcThinResultSet implements ResultSet {
     @Override public ResultSetMetaData getMetaData() throws SQLException {
         ensureNotClosed();
 
-        return new JdbcThinResultSetMetadata(meta());
+        if (jdbcMeta == null)
+            jdbcMeta = new JdbcThinResultSetMetadata(meta());
+
+        return jdbcMeta;
     }
 
     /** {@inheritDoc} */
@@ -1648,7 +1679,6 @@ public class JdbcThinResultSet implements ResultSet {
     }
 
     /**
-     * Init column order map.
      * @throws SQLException On error.
      * @return Column order map.
      */
@@ -1659,6 +1689,15 @@ public class JdbcThinResultSet implements ResultSet {
         if(!metaInit)
             meta();
 
+        initColumnOrder();
+
+        return colOrder;
+    }
+
+    /**
+     * Init column order map.
+     */
+    private void initColumnOrder() {
         colOrder = new HashMap<>(meta.size());
 
         for (int i = 0; i < meta.size(); ++i) {
@@ -1667,8 +1706,6 @@ public class JdbcThinResultSet implements ResultSet {
             if(!colOrder.containsKey(colName))
                 colOrder.put(colName, i);
         }
-
-        return colOrder;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
index b01350a..3772b83 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
@@ -46,8 +46,8 @@ public class JdbcThinStatement implements Statement {
     /** Default queryPage size. */
     private static final int DFLT_PAGE_SIZE = SqlQuery.DFLT_PAGE_SIZE;
 
-    /** Ignite endpoint and I/O protocol implementation. */
-    private JdbcThinConnection conn;
+    /** JDBC Connection implementation. */
+    protected JdbcThinConnection conn;
 
     /** Closed flag. */
     private boolean closed;

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
index f54d5fd..e124921 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
@@ -34,6 +34,18 @@ import org.apache.ignite.internal.processors.odbc.SqlListenerRequest;
 import org.apache.ignite.internal.processors.odbc.SqlListenerResponse;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteRequest;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaColumnsRequest;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaColumnsResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaIndexesRequest;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaIndexesResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaParamsRequest;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaParamsResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaPrimaryKeysRequest;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaPrimaryKeysResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaSchemasRequest;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaSchemasResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaTablesRequest;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaTablesResult;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryCloseRequest;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteRequest;
@@ -47,6 +59,7 @@ import org.apache.ignite.internal.processors.odbc.jdbc.JdbcResponse;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcResult;
 import org.apache.ignite.internal.util.ipc.loopback.IpcClientTcpEndpoint;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteProductVersion;
 
 /**
  * JDBC IO layer implementation based on blocking IPC streams.
@@ -59,7 +72,7 @@ public class JdbcThinTcpIo {
     private static final int HANDSHAKE_MSG_SIZE = 13;
 
     /** Initial output for query message. */
-    private static final int QUERY_EXEC_MSG_INIT_CAP = 256;
+    private static final int DYNAMIC_SIZE_MSG_CAP = 256;
 
     /** Maximum batch query count. */
     private static final int MAX_BATCH_QRY_CNT = 32;
@@ -115,6 +128,9 @@ public class JdbcThinTcpIo {
     /** Closed flag. */
     private boolean closed;
 
+    /** Ignite server version. */
+    private IgniteProductVersion igniteVer;
+
     /**
      * Constructor.
      *
@@ -202,8 +218,20 @@ public class JdbcThinTcpIo {
 
         boolean accepted = reader.readBoolean();
 
-        if (accepted)
+        if (accepted) {
+            byte maj = reader.readByte();
+            byte min = reader.readByte();
+            byte maintenance = reader.readByte();
+
+            String stage = reader.readString();
+
+            long ts = reader.readLong();
+            byte[] hash = reader.readByteArray();
+
+            igniteVer = new IgniteProductVersion(maj, min, maintenance, stage, ts, hash);
+
             return;
+        }
 
         short maj = reader.readShort();
         short min = reader.readShort();
@@ -231,7 +259,7 @@ public class JdbcThinTcpIo {
         String sql, List<Object> args)
         throws IOException, IgniteCheckedException {
         return sendRequest(new JdbcQueryExecuteRequest(cache, fetchSize, maxRows, sql,
-            args == null ? null : args.toArray(new Object[args.size()])), QUERY_EXEC_MSG_INIT_CAP);
+            args == null ? null : args.toArray(new Object[args.size()])), DYNAMIC_SIZE_MSG_CAP);
     }
 
     /**
@@ -295,21 +323,89 @@ public class JdbcThinTcpIo {
     }
 
     /**
-     * @param schema Schema.
+     * @param schemaName Schema.
      * @param batch Batch queries.
      * @return Result.
      * @throws IOException On error.
      * @throws IgniteCheckedException On error.
      */
-    public JdbcBatchExecuteResult batchExecute(String schema, List<JdbcQuery> batch)
+    public JdbcBatchExecuteResult batchExecute(String schemaName, List<JdbcQuery> batch)
         throws IOException, IgniteCheckedException {
         int cnt = Math.min(MAX_BATCH_QRY_CNT, batch.size());
 
-        return sendRequest(new JdbcBatchExecuteRequest(schema, batch), QUERY_EXEC_MSG_INIT_CAP * cnt);
+        return sendRequest(new JdbcBatchExecuteRequest(schemaName, batch), DYNAMIC_SIZE_MSG_CAP * cnt);
+    }
+
+    /**
+     * @param schemaPtrn Schema name pattern.
+     * @param tablePtrn Table name pattern.
+     * @return Result.
+     * @throws IOException On error.
+     * @throws IgniteCheckedException On error.
+     */
+    public JdbcMetaTablesResult tablesMeta(String schemaPtrn, String tablePtrn)
+        throws IOException, IgniteCheckedException {
+        return sendRequest(new JdbcMetaTablesRequest(schemaPtrn, tablePtrn), DYNAMIC_SIZE_MSG_CAP);
+    }
+
+    /**
+     * @param schemaPtrn Schema name pattern.
+     * @param tablePtrn Table name pattern.
+     * @param columnPtrn Column name pattern.
+     * @return Result.
+     * @throws IOException On error.
+     * @throws IgniteCheckedException On error.
+     */
+    public JdbcMetaColumnsResult columnsMeta(String schemaPtrn, String tablePtrn, String columnPtrn)
+        throws IOException, IgniteCheckedException {
+        return sendRequest(new JdbcMetaColumnsRequest(schemaPtrn, tablePtrn, columnPtrn), DYNAMIC_SIZE_MSG_CAP);
+    }
+
+    /**
+     * @param schemaPtrn Schema name pattern.
+     * @param tablePtrn Table name pattern.
+     * @return Result.
+     * @throws IOException On error.
+     * @throws IgniteCheckedException On error.
+     */
+    public JdbcMetaIndexesResult indexMeta(String schemaPtrn, String tablePtrn) throws IOException, IgniteCheckedException {
+        return sendRequest(new JdbcMetaIndexesRequest(schemaPtrn, tablePtrn), DYNAMIC_SIZE_MSG_CAP);
+    }
+
+    /**
+     * @param schemaPtrn Schema name pattern.
+     * @param sql SQL query.
+     * @return Result.
+     * @throws IOException On error.
+     * @throws IgniteCheckedException On error.
+     */
+    public JdbcMetaParamsResult parametersMeta(String schemaPtrn, String sql) throws IOException, IgniteCheckedException {
+        return sendRequest(new JdbcMetaParamsRequest(schemaPtrn, sql), DYNAMIC_SIZE_MSG_CAP);
     }
 
     /**
-     * @param req ODBC request.
+     * @param schemaPtrn Schema name pattern.
+     * @param tablePtrn Table name pattern.
+     * @return Result.
+     * @throws IOException On error.
+     * @throws IgniteCheckedException On error.
+     */
+    public JdbcMetaPrimaryKeysResult primaryKeysMeta(String schemaPtrn, String tablePtrn) throws IOException, IgniteCheckedException {
+        return sendRequest(new JdbcMetaPrimaryKeysRequest(schemaPtrn, tablePtrn), DYNAMIC_SIZE_MSG_CAP);
+    }
+
+    /**
+     * @param schemaPtrn Schema name pattern.
+     * @return Result.
+     * @throws IOException On error.
+     * @throws IgniteCheckedException On error.
+     */
+    public JdbcMetaSchemasResult schemasMeta(String schemaPtrn) throws IOException, IgniteCheckedException {
+        return sendRequest(new JdbcMetaSchemasRequest(schemaPtrn), DYNAMIC_SIZE_MSG_CAP);
+    }
+
+    /**
+     * @param req JDBC request bytes.
      * @throws IOException On error.
      */
     private void send(byte[] req) throws IOException {
@@ -434,4 +530,11 @@ public class JdbcThinTcpIo {
     public boolean tcpNoDelay() {
         return tcpNoDelay;
     }
+
+    /**
+     * @return Ignnite server version.
+     */
+    IgniteProductVersion igniteVersion() {
+        return igniteVer;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
index a879796..5a49e3f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerNioListener.java
@@ -198,9 +198,11 @@ public class SqlListenerNioListener extends GridNioServerListenerAdapter<byte[]>
 
         String errMsg = null;
 
+        SqlListenerConnectionContext connCtx = null;
+
         if (SUPPORTED_VERS.contains(ver)) {
             // Prepare context.
-            SqlListenerConnectionContext connCtx = prepareContext(ver, reader);
+            connCtx = prepareContext(ver, reader);
 
             ses.addMeta(CONN_CTX_META_KEY, connCtx);
         }
@@ -213,9 +215,10 @@ public class SqlListenerNioListener extends GridNioServerListenerAdapter<byte[]>
         // Send response.
         BinaryWriterExImpl writer = new BinaryWriterExImpl(null, new BinaryHeapOutputStream(8), null, null);
 
-        if (errMsg == null)
-            writer.writeBoolean(true);
+        if (connCtx != null)
+            connCtx.handler().writeHandshake(writer);
         else {
+            // Failed handshake response
             writer.writeBoolean(false);
             writer.writeShort(CURRENT_VER.major());
             writer.writeShort(CURRENT_VER.minor());

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerRequestHandler.java
index 98dc039..348054f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerRequestHandler.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.internal.processors.odbc;
 
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+
 /**
  * SQL listener request handler.
  */
@@ -36,4 +38,11 @@ public interface SqlListenerRequestHandler {
      * @return Error response.
      */
     public SqlListenerResponse handleException(Exception e);
+
+    /**
+     * Write successful handshake response.
+     *
+     * @param writer Binary writer.
+     */
+    public void writeHandshake(BinaryWriterExImpl writer);
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java
index 9f71bff..25e1049 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java
@@ -31,8 +31,8 @@ import org.jetbrains.annotations.Nullable;
  * JDBC batch execute request.
  */
 public class JdbcBatchExecuteRequest extends JdbcRequest {
-    /** Cache name. */
-    private String schema;
+    /** Schema name. */
+    private String schemaName;
 
     /** Sql query. */
     @GridToStringInclude(sensitive = true)
@@ -46,23 +46,23 @@ public class JdbcBatchExecuteRequest extends JdbcRequest {
     }
 
     /**
-     * @param schema Schema.
+     * @param schemaName Schema name.
      * @param queries Queries.
      */
-    public JdbcBatchExecuteRequest(String schema, List<JdbcQuery> queries) {
+    public JdbcBatchExecuteRequest(String schemaName, List<JdbcQuery> queries) {
         super(BATCH_EXEC);
 
         assert !F.isEmpty(queries);
 
-        this.schema = schema;
+        this.schemaName = schemaName;
         this.queries = queries;
     }
 
     /**
-     * @return Schema.
+     * @return Schema name.
      */
-    @Nullable public String schema() {
-        return schema;
+    @Nullable public String schemaName() {
+        return schemaName;
     }
 
     /**
@@ -76,7 +76,7 @@ public class JdbcBatchExecuteRequest extends JdbcRequest {
     @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
         super.writeBinary(writer);
 
-        writer.writeString(schema);
+        writer.writeString(schemaName);
         writer.writeInt(queries.size());
 
         for (JdbcQuery q : queries)
@@ -87,7 +87,7 @@ public class JdbcBatchExecuteRequest extends JdbcRequest {
     @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
         super.readBinary(reader);
 
-        schema = reader.readString();
+        schemaName = reader.readString();
 
         int n = reader.readInt();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java
index 7977c22..917e60a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.odbc.jdbc;
 import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.internal.binary.BinaryReaderExImpl;
 import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  * JDBC batch execute result.
@@ -93,4 +94,9 @@ public class JdbcBatchExecuteResult extends JdbcResult {
         errMsg = reader.readString();
         updateCnts = reader.readIntArray();
     }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcBatchExecuteResult.class, this);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
index 07cbabe..9f145e0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java
@@ -21,19 +21,21 @@ import org.apache.ignite.internal.binary.BinaryReaderExImpl;
 import org.apache.ignite.internal.binary.BinaryWriterExImpl;
 import org.apache.ignite.internal.jdbc.thin.JdbcThinUtils;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
- * SQL listener column metadata.
+ * JDBC column metadata.
  */
 public class JdbcColumnMeta implements JdbcRawBinarylizable {
     /** Cache name. */
     private String schemaName;
 
     /** Table name. */
-    private String tableName;
+    private String tblName;
 
     /** Column name. */
-    private String columnName;
+    private String colName;
 
     /** Data type. */
     private int dataType;
@@ -47,16 +49,17 @@ public class JdbcColumnMeta implements JdbcRawBinarylizable {
     /**
      * Default constructor is used for serialization.
      */
-    public JdbcColumnMeta() {
+    JdbcColumnMeta() {
+        // No-op.
     }
 
     /**
      * @param info Field metadata.
      */
-    public JdbcColumnMeta(GridQueryFieldMetadata info) {
+    JdbcColumnMeta(GridQueryFieldMetadata info) {
         this.schemaName = info.schemaName();
-        this.tableName = info.typeName();
-        this.columnName = info.fieldName();
+        this.tblName = info.typeName();
+        this.colName = info.fieldName();
 
         dataType = JdbcThinUtils.type(info.fieldTypeName());
         dataTypeName = JdbcThinUtils.typeName(info.fieldTypeName());
@@ -64,6 +67,24 @@ public class JdbcColumnMeta implements JdbcRawBinarylizable {
     }
 
     /**
+     * @param schemaName Schema.
+     * @param tblName Table.
+     * @param colName Column.
+     * @param cls Type.
+     */
+    public JdbcColumnMeta(String schemaName, String tblName, String colName, Class<?> cls) {
+        this.schemaName = schemaName;
+        this.tblName = tblName;
+        this.colName = colName;
+
+        String type = cls.getName();
+
+        dataType = JdbcThinUtils.type(type);
+        dataTypeName = JdbcThinUtils.typeName(type);
+        dataTypeClass = type;
+    }
+
+    /**
      * @return Schema name.
      */
     public String schemaName() {
@@ -74,14 +95,14 @@ public class JdbcColumnMeta implements JdbcRawBinarylizable {
      * @return Table name.
      */
     public String tableName() {
-        return tableName;
+        return tblName;
     }
 
     /**
      * @return Column name.
      */
     public String columnName() {
-        return columnName;
+        return colName;
     }
 
     /**
@@ -108,8 +129,8 @@ public class JdbcColumnMeta implements JdbcRawBinarylizable {
     /** {@inheritDoc} */
     @Override public void writeBinary(BinaryWriterExImpl writer) {
         writer.writeString(schemaName);
-        writer.writeString(tableName);
-        writer.writeString(columnName);
+        writer.writeString(tblName);
+        writer.writeString(colName);
 
         writer.writeInt(dataType);
         writer.writeString(dataTypeName);
@@ -119,11 +140,39 @@ public class JdbcColumnMeta implements JdbcRawBinarylizable {
     /** {@inheritDoc} */
     @Override public void readBinary(BinaryReaderExImpl reader) {
         schemaName = reader.readString();
-        tableName = reader.readString();
-        columnName = reader.readString();
+        tblName = reader.readString();
+        colName = reader.readString();
 
         dataType = reader.readInt();
         dataTypeName = reader.readString();
         dataTypeClass = reader.readString();
     }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        JdbcColumnMeta meta = (JdbcColumnMeta)o;
+
+        return F.eq(schemaName, meta.schemaName) && F.eq(tblName, meta.tblName) && F.eq(colName, meta.colName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int result = schemaName != null ? schemaName.hashCode() : 0;
+
+        result = 31 * result + (tblName != null ? tblName.hashCode() : 0);
+        result = 31 * result + colName.hashCode();
+
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcColumnMeta.class, this);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcIndexMeta.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcIndexMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcIndexMeta.java
new file mode 100644
index 0000000..d33f887
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcIndexMeta.java
@@ -0,0 +1,192 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC index metadata.
+ */
+public class JdbcIndexMeta implements JdbcRawBinarylizable {
+    /** Index schema name. */
+    private String schemaName;
+
+    /** Index table name. */
+    private String tblName;
+
+    /** Index name. */
+    private String idxName;
+
+    /** Index type. */
+    private QueryIndexType type;
+
+    /** Index fields */
+    private List<String> fields;
+
+    /** Index fields is ascending. */
+    private List<Boolean> fieldsAsc;
+
+    /**
+     * Default constructor is used for binary serialization.
+     */
+    JdbcIndexMeta() {
+        // No-op.
+    }
+
+    /**
+     * @param schemaName Schema name.
+     * @param tblName Table name.
+     * @param idx Index info.
+     */
+    JdbcIndexMeta(String schemaName, String tblName, GridQueryIndexDescriptor idx) {
+        assert tblName != null;
+        assert idx != null;
+        assert idx.fields() != null;
+
+        this.schemaName = schemaName;
+        this.tblName = tblName;
+
+        idxName = idx.name();
+        type = idx.type();
+        fields = new ArrayList(idx.fields());
+
+        fieldsAsc = new ArrayList<>(fields.size());
+
+        for (int i = 0; i < fields.size(); ++i)
+            fieldsAsc.add(!idx.descending(fields.get(i)));
+    }
+
+    /**
+     * @return Schema name.
+     */
+    public String schemaName() {
+        return schemaName;
+    }
+
+    /**
+     * @return Table name.
+     */
+    public String tableName() {
+        return tblName;
+    }
+
+    /**
+     * @return Index name.
+     */
+    public String indexName() {
+        return idxName;
+    }
+
+    /**
+     * @return Index type.
+     */
+    public QueryIndexType type() {
+        return type;
+    }
+
+    /**
+     * @return Index fields
+     */
+    public List<String> fields() {
+        return fields;
+    }
+
+    /**
+     * @return Index fields is ascending.
+     */
+    public List<Boolean> fieldsAsc() {
+        return fieldsAsc;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        writer.writeString(schemaName);
+        writer.writeString(tblName);
+        writer.writeString(idxName);
+        writer.writeByte((byte)type.ordinal());
+
+        JdbcUtils.writeStringCollection(writer, fields);
+
+        if (fieldsAsc == null)
+            writer.writeInt(0);
+        else {
+            writer.writeInt(fieldsAsc.size());
+
+            for (Boolean b : fieldsAsc)
+                writer.writeBoolean(b.booleanValue());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        schemaName = reader.readString();
+        tblName = reader.readString();
+        idxName = reader.readString();
+        type = QueryIndexType.fromOrdinal(reader.readByte());
+
+        fields = JdbcUtils.readStringList(reader);
+
+        int size = reader.readInt();
+
+        if (size > 0) {
+            fieldsAsc = new ArrayList<>(size);
+
+            for (int i = 0; i < size; ++i)
+                fieldsAsc .add(reader.readBoolean());
+        }
+        else
+            fieldsAsc = Collections.emptyList();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        JdbcIndexMeta meta = (JdbcIndexMeta)o;
+
+        return F.eq(schemaName, meta.schemaName) && F.eq(tblName, meta.tblName) && F.eq(idxName, meta.idxName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int result = schemaName != null ? schemaName.hashCode() : 0;
+
+        result = 31 * result + tblName.hashCode();
+        result = 31 * result + idxName.hashCode();
+
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcIndexMeta.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsRequest.java
new file mode 100644
index 0000000..fca1bf7
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsRequest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * JDBC get columns metadata request.
+ */
+public class JdbcMetaColumnsRequest extends JdbcRequest {
+    /** Schema name pattern. */
+    private String schemaName;
+
+    /** Table name pattern. */
+    private String tblName;
+
+    /** Column name pattern. */
+    private String colName;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaColumnsRequest() {
+        super(META_COLUMNS);
+    }
+
+    /**
+     * @param schemaName Schema name.
+     * @param tblName Table name.
+     * @param colName Column name.
+     */
+    public JdbcMetaColumnsRequest(String schemaName, String tblName, String colName) {
+        super(META_COLUMNS);
+
+        this.schemaName = schemaName;
+        this.tblName = tblName;
+        this.colName = colName;
+    }
+
+    /**
+     * @return Schema name pattern.
+     */
+    @Nullable public String schemaName() {
+        return schemaName;
+    }
+
+    /**
+     * @return Table name pattern.
+     */
+    public String tableName() {
+        return tblName;
+    }
+
+    /**
+     * @return Column name pattern.
+     */
+    public String columnName() {
+        return colName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        writer.writeString(schemaName);
+        writer.writeString(tblName);
+        writer.writeString(colName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        schemaName = reader.readString();
+        tblName = reader.readString();
+        colName = reader.readString();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaColumnsRequest.class, this);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResult.java
new file mode 100644
index 0000000..da270de
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaColumnsResult.java
@@ -0,0 +1,99 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC columns metadata result.
+ */
+public class JdbcMetaColumnsResult extends JdbcResult {
+    /** Columns metadata. */
+    private List<JdbcColumnMeta> meta;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaColumnsResult() {
+        super(META_COLUMNS);
+    }
+
+    /**
+     * @param meta Columns metadata.
+     */
+    JdbcMetaColumnsResult(Collection<JdbcColumnMeta> meta) {
+        super(META_COLUMNS);
+
+        this.meta = new ArrayList<>(meta);
+    }
+
+    /**
+     * @return Columns metadata.
+     */
+    public List<JdbcColumnMeta> meta() {
+        return meta;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        if (F.isEmpty(meta))
+            writer.writeInt(0);
+        else {
+            writer.writeInt(meta.size());
+
+            for(JdbcColumnMeta m : meta)
+                m.writeBinary(writer);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        int size = reader.readInt();
+
+        if (size == 0)
+            meta = Collections.emptyList();
+        else {
+            meta = new ArrayList<>(size);
+
+            for (int i = 0; i < size; ++i) {
+                JdbcColumnMeta m = new JdbcColumnMeta();
+
+                m.readBinary(reader);
+
+                meta.add(m);
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaColumnsResult.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaIndexesRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaIndexesRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaIndexesRequest.java
new file mode 100644
index 0000000..d4a53d8
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaIndexesRequest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * JDBC indexes metadata request.
+ */
+public class JdbcMetaIndexesRequest extends JdbcRequest {
+    /** Schema name pattern. */
+    private String schemaName;
+
+    /** Table name pattern. */
+    private String tblName;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaIndexesRequest() {
+        super(META_INDEXES);
+    }
+
+    /**
+     * @param schemaName Cache name.
+     * @param tblName Table name.
+     */
+    public JdbcMetaIndexesRequest(String schemaName, String tblName) {
+        super(META_INDEXES);
+
+        this.schemaName = schemaName;
+        this.tblName = tblName;
+    }
+
+    /**
+     * @return Schema name.
+     */
+    @Nullable public String schemaName() {
+        return schemaName;
+    }
+
+    /**
+     * @return Table name.
+     */
+    public String tableName() {
+        return tblName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        writer.writeString(schemaName);
+        writer.writeString(tblName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        schemaName = reader.readString();
+        tblName = reader.readString();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaIndexesRequest.class, this);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaIndexesResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaIndexesResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaIndexesResult.java
new file mode 100644
index 0000000..2316dfc
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaIndexesResult.java
@@ -0,0 +1,98 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC indexes metadata result.
+ */
+public class JdbcMetaIndexesResult extends JdbcResult {
+    /** Indexes metadata. */
+    private List<JdbcIndexMeta> meta;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaIndexesResult() {
+        super(META_INDEXES);
+    }
+
+    /**
+     * @param meta Indexes metadata.
+     */
+    JdbcMetaIndexesResult(Collection<JdbcIndexMeta> meta) {
+        super(META_INDEXES);
+        this.meta = new ArrayList<>(meta);
+    }
+
+    /**
+     * @return Indexes metadata.
+     */
+    public List<JdbcIndexMeta> meta() {
+        return meta;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        if (F.isEmpty(meta))
+            writer.writeInt(0);
+        else {
+            writer.writeInt(meta.size());
+
+            for(JdbcIndexMeta m : meta)
+                m.writeBinary(writer);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        int size = reader.readInt();
+
+        if (size == 0)
+            meta = Collections.emptyList();
+        else {
+            meta = new ArrayList<>(size);
+
+            for (int i = 0; i < size; ++i) {
+                JdbcIndexMeta m = new JdbcIndexMeta();
+
+                m.readBinary(reader);
+
+                meta.add(m);
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaIndexesResult.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaParamsRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaParamsRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaParamsRequest.java
new file mode 100644
index 0000000..6b955f9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaParamsRequest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC SQL query parameters metadata request.
+ */
+public class JdbcMetaParamsRequest extends JdbcRequest {
+    /** Schema name. */
+    private String schemaName;
+
+    /** Query. */
+    private String sql;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaParamsRequest() {
+        super(META_PARAMS);
+    }
+
+    /**
+     * @param schemaName Schema name.
+     * @param sql SQL Query.
+     */
+    public JdbcMetaParamsRequest(String schemaName, String sql) {
+        super(META_PARAMS);
+
+        this.schemaName = schemaName;
+        this.sql = sql;
+    }
+
+    /**
+     * @return Schema name.
+     */
+    public String schemaName() {
+        return schemaName;
+    }
+
+    /**
+     * @return SQL Query.
+     */
+    public String sql() {
+        return sql;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        writer.writeString(schemaName);
+        writer.writeString(sql);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        schemaName = reader.readString();
+        sql = reader.readString();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaParamsRequest.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaParamsResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaParamsResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaParamsResult.java
new file mode 100644
index 0000000..7563e01
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaParamsResult.java
@@ -0,0 +1,97 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC SQL query parameters metadata result.
+ */
+public class JdbcMetaParamsResult extends JdbcResult {
+    /** Parameters meta results. */
+    private List<JdbcParameterMeta> meta;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaParamsResult() {
+        super(META_PARAMS);
+    }
+
+    /**
+     * @param meta Column metadata.
+     */
+    JdbcMetaParamsResult(List<JdbcParameterMeta> meta) {
+        super(META_PARAMS);
+        this.meta = meta;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        if (F.isEmpty(meta))
+            writer.writeInt(0);
+        else {
+            writer.writeInt(meta.size());
+
+            for(JdbcParameterMeta m : meta)
+                m.writeBinary(writer);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        int size = reader.readInt();
+
+        if (size == 0)
+            meta = Collections.emptyList();
+        else {
+            meta = new ArrayList<>(size);
+
+            for (int i = 0; i < size; ++i) {
+                JdbcParameterMeta m = new JdbcParameterMeta();
+
+                m.readBinary(reader);
+
+                meta.add(m);
+            }
+        }
+    }
+
+    /**
+     * @return SQL query parameters metadata.
+     */
+    public List<JdbcParameterMeta> meta() {
+        return meta;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaParamsResult.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaPrimaryKeysRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaPrimaryKeysRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaPrimaryKeysRequest.java
new file mode 100644
index 0000000..957225a
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaPrimaryKeysRequest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * JDBC get primary keys metadata request.
+ */
+public class JdbcMetaPrimaryKeysRequest extends JdbcRequest {
+    /** Schema name pattern. */
+    private String schemaName;
+
+    /** Table name pattern. */
+    private String tblName;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaPrimaryKeysRequest() {
+        super(META_PRIMARY_KEYS);
+    }
+
+    /**
+     * @param schemaName Cache name.
+     * @param tblName Table name.
+     */
+    public JdbcMetaPrimaryKeysRequest(String schemaName, String tblName) {
+        super(META_PRIMARY_KEYS);
+
+        this.schemaName = schemaName;
+        this.tblName = tblName;
+    }
+
+    /**
+     * @return Schema name pattern.
+     */
+    @Nullable public String schemaName() {
+        return schemaName;
+    }
+
+    /**
+     * @return Table name pattern.
+     */
+    public String tableName() {
+        return tblName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        writer.writeString(schemaName);
+        writer.writeString(tblName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        schemaName = reader.readString();
+        tblName = reader.readString();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaPrimaryKeysRequest.class, this);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaPrimaryKeysResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaPrimaryKeysResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaPrimaryKeysResult.java
new file mode 100644
index 0000000..bd0dd90
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaPrimaryKeysResult.java
@@ -0,0 +1,99 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC primary keys metadata result.
+ */
+public class JdbcMetaPrimaryKeysResult extends JdbcResult {
+    /** Query result rows. */
+    private List<JdbcPrimaryKeyMeta> meta;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaPrimaryKeysResult() {
+        super(META_PRIMARY_KEYS);
+    }
+
+    /**
+     * @param meta Column metadata.
+     */
+    JdbcMetaPrimaryKeysResult(Collection<JdbcPrimaryKeyMeta> meta) {
+        super(META_PRIMARY_KEYS);
+
+        this.meta = new ArrayList<>(meta);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        if (F.isEmpty(meta))
+            writer.writeInt(0);
+        else {
+            writer.writeInt(meta.size());
+
+            for(JdbcPrimaryKeyMeta m : meta)
+                m.writeBinary(writer);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        int size = reader.readInt();
+
+        if (size == 0)
+            meta = Collections.emptyList();
+        else {
+            meta = new ArrayList<>(size);
+
+            for (int i = 0; i < size; ++i) {
+                JdbcPrimaryKeyMeta m = new JdbcPrimaryKeyMeta();
+
+                m.readBinary(reader);
+
+                meta.add(m);
+            }
+        }
+    }
+
+    /**
+     * @return Primary keys metadata.
+     */
+    public List<JdbcPrimaryKeyMeta> meta() {
+        return meta;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaPrimaryKeysResult.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaSchemasRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaSchemasRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaSchemasRequest.java
new file mode 100644
index 0000000..43bbe5d
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaSchemasRequest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC tables metadata request.
+ */
+public class JdbcMetaSchemasRequest extends JdbcRequest {
+    /** Schema search pattern. */
+    private String schemaName;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaSchemasRequest() {
+        super(META_SCHEMAS);
+    }
+
+    /**
+     * @param schemaName Schema search pattern.
+     */
+    public JdbcMetaSchemasRequest(String schemaName) {
+        super(META_SCHEMAS);
+
+        this.schemaName = schemaName;
+    }
+
+    /**
+     * @return Schema search pattern.
+     */
+    public String schemaName() {
+        return schemaName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        writer.writeString(schemaName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        this.schemaName = reader.readString();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaSchemasRequest.class, this);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaSchemasResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaSchemasResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaSchemasResult.java
new file mode 100644
index 0000000..48b6aae
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaSchemasResult.java
@@ -0,0 +1,73 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import java.util.Collection;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC tables metadata result.
+ */
+public class JdbcMetaSchemasResult extends JdbcResult {
+    /** Found schemas. */
+    private Collection<String> schemas;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaSchemasResult() {
+        super(META_SCHEMAS);
+    }
+
+    /**
+     * @param schemas Found schemas.
+     */
+    JdbcMetaSchemasResult(Collection<String> schemas) {
+        super(META_SCHEMAS);
+        this.schemas = schemas;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        JdbcUtils.writeStringCollection(writer, schemas);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        schemas = JdbcUtils.readStringList(reader);
+    }
+
+    /**
+     * @return Found schemas.
+     */
+    public Collection<String> schemas() {
+        return schemas;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaSchemasResult.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaTablesRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaTablesRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaTablesRequest.java
new file mode 100644
index 0000000..740b656
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaTablesRequest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC tables metadata request.
+ */
+public class JdbcMetaTablesRequest extends JdbcRequest {
+    /** Schema search pattern. */
+    private String schemaName;
+
+    /** Table search pattern. */
+    private String tblName;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaTablesRequest() {
+        super(META_TABLES);
+    }
+
+    /**
+     * @param schemaName Schema search pattern.
+     * @param tblName Table search pattern.
+     */
+    public JdbcMetaTablesRequest(String schemaName, String tblName) {
+        super(META_TABLES);
+
+        this.schemaName = schemaName;
+        this.tblName = tblName;
+    }
+
+    /**
+     * @return Schema search pattern.
+     */
+    public String schemaName() {
+        return schemaName;
+    }
+
+    /**
+     * @return Table search pattern.
+     */
+    public String tableName() {
+        return tblName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        writer.writeString(schemaName);
+        writer.writeString(tblName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        this.schemaName = reader.readString();
+        this.tblName = reader.readString();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaTablesRequest.class, this);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaTablesResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaTablesResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaTablesResult.java
new file mode 100644
index 0000000..585667e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMetaTablesResult.java
@@ -0,0 +1,97 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC tables metadata result.
+ */
+public class JdbcMetaTablesResult extends JdbcResult {
+    /** Tables metadata. */
+    private List<JdbcTableMeta> meta;
+
+    /**
+     * Default constructor is used for deserialization.
+     */
+    JdbcMetaTablesResult() {
+        super(META_TABLES);
+    }
+
+    /**
+     * @param meta Tables metadata.
+     */
+    JdbcMetaTablesResult(List<JdbcTableMeta> meta) {
+        super(META_TABLES);
+        this.meta = meta;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        if (F.isEmpty(meta))
+            writer.writeInt(0);
+        else {
+            writer.writeInt(meta.size());
+
+            for(JdbcTableMeta m : meta)
+                m.writeBinary(writer);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        int size = reader.readInt();
+
+        if (size == 0)
+            meta = Collections.emptyList();
+        else {
+            meta = new ArrayList<>(size);
+
+            for (int i = 0; i < size; ++i) {
+                JdbcTableMeta m = new JdbcTableMeta();
+
+                m.readBinary(reader);
+
+                meta.add(m);
+            }
+        }
+    }
+
+    /**
+     * @return Tables metadata.
+     */
+    public List<JdbcTableMeta> meta() {
+        return meta;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcMetaTablesResult.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcParameterMeta.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcParameterMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcParameterMeta.java
new file mode 100644
index 0000000..dd3b18b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcParameterMeta.java
@@ -0,0 +1,165 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import java.sql.ParameterMetaData;
+import java.sql.SQLException;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC SQL query parameter metadata.
+ *
+ * {@see java.sql.ParameterMetaData}.
+ */
+public class JdbcParameterMeta implements JdbcRawBinarylizable {
+    /** Null value is allow for the param. */
+    private int isNullable;
+
+    /** Signed flag. */
+    private boolean signed;
+
+    /** Precision. */
+    private int precision;
+
+    /** Scale. */
+    private int scale;
+
+    /** SQL type ID. */
+    private int type;
+
+    /** SQL type name. */
+    private String typeName;
+
+    /** Java type class name. */
+    private String typeClass;
+
+    /** Mode. */
+    private int mode;
+
+
+    /**
+     * Default constructor is used for binary serialization.
+     */
+    public JdbcParameterMeta() {
+        // No-op.
+    }
+
+    /**
+     * @param meta Param metadata.
+     * @param order Param order.
+     * @throws SQLException On errror.
+     */
+    public JdbcParameterMeta(ParameterMetaData meta, int order) throws SQLException {
+        isNullable = meta.isNullable(order);
+        signed = meta.isSigned(order);
+        precision = meta.getPrecision(order);
+        scale = meta.getScale(order);
+        type = meta.getParameterType(order);
+        typeName = meta.getParameterTypeName(order);
+        typeClass = meta.getParameterClassName(order);
+        mode = meta.getParameterMode(order);
+    }
+
+    /**
+     * @return Nullable mode.
+     */
+    public int isNullable() {
+        return isNullable;
+    }
+
+    /**
+     * @return Signed flag.
+     */
+    public boolean isSigned() {
+        return signed;
+    }
+
+    /**
+     * @return Precision.
+     */
+    public int precision() {
+        return precision;
+    }
+
+    /**
+     * @return Scale.
+     */
+    public int scale() {
+        return scale;
+    }
+
+    /**
+     * @return SQL type.
+     */
+    public int type() {
+        return type;
+    }
+
+    /**
+     * @return SQL type name.
+     */
+    public String typeName() {
+        return typeName;
+    }
+
+    /**
+     * @return Java type class name.
+     */
+    public String typeClass() {
+        return typeClass;
+    }
+
+    /**
+     * @return Mode.
+     */
+    public int mode() {
+        return mode;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        writer.writeInt(isNullable);
+        writer.writeBoolean(signed);
+        writer.writeInt(precision);
+        writer.writeInt(scale);
+        writer.writeInt(type);
+        writer.writeString(typeName);
+        writer.writeString(typeClass);
+        writer.writeInt(mode);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        isNullable = reader.readInt();
+        signed = reader.readBoolean();
+        precision = reader.readInt();
+        scale = reader.readInt();
+        type = reader.readInt();
+        typeName = reader.readString();
+        typeClass = reader.readString();
+        mode = reader.readInt();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcParameterMeta.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcPrimaryKeyMeta.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcPrimaryKeyMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcPrimaryKeyMeta.java
new file mode 100644
index 0000000..6b9bf70
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcPrimaryKeyMeta.java
@@ -0,0 +1,131 @@
+/*
+ * 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.processors.odbc.jdbc;
+
+import java.util.List;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ * JDBC primary key metadata.
+ */
+public class JdbcPrimaryKeyMeta implements JdbcRawBinarylizable {
+    /** Schema name. */
+    private String schemaName;
+
+    /** Table name. */
+    private String tblName;
+
+    /** Primary key name. */
+    private String name;
+
+    /** Primary key fields. */
+    private List<String> fields;
+
+    /**
+     * Default constructor is used for binary serialization.
+     */
+    JdbcPrimaryKeyMeta() {
+        // No-op.
+    }
+
+    /**
+     * @param schemaName Schema.
+     * @param tblName Table.
+     * @param name Name.
+     * @param fields Primary key fields.
+     */
+    JdbcPrimaryKeyMeta(String schemaName, String tblName, String name, List<String> fields) {
+        this.schemaName = schemaName;
+        this.tblName = tblName;
+        this.name = name;
+        this.fields = fields;
+    }
+
+    /**
+     * @return Schema name.
+     */
+    public String schemaName() {
+        return schemaName;
+    }
+
+    /**
+     * @return Table name.
+     */
+    public String tableName() {
+        return tblName;
+    }
+
+    /**
+     * @return Primary key name.
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * @return Key fields.
+     */
+    public List<String> fields() {
+        return fields;
+    }
+
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        writer.writeString(schemaName);
+        writer.writeString(tblName);
+        writer.writeString(name);
+
+        JdbcUtils.writeStringCollection(writer, fields);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        schemaName = reader.readString();
+        tblName = reader.readString();
+        name = reader.readString();
+
+        fields = JdbcUtils.readStringList(reader);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        JdbcPrimaryKeyMeta meta = (JdbcPrimaryKeyMeta)o;
+
+        return F.eq(schemaName, meta.schemaName) && F.eq(tblName, meta.tblName) && F.eq(name, meta.name);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int result = schemaName != null ? schemaName.hashCode() : 0;
+
+        result = 31 * result + tblName.hashCode();
+        result = 31 * result + name.hashCode();
+
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCloseRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCloseRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCloseRequest.java
index 411d1e0..872889c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCloseRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCloseRequest.java
@@ -23,7 +23,7 @@ import org.apache.ignite.internal.binary.BinaryWriterExImpl;
 import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
- * SQL listener query close request.
+ * JDBC query close request.
  */
 public class JdbcQueryCloseRequest extends JdbcRequest {
     /** Query ID. */
@@ -31,7 +31,7 @@ public class JdbcQueryCloseRequest extends JdbcRequest {
 
     /**
      */
-    public JdbcQueryCloseRequest() {
+    JdbcQueryCloseRequest() {
         super(QRY_CLOSE);
     }