ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject ignite git commit: IGNITE-3910: ODBC: Implemented SQLDescribeParam. This closes #1269.
Date Wed, 23 Nov 2016 15:11:41 GMT
Repository: ignite
Updated Branches:
  refs/heads/ignite-1.8 83363d8e0 -> 4d2432510


IGNITE-3910: ODBC: Implemented SQLDescribeParam. This closes #1269.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4d243251
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4d243251
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4d243251

Branch: refs/heads/ignite-1.8
Commit: 4d243251006bc8d1de85d7b6a481976899755a82
Parents: 83363d8
Author: isapego <igorsapg@gmail.com>
Authored: Wed Nov 23 18:11:35 2016 +0300
Committer: devozerov <vozerov@gridgain.com>
Committed: Wed Nov 23 18:11:35 2016 +0300

----------------------------------------------------------------------
 .../processors/odbc/OdbcMessageParser.java      |  16 ++
 .../odbc/OdbcQueryGetParamsMetaRequest.java     |  60 ++++++
 .../odbc/OdbcQueryGetParamsMetaResult.java      |  40 ++++
 .../internal/processors/odbc/OdbcRequest.java   |   3 +
 .../processors/odbc/OdbcRequestHandler.java     | 128 +++++++++++--
 .../query-example/src/query_example.cpp         |   8 +-
 .../platforms/cpp/odbc/include/ignite/odbc.h    |  14 +-
 .../cpp/odbc/include/ignite/odbc/common_types.h |   2 +
 .../cpp/odbc/include/ignite/odbc/message.h      | 129 ++++++++++++-
 .../odbc/include/ignite/odbc/query/data_query.h |  12 +-
 .../cpp/odbc/include/ignite/odbc/query/query.h  |  44 ++++-
 .../cpp/odbc/include/ignite/odbc/statement.h    |  35 ++++
 .../cpp/odbc/include/ignite/odbc/type_traits.h  |   2 +-
 .../cpp/odbc/include/ignite/odbc/utility.h      |  11 +-
 .../platforms/cpp/odbc/src/app/parameter.cpp    |   3 +-
 modules/platforms/cpp/odbc/src/entry_points.cpp |  32 ++--
 modules/platforms/cpp/odbc/src/odbc.cpp         |  21 +++
 .../odbc/src/query/column_metadata_query.cpp    |   2 +-
 .../platforms/cpp/odbc/src/query/data_query.cpp |   2 +-
 .../cpp/odbc/src/query/foreign_keys_query.cpp   |   2 +-
 .../cpp/odbc/src/query/primary_keys_query.cpp   |   2 +-
 .../odbc/src/query/special_columns_query.cpp    |   2 +-
 .../cpp/odbc/src/query/table_metadata_query.cpp |   2 +-
 .../cpp/odbc/src/query/type_info_query.cpp      |   2 +-
 modules/platforms/cpp/odbc/src/statement.cpp    | 187 +++++++++++++++++--
 modules/platforms/cpp/odbc/src/utility.cpp      |  14 ++
 26 files changed, 697 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
index 19aace8..7b863d6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
@@ -154,6 +154,15 @@ public class OdbcMessageParser {
                 break;
             }
 
+            case OdbcRequest.GET_PARAMS_META: {
+                String cacheName = reader.readString();
+                String sqlQuery = reader.readString();
+
+                res = new OdbcQueryGetParamsMetaRequest(cacheName, sqlQuery);
+
+                break;
+            }
+
             default:
                 throw new IgniteException("Unknown ODBC command: [cmd=" + cmd + ']');
         }
@@ -287,6 +296,13 @@ public class OdbcMessageParser {
             for (OdbcTableMeta tableMeta : tablesMeta)
                 tableMeta.writeBinary(writer);
         }
