You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by yz...@apache.org on 2016/12/28 14:05:02 UTC

[36/50] [abbrv] ignite git commit: IGNITE-4471: Fixed ODBC string-reading utility function

IGNITE-4471: Fixed ODBC string-reading utility function

 This closes #1377


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

Branch: refs/heads/ignite-comm-balance-master
Commit: 8cffe90010e1f0dbb0b93c33fe6a08bd27fa9477
Parents: dbc8a0f
Author: Igor Sapego <is...@gridgain.com>
Authored: Fri Dec 23 13:51:39 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Dec 23 13:51:39 2016 +0300

----------------------------------------------------------------------
 .../processors/odbc/OdbcRequestHandler.java     |   2 +-
 .../internal/processors/odbc/OdbcTableMeta.java |  15 +-
 .../cpp/odbc-test/config/queries-default.xml    | 145 +++++++++++++++++++
 .../odbc-test/config/queries-test-noodbc.xml    |  84 +----------
 .../cpp/odbc-test/config/queries-test.xml       | 122 +---------------
 .../cpp/odbc-test/src/queries_test.cpp          |  76 ++++++++++
 .../cpp/odbc-test/src/utility_test.cpp          |  27 +++-
 modules/platforms/cpp/odbc/src/utility.cpp      |  10 ++
 8 files changed, 271 insertions(+), 210 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8cffe900/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 2e0fd10..f922d9a 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