+        else if (res0 instanceof OdbcQueryGetParamsMetaResult) {
+            OdbcQueryGetParamsMetaResult res = (OdbcQueryGetParamsMetaResult) res0;
+
+            byte[] typeIds = res.typeIds();
+
+            writer.writeObjectDetached(typeIds);
+        }
         else
             assert false : "Should not reach here.";
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcQueryGetParamsMetaRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcQueryGetParamsMetaRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcQueryGetParamsMetaRequest.java
new file mode 100644
index 0000000..c372c0b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcQueryGetParamsMetaRequest.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * ODBC query get params meta request.
+ */
+public class OdbcQueryGetParamsMetaRequest extends OdbcRequest {
+    /** Cache. */
+    private final String cacheName;
+
+    /** Query. */
+    private final String query;
+
+    /**
+     * @param query SQL Query.
+     */
+    public OdbcQueryGetParamsMetaRequest(String cacheName, String query) {
+        super(GET_PARAMS_META);
+
+        this.cacheName = cacheName;
+        this.query = query;
+    }
+
+    /**
+     * @return SQL Query.
+     */
+    public String query() {
+        return query;
+    }
+
+    /**
+     * @return Cache name.
+     */
+    public String cacheName() {
+        return cacheName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(OdbcQueryGetParamsMetaRequest.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcQueryGetParamsMetaResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcQueryGetParamsMetaResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcQueryGetParamsMetaResult.java
new file mode 100644
index 0000000..616c82d
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcQueryGetParamsMetaResult.java
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+/**
+ * ODBC query get params meta result.
+ */
+public class OdbcQueryGetParamsMetaResult {
+    /** List of parameter type IDs. */
+    private final byte[] typeIds;
+
+    /**
+     * @param typeIds List of parameter type IDs.
+     */
+    public OdbcQueryGetParamsMetaResult(byte[] typeIds) {
+        this.typeIds = typeIds;
+    }
+
+    /**
+     * @return List of parameter type IDs.
+     */
+    public byte[] typeIds() {
+        return typeIds;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequest.java
index ebecb60..f056fed 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequest.java
@@ -39,6 +39,9 @@ public class OdbcRequest {
     /** Get columns meta query. */
     public static final int GET_TABLES_META = 6;
 
+    /** Get parameters meta. */
+    public static final int GET_PARAMS_META = 7;
+
     /** Command. */
     private final int cmd;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
index cf2615d..588fc66 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
@@ -18,10 +18,12 @@
 package org.apache.ignite.internal.processors.odbc;
 
 import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cache.query.QueryCursor;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.binary.GridBinaryMarshaller;
 import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
 import org.apache.ignite.internal.processors.odbc.escape.OdbcEscapeUtils;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
@@ -32,6 +34,9 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteProductVersion;
 
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Types;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
@@ -114,6 +119,9 @@ public class OdbcRequestHandler {
 
                 case GET_TABLES_META:
                     return getTablesMeta(reqId, (OdbcQueryGetTablesMetaRequest)req);
+
+                case GET_PARAMS_META:
+                    return getParamsMeta(reqId, (OdbcQueryGetParamsMetaRequest)req);
             }
 
             return new OdbcResponse(OdbcResponse.STATUS_FAILED, "Unsupported ODBC request: " + req);
@@ -131,26 +139,33 @@ public class OdbcRequestHandler {
      * @return Response.
      */
     private OdbcResponse performHandshake(long reqId, OdbcHandshakeRequest req) {
-        OdbcProtocolVersion version = req.version();
+        try {
+            OdbcProtocolVersion version = req.version();
 
-        if (version.isUnknown()) {
-            IgniteProductVersion ver = ctx.grid().version();
+            if (version.isUnknown()) {
+                IgniteProductVersion ver = ctx.grid().version();
 
-            String verStr = Byte.toString(ver.major()) + '.' + ver.minor() + '.' + ver.maintenance();
+                String verStr = Byte.toString(ver.major()) + '.' + ver.minor() + '.' + ver.maintenance();
 
-            OdbcHandshakeResult res = new OdbcHandshakeResult(false, OdbcProtocolVersion.current().since(), verStr);
+                OdbcHandshakeResult res = new OdbcHandshakeResult(false, OdbcProtocolVersion.current().since(), verStr);
 
-            return new OdbcResponse(res);
-        }
+                return new OdbcResponse(res);
+            }
+
+            OdbcHandshakeResult res = new OdbcHandshakeResult(true, null, null);
 
-        OdbcHandshakeResult res = new OdbcHandshakeResult(true, null, null);
+            if (version.isDistributedJoinsSupported()) {
+                distributedJoins = req.distributedJoins();
+                enforceJoinOrder = req.enforceJoinOrder();
+            }
 
-        if (version.isDistributedJoinsSupported()) {
-            distributedJoins = req.distributedJoins();
-            enforceJoinOrder = req.enforceJoinOrder();
+            return new OdbcResponse(res);
         }
+        catch (Exception e) {
+            U.error(log, "Failed to perform handshake [reqId=" + reqId + ", req=" + req + ']', e);
 
-        return new OdbcResponse(res);
+            return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage());
+        }
     }
 
     /**
@@ -387,6 +402,95 @@ public class OdbcRequestHandler {
     }
 
     /**
+     * {@link OdbcQueryGetParamsMetaRequest} command handler.
+     *
+     * @param reqId Request ID.
+     * @param req Get params metadata request.
+     * @return Response.
+     */
+    private OdbcResponse getParamsMeta(long reqId, OdbcQueryGetParamsMetaRequest req) {
+        try {
+            PreparedStatement stmt = ctx.query().prepareNativeStatement(req.cacheName(), req.query());
+
+            ParameterMetaData pmd = stmt.getParameterMetaData();
+
+            byte[] typeIds = new byte[pmd.getParameterCount()];
+
+            for (int i = 1; i <= pmd.getParameterCount(); ++i) {
+                int sqlType = pmd.getParameterType(i);
+
+                typeIds[i - 1] = sqlTypeToBinary(sqlType);
+            }
+
+            OdbcQueryGetParamsMetaResult res = new OdbcQueryGetParamsMetaResult(typeIds);
+
+            return new OdbcResponse(res);
+        }
+        catch (Exception e) {
+            U.error(log, "Failed to get params metadata [reqId=" + reqId + ", req=" + req + ']', e);
+
+            return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage());
+        }
+    }
+
+    /**
+     * Convert {@link java.sql.Types} to binary type constant (See {@link GridBinaryMarshaller} constants).
+     *
+     * @param sqlType SQL type.
+     * @return Binary type.
+     */
+    private static byte sqlTypeToBinary(int sqlType) {
+        switch (sqlType) {
+            case Types.BIGINT:
+                return GridBinaryMarshaller.LONG;
+
+            case Types.BOOLEAN:
+                return GridBinaryMarshaller.BOOLEAN;
+
+            case Types.DATE:
+                return GridBinaryMarshaller.DATE;
+
+            case Types.DOUBLE:
+                return GridBinaryMarshaller.DOUBLE;
+
+            case Types.FLOAT:
+            case Types.REAL:
+                return GridBinaryMarshaller.FLOAT;
+
+            case Types.NUMERIC:
+            case Types.DECIMAL:
+                return GridBinaryMarshaller.DECIMAL;
+
+            case Types.INTEGER:
+                return GridBinaryMarshaller.INT;
+
+            case Types.SMALLINT:
+                return GridBinaryMarshaller.SHORT;
+
+            case Types.TIME:
+            case Types.TIMESTAMP:
+                return GridBinaryMarshaller.TIMESTAMP;
+
+            case Types.TINYINT:
+                return GridBinaryMarshaller.BYTE;
+
+            case Types.CHAR:
+            case Types.VARCHAR:
+            case Types.LONGNVARCHAR:
+                return GridBinaryMarshaller.STRING;
+
+            case Types.NULL:
+                return GridBinaryMarshaller.NULL;
+
+            case Types.BINARY:
+            case Types.VARBINARY:
+            case Types.LONGVARBINARY:
+            default:
+                return GridBinaryMarshaller.BYTE_ARR;
+        }
+    }
+
+    /**
      * Convert metadata in collection from {@link GridQueryFieldMetadata} to
      * {@link OdbcColumnMeta}.
      *

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/examples/query-example/src/query_example.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/examples/query-example/src/query_example.cpp b/modules/platforms/cpp/examples/query-example/src/query_example.cpp
index 9bf3e52..8b8d008 100644
--- a/modules/platforms/cpp/examples/query-example/src/query_example.cpp
+++ b/modules/platforms/cpp/examples/query-example/src/query_example.cpp
@@ -416,6 +416,12 @@ int main()
         // Populate cache.
         Initialize();
 
+        std::cout << std::endl;
+        std::cout << ">>> Ready" << std::endl;
+        std::cout << std::endl;
+
+        std::cin.get();
+
         // Example for SCAN-based query based on a predicate.
         DoScanQuery();
 
@@ -456,4 +462,4 @@ int main()
     std::cin.get();
 
     return 0;
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/include/ignite/odbc.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc.h b/modules/platforms/cpp/odbc/include/ignite/odbc.h
index 345cdb8..639a02a 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc.h
@@ -34,11 +34,6 @@
 
 namespace ignite
 {
-    BOOL ConfigDSN(HWND     hwndParent,
-                   WORD     req,
-                   LPCSTR   driver,
-                   LPCSTR   attributes);
-
     SQLRETURN SQLGetInfo(SQLHDBC        conn,
                          SQLUSMALLINT   infoType,
                          SQLPOINTER     infoValue,
@@ -265,6 +260,13 @@ namespace ignite
                        SQLSMALLINT  msgBufLen,
                        SQLSMALLINT* msgResLen);
 
+    SQLRETURN SQLDescribeParam(SQLHSTMT     stmt,
+                               SQLUSMALLINT paramNum,
+                               SQLSMALLINT* dataType,
+                               SQLULEN*     paramSize,
+                               SQLSMALLINT* decimalDigits,
+                               SQLSMALLINT* nullable);
+
 } // namespace ignite
 
-#endif //_IGNITE_ODBC
\ No newline at end of file
+#endif //_IGNITE_ODBC

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h b/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
index 354cf08..a61be53 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
@@ -23,6 +23,8 @@
 
 #include <ignite/odbc/system/odbc_constants.h>
 
+#include <ignite/odbc/system/odbc_constants.h>
+
 namespace ignite
 {
     namespace odbc

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
index 03fa627..5c6a933 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
@@ -46,7 +46,9 @@ namespace ignite
 
             REQUEST_TYPE_GET_COLUMNS_METADATA = 5,
 
-            REQUEST_TYPE_GET_TABLES_METADATA = 6
+            REQUEST_TYPE_GET_TABLES_METADATA = 6,
+
+            REQUEST_TYPE_GET_PARAMS_METADATA = 7
         };
 
         enum ResponseStatus
@@ -125,7 +127,9 @@ namespace ignite
              */
             QueryExecuteRequest(const std::string& cache, const std::string& sql,
                 const app::ParameterBindingMap& params) :
-                cache(cache), sql(sql), params(params)
+                cache(cache),
+                sql(sql),
+                params(params)
             {
                 // No-op.
             }
@@ -151,9 +155,20 @@ namespace ignite
                 writer.WriteInt32(static_cast<int32_t>(params.size()));
 
                 app::ParameterBindingMap::const_iterator i;
+                uint16_t prev = 0;
+
+                for (i = params.begin(); i != params.end(); ++i) {
+                    uint16_t current = i->first;
+
+                    while ((current - prev) > 1) {
+                        writer.WriteNull();
+                        ++prev;
+                    }
 
-                for (i = params.begin(); i != params.end(); ++i)
                     i->second.Write(writer);
+
+                    prev = current;
+                }
             }
 
         private:
@@ -220,7 +235,8 @@ namespace ignite
              * @param pageSize Required page size.
              */
             QueryFetchRequest(int64_t queryId, int32_t pageSize) :
-                queryId(queryId), pageSize(pageSize)
+                queryId(queryId),
+                pageSize(pageSize)
             {
                 // No-op.
             }
@@ -266,7 +282,9 @@ namespace ignite
              * @param column Column name.
              */
             QueryGetColumnsMetaRequest(const std::string& schema, const std::string& table, const std::string& column) :
-                schema(schema), table(table), column(column)
+                schema(schema),
+                table(table),
+                column(column)
             {
                 // No-op.
             }
@@ -319,7 +337,10 @@ namespace ignite
              */
             QueryGetTablesMetaRequest(const std::string& catalog, const std::string& schema,
                                       const std::string& table, const std::string& tableTypes) :
-                catalog(catalog), schema(schema), table(table), tableTypes(tableTypes)
+                catalog(catalog),
+                schema(schema),
+                table(table),
+                tableTypes(tableTypes)
             {
                 // No-op.
             }
@@ -361,6 +382,55 @@ namespace ignite
         };
 
         /**
+         * Get parameter metadata request.
+         */
+        class QueryGetParamsMetaRequest
+        {
+        public:
+            /**
+             * Constructor.
+             *
+             * @param catalog Catalog search pattern.
+             * @param schema Schema search pattern.
+             * @param table Table search pattern.
+             * @param tableTypes Table types search pattern.
+             */
+            QueryGetParamsMetaRequest(const std::string& cacheName, const std::string& sqlQuery) :
+                cacheName(cacheName),
+                sqlQuery(sqlQuery)
+            {
+                // No-op.
+            }
+
+            /**
+             * Destructor.
+             */
+            ~QueryGetParamsMetaRequest()
+            {
+                // No-op.
+            }
+
+            /**
+             * Write request using provided writer.
+             * @param writer Writer.
+             */
+            void Write(ignite::impl::binary::BinaryWriterImpl& writer) const
+            {
+                writer.WriteInt8(REQUEST_TYPE_GET_PARAMS_METADATA);
+
+                utility::WriteString(writer, cacheName);
+                utility::WriteString(writer, sqlQuery);
+            }
+
+        private:
+            /** Cache name. */
+            std::string cacheName;
+
+            /** SQL query. */
+            std::string sqlQuery;
+        };
+
+        /**
          * Query close response.
          */
         class Response
@@ -760,7 +830,52 @@ namespace ignite
             /** Columns metadata. */
             meta::TableMetaVector meta;
         };
+
+        /**
+         * Get params metadata response.
+         */
+        class QueryGetParamsMetaResponse : public Response
+        {
+        public:
+            /**
+             * Constructor.
+             */
+            QueryGetParamsMetaResponse()
+            {
+                // No-op.
+            }
+
+            /**
+             * Destructor.
+             */
+            ~QueryGetParamsMetaResponse()
+            {
+                // No-op.
+            }
+
+            /**
+             * Get parameter type IDs.
+             * @return Type IDs.
+             */
+            const std::vector<int8_t>& GetTypeIds() const
+            {
+                return typeIds;
+            }
+
+        private:
+            /**
+             * Read response using provided reader.
+             * @param reader Reader.
+             */
+            virtual void ReadOnSuccess(ignite::impl::binary::BinaryReaderImpl& reader)
+            {
+                utility::ReadByteArray(reader, typeIds);
+            }
+
+            /** Columns metadata. */
+            std::vector<int8_t> typeIds;
+        };
     }
 }
 
-#endif //_IGNITE_ODBC_MESSAGE
\ No newline at end of file
+#endif //_IGNITE_ODBC_MESSAGE

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h
index 3db3b46..68bb877 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h
@@ -105,6 +105,16 @@ namespace ignite
                  */
                 virtual int64_t AffectedRows() const;
 
+                /**
+                 * Get SQL query string.
+                 *
+                 * @return SQL query string.
+                 */
+                const std::string& GetSql() const
+                {
+                    return sql;
+                }
+
             private:
                 IGNITE_NO_COPY_ASSIGNMENT(DataQuery);
 
@@ -149,4 +159,4 @@ namespace ignite
     }
 }
 
-#endif //_IGNITE_ODBC_QUERY_DATA_QUERY
\ No newline at end of file
+#endif //_IGNITE_ODBC_QUERY_DATA_QUERY

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/include/ignite/odbc/query/query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/query.h
index 1b3512d..40be1ed 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/query.h
@@ -39,6 +39,30 @@ namespace ignite
             class Query
             {
             public:
+                /** Query type. */
+                enum Type {
+                    /** Column metadata query type. */
+                    COLUMN_METADATA,
+
+                    /** Data query type. */
+                    DATA,
+
+                    /** Foreign keys query type. */
+                    FOREIGN_KEYS,
+
+                    /** Primary keys query type. */
+                    PRIMARY_KEYS,
+
+                    /** Special columns query type. */
+                    SPECIAL_COLUMNS,
+
+                    /** Table metadata query type. */
+                    TABLE_METADATA,
+
+                    /** Type info query type. */
+                    TYPE_INFO
+                };
+
                 /**
                  * Destructor.
                  */
@@ -99,21 +123,35 @@ namespace ignite
                  */
                 virtual int64_t AffectedRows() const = 0;
 
+                /**
+                 * Get query type.
+                 *
+                 * @return Query type.
+                 */
+                Type GetType() const
+                {
+                    return type;
+                }
+
             protected:
                 /**
                  * Constructor.
                  */
-                Query(diagnostic::Diagnosable& diag) :
-                    diag(diag)
+                Query(diagnostic::Diagnosable& diag, Type type) :
+                    diag(diag),
+                    type(type)
                 {
                     // No-op.
                 }
 
                 /** Diagnostics collector. */
                 diagnostic::Diagnosable& diag;
+
+                /** Query type. */
+                Type type;
             };
         }
     }
 }
 