@@ -388,7 +388,7 @@ public class OdbcRequestHandler {
                     if (!matches("TABLE", req.tableType()))
                         continue;
 
-                    OdbcTableMeta tableMeta = new OdbcTableMeta(req.catalog(), cacheName, table.name(), "TABLE");
+                    OdbcTableMeta tableMeta = new OdbcTableMeta(null, cacheName, table.name(), "TABLE");
 
                     if (!meta.contains(tableMeta))
                         meta.add(tableMeta);

http://git-wip-us.apache.org/repos/asf/ignite/blob/8cffe900/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcTableMeta.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcTableMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcTableMeta.java
index fb7df50..ca630dd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcTableMeta.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcTableMeta.java
@@ -19,6 +19,8 @@ package org.apache.ignite.internal.processors.odbc;
 
 import org.apache.ignite.internal.binary.BinaryRawWriterEx;
 
+import java.util.Objects;
+
 /**
  * ODBC table-related metadata.
  */
@@ -50,11 +52,11 @@ public class OdbcTableMeta {
 
     /** {@inheritDoc} */
     @Override public int hashCode() {
-        int hash = catalog.hashCode();
+        int hash = Objects.hashCode(catalog);
 
-        hash = 31 * hash + schema.hashCode();
-        hash = 31 * hash + table.hashCode();
-        hash = 31 * hash + tableType.hashCode();
+        hash = 31 * hash + Objects.hashCode(schema);
+        hash = 31 * hash + Objects.hashCode(table);
+        hash = 31 * hash + Objects.hashCode(tableType);
 
         return hash;
     }
@@ -64,8 +66,9 @@ public class OdbcTableMeta {
         if (o instanceof OdbcTableMeta) {
             OdbcTableMeta other = (OdbcTableMeta) o;
 
-            return this == other || catalog.equals(other.catalog) && schema.equals(other.schema) &&
-                table.equals(other.table) && tableType.equals(other.tableType);
+            return this == other ||
+                    Objects.equals(catalog, other.catalog) && Objects.equals(schema, other.schema) &&
+                    Objects.equals(table, other.table) && Objects.equals(tableType, other.tableType);
         }
 
         return false;

http://git-wip-us.apache.org/repos/asf/ignite/blob/8cffe900/modules/platforms/cpp/odbc-test/config/queries-default.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-default.xml b/modules/platforms/cpp/odbc-test/config/queries-default.xml
new file mode 100644
index 0000000..6614e93
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/config/queries-default.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="
+        http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://www.springframework.org/schema/util
+        http://www.springframework.org/schema/util/spring-util.xsd">
+
+    <bean abstract="true" id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+        <property name="localHost" value="127.0.0.1"/>
+        <property name="connectorConfiguration"><null/></property>
+        <!--<property name="odbcConfiguration"><null/></property>-->
+
+        <property name="cacheConfiguration">
+            <list>
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="cache"/>
+                    <property name="cacheMode" value="PARTITIONED"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="writeSynchronizationMode" value="FULL_SYNC"/>
+
+                    <!-- Configure type metadata to enable queries. -->
+                    <property name="queryEntities">
+                        <list>
+                            <bean class="org.apache.ignite.cache.QueryEntity">
+                                <property name="keyType" value="java.lang.Long"/>
+                                <property name="valueType" value="TestType"/>
+
+                                <property name="fields">
+                                    <map>
+                                        <entry key="i8Field" value="java.lang.Byte"/>
+                                        <entry key="i16Field" value="java.lang.Short"/>
+                                        <entry key="i32Field" value="java.lang.Integer"/>
+                                        <entry key="i64Field" value="java.lang.Long"/>
+                                        <entry key="strField" value="java.lang.String"/>
+                                        <entry key="floatField" value="java.lang.Float"/>
+                                        <entry key="doubleField" value="java.lang.Double"/>
+                                        <entry key="boolField" value="java.lang.Boolean"/>
+                                        <entry key="guidField" value="java.util.UUID"/>
+                                        <entry key="dateField" value="java.util.Date"/>
+                                        <entry key="timestampField" value="java.sql.Timestamp"/>
+                                    </map>
+                                </property>
+
+                                <property name="keyFields">
+                                    <list></list>
+                                </property>
+
+                                <property name="indexes">
+                                    <list>
+                                        <bean class="org.apache.ignite.cache.QueryIndex">
+                                            <constructor-arg value="i32Field"/>
+                                        </bean>
+                                        <bean class="org.apache.ignite.cache.QueryIndex">
+                                            <constructor-arg value="i64Field"/>
+                                        </bean>
+                                    </list>
+                                </property>
+                            </bean>
+                        </list>
+                    </property>
+                </bean>
+
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="cache2"/>
+                    <property name="cacheMode" value="PARTITIONED"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="writeSynchronizationMode" value="FULL_SYNC"/>
+
+                    <!-- Configure type metadata to enable queries. -->
+                    <property name="queryEntities">
+                        <list>
+                            <bean class="org.apache.ignite.cache.QueryEntity">
+                                <property name="keyType" value="java.lang.Long"/>
+                                <property name="valueType" value="ComplexType"/>
+
+                                <property name="fields">
+                                    <map>
+                                        <entry key="i32Field" value="java.lang.Integer"/>
+                                        <entry key="objField" value="TestObject"/>
+                                        <entry key="strField" value="java.lang.String"/>
+                                    </map>
+                                </property>
+
+                                <property name="keyFields">
+                                    <list></list>
+                                </property>
+
+                                <property name="indexes">
+                                    <list>
+                                        <bean class="org.apache.ignite.cache.QueryIndex">
+                                            <constructor-arg value="i32Field"/>
+                                        </bean>
+                                    </list>
+                                </property>
+                            </bean>
+                        </list>
+                    </property>
+                </bean>
+            </list>
+        </property>
+
+        <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
+        <property name="discoverySpi">
+            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+                <property name="ipFinder">
+                    <!--
+                        Ignite provides several options for automatic discovery that can be used
+                        instead os static IP based discovery.
+                    -->
+                    <!-- Uncomment static IP finder to enable static-based discovery of initial nodes. -->
+                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+                        <property name="addresses">
+                            <list>
+                                <!-- In distributed environment, replace with actual host IP address. -->
+                                <value>127.0.0.1:47500</value>
+                            </list>
+                        </property>
+                    </bean>
+                </property>
+                <property name="socketTimeout" value="300" />
+            </bean>
+        </property>
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/8cffe900/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml b/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml
index 82173de..b21287f 100644
--- a/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml
+++ b/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml
@@ -22,86 +22,10 @@
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="
         http://www.springframework.org/schema/beans
-        http://www.springframework.org/schema/beans/spring-beans.xsd
-        http://www.springframework.org/schema/util
-        http://www.springframework.org/schema/util/spring-util.xsd">
-    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
-        <property name="localHost" value="127.0.0.1"/>
-        <property name="connectorConfiguration"><null/></property>
-        <property name="odbcConfiguration"><null/></property>
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
 
-        <property name="cacheConfiguration">
-            <list>
-                <bean class="org.apache.ignite.configuration.CacheConfiguration">
-                    <property name="name" value="cache"/>
-                    <property name="cacheMode" value="PARTITIONED"/>
-                    <property name="atomicityMode" value="TRANSACTIONAL"/>
-                    <property name="writeSynchronizationMode" value="FULL_SYNC"/>
+    <!-- Imports no-ODBC Ignite configuration -->
+    <import resource="queries-default.xml"/>
 
-                    <!-- Configure type metadata to enable queries. -->
-                    <property name="queryEntities">
-                        <list>
-                            <bean class="org.apache.ignite.cache.QueryEntity">
-                                <property name="keyType" value="java.lang.Long"/>
-                                <property name="valueType" value="TestType"/>
-
-                                <property name="fields">
-                                    <map>
-                                        <entry key="i8Field" value="java.lang.Byte"/>
-                                        <entry key="i16Field" value="java.lang.Short"/>
-                                        <entry key="i32Field" value="java.lang.Integer"/>
-                                        <entry key="i64Field" value="java.lang.Long"/>
-                                        <entry key="strField" value="java.lang.String"/>
-                                        <entry key="floatField" value="java.lang.Float"/>
-                                        <entry key="doubleField" value="java.lang.Double"/>
-                                        <entry key="boolField" value="java.lang.Boolean"/>
-                                        <entry key="guidField" value="java.util.UUID"/>
-                                        <entry key="dateField" value="java.util.Date"/>
-                                        <entry key="timestampField" value="java.sql.Timestamp"/>
-                                    </map>
-                                </property>
-
-                                <property name="keyFields">
-                                    <list></list>
-                                </property>
-
-                                <property name="indexes">
-                                    <list>
-                                        <bean class="org.apache.ignite.cache.QueryIndex">
-                                            <constructor-arg value="i32Field"/>
-                                        </bean>
-                                        <bean class="org.apache.ignite.cache.QueryIndex">
-                                            <constructor-arg value="i64Field"/>
-                                        </bean>
-                                    </list>
-                                </property>
-                            </bean>
-                        </list>
-                    </property>
-                </bean>
-            </list>
-        </property>
-
-        <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
-        <property name="discoverySpi">
-            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
-                <property name="ipFinder">
-                    <!--
-                        Ignite provides several options for automatic discovery that can be used
-                        instead os static IP based discovery.
-                    -->
-                    <!-- Uncomment static IP finder to enable static-based discovery of initial nodes. -->
-                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
-                        <property name="addresses">
-                            <list>
-                                <!-- In distributed environment, replace with actual host IP address. -->
-                                <value>127.0.0.1:47500</value>
-                            </list>
-                        </property>
-                    </bean>
-                </property>
-                <property name="socketTimeout" value="300" />
-            </bean>
-        </property>
-    </bean>
+    <bean parent="ignite.cfg"/>
 </beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/8cffe900/modules/platforms/cpp/odbc-test/config/queries-test.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-test.xml b/modules/platforms/cpp/odbc-test/config/queries-test.xml
index 906fadf..d08d4f1 100644
--- a/modules/platforms/cpp/odbc-test/config/queries-test.xml
+++ b/modules/platforms/cpp/odbc-test/config/queries-test.xml
@@ -22,129 +22,17 @@
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="
         http://www.springframework.org/schema/beans
-        http://www.springframework.org/schema/beans/spring-beans.xsd
-        http://www.springframework.org/schema/util
-        http://www.springframework.org/schema/util/spring-util.xsd">
-    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
-        <property name="localHost" value="127.0.0.1"/>
-        <property name="connectorConfiguration"><null/></property>
+        http://www.springframework.org/schema/beans/spring-beans.xsd">
 
+    <!-- Imports no-ODBC Ignite configuration -->
+    <import resource="queries-default.xml"/>
+
+    <bean parent="ignite.cfg">
         <!-- Enabling ODBC. -->
         <property name="odbcConfiguration">
             <bean class="org.apache.ignite.configuration.OdbcConfiguration">
                 <property name="endpointAddress" value="127.0.0.1:11110"/>
             </bean>
         </property>
-
-        <property name="cacheConfiguration">
-            <list>
-                <bean class="org.apache.ignite.configuration.CacheConfiguration">
-                    <property name="name" value="cache"/>
-                    <property name="cacheMode" value="PARTITIONED"/>
-                    <property name="atomicityMode" value="TRANSACTIONAL"/>
-                    <property name="writeSynchronizationMode" value="FULL_SYNC"/>
-
-                    <!-- Configure type metadata to enable queries. -->
-                    <property name="queryEntities">
-                        <list>
-                            <bean class="org.apache.ignite.cache.QueryEntity">
-                                <property name="keyType" value="java.lang.Long"/>
-                                <property name="valueType" value="TestType"/>
-
-                                <property name="fields">
-                                    <map>
-                                        <entry key="i8Field" value="java.lang.Byte"/>
-                                        <entry key="i16Field" value="java.lang.Short"/>
-                                        <entry key="i32Field" value="java.lang.Integer"/>
-                                        <entry key="i64Field" value="java.lang.Long"/>
-                                        <entry key="strField" value="java.lang.String"/>
-                                        <entry key="floatField" value="java.lang.Float"/>
-                                        <entry key="doubleField" value="java.lang.Double"/>
-                                        <entry key="boolField" value="java.lang.Boolean"/>
-                                        <entry key="guidField" value="java.util.UUID"/>
-                                        <entry key="dateField" value="java.util.Date"/>
-                                        <entry key="timestampField" value="java.sql.Timestamp"/>
-                                    </map>
-                                </property>
-
-                                <property name="keyFields">
-                                    <list></list>
-                                </property>
-
-                                <property name="indexes">
-                                    <list>
-                                        <bean class="org.apache.ignite.cache.QueryIndex">
-                                            <constructor-arg value="i32Field"/>
-                                        </bean>
-                                        <bean class="org.apache.ignite.cache.QueryIndex">
-                                            <constructor-arg value="i64Field"/>
-                                        </bean>
-                                    </list>
-                                </property>
-                            </bean>
-                        </list>
-                    </property>
-                </bean>
-
-                <bean class="org.apache.ignite.configuration.CacheConfiguration">
-                    <property name="name" value="cache2"/>
-                    <property name="cacheMode" value="PARTITIONED"/>
-                    <property name="atomicityMode" value="TRANSACTIONAL"/>
-                    <property name="writeSynchronizationMode" value="FULL_SYNC"/>
-
-                    <!-- Configure type metadata to enable queries. -->
-                    <property name="queryEntities">
-                        <list>
-                            <bean class="org.apache.ignite.cache.QueryEntity">
-                                <property name="keyType" value="java.lang.Long"/>
-                                <property name="valueType" value="ComplexType"/>
-
-                                <property name="fields">
-                                    <map>
-                                        <entry key="i32Field" value="java.lang.Integer"/>
-                                        <entry key="objField" value="TestObject"/>
-                                        <entry key="strField" value="java.lang.String"/>
-                                    </map>
-                                </property>
-
-                                <property name="keyFields">
-                                    <list></list>
-                                </property>
-
-                                <property name="indexes">
-                                    <list>
-                                        <bean class="org.apache.ignite.cache.QueryIndex">
-                                            <constructor-arg value="i32Field"/>
-                                        </bean>
-                                    </list>
-                                </property>
-                            </bean>
-                        </list>
-                    </property>
-                </bean>
-            </list>
-        </property>
-
-        <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
-        <property name="discoverySpi">
-            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
-                <property name="ipFinder">
-                    <!--
-                        Ignite provides several options for automatic discovery that can be used
-                        instead os static IP based discovery.
-                    -->
-                    <!-- Uncomment static IP finder to enable static-based discovery of initial nodes. -->
-                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
-                        <property name="addresses">
-                            <list>
-                                <!-- In distributed environment, replace with actual host IP address. -->
-                                <value>127.0.0.1:47500</value>
-                            </list>
-                        </property>
-                    </bean>
-                </property>
-                <property name="socketTimeout" value="300" />
-            </bean>
-        </property>
     </bean>
 </beans>

http://git-wip-us.apache.org/repos/asf/ignite/blob/8cffe900/modules/platforms/cpp/odbc-test/src/queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/queries_test.cpp b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
index 52b885d..a304229 100644
--- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
@@ -1342,4 +1342,80 @@ BOOST_AUTO_TEST_CASE(TestInsertMergeSelect)
     BOOST_CHECK_EQUAL(recordsNum, selectedRecordsNum);
 }
 
+template<size_t n, size_t k>
+void CheckMeta(char columns[n][k], SQLLEN columnsLen[n])
+{
+    std::string catalog(columns[0], columnsLen[0]);
+    std::string schema(columns[1], columnsLen[1]);
+    std::string table(columns[2], columnsLen[2]);
+    std::string tableType(columns[3], columnsLen[3]);
+
+    BOOST_CHECK_EQUAL(catalog, std::string(""));
+    BOOST_CHECK_EQUAL(tableType, std::string("TABLE"));
+    BOOST_CHECK_EQUAL(columnsLen[4], SQL_NULL_DATA);
+
+    if (schema == "\"cache\"")
+    {
+        BOOST_CHECK_EQUAL(table, std::string("TestType"));
+    }
+    else if (schema == "\"cache2\"")
+    {
+        BOOST_CHECK_EQUAL(table, std::string("ComplexType"));
+    }
+    else
+    {
+        BOOST_FAIL("Unknown schema: " + schema);
+    }
+}
+
+BOOST_AUTO_TEST_CASE(TestTablesMeta)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache2");
+
+    SQLRETURN ret;
+
+    enum { COLUMNS_NUM = 5 };
+
+    // Five collumns: TABLE_CAT, TABLE_SCHEM, TABLE_NAME, TABLE_TYPE, REMARKS
+    char columns[COLUMNS_NUM][ODBC_BUFFER_SIZE];
+    SQLLEN columnsLen[COLUMNS_NUM];
+
+    // Binding columns.
+    for (size_t i = 0; i < COLUMNS_NUM; ++i)
+    {
+        columnsLen[i] = ODBC_BUFFER_SIZE;
+
+        ret = SQLBindCol(stmt, static_cast<SQLSMALLINT>(i + 1), SQL_C_CHAR, columns[i], columnsLen[i], &columnsLen[i]);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+    }
+
+    SQLCHAR catalogPattern[] = "";
+    SQLCHAR schemaPattern[] = "";
+    SQLCHAR tablePattern[] = "";
+    SQLCHAR tableTypePattern[] = "";
+
+    ret = SQLTables(stmt, catalogPattern, SQL_NTS, schemaPattern,
+        SQL_NTS, tablePattern, SQL_NTS, tableTypePattern, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLFetch(stmt);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    CheckMeta<COLUMNS_NUM, ODBC_BUFFER_SIZE>(columns, columnsLen);
+
+    ret = SQLFetch(stmt);
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    CheckMeta<COLUMNS_NUM, ODBC_BUFFER_SIZE>(columns, columnsLen);
+
+    ret = SQLFetch(stmt);
+    BOOST_CHECK(ret == SQL_NO_DATA);
+}
+
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/8cffe900/modules/platforms/cpp/odbc-test/src/utility_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/utility_test.cpp b/modules/platforms/cpp/odbc-test/src/utility_test.cpp
index 6c4d104..a66860f 100644
--- a/modules/platforms/cpp/odbc-test/src/utility_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/utility_test.cpp
@@ -54,28 +54,43 @@ BOOST_AUTO_TEST_CASE(TestUtilityCopyStringToBuffer)
     BOOST_REQUIRE(!strcmp(buffer, str.substr(0, 10).c_str()));
 }
 
-BOOST_AUTO_TEST_CASE(TestUtilityReadString)
+BOOST_AUTO_TEST_CASE(TestUtilityWriteReadString)
 {
     using namespace ignite::impl::binary;
     using namespace ignite::impl::interop;
 
-    std::string inputStr("Hello World!");
-    std::string outputStr;
+    std::string inStr1("Hello World!");
+    std::string inStr2;
+    std::string inStr3("Lorem ipsum");
+
+    std::string outStr1;
+    std::string outStr2;
+    std::string outStr3;
+    std::string outStr4;
 
     ignite::impl::interop::InteropUnpooledMemory mem(1024);
     InteropOutputStream outStream(&mem);
     BinaryWriterImpl writer(&outStream, 0);
 
-    writer.WriteString(inputStr.data(), static_cast<int32_t>(inputStr.size()));
+    WriteString(writer, inStr1);
+    WriteString(writer, inStr2);
+    WriteString(writer, inStr3);
+    writer.WriteNull();
 
     outStream.Synchronize();
 
     InteropInputStream inStream(&mem);
     BinaryReaderImpl reader(&inStream);
 
-    ReadString(reader, outputStr);
+    ReadString(reader, outStr1);
+    ReadString(reader, outStr2);
+    ReadString(reader, outStr3);
+    ReadString(reader, outStr4);
 
-    BOOST_REQUIRE(inputStr == outputStr);
+    BOOST_REQUIRE(inStr1 == outStr1);
+    BOOST_REQUIRE(inStr2 == outStr2);
+    BOOST_REQUIRE(inStr3 == outStr3);
+    BOOST_REQUIRE(outStr4.empty());
 }
 
 BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/8cffe900/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 22191eb..756ab36 100644
--- a/modules/platforms/cpp/odbc/src/utility.cpp
+++ b/modules/platforms/cpp/odbc/src/utility.cpp
@@ -56,6 +56,7 @@ namespace ignite
         void ReadString(ignite::impl::binary::BinaryReaderImpl& reader, std::string& str)
         {
             int32_t strLen = reader.ReadString(0, 0);
+
             if (strLen > 0)
             {
                 str.resize(strLen);
@@ -63,7 +64,16 @@ namespace ignite
                 reader.ReadString(&str[0], static_cast<int32_t>(str.size()));
             }
             else
+            {
                 str.clear();
+
+                if (strLen == 0)
+                {
+                    char dummy;
+
+                    reader.ReadString(&dummy, sizeof(dummy));
+                }
+            }
         }
 
         void WriteString(ignite::impl::binary::BinaryWriterImpl& writer, const std::string & str)