-#endif //_IGNITE_ODBC_QUERY_QUERY
\ No newline at end of file
+#endif //_IGNITE_ODBC_QUERY_QUERY

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h b/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
index 981ade1..8adcc60 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
@@ -347,6 +347,18 @@ namespace ignite
              */
             void PutData(void* data, SqlLen len);
 
+            /**
+             * Get type info of the parameter of the prepared statement.
+             *
+             * @param paramNum - Parameter index.
+             * @param dataType - Data type.
+             * @param paramSize - Size of the parameter.
+             * @param decimalDigits - Decimal digits.
+             * @param nullable - Nullability flag.
+             */
+            void DescribeParam(int16_t paramNum, int16_t* dataType,
+                size_t* paramSize, int16_t* decimalDigits, int16_t* nullable);
+
         private:
             IGNITE_NO_COPY_ASSIGNMENT(Statement);
 
@@ -547,6 +559,7 @@ namespace ignite
              * Select next parameter data for which is required.
              *
              * @param paramPtr Pointer to param id stored here.
+             * @return Operation result.
              */
             SqlResult InternalSelectParam(void** paramPtr);
 
@@ -555,10 +568,29 @@ namespace ignite
              *
              * @param data Data.
              * @param len Data length.
+             * @return Operation result.
              */
             SqlResult InternalPutData(void* data, SqlLen len);
 
             /**
+             * Get type info of the parameter of the prepared statement.
+             *
+             * @param paramNum - Parameter index.
+             * @param dataType - Data type.
+             * @param paramSize - Size of the parameter.
+             * @param decimalDigits - Decimal digits.
+             * @param nullable - Nullability flag.
+             * @return Operation result.
+             */
+            SqlResult InternalDescribeParam(int16_t paramNum, int16_t* dataType,
+                size_t* paramSize, int16_t* decimalDigits, int16_t* nullable);
+
+            /**
+             * Make request to data source to update parameters metadata.
+             */
+            SqlResult UpdateParamsMeta();
+
+            /**
              * Constructor.
              * Called by friend classes.
              *
@@ -575,6 +607,9 @@ namespace ignite
             /** Parameter bindings. */
             app::ParameterBindingMap paramBindings;
 
+            /** Parameter meta. */
+            std::vector<int8_t> paramTypes;
+
             /** Underlying query. */
             std::auto_ptr<query::Query> currentQuery;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/include/ignite/odbc/type_traits.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/type_traits.h b/modules/platforms/cpp/odbc/include/ignite/odbc/type_traits.h
index a85cfeb..a57abdd 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/type_traits.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/type_traits.h
@@ -313,4 +313,4 @@ namespace ignite
     }
 }
 
-#endif //_IGNITE_ODBC_TYPE_TRAITS
\ No newline at end of file
+#endif //_IGNITE_ODBC_TYPE_TRAITS

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h b/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h
index 34627c1..37daa50 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h
@@ -43,7 +43,7 @@ void logInit(const char*);
 #   define LOG_MSG(fmt, ...)                                        \
     do {                                                            \
         logInit(ODBC_LOG_PATH);                                     \
-        fprintf(log_file, "%s: " fmt, __FUNCTION__, __VA_ARGS__);   \
+        fprintf(log_file, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__);   \
         fflush(log_file);                                           \
     } while (false)
 
@@ -137,6 +137,13 @@ namespace ignite
         size_t CopyStringToBuffer(const std::string& str, char* buf, size_t buflen);
 
         /**
+         * Read array from reader.
+         * @param reader Reader.
+         * @param res Resulting vector.
+         */
+        void ReadByteArray(impl::binary::BinaryReaderImpl& reader, std::vector<int8_t>& res);
+
+        /**
          * Read string from reader.
          * @param reader Reader.
          * @param str String.
@@ -177,4 +184,4 @@ namespace ignite
     }
 }
 
-#endif //_IGNITE_ODBC_UTILITY
\ No newline at end of file
+#endif //_IGNITE_ODBC_UTILITY

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/app/parameter.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/app/parameter.cpp b/modules/platforms/cpp/odbc/src/app/parameter.cpp
index d70ef6a..937ef58 100644
--- a/modules/platforms/cpp/odbc/src/app/parameter.cpp
+++ b/modules/platforms/cpp/odbc/src/app/parameter.cpp
@@ -52,7 +52,7 @@ namespace ignite
                 // No-op.
             }
 
-            Parameter::Parameter(const Parameter & other) :
+            Parameter::Parameter(const Parameter& other) :
                 buffer(other.buffer),
                 sqlType(other.sqlType),
                 columnSize(other.columnSize),
@@ -266,4 +266,3 @@ namespace ignite
         }
     }
 }
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/entry_points.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/entry_points.cpp b/modules/platforms/cpp/odbc/src/entry_points.cpp
index a85b3cf..850fa10 100644
--- a/modules/platforms/cpp/odbc/src/entry_points.cpp
+++ b/modules/platforms/cpp/odbc/src/entry_points.cpp
@@ -394,13 +394,11 @@ SQLRETURN SQL_API SQLSpecialColumns(SQLHSTMT    stmt,
                                     SQLUSMALLINT scope,
                                     SQLUSMALLINT nullable)
 {
-    return ignite::SQLSpecialColumns(stmt, idType, catalogName,
-        catalogNameLen, schemaName, schemaNameLen, tableName,
-        tableNameLen, scope, nullable);
+    return ignite::SQLSpecialColumns(stmt, idType, catalogName, catalogNameLen, schemaName,
+        schemaNameLen, tableName, tableNameLen, scope, nullable);
 }
 
-SQLRETURN SQL_API SQLParamData(SQLHSTMT    stmt,
-                               SQLPOINTER* value)
+SQLRETURN SQL_API SQLParamData(SQLHSTMT stmt, SQLPOINTER* value)
 {
     return ignite::SQLParamData(stmt, value);
 }
@@ -412,6 +410,17 @@ SQLRETURN SQL_API SQLPutData(SQLHSTMT     stmt,
     return ignite::SQLPutData(stmt, data, strLengthOrIndicator);
 }
 
+SQLRETURN SQL_API SQLDescribeParam(SQLHSTMT     stmt,
+                                   SQLUSMALLINT paramNum,
+                                   SQLSMALLINT* dataType,
+                                   SQLULEN*     paramSize,
+                                   SQLSMALLINT* decimalDigits,
+                                   SQLSMALLINT* nullable)
+{
+    return ignite::SQLDescribeParam(stmt, paramNum, dataType,
+     paramSize, decimalDigits, nullable);
+}
+
 SQLRETURN SQL_API SQLError(SQLHENV      env,
                            SQLHDBC      conn,
                            SQLHSTMT     stmt,
@@ -663,19 +672,6 @@ SQLRETURN SQL_API SQLColumnPrivileges(SQLHSTMT      stmt,
     return SQL_SUCCESS;
 }
 
-/*
-SQLRETURN SQL_API SQLDescribeParam(SQLHSTMT     stmt,
-                                   SQLUSMALLINT paramNum,
-                                   SQLSMALLINT* dataType,
-                                   SQLULEN*     paramSize,
-                                   SQLSMALLINT* decimalDigits,
-                                   SQLSMALLINT* nullable)
-{
-    LOG_MSG("SQLDescribeParam called\n");
-    return SQL_SUCCESS;
-}
-*/
-
 SQLRETURN SQL_API SQLParamOptions(SQLHSTMT  stmt,
                                   SQLULEN   paramSetSize,
                                   SQLULEN*  paramsProcessed)

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/odbc.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/odbc.cpp b/modules/platforms/cpp/odbc/src/odbc.cpp
index 8ecc0f8..0b18a11 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -1257,6 +1257,27 @@ namespace ignite
         return statement->GetDiagnosticRecords().GetReturnCode();
     }
 
+    SQLRETURN SQLDescribeParam(SQLHSTMT     stmt,
+                               SQLUSMALLINT paramNum,
+                               SQLSMALLINT* dataType,
+                               SQLULEN*     paramSize,
+                               SQLSMALLINT* decimalDigits,
+                               SQLSMALLINT* nullable)
+    {
+        using namespace ignite::odbc;
+
+        LOG_MSG("SQLDescribeParam called\n");
+
+        Statement *statement = reinterpret_cast<Statement*>(stmt);
+
+        if (!statement)
+            return SQL_INVALID_HANDLE;
+
+        statement->DescribeParam(paramNum, dataType, paramSize, decimalDigits, nullable);
+
+        return statement->GetDiagnosticRecords().GetReturnCode();
+    }
+
     SQLRETURN SQLError(SQLHENV      env,
                        SQLHDBC      conn,
                        SQLHSTMT     stmt,

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
index 5e764a2..1cd2a9f 100644
--- a/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
@@ -73,7 +73,7 @@ namespace ignite
             ColumnMetadataQuery::ColumnMetadataQuery(diagnostic::Diagnosable& diag, 
                 Connection& connection, const std::string& schema,
                 const std::string& table, const std::string& column) :
-                Query(diag),
+                Query(diag, COLUMN_METADATA),
                 connection(connection),
                 schema(schema),
                 table(table),

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/query/data_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/data_query.cpp b/modules/platforms/cpp/odbc/src/query/data_query.cpp
index 8f76153..5b1b758 100644
--- a/modules/platforms/cpp/odbc/src/query/data_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/data_query.cpp
@@ -28,7 +28,7 @@ namespace ignite
             DataQuery::DataQuery(diagnostic::Diagnosable& diag,
                 Connection& connection, const std::string& sql,
                 const app::ParameterBindingMap& params) :
-                Query(diag),
+                Query(diag, DATA),
                 connection(connection),
                 sql(sql),
                 params(params)

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/query/foreign_keys_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/foreign_keys_query.cpp b/modules/platforms/cpp/odbc/src/query/foreign_keys_query.cpp
index 4fefa22..5813767 100644
--- a/modules/platforms/cpp/odbc/src/query/foreign_keys_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/foreign_keys_query.cpp
@@ -32,7 +32,7 @@ namespace ignite
                 const std::string& primaryCatalog, const std::string& primarySchema,
                 const std::string& primaryTable, const std::string& foreignCatalog,
                 const std::string& foreignSchema, const std::string& foreignTable) :
-                Query(diag),
+                Query(diag, FOREIGN_KEYS),
                 connection(connection),
                 primaryCatalog(primaryCatalog),
                 primarySchema(primarySchema),

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/query/primary_keys_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/primary_keys_query.cpp b/modules/platforms/cpp/odbc/src/query/primary_keys_query.cpp
index 11ff4fa..a24670d 100644
--- a/modules/platforms/cpp/odbc/src/query/primary_keys_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/primary_keys_query.cpp
@@ -55,7 +55,7 @@ namespace ignite
             PrimaryKeysQuery::PrimaryKeysQuery(diagnostic::Diagnosable& diag,
                 Connection& connection, const std::string& catalog,
                 const std::string& schema, const std::string& table) :
-                Query(diag),
+                Query(diag, PRIMARY_KEYS),
                 connection(connection),
                 catalog(catalog),
                 schema(schema),

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/query/special_columns_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/special_columns_query.cpp b/modules/platforms/cpp/odbc/src/query/special_columns_query.cpp
index ad8aea6..f507c52 100644
--- a/modules/platforms/cpp/odbc/src/query/special_columns_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/special_columns_query.cpp
@@ -29,7 +29,7 @@ namespace ignite
             SpecialColumnsQuery::SpecialColumnsQuery(diagnostic::Diagnosable& diag,
                 int16_t type, const std::string& catalog, const std::string& schema,
                 const std::string& table, int16_t scope, int16_t nullable) :
-                Query(diag),
+                Query(diag, SPECIAL_COLUMNS),
                 type(type),
                 catalog(catalog),
                 schema(schema),

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
index 53aebe4..3cddd1b 100644
--- a/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
@@ -52,7 +52,7 @@ namespace ignite
             TableMetadataQuery::TableMetadataQuery(diagnostic::Diagnosable& diag,
                 Connection& connection, const std::string& catalog,const std::string& schema,
                 const std::string& table, const std::string& tableType) :
-                Query(diag),
+                Query(diag, TABLE_METADATA),
                 connection(connection),
                 catalog(catalog),
                 schema(schema),

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
index 96bed3a..2de2a7c 100644
--- a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
@@ -116,7 +116,7 @@ namespace ignite
         namespace query
         {
             TypeInfoQuery::TypeInfoQuery(diagnostic::Diagnosable& diag, int16_t sqlType) :
-                Query(diag),
+                Query(diag, TYPE_INFO),
                 columnsMeta(),
                 executed(false),
                 types(),

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/statement.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/statement.cpp b/modules/platforms/cpp/odbc/src/statement.cpp
index 49a9acf..a0b38d7 100644
--- a/modules/platforms/cpp/odbc/src/statement.cpp
+++ b/modules/platforms/cpp/odbc/src/statement.cpp
@@ -320,11 +320,13 @@ namespace ignite
             IGNITE_ODBC_API_CALL(InternalGetColumnData(columnIdx, buffer));
         }
 
-        SqlResult Statement::InternalGetColumnData(uint16_t columnIdx, app::ApplicationDataBuffer& buffer)
+        SqlResult Statement::InternalGetColumnData(uint16_t columnIdx,
+            app::ApplicationDataBuffer& buffer)
         {
             if (!currentQuery.get())
             {
-                AddStatusRecord(SQL_STATE_24000_INVALID_CURSOR_STATE, "Cursor is not in the open state.");
+                AddStatusRecord(SQL_STATE_24000_INVALID_CURSOR_STATE,
+                    "Cursor is not in the open state.");
 
                 return SQL_RESULT_ERROR;
             }
@@ -346,6 +348,9 @@ namespace ignite
 
             currentQuery.reset(new query::DataQuery(*this, connection, query, paramBindings));
 
+            // Resetting parameters types as we are changing the query.
+            paramTypes.clear();
+
             return SQL_RESULT_SUCCESS;
         }
 
@@ -413,7 +418,8 @@ namespace ignite
             if (cache.empty())
                 cache = connection.GetCache();
 
-            currentQuery.reset(new query::ColumnMetadataQuery(*this, connection, cache, table, column));
+            currentQuery.reset(new query::ColumnMetadataQuery(*this,
+                connection, cache, table, column));
 
             return currentQuery->Execute();
         }
@@ -421,7 +427,8 @@ namespace ignite
         void Statement::ExecuteGetTablesMetaQuery(const std::string& catalog,
             const std::string& schema, const std::string& table, const std::string& tableType)
         {
-            IGNITE_ODBC_API_CALL(InternalExecuteGetTablesMetaQuery(catalog, schema, table, tableType));
+            IGNITE_ODBC_API_CALL(InternalExecuteGetTablesMetaQuery(
+                catalog, schema, table, tableType));
         }
 
         SqlResult Statement::InternalExecuteGetTablesMetaQuery(const std::string& catalog,
@@ -430,7 +437,8 @@ namespace ignite
             if (currentQuery.get())
                 currentQuery->Close();
 
-            currentQuery.reset(new query::TableMetadataQuery(*this, connection, catalog, schema, table, tableType));
+            currentQuery.reset(new query::TableMetadataQuery(*this,
+                connection, catalog, schema, table, tableType));
 
             return currentQuery->Execute();
         }
@@ -452,25 +460,26 @@ namespace ignite
             if (currentQuery.get())
                 currentQuery->Close();
 
-            currentQuery.reset(new query::ForeignKeysQuery(*this, connection, primaryCatalog, primarySchema,
-                primaryTable, foreignCatalog, foreignSchema, foreignTable));
+            currentQuery.reset(new query::ForeignKeysQuery(*this, connection, primaryCatalog,
+                primarySchema, primaryTable, foreignCatalog, foreignSchema, foreignTable));
 
             return currentQuery->Execute();
         }
 
-        void Statement::ExecuteGetPrimaryKeysQuery(const std::string& catalog, const std::string& schema,
-            const std::string& table)
+        void Statement::ExecuteGetPrimaryKeysQuery(const std::string& catalog,
+            const std::string& schema, const std::string& table)
         {
             IGNITE_ODBC_API_CALL(InternalExecuteGetPrimaryKeysQuery(catalog, schema, table));
         }
 
-        SqlResult Statement::InternalExecuteGetPrimaryKeysQuery(const std::string& catalog, const std::string& schema,
-            const std::string& table)
+        SqlResult Statement::InternalExecuteGetPrimaryKeysQuery(const std::string& catalog,
+            const std::string& schema, const std::string& table)
         {
             if (currentQuery.get())
                 currentQuery->Close();
 
-            currentQuery.reset(new query::PrimaryKeysQuery(*this, connection, catalog, schema, table));
+            currentQuery.reset(new query::PrimaryKeysQuery(*this,
+                connection, catalog, schema, table));
 
             return currentQuery->Execute();
         }
@@ -513,7 +522,8 @@ namespace ignite
         {
             if (!type_traits::IsSqlTypeSupported(sqlType))
             {
-                AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED, "Data type is not supported.");
+                AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+                    "Data type is not supported.");
 
                 return SQL_RESULT_ERROR;
             }
@@ -535,7 +545,7 @@ namespace ignite
         {
             if (!currentQuery.get())
                 return SQL_RESULT_SUCCESS;
-
+            
             SqlResult result = currentQuery->Close();
 
             if (result == SQL_RESULT_SUCCESS)
@@ -556,7 +566,8 @@ namespace ignite
 
             if (!currentQuery.get())
             {
-                AddStatusRecord(SQL_STATE_24000_INVALID_CURSOR_STATE, "Cursor is not in the open state.");
+                AddStatusRecord(SQL_STATE_24000_INVALID_CURSOR_STATE,
+                    "Cursor is not in the open state.");
 
                 return SQL_RESULT_ERROR;
             }
@@ -625,7 +636,8 @@ namespace ignite
 
             if (colIdx > meta->size() + 1 || colIdx < 1)
             {
-                AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, "Column index is out of range.", 0, colIdx);
+                AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR,
+                    "Column index is out of range.", 0, colIdx);
 
                 return SQL_RESULT_ERROR;
             }
@@ -654,7 +666,8 @@ namespace ignite
 
             if (!found)
             {
-                AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED, "Unknown attribute.");
+                AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+                    "Unknown attribute.");
 
                 return SQL_RESULT_ERROR;
             }
@@ -714,7 +727,8 @@ namespace ignite
         {
             if (!paramPtr)
             {
-                AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, "Invalid parameter: ValuePtrPtr is null.");
+                AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR,
+                    "Invalid parameter: ValuePtrPtr is null.");
 
                 return SQL_RESULT_ERROR;
             }
@@ -805,6 +819,143 @@ namespace ignite
 
             return SQL_RESULT_SUCCESS;
         }
+
+        void Statement::DescribeParam(int16_t paramNum, int16_t* dataType,
+            size_t* paramSize, int16_t* decimalDigits, int16_t* nullable)
+        {
+            IGNITE_ODBC_API_CALL(InternalDescribeParam(paramNum,
+                dataType, paramSize, decimalDigits, nullable));
+        }
+
+        SqlResult Statement::InternalDescribeParam(int16_t paramNum, int16_t* dataType,
+            size_t* paramSize, int16_t* decimalDigits, int16_t* nullable)
+        {
+            query::Query *qry = currentQuery.get();
+            if (!qry)
+            {
+                AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query is not prepared.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            if (qry->GetType() != query::Query::DATA)
+            {
+                AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query is not SQL data query.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            int8_t type = 0;
+
+            if (paramNum > 0 && static_cast<size_t>(paramNum) <= paramTypes.size())
+                type = paramTypes[paramNum - 1];
+
+            LOG_MSG("Type: %d\n", type);
+
+            if (!type)
+            {
+                SqlResult res = UpdateParamsMeta();
+
+                if (res != SQL_RESULT_SUCCESS)
+                    return res;
+
+                if (paramNum < 1 || static_cast<size_t>(paramNum) > paramTypes.size())
+                    type = impl::binary::IGNITE_HDR_NULL;
+                else
+                    type = paramTypes[paramNum - 1];
+            }
+
+            if (dataType)
+                *dataType = type_traits::BinaryToSqlType(type);
+
+            if (paramSize)
+                *paramSize = type_traits::BinaryTypeColumnSize(type);
+
+            if (decimalDigits)
+                *decimalDigits = type_traits::BinaryTypeDecimalDigits(type);
+
+            if (nullable)
+                *nullable = type_traits::BinaryTypeNullability(type);
+
+            return SQL_RESULT_SUCCESS;
+        }
+
+        SqlResult Statement::UpdateParamsMeta()
+        {
+            query::Query *qry0 = currentQuery.get();
+
+            assert(qry0 != 0);
+            assert(qry0->GetType() == query::Query::DATA);
+
+            query::DataQuery* qry = static_cast<query::DataQuery*>(qry0);
+
+            const std::string& cacheName = connection.GetCache();
+            const std::string& sql = qry->GetSql();
+
+            QueryGetParamsMetaRequest req(cacheName, sql);
+            QueryGetParamsMetaResponse rsp;
+
+            try
+            {
+                connection.SyncMessage(req, rsp);
+            }
+            catch (const IgniteError& err)
+            {
+                AddStatusRecord(SQL_STATE_HYT01_CONNECTIOIN_TIMEOUT, err.GetText());
+
+                return SQL_RESULT_ERROR;
+            }
+
+            if (rsp.GetStatus() != RESPONSE_STATUS_SUCCESS)
+            {
+                LOG_MSG("Error: %s\n", rsp.GetError().c_str());
+
+                AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, rsp.GetError());
+
+                return SQL_RESULT_ERROR;
+            }
+
+            paramTypes = rsp.GetTypeIds();
+
+            for (size_t i = 0; i < paramTypes.size(); ++i)
+                LOG_MSG("[%zu] Parameter type: %u\n", i, paramTypes[i]);
+
+            return SQL_RESULT_SUCCESS;
+        }
     }
 }
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/4d243251/modules/platforms/cpp/odbc/src/utility.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/utility.cpp b/modules/platforms/cpp/odbc/src/utility.cpp
index d4a48af..9763144 100644
--- a/modules/platforms/cpp/odbc/src/utility.cpp
+++ b/modules/platforms/cpp/odbc/src/utility.cpp
@@ -136,6 +136,20 @@ namespace ignite
 
             return res;
         }
+
+        void ReadByteArray(impl::binary::BinaryReaderImpl& reader, std::vector<int8_t>& res)
+        {
+            int32_t len = reader.ReadInt8Array(0, 0);
+
+            if (len > 0)
+            {
+                res.resize(len);
+
+                reader.ReadInt8Array(&res[0], static_cast<int32_t>(res.size()));
+            }
+            else
+                res.clear();
+        }
     }
 }
 


Mime
View raw message