ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From yzhda...@apache.org
Subject [26/50] [abbrv] ignite git commit: IGNITE-6294: ODBC: implemented SQLSTATE management. This closes #2716.
Date Fri, 13 Oct 2017 17:43:11 GMT
IGNITE-6294: ODBC: implemented SQLSTATE management. This closes #2716.


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

Branch: refs/heads/ignite-2.1.5-p1
Commit: fc34091c750cdaf759a54a989a84c76f8d9f9f7f
Parents: 49a3631
Author: Igor Sapego <igorsapg@gmail.com>
Authored: Thu Sep 21 20:02:33 2017 +0300
Committer: devozerov <ppozerov@gmail.com>
Committed: Thu Sep 21 20:05:40 2017 +0300

----------------------------------------------------------------------
 .../odbc/odbc/OdbcConnectionContext.java        |   6 +-
 .../processors/odbc/odbc/OdbcMessageParser.java |  17 +-
 .../odbc/odbc/OdbcQueryExecuteBatchResult.java  |  16 +-
 .../odbc/odbc/OdbcRequestHandler.java           |  54 +++-
 .../processors/odbc/odbc/OdbcUtils.java         |  24 +-
 modules/platforms/cpp/odbc-test/Makefile.am     |   1 +
 .../cpp/odbc-test/project/vs/odbc-test.vcxproj  |   1 +
 .../project/vs/odbc-test.vcxproj.filters        |   3 +
 .../platforms/cpp/odbc-test/src/errors_test.cpp | 289 +++++++++++++++++++
 .../platforms/cpp/odbc-test/src/parser_test.cpp |   4 +-
 .../cpp/odbc-test/src/queries_test.cpp          |  16 +-
 modules/platforms/cpp/odbc/include/Makefile.am  |   1 +
 .../cpp/odbc/include/ignite/odbc/common_types.h | 131 ++++++++-
 .../ignite/odbc/diagnostic/diagnosable.h        |   9 +
 .../odbc/diagnostic/diagnosable_adapter.h       |   8 +
 .../cpp/odbc/include/ignite/odbc/message.h      |  48 +--
 .../cpp/odbc/include/ignite/odbc/odbc_error.h   |  94 ++++++
 .../cpp/odbc/include/ignite/odbc/parser.h       |  35 ++-
 .../platforms/cpp/odbc/project/vs/odbc.vcxproj  |   1 +
 .../cpp/odbc/project/vs/odbc.vcxproj.filters    |   3 +
 modules/platforms/cpp/odbc/src/common_types.cpp |  51 ++++
 modules/platforms/cpp/odbc/src/connection.cpp   |  25 +-
 .../odbc/src/diagnostic/diagnosable_adapter.cpp |   8 +
 .../odbc/src/diagnostic/diagnostic_record.cpp   | 105 ++++++-
 modules/platforms/cpp/odbc/src/message.cpp      |  37 ++-
 .../cpp/odbc/src/query/batch_query.cpp          |  13 +-
 .../odbc/src/query/column_metadata_query.cpp    |  11 +-
 .../platforms/cpp/odbc/src/query/data_query.cpp |  31 +-
 .../cpp/odbc/src/query/table_metadata_query.cpp |  11 +-
 modules/platforms/cpp/odbc/src/statement.cpp    |  11 +-
 30 files changed, 960 insertions(+), 104 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
index f2450e2..a4af478 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcConnectionContext.java
@@ -32,10 +32,10 @@ import org.apache.ignite.internal.util.GridSpinBusyLock;
  */
 public class OdbcConnectionContext implements ClientListenerConnectionContext {
     /** Version 2.1.0. */
-    private static final ClientListenerProtocolVersion VER_2_1_0 = ClientListenerProtocolVersion.create(2, 1, 0);
+    public static final ClientListenerProtocolVersion VER_2_1_0 = ClientListenerProtocolVersion.create(2, 1, 0);
 
     /** Version 2.1.5: added "lazy" flag. */
-    private static final ClientListenerProtocolVersion VER_2_1_5 = ClientListenerProtocolVersion.create(2, 1, 5);
+    public static final ClientListenerProtocolVersion VER_2_1_5 = ClientListenerProtocolVersion.create(2, 1, 5);
 
     /** Current version. */
     private static final ClientListenerProtocolVersion CURRENT_VER = VER_2_1_5;
@@ -101,7 +101,7 @@ public class OdbcConnectionContext implements ClientListenerConnectionContext {
         handler = new OdbcRequestHandler(ctx, busyLock, maxCursors, distributedJoins,
                 enforceJoinOrder, replicatedOnly, collocated, lazy);
 
-        parser = new OdbcMessageParser(ctx);
+        parser = new OdbcMessageParser(ctx, ver);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java
index 2ab7cee..04e2e25 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcMessageParser.java
@@ -30,6 +30,7 @@ import org.apache.ignite.internal.binary.streams.BinaryHeapOutputStream;
 import org.apache.ignite.internal.binary.streams.BinaryInputStream;
 import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
 import org.apache.ignite.internal.processors.odbc.ClientListenerMessageParser;
+import org.apache.ignite.internal.processors.odbc.ClientListenerProtocolVersion;
 import org.apache.ignite.internal.processors.odbc.ClientListenerRequest;
 import org.apache.ignite.internal.processors.odbc.ClientListenerResponse;
 import org.apache.ignite.internal.processors.odbc.SqlListenerUtils;
@@ -51,11 +52,16 @@ public class OdbcMessageParser implements ClientListenerMessageParser {
     /** Logger. */
     private final IgniteLogger log;
 
+    /** Protocol version */
+    private final ClientListenerProtocolVersion ver;
+
     /**
      * @param ctx Context.
+     * @param ver Protocol version.
      */
-    public OdbcMessageParser(GridKernalContext ctx) {
+    public OdbcMessageParser(GridKernalContext ctx, ClientListenerProtocolVersion ver) {
         this.ctx = ctx;
+        this.ver = ver;
 
         log = ctx.log(getClass());
 
@@ -194,7 +200,11 @@ public class OdbcMessageParser implements ClientListenerMessageParser {
             BinaryThreadLocalContext.get().schemaHolder(), null);
 
         // Writing status.
-        writer.writeByte((byte) msg.status());
+        if (ver.compareTo(OdbcConnectionContext.VER_2_1_5) < 0) {
+            writer.writeByte((byte) (msg.status() == ClientListenerResponse.STATUS_SUCCESS ?
+                ClientListenerResponse.STATUS_SUCCESS : ClientListenerResponse.STATUS_FAILED));
+        } else
+            writer.writeInt(msg.status());
 
         if (msg.status() != ClientListenerResponse.STATUS_SUCCESS) {
             writer.writeString(msg.error());
@@ -234,6 +244,9 @@ public class OdbcMessageParser implements ClientListenerMessageParser {
             if (res.errorMessage() != null) {
                 writer.writeLong(res.errorSetIdx());
                 writer.writeString(res.errorMessage());
+
+                if (ver.compareTo(OdbcConnectionContext.VER_2_1_5) >= 0)
+                    writer.writeInt(res.errorCode());
             }
         }
         else if (res0 instanceof OdbcQueryFetchResult) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryExecuteBatchResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryExecuteBatchResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryExecuteBatchResult.java
index ee02fd6..c8f61dc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryExecuteBatchResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQueryExecuteBatchResult.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.processors.odbc.odbc;
 
+import org.apache.ignite.internal.processors.odbc.ClientListenerResponse;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -29,6 +30,9 @@ public class OdbcQueryExecuteBatchResult {
     /** Index of the set which caused an error. */
     private final long errorSetIdx;
 
+    /** Error code. */
+    private final int errorCode;
+
     /** Error message. */
     private final String errorMessage;
 
@@ -39,17 +43,20 @@ public class OdbcQueryExecuteBatchResult {
         this.rowsAffected = rowsAffected;
         this.errorSetIdx = -1;
         this.errorMessage = null;
+        this.errorCode = ClientListenerResponse.STATUS_SUCCESS;
     }
 
     /**
      * @param rowsAffected Number of rows affected by the query.
      * @param errorSetIdx Sets processed.
+     * @param errorCode Error code.
      * @param errorMessage Error message.
      */
-    public OdbcQueryExecuteBatchResult(long rowsAffected, long errorSetIdx, String errorMessage) {
+    public OdbcQueryExecuteBatchResult(long rowsAffected, long errorSetIdx, int errorCode, String errorMessage) {
         this.rowsAffected = rowsAffected;
         this.errorSetIdx = errorSetIdx;
         this.errorMessage = errorMessage;
+        this.errorCode = errorCode;
     }
 
     /**
@@ -72,4 +79,11 @@ public class OdbcQueryExecuteBatchResult {
     @Nullable public String errorMessage() {
         return errorMessage;
     }
+
+    /**
+     * @return Error code.
+     */
+    public int errorCode() {
+        return errorCode;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
index fd31f39..07b41f3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
@@ -35,6 +35,7 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.binary.BinaryWriterExImpl;
 import org.apache.ignite.internal.binary.GridBinaryMarshaller;
 import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
+import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
 import org.apache.ignite.internal.processors.odbc.ClientListenerRequest;
 import org.apache.ignite.internal.processors.odbc.ClientListenerRequestHandler;
 import org.apache.ignite.internal.processors.odbc.ClientListenerResponse;
@@ -42,6 +43,7 @@ import org.apache.ignite.internal.processors.odbc.odbc.escape.OdbcEscapeUtils;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
 import org.apache.ignite.internal.processors.query.GridQueryIndexing;
 import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
+import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -125,7 +127,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         OdbcRequest req = (OdbcRequest)req0;
 
         if (!busyLock.enterBusy())
-            return new OdbcResponse(OdbcResponse.STATUS_FAILED,
+            return new OdbcResponse(IgniteQueryErrorCode.UNKNOWN,
                     "Failed to handle ODBC request because node is stopping: " + req);
 
         try {
@@ -152,7 +154,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
                     return getParamsMeta((OdbcQueryGetParamsMetaRequest)req);
             }
 
-            return new OdbcResponse(OdbcResponse.STATUS_FAILED, "Unsupported ODBC request: " + req);
+            return new OdbcResponse(IgniteQueryErrorCode.UNKNOWN, "Unsupported ODBC request: " + req);
         }
         finally {
             busyLock.leaveBusy();
@@ -161,7 +163,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
 
     /** {@inheritDoc} */
     @Override public ClientListenerResponse handleException(Exception e, ClientListenerRequest req) {
-        return new OdbcResponse(ClientListenerResponse.STATUS_FAILED, e.toString());
+        return exceptionToResult(e);
     }
 
     /** {@inheritDoc} */
@@ -219,7 +221,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         int cursorCnt = qryCursors.size();
 
         if (maxCursors > 0 && cursorCnt >= maxCursors)
-            return new OdbcResponse(ClientListenerResponse.STATUS_FAILED, "Too many open cursors (either close " +
+            return new OdbcResponse(IgniteQueryErrorCode.UNKNOWN, "Too many open cursors (either close " +
                 "other open cursors or increase the limit through " +
                 "ClientConnectorConfiguration.maxOpenCursorsPerConnection) [maximum=" + maxCursors +
                 ", current=" + cursorCnt + ']');
@@ -258,7 +260,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
 
             U.error(log, "Failed to execute SQL query [reqId=" + req.requestId() + ", req=" + req + ']', e);
 
-            return new OdbcResponse(ClientListenerResponse.STATUS_FAILED, OdbcUtils.retrieveH2ErrorMessage(e));
+            return exceptionToResult(e);
         }
     }
 
@@ -308,10 +310,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         catch (Exception e) {
             U.error(log, "Failed to execute SQL query [reqId=" + req.requestId() + ", req=" + req + ']', e);
 
-            OdbcQueryExecuteBatchResult res = new OdbcQueryExecuteBatchResult(rowsAffected, currentSet,
-                    OdbcUtils.retrieveH2ErrorMessage(e));
-
-            return new OdbcResponse(res);
+            return exceptionToBatchResult(e, rowsAffected, currentSet);
         }
     }
 
@@ -364,7 +363,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
             IgniteBiTuple<QueryCursor, Iterator> tuple = qryCursors.get(queryId);
 
             if (tuple == null)
-                return new OdbcResponse(ClientListenerResponse.STATUS_FAILED,
+                return new OdbcResponse(IgniteQueryErrorCode.UNKNOWN,
                     "Failed to find query with ID: " + queryId);
 
             CloseCursor(tuple, queryId);
@@ -378,7 +377,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
 
             U.error(log, "Failed to close SQL query [reqId=" + req.requestId() + ", req=" + queryId + ']', e);
 
-            return new OdbcResponse(ClientListenerResponse.STATUS_FAILED, OdbcUtils.retrieveH2ErrorMessage(e));
+            return exceptionToResult(e);
         }
     }
 
@@ -427,7 +426,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         catch (Exception e) {
             U.error(log, "Failed to fetch SQL query result [reqId=" + req.requestId() + ", req=" + req + ']', e);
 
-            return new OdbcResponse(ClientListenerResponse.STATUS_FAILED, OdbcUtils.retrieveH2ErrorMessage(e));
+            return exceptionToResult(e);
         }
     }
 
@@ -492,7 +491,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         catch (Exception e) {
             U.error(log, "Failed to get columns metadata [reqId=" + req.requestId() + ", req=" + req + ']', e);
 
-            return new OdbcResponse(ClientListenerResponse.STATUS_FAILED, OdbcUtils.retrieveH2ErrorMessage(e));
+            return exceptionToResult(e);
         }
     }
 
@@ -540,7 +539,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         catch (Exception e) {
             U.error(log, "Failed to get tables metadata [reqId=" + req.requestId() + ", req=" + req + ']', e);
 
-            return new OdbcResponse(ClientListenerResponse.STATUS_FAILED, OdbcUtils.retrieveH2ErrorMessage(e));
+            return exceptionToResult(e);
         }
     }
 
@@ -571,7 +570,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         catch (Exception e) {
             U.error(log, "Failed to get params metadata [reqId=" + req.requestId() + ", req=" + req + ']', e);
 
-            return new OdbcResponse(ClientListenerResponse.STATUS_FAILED, OdbcUtils.retrieveH2ErrorMessage(e));
+            return exceptionToResult(e);
         }
     }
 
@@ -681,4 +680,29 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         return str != null && (F.isEmpty(ptrn) ||
             str.toUpperCase().matches(ptrn.toUpperCase().replace("%", ".*").replace("_", ".")));
     }
+
+    /**
+     * Create {@link OdbcResponse} bearing appropriate Ignite specific result code if possible
+     *     from given {@link Exception}.
+     *
+     * @param e Exception to convert.
+     * @return resulting {@link OdbcResponse}.
+     */
+    private OdbcResponse exceptionToBatchResult(Exception e, long rowsAffected, long currentSet) {
+        OdbcQueryExecuteBatchResult res = new OdbcQueryExecuteBatchResult(rowsAffected, currentSet,
+            OdbcUtils.tryRetrieveSqlErrorCode(e), OdbcUtils.tryRetrieveH2ErrorMessage(e));
+
+        return new OdbcResponse(res);
+    }
+
+    /**
+     * Create {@link OdbcResponse} bearing appropriate Ignite specific result code if possible
+     *     from given {@link Exception}.
+     *
+     * @param e Exception to convert.
+     * @return resulting {@link OdbcResponse}.
+     */
+    private OdbcResponse exceptionToResult(Exception e) {
+        return new OdbcResponse(OdbcUtils.tryRetrieveSqlErrorCode(e), OdbcUtils.tryRetrieveH2ErrorMessage(e));
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java
index 3578145..98fa045 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java
@@ -18,7 +18,9 @@
 package org.apache.ignite.internal.processors.odbc.odbc;
 
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
 import org.apache.ignite.internal.processors.odbc.SqlListenerDataTypes;
+import org.apache.ignite.internal.processors.query.IgniteSQLException;
 
 /**
  * Various ODBC utility methods.
@@ -141,11 +143,29 @@ public class OdbcUtils {
     }
 
     /**
-     * Retrieves error message from exception.
+     * Tries to retrieve SQL error code of the exception. If the exception is not {@link IgniteSQLException} returns
+     * {@link IgniteQueryErrorCode#UNKNOWN}.
+     *
+     * @param err Error to retrieve code from.
+     * @return Error code.
+     */
+    public static int tryRetrieveSqlErrorCode(Throwable err) {
+        int errorCode = IgniteQueryErrorCode.UNKNOWN;
+
+        if (err instanceof IgniteSQLException)
+            errorCode = ((IgniteSQLException) err).statusCode();
+
+        return errorCode;
+    }
+
+    /**
+     * Tries to retrieve H2 engine error message from exception. If the exception is not of type
+     * "org.h2.jdbc.JdbcSQLException" returns original error message.
+     *
      * @param err Exception.
      * @return Error message.
      */
-    public static String retrieveH2ErrorMessage(Throwable err) {
+    public static String tryRetrieveH2ErrorMessage(Throwable err) {
         String msg = err.getMessage();
 
         Throwable e = err.getCause();

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/Makefile.am b/modules/platforms/cpp/odbc-test/Makefile.am
index 69b62f9..5c335cf 100644
--- a/modules/platforms/cpp/odbc-test/Makefile.am
+++ b/modules/platforms/cpp/odbc-test/Makefile.am
@@ -79,6 +79,7 @@ ignite_odbc_tests_SOURCES = \
     src/sql_outer_join_test.cpp \
     src/api_robustness_test.cpp \
     src/attributes_test.cpp \
+    src/errors_test.cpp \
     ../odbc/src/cursor.cpp \
     ../odbc/src/config/connection_info.cpp \
     ../odbc/src/app/application_data_buffer.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
index 3977a24..6ee999e 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
@@ -169,6 +169,7 @@
     <ClCompile Include="..\..\src\configuration_test.cpp" />
     <ClCompile Include="..\..\src\connection_info_test.cpp" />
     <ClCompile Include="..\..\src\cursor_test.cpp" />
+    <ClCompile Include="..\..\src\errors_test.cpp" />
     <ClCompile Include="..\..\src\meta_queries_test.cpp" />
     <ClCompile Include="..\..\src\queries_test.cpp" />
     <ClCompile Include="..\..\src\parser_test.cpp" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
index 2a0c7b4..abfe303 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
@@ -127,6 +127,9 @@
     <ClCompile Include="..\..\src\attributes_test.cpp">
       <Filter>Code</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\errors_test.cpp">
+      <Filter>Code</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\test_type.h">

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc-test/src/errors_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/errors_test.cpp b/modules/platforms/cpp/odbc-test/src/errors_test.cpp
new file mode 100644
index 0000000..bac9fd4
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/src/errors_test.cpp
@@ -0,0 +1,289 @@
+/*
+ * 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.
+ */
+
+#ifdef _WIN32
+#   include <windows.h>
+#endif
+
+#include <sql.h>
+#include <sqlext.h>
+
+#include <vector>
+#include <string>
+#include <algorithm>
+
+#ifndef _MSC_VER
+#   define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/regex.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include "ignite/ignite.h"
+#include "ignite/common/fixed_size_array.h"
+#include "ignite/ignition.h"
+#include "ignite/impl/binary/binary_utils.h"
+#include "ignite/binary/binary_object.h"
+
+#include "test_type.h"
+#include "complex_type.h"
+#include "test_utils.h"
+
+using namespace ignite;
+using namespace ignite::cache;
+using namespace ignite::cache::query;
+using namespace ignite::common;
+using namespace ignite_test;
+using namespace ignite::binary;
+using namespace ignite::impl::binary;
+using namespace ignite::impl::interop;
+
+using namespace boost::unit_test;
+
+using ignite::impl::binary::BinaryUtils;
+
+/**
+ * Test setup fixture.
+ */
+struct ErrorTestSuiteFixture 
+{
+    /**
+     * Establish connection to node.
+     *
+     * @param connectStr Connection string.
+     */
+    void Connect(const std::string& connectStr)
+    {
+        // Allocate an environment handle
+        SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
+
+        BOOST_REQUIRE(env != NULL);
+
+        // We want ODBC 3 support
+        SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, reinterpret_cast<void*>(SQL_OV_ODBC3), 0);
+
+        // Allocate a connection handle
+        SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
+
+        BOOST_REQUIRE(dbc != NULL);
+
+        // Connect string
+        std::vector<SQLCHAR> connectStr0;
+
+        connectStr0.reserve(connectStr.size() + 1);
+        std::copy(connectStr.begin(), connectStr.end(), std::back_inserter(connectStr0));
+
+        SQLCHAR outstr[ODBC_BUFFER_SIZE];
+        SQLSMALLINT outstrlen;
+
+        // Connecting to ODBC server.
+        SQLRETURN ret = SQLDriverConnect(dbc, NULL, &connectStr0[0], static_cast<SQLSMALLINT>(connectStr0.size()),
+            outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);
+
+        if (!SQL_SUCCEEDED(ret))
+        {
+            Ignition::StopAll(true);
+
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_DBC, dbc));
+        }
+
+        // Allocate a statement handle
+        SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
+
+        BOOST_REQUIRE(stmt != NULL);
+    }
+
+    void Disconnect()
+    {
+        // Releasing statement handle.
+        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+
+        // Disconneting from the server.
+        SQLDisconnect(dbc);
+
+        // Releasing allocated handles.
+        SQLFreeHandle(SQL_HANDLE_DBC, dbc);
+        SQLFreeHandle(SQL_HANDLE_ENV, env);
+    }
+
+    static Ignite StartAdditionalNode(const char* name)
+    {
+#ifdef IGNITE_TESTS_32
+        return StartNode("queries-test-32.xml", name);
+#else
+        return StartNode("queries-test.xml", name);
+#endif
+    }
+
+    /**
+     * Constructor.
+     */
+    ErrorTestSuiteFixture() :
+        env(NULL),
+        dbc(NULL),
+        stmt(NULL)
+    {
+        // No-op.
+    }
+
+    /**
+     * Destructor.
+     */
+    ~ErrorTestSuiteFixture()
+    {
+        Disconnect();
+
+        Ignition::StopAll(true);
+    }
+
+    /** Frist cache instance. */
+    //Cache<int64_t, TestType> cache;
+
+    /** ODBC Environment. */
+    SQLHENV env;
+
+    /** ODBC Connect. */
+    SQLHDBC dbc;
+
+    /** ODBC Statement. */
+    SQLHSTMT stmt;
+};
+
+BOOST_FIXTURE_TEST_SUITE(ErrorTestSuite, ErrorTestSuiteFixture)
+
+BOOST_AUTO_TEST_CASE(TestConnectFail)
+{
+    // Allocate an environment handle
+    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
+
+    BOOST_REQUIRE(env != NULL);
+
+    // We want ODBC 3 support
+    SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, reinterpret_cast<void*>(SQL_OV_ODBC3), 0);
+
+    // Allocate a connection handle
+    SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
+
+    BOOST_REQUIRE(dbc != NULL);
+
+    // Connect string
+    SQLCHAR connectStr[] = "DRIVER={Apache Ignite};ADDRESS=127.0.0.1:9999;SCHEMA=cache";
+
+    SQLCHAR outstr[ODBC_BUFFER_SIZE];
+    SQLSMALLINT outstrlen;
+
+    // Connecting to ODBC server.
+    SQLRETURN ret = SQLDriverConnect(dbc, NULL, connectStr, SQL_NTS,
+        outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);
+
+    BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+    BOOST_CHECK_EQUAL(GetOdbcErrorState(SQL_HANDLE_DBC, dbc), "08001");
+}
+
+BOOST_AUTO_TEST_CASE(TestDuplicateKey)
+{
+    StartAdditionalNode("Node1");
+
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLCHAR insertReq[] = "INSERT INTO TestType(_key, strField) VALUES(1, 'some')";
+
+    SQLRETURN ret;
+
+    ret = SQLExecDirect(stmt, insertReq, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLExecDirect(stmt, insertReq, SQL_NTS);
+
+    BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+    BOOST_CHECK_EQUAL(GetOdbcErrorState(SQL_HANDLE_STMT, stmt), "23000");
+}
+
+BOOST_AUTO_TEST_CASE(TestUpdateKey)
+{
+    StartAdditionalNode("Node1");
+
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLCHAR insertReq[] = "INSERT INTO TestType(_key, strField) VALUES(1, 'some')";
+
+    SQLRETURN ret;
+
+    ret = SQLExecDirect(stmt, insertReq, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    SQLCHAR updateReq[] = "UPDATE TestType SET _key=2 WHERE _key=1";
+
+    ret = SQLExecDirect(stmt, updateReq, SQL_NTS);
+
+    BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+    BOOST_CHECK_EQUAL(GetOdbcErrorState(SQL_HANDLE_STMT, stmt), "42000");
+}
+
+BOOST_AUTO_TEST_CASE(TestTableNotFound)
+{
+    StartAdditionalNode("Node1");
+
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=PUBLIC");
+
+    SQLCHAR req[] = "DROP TABLE Nonexisting";
+
+    SQLRETURN ret;
+
+    ret = SQLExecDirect(stmt, req, SQL_NTS);
+
+    BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+    BOOST_CHECK_EQUAL(GetOdbcErrorState(SQL_HANDLE_STMT, stmt), "42S02");
+}
+
+BOOST_AUTO_TEST_CASE(TestIndexNotFound)
+{
+    StartAdditionalNode("Node1");
+
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=PUBLIC");
+
+    SQLCHAR req[] = "DROP INDEX Nonexisting";
+
+    SQLRETURN ret;
+
+    ret = SQLExecDirect(stmt, req, SQL_NTS);
+
+    BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+    BOOST_CHECK_EQUAL(GetOdbcErrorState(SQL_HANDLE_STMT, stmt), "42S12");
+}
+
+BOOST_AUTO_TEST_CASE(TestSyntaxError)
+{
+    StartAdditionalNode("Node1");
+
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=PUBLIC");
+
+    SQLCHAR req[] = "INSERT INTO TestType(_key, fasf) VALUES(1, 'some')";
+
+    SQLRETURN ret;
+
+    ret = SQLExecDirect(stmt, req, SQL_NTS);
+
+    BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+    BOOST_CHECK_EQUAL(GetOdbcErrorState(SQL_HANDLE_STMT, stmt), "42000");
+}
+
+BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc-test/src/parser_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/parser_test.cpp b/modules/platforms/cpp/odbc-test/src/parser_test.cpp
index 7c8a73d..51539ae 100644
--- a/modules/platforms/cpp/odbc-test/src/parser_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/parser_test.cpp
@@ -27,7 +27,7 @@ using namespace ignite::odbc;
 
 struct TestMessage
 {
-    TestMessage()
+    TestMessage() : a(0), b()
     {
         // No-op.
     }
@@ -48,7 +48,7 @@ struct TestMessage
         writer.WriteString(b.data(), static_cast<int32_t>(b.size()));
     }
 
-    void Read(ignite::impl::binary::BinaryReaderImpl& reader)
+    void Read(ignite::impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&)
     {
         a = reader.ReadInt32();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/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 e7168fe..4c7e402 100644
--- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
@@ -734,11 +734,25 @@ BOOST_FIXTURE_TEST_SUITE(QueriesTestSuite, QueriesTestSuiteFixture)
 BOOST_AUTO_TEST_CASE(TestLegacyConnection)
 {
     Connect("DRIVER={Apache Ignite};SERVER=127.0.0.1;PORT=11110;SCHEMA=cache");
+
+    InsertTestStrings(10, false);
+    InsertTestBatch(11, 20, 9);
 }
 
 BOOST_AUTO_TEST_CASE(TestConnectionProtocolVersion_2_1_0)
 {
     Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache;PROTOCOL_VERSION=2.1.0");
+
+    InsertTestStrings(10, false);
+    InsertTestBatch(11, 20, 9);
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectionProtocolVersion_2_1_5)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache;PROTOCOL_VERSION=2.1.5");
+
+    InsertTestStrings(10, false);
+    InsertTestBatch(11, 20, 9);
 }
 
 BOOST_AUTO_TEST_CASE(TestTwoRowsInt8)
@@ -2119,7 +2133,7 @@ BOOST_AUTO_TEST_CASE(TestErrorMessage)
     BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
 
     std::string error = GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt);
-    std::string pattern = "HY000: Table \"B\" not found; SQL statement:\\vSELECT a FROM B.*";
+    std::string pattern = "42000: Table \"B\" not found; SQL statement:\\vSELECT a FROM B.*";
 
     boost::cmatch what;
     if (!boost::regex_match(error.c_str(), what, boost::regex(pattern)))

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/include/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/Makefile.am b/modules/platforms/cpp/odbc/include/Makefile.am
index 92c85c5..7c64754 100644
--- a/modules/platforms/cpp/odbc/include/Makefile.am
+++ b/modules/platforms/cpp/odbc/include/Makefile.am
@@ -51,6 +51,7 @@ noinst_HEADERS = \
     ignite/odbc/diagnostic/diagnosable.h \
     ignite/odbc/diagnostic/diagnosable_adapter.h \
     ignite/odbc/connection.h \
+    ignite/odbc/odbc_error.h \
     ignite/odbc/message.h \
     ignite/odbc/cursor.h \
     ignite/odbc/common_types.h \

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/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 0a3b02f..349147f 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
@@ -77,12 +77,42 @@ namespace ignite
                  */
                 S01S02_OPTION_VALUE_CHANGED,
 
+                /** Restricted data type attribute violation. */
+                S07006_RESTRICTION_VIOLATION,
+
                 /** String data, length mismatch. */
                 S22026_DATA_LENGTH_MISMATCH,
 
+                /** Integrity constraint violation. */
+                S23000_INTEGRITY_CONSTRAINT_VIOLATION,
+
                 /** Invalid cursor state. */
                 S24000_INVALID_CURSOR_STATE,
 
+                /** Invalid schema name. */
+                S3F000_INVALID_SCHEMA_NAME,
+
+                /** Syntax error or access violation. */
+                S42000_SYNTAX_ERROR_OR_ACCESS_VIOLATION,
+
+                /** Base table or view already exists. */
+                S42S01_TABLE_OR_VIEW_ALREADY_EXISTS,
+
+                /** Base table or view not found. */
+                S42S02_TABLE_OR_VIEW_NOT_FOUND,
+
+                /** Index already exists. */
+                S42S11_INDEX_ALREADY_EXISTS,
+
+                /** Index not found. */
+                S42S12_INDEX_NOT_FOUND,
+
+                /** Column already exists. */
+                S42S21_COLUMN_ALREADY_EXISTS,
+
+                /** Column not found. */
+                S42S22_COLUMN_NOT_FOUND,
+
                 /** Invalid descriptor index. */
                 S07009_INVALID_DESCRIPTOR_INDEX,
 
@@ -102,6 +132,12 @@ namespace ignite
                 /** The connection specified was not open. */
                 S08003_NOT_CONNECTED,
 
+                /** Server rejected the connection. */
+                S08004_CONNECTION_REJECTED,
+
+                /** Communication link failure. */
+                S08S01_LINK_FAILURE,
+
                 /**
                  * An error occurred for which there was no specific SQLSTATE
                  * and for which no implementation-specific SQLSTATE was defined.
@@ -120,6 +156,9 @@ namespace ignite
                  */
                 SHY003_INVALID_APPLICATION_BUFFER_TYPE,
 
+                /** Invalid SQL data type. */
+                SHY004_INVALID_SQL_DATA_TYPE,
+
                 /** Invalid use of null pointer. */
                 SHY009_INVALID_USE_OF_NULL_POINTER,
 
@@ -155,7 +194,7 @@ namespace ignite
                  * The connection timeout period expired before the data source
                  * responded to the request.
                  */
-                SHYT01_CONNECTIOIN_TIMEOUT,
+                SHYT01_CONNECTION_TIMEOUT,
 
                 /**
                  * Driver does not support this function.
@@ -245,6 +284,88 @@ namespace ignite
             };
         };
 
+        struct ResponseStatus
+        {
+            enum Type
+            {
+                /** Operation completed successfully. */
+                SUCCESS = 0,
+
+                /* 1xxx - parsing errors */
+
+                /** Unknown error, or the one without specific code. */
+                UNKNOWN_ERROR = 1,
+
+                /** General parsing error - for the cases when there's no more specific code available. */
+                PARSING_FAILURE = 1001,
+
+                /** Requested operation is not supported. */
+                UNSUPPORTED_OPERATION = 1002,
+
+                /* 2xxx - analysis errors */
+
+                /** Code encountered SQL statement of some type that it did not expect in current analysis context. */
+                UNEXPECTED_OPERATION = 2001,
+
+                /** Code encountered SQL expression of some type that it did not expect in current analysis context. */
+                UNEXPECTED_ELEMENT_TYPE = 2002,
+
+                /** Analysis detected that the statement is trying to directly UPDATE key or its fields. */
+                KEY_UPDATE = 2003,
+
+                /* 3xxx - database API related runtime errors */
+                /** Required table not found. */
+                TABLE_NOT_FOUND = 3001,
+
+                /** Required table does not have a descriptor set. */
+                NULL_TABLE_DESCRIPTOR = 3002,
+
+                /** Statement type does not match that declared by JDBC driver. */
+                STMT_TYPE_MISMATCH = 3003,
+
+                /** DROP TABLE failed. */
+                TABLE_DROP_FAILED = 3004,
+
+                /** Index already exists. */
+                INDEX_ALREADY_EXISTS = 3005,
+
+                /** Index does not exist. */
+                INDEX_NOT_FOUND = 3006,
+
+                /** Required table already exists. */
+                TABLE_ALREADY_EXISTS = 3007,
+
+                /** Required column not found. */
+                COLUMN_NOT_FOUND = 3008,
+
+                /** Required column already exists. */
+                COLUMN_ALREADY_EXISTS = 3009,
+
+                /** Conversion failure. */
+                CONVERSION_FAILED = 3013,
+
+                /* 4xxx - cache related runtime errors */
+
+                /** Attempt to INSERT a key that is already in cache. */
+                DUPLICATE_KEY = 4001,
+
+                /** Attempt to UPDATE or DELETE a key whose value has been updated concurrently by someone else. */
+                CONCURRENT_UPDATE = 4002,
+
+                /** Attempt to INSERT or MERGE {@code null} key. */
+                NULL_KEY = 4003,
+
+                /** Attempt to INSERT or MERGE {@code null} value. */
+                NULL_VALUE = 4004,
+
+                /** EntryProcessor has thrown an exception during IgniteCache::invokeAll. */
+                ENTRY_PROCESSING = 4005,
+
+                /** Cache not found. */
+                CACHE_NOT_FOUND = 4006
+            };
+        };
+
         /**
          * Convert internal Ignite type into ODBC SQL return code.
          *
@@ -269,7 +390,13 @@ namespace ignite
          */
         EnvironmentAttribute::Type EnvironmentAttributeToInternal(int32_t attr);
 
-
+        /**
+         * Convert request response status to SQL state.
+         *
+         * @param status Response status.
+         * @return SQL state.
+         */
+        SqlState::Type ResponseStatusToSqlState(int32_t status);
     }
 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
index 2ec1b5b..46d79ce 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
@@ -24,6 +24,8 @@ namespace ignite
 {
     namespace odbc
     {
+        class OdbcError;
+
         namespace diagnostic
         {
             /**
@@ -73,6 +75,13 @@ namespace ignite
                  */
                 virtual void AddStatusRecord(SqlState::Type sqlState, const std::string& message) = 0;
 
+                /**
+                 * Add new status record.
+                 *
+                 * @param err Error.
+                 */
+                virtual void AddStatusRecord(const OdbcError& err) = 0;
+
             protected:
                 /**
                  * Default constructor.

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
index 45f47f0..461bfc9 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
@@ -33,6 +33,7 @@ namespace ignite
 {
     namespace odbc
     {
+        class OdbcError;
         class Connection;
 
         namespace diagnostic
@@ -90,6 +91,13 @@ namespace ignite
                  */
                 virtual void AddStatusRecord(SqlState::Type  sqlState, const std::string& message);
 
+                /**
+                 * Add new status record.
+                 *
+                 * @param err Error.
+                 */
+                virtual void AddStatusRecord(const OdbcError& err);
+
             protected:
                 /**
                  * Constructor.

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/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 fd7897f..91a808c 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
@@ -64,16 +64,6 @@ namespace ignite
             };
         };
 
-        struct ResponseStatus
-        {
-            enum Type
-            {
-                SUCCESS = 0,
-
-                FAILED = 1
-            };
-        };
-
         /**
          * Handshake request.
          */
@@ -411,14 +401,15 @@ namespace ignite
             /**
              * Read response using provided reader.
              * @param reader Reader.
+             * @param ver Protocol version.
              */
-            void Read(impl::binary::BinaryReaderImpl& reader);
+            void Read(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion& ver);
 
             /**
              * Get request processing status.
              * @return Status.
              */
-            int8_t GetStatus() const
+            int32_t GetStatus() const
             {
                 return status;
             }
@@ -436,11 +427,11 @@ namespace ignite
             /**
              * Read data if response status is ResponseStatus::SUCCESS.
              */
-            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl&);
+            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl&, const ProtocolVersion&);
 
         private:
             /** Request processing status. */
-            int8_t status;
+            int32_t status;
 
             /** Error message. */
             std::string error;
@@ -493,7 +484,7 @@ namespace ignite
              * Read response using provided reader.
              * @param reader Reader.
              */
-            void Read(impl::binary::BinaryReaderImpl& reader);
+            void Read(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&);
 
         private:
             /** Handshake accepted. */
@@ -536,7 +527,7 @@ namespace ignite
              * Read response using provided reader.
              * @param reader Reader.
              */
-            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader);
+            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&);
 
             /** Query ID. */
             int64_t queryId;
@@ -590,7 +581,7 @@ namespace ignite
              * Read response using provided reader.
              * @param reader Reader.
              */
-            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader);
+            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&);
 
             /** Query ID. */
             int64_t queryId;
@@ -645,12 +636,22 @@ namespace ignite
                 return errorMessage;
             }
 
+            /**
+             * Get error code.
+             * @return Error code.
+             */
+            int32_t GetErrorCode() const
+            {
+                return errorCode;
+            }
+
         private:
             /**
              * Read response using provided reader.
              * @param reader Reader.
+             * @param ver Protocol version.
              */
-            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader);
+            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion& ver);
 
             /** Affected rows. */
             int64_t affectedRows;
@@ -660,6 +661,9 @@ namespace ignite
 
             /** Error message. */
             std::string errorMessage;
+
+            /** Error code. */
+            int32_t errorCode;
         };
 
         /**
@@ -693,7 +697,7 @@ namespace ignite
              * Read response using provided reader.
              * @param reader Reader.
              */
-            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader);
+            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&);
 
             /** Query ID. */
             int64_t queryId;
@@ -732,7 +736,7 @@ namespace ignite
              * Read response using provided reader.
              * @param reader Reader.
              */
-            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader);
+            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&);
 
             /** Columns metadata. */
             meta::ColumnMetaVector meta;
@@ -768,7 +772,7 @@ namespace ignite
              * Read response using provided reader.
              * @param reader Reader.
              */
-            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader);
+            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&);
 
             /** Columns metadata. */
             meta::TableMetaVector meta;
@@ -804,7 +808,7 @@ namespace ignite
              * Read response using provided reader.
              * @param reader Reader.
              */
-            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader);
+            virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&);
 
             /** Columns metadata. */
             std::vector<int8_t> typeIds;

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/include/ignite/odbc/odbc_error.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/odbc_error.h b/modules/platforms/cpp/odbc/include/ignite/odbc/odbc_error.h
new file mode 100644
index 0000000..361b2b5
--- /dev/null
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/odbc_error.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_ODBC_ODBC_ERROR
+#define _IGNITE_ODBC_ODBC_ERROR
+
+#include <string>
+
+#include "ignite/odbc/common_types.h"
+
+namespace ignite
+{
+    namespace odbc
+    {
+        /**
+         * ODBC error.
+         */
+        class OdbcError
+        {
+        public:
+            /**
+             * Constructor.
+             *
+             * @param status SQL status.
+             * @param message Error message.
+             */
+            OdbcError(SqlState::Type status, const std::string& message) :
+                status(status),
+                errMessage(message)
+            {
+                // No-op.
+            }
+
+            /**
+             * Default constructor.
+             */
+            OdbcError() :
+                status(SqlState::UNKNOWN),
+                errMessage()
+            {
+                // No-op.
+            }
+
+            /**
+             * Destructor.
+             */
+            ~OdbcError()
+            {
+                // No-op.
+            }
+
+            /**
+             * Get status.
+             * @return Status.
+             */
+            SqlState::Type GetStatus() const
+            {
+                return status;
+            }
+
+            /**
+             * Get error message.
+             * @return Error message.
+             */
+            const std::string& GetErrorMessage() const
+            {
+                return errMessage;
+            }
+
+        private:
+            /** Status. */
+            SqlState::Type status;
+
+            /** Error message. */
+            std::string errMessage;
+        };
+    }
+}
+
+#endif //_IGNITE_ODBC_ODBC_ERROR
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/include/ignite/odbc/parser.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/parser.h b/modules/platforms/cpp/odbc/include/ignite/odbc/parser.h
index a91af22..bfea67c 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/parser.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/parser.h
@@ -28,6 +28,7 @@
 #include <ignite/impl/binary/binary_reader_impl.h>
 
 #include "ignite/odbc/utility.h"
+#include "ignite/odbc/protocol_version.h"
 
 namespace ignite
 {
@@ -44,8 +45,13 @@ namespace ignite
 
             /**
              * Constructor.
+             * @param cap Initial capasity.
              */
-            Parser(int32_t cap = DEFAULT_MEM_ALLOCATION) : inMem(cap), outMem(cap), outStream(&outMem)
+            Parser(int32_t cap = DEFAULT_MEM_ALLOCATION) :
+                protocolVer(ProtocolVersion::GetCurrent()),
+                inMem(cap),
+                outMem(cap),
+                outStream(&outMem)
             {
                 //No-op.
             }
@@ -67,7 +73,7 @@ namespace ignite
             template<typename MsgT>
             void Encode(const MsgT& msg, std::vector<int8_t>& buf)
             {
-                using namespace ignite::impl::binary;
+                using namespace impl::binary;
 
                 ResetState();
 
@@ -90,7 +96,7 @@ namespace ignite
             template<typename MsgT>
             void Decode(MsgT& msg, const std::vector<int8_t>& buf)
             {
-                using namespace ignite::impl::binary;
+                using namespace impl::binary;
 
                 if (inMem.Capacity() < static_cast<int32_t>(buf.size()))
                     inMem.Reallocate(static_cast<int32_t>(buf.size()));
@@ -99,11 +105,21 @@ namespace ignite
 
                 inMem.Length(static_cast<int32_t>(buf.size()));
 
-                ignite::impl::interop::InteropInputStream inStream(&inMem);
+                impl::interop::InteropInputStream inStream(&inMem);
 
                 BinaryReaderImpl reader(&inStream);
 
-                msg.Read(reader);
+                msg.Read(reader, protocolVer);
+            }
+
+            /**
+             * Set protocol version.
+             *
+             * @param ver Version to set.
+             */
+            void SetProtocolVersion(const ProtocolVersion& ver)
+            {
+                protocolVer = ver;
             }
 
         private:
@@ -119,14 +135,17 @@ namespace ignite
                 outStream.Position(0);
             }
 
+            /** Protocol version. */
+            ProtocolVersion protocolVer;
+
             /** Input operational memory. */
-            ignite::impl::interop::InteropUnpooledMemory inMem;
+            impl::interop::InteropUnpooledMemory inMem;
 
             /** Output operational memory. */
-            ignite::impl::interop::InteropUnpooledMemory outMem;
+            impl::interop::InteropUnpooledMemory outMem;
 
             /** Output stream. */
-            ignite::impl::interop::InteropOutputStream outStream;
+            impl::interop::InteropOutputStream outStream;
         };
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
index e47f618..c5783ff 100644
--- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
+++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
@@ -217,6 +217,7 @@
     <ClInclude Include="..\..\include\ignite\odbc\meta\column_meta.h" />
     <ClInclude Include="..\..\include\ignite\odbc\meta\primary_key_meta.h" />
     <ClInclude Include="..\..\include\ignite\odbc\meta\table_meta.h" />
+    <ClInclude Include="..\..\include\ignite\odbc\odbc_error.h" />
     <ClInclude Include="..\..\include\ignite\odbc\parser.h" />
     <ClInclude Include="..\..\include\ignite\odbc\protocol_version.h" />
     <ClInclude Include="..\..\include\ignite\odbc\query\batch_query.h" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
index e252d5d..8934625 100644
--- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
+++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
@@ -281,5 +281,8 @@
     <ClInclude Include="..\..\include\ignite\odbc\query\batch_query.h">
       <Filter>Code\query</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\include\ignite\odbc\odbc_error.h">
+      <Filter>Code</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/src/common_types.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/common_types.cpp b/modules/platforms/cpp/odbc/src/common_types.cpp
index 09ea3dc..10c4f77 100644
--- a/modules/platforms/cpp/odbc/src/common_types.cpp
+++ b/modules/platforms/cpp/odbc/src/common_types.cpp
@@ -118,6 +118,57 @@ namespace ignite
 
             return EnvironmentAttribute::UNKNOWN;
         }
+
+        SqlState::Type ResponseStatusToSqlState(int32_t status)
+        {
+            switch (status)
+            {
+                case ResponseStatus::PARSING_FAILURE:
+                case ResponseStatus::KEY_UPDATE:
+                case ResponseStatus::UNEXPECTED_OPERATION:
+                    return SqlState::S42000_SYNTAX_ERROR_OR_ACCESS_VIOLATION;
+
+                case ResponseStatus::UNSUPPORTED_OPERATION:
+                    return SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED;
+
+                case ResponseStatus::UNEXPECTED_ELEMENT_TYPE:
+                    return SqlState::SHY004_INVALID_SQL_DATA_TYPE;
+
+                case ResponseStatus::DUPLICATE_KEY:
+                case ResponseStatus::NULL_KEY:
+                case ResponseStatus::NULL_VALUE:
+                    return SqlState::S23000_INTEGRITY_CONSTRAINT_VIOLATION;
+
+                case ResponseStatus::TABLE_NOT_FOUND:
+                    return SqlState::S42S02_TABLE_OR_VIEW_NOT_FOUND;
+
+                case ResponseStatus::INDEX_ALREADY_EXISTS:
+                    return SqlState::S42S11_INDEX_ALREADY_EXISTS;
+
+                case ResponseStatus::INDEX_NOT_FOUND:
+                    return SqlState::S42S12_INDEX_NOT_FOUND;
+
+                case ResponseStatus::TABLE_ALREADY_EXISTS:
+                    return SqlState::S42S01_TABLE_OR_VIEW_ALREADY_EXISTS;
+
+                case ResponseStatus::COLUMN_NOT_FOUND:
+                    return SqlState::S42S22_COLUMN_NOT_FOUND;
+
+                case ResponseStatus::COLUMN_ALREADY_EXISTS:
+                    return SqlState::S42S21_COLUMN_ALREADY_EXISTS;
+
+                case ResponseStatus::CACHE_NOT_FOUND:
+                case ResponseStatus::NULL_TABLE_DESCRIPTOR:
+                case ResponseStatus::CONVERSION_FAILED:
+                case ResponseStatus::CONCURRENT_UPDATE:
+                case ResponseStatus::ENTRY_PROCESSING:
+                case ResponseStatus::TABLE_DROP_FAILED:
+                case ResponseStatus::STMT_TYPE_MISMATCH:
+                case ResponseStatus::UNKNOWN_ERROR:
+                default:
+                    return SqlState::SHY000_GENERAL_ERROR;
+            }
+        }
     }
 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/src/connection.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/connection.cpp b/modules/platforms/cpp/odbc/src/connection.cpp
index 777973a..161e1c4 100644
--- a/modules/platforms/cpp/odbc/src/connection.cpp
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -27,6 +27,7 @@
 #include "ignite/odbc/connection.h"
 #include "ignite/odbc/message.h"
 #include "ignite/odbc/config/configuration.h"
+#include "ignite/odbc/odbc_error.h"
 
 namespace
 {
@@ -138,6 +139,8 @@ namespace ignite
 
             if (res == SqlResult::AI_ERROR)
                 Close();
+            else
+                parser.SetProtocolVersion(config.GetProtocolVersion());
 
             return res;
         }
@@ -194,7 +197,7 @@ namespace ignite
         void Connection::Send(const int8_t* data, size_t len)
         {
             if (!connected)
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_ILLEGAL_STATE, "Connection is not established");
+                throw OdbcError(SqlState::S08003_NOT_CONNECTED, "Connection is not established");
 
             int32_t newLen = static_cast<int32_t>(len + sizeof(OdbcProtocolHeader));
 
@@ -209,7 +212,7 @@ namespace ignite
             size_t sent = SendAll(msg.GetData(), msg.GetSize());
 
             if (sent != len + sizeof(OdbcProtocolHeader))
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Can not send message");
+                throw OdbcError(SqlState::S08S01_LINK_FAILURE, "Can not send message due to connection failure");
 
             LOG_MSG("message sent: (" <<  msg.GetSize() << " bytes)" << utility::HexDump(msg.GetData(), msg.GetSize()));
         }
@@ -240,7 +243,7 @@ namespace ignite
         void Connection::Receive(std::vector<int8_t>& msg)
         {
             if (!connected)
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_ILLEGAL_STATE, "Connection is not established");
+                throw OdbcError(SqlState::S08003_NOT_CONNECTED, "Connection is not established");
 
             msg.clear();
 
@@ -249,13 +252,13 @@ namespace ignite
             size_t received = ReceiveAll(reinterpret_cast<int8_t*>(&hdr), sizeof(hdr));
 
             if (received != sizeof(hdr))
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Can not receive message header");
+                throw OdbcError(SqlState::S08S01_LINK_FAILURE, "Can not receive message header");
 
             if (hdr.len < 0)
             {
                 Close();
 
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Message length is negative");
+                throw OdbcError(SqlState::S08S01_LINK_FAILURE, "Protocol error: Message length is negative");
             }
 
             if (hdr.len == 0)
@@ -269,7 +272,7 @@ namespace ignite
             {
                 msg.resize(received);
 
-                IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Can not receive message body");
+                throw OdbcError(SqlState::S08S01_LINK_FAILURE, "Can not receive message body");
             }
 
             LOG_MSG("Message received: " << utility::HexDump(&msg[0], msg.size()));
@@ -447,9 +450,15 @@ namespace ignite
             {
                 SyncMessage(req, rsp);
             }
+            catch (const OdbcError& err)
+            {
+                AddStatusRecord(err);
+
+                return SqlResult::AI_ERROR;
+            }
             catch (const IgniteError& err)
             {
-                AddStatusRecord(SqlState::SHYT01_CONNECTIOIN_TIMEOUT, err.GetText());
+                AddStatusRecord(SqlState::S08004_CONNECTION_REJECTED, err.GetText());
 
                 return SqlResult::AI_ERROR;
             }
@@ -469,7 +478,7 @@ namespace ignite
                             << "driver protocol version introduced in version: "
                             << config.GetProtocolVersion().ToString() << ".";
 
-                AddStatusRecord(SqlState::S08001_CANNOT_CONNECT, constructor.str());
+                AddStatusRecord(SqlState::S08004_CONNECTION_REJECTED, constructor.str());
 
                 return SqlResult::AI_ERROR;
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp b/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
index 6c07c29..096593f 100644
--- a/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
@@ -17,6 +17,7 @@
 
 #include "ignite/odbc/log.h"
 #include "ignite/odbc/connection.h"
+#include "ignite/odbc/odbc_error.h"
 #include "ignite/odbc/diagnostic/diagnosable_adapter.h"
 
 namespace ignite
@@ -46,6 +47,13 @@ namespace ignite
 
                 AddStatusRecord(sqlState, message, 0, 0);
             }
+
+            void DiagnosableAdapter::AddStatusRecord(const OdbcError& err)
+            {
+                LOG_MSG("Adding new record: " << err.GetErrorMessage());
+
+                AddStatusRecord(err.GetStatus(), err.GetErrorMessage(), 0, 0);
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
index c8e0e81..0a02310 100644
--- a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
@@ -40,15 +40,15 @@ namespace
     /** SQL state 01S01 constant. */
     const std::string STATE_01S01 = "01S01";
 
-    /** SQL state 22026 constant. */
-    const std::string STATE_22026 = "22026";
-
-    /** SQL state 24000 constant. */
-    const std::string STATE_24000 = "24000";
+    /** SQL state 01S02 constant. */
+    const std::string STATE_01S02 = "01S02";
 
     /** SQL state 07009 constant. */
     const std::string STATE_07009 = "07009";
 
+    /** SQL state 07006 constant. */
+    const std::string STATE_07006 = "07006";
+
     /** SQL state 08001 constant. */
     const std::string STATE_08001 = "08001";
 
@@ -58,6 +58,45 @@ namespace
     /** SQL state 08003 constant. */
     const std::string STATE_08003 = "08003";
 
+    /** SQL state 08004 constant. */
+    const std::string STATE_08004 = "08004";
+
+    /** SQL state 08S01 constant. */
+    const std::string STATE_08S01 = "08S01";
+
+    /** SQL state 22026 constant. */
+    const std::string STATE_22026 = "22026";
+
+    /** SQL state 23000 constant. */
+    const std::string STATE_23000 = "23000";
+
+    /** SQL state 24000 constant. */
+    const std::string STATE_24000 = "24000";
+
+    /** SQL state 3F000 constant. */
+    const std::string STATE_3F000 = "3F000";
+
+    /** SQL state 42000 constant. */
+    const std::string STATE_42000 = "42000";
+
+    /** SQL state 42S01 constant. */
+    const std::string STATE_42S01 = "42S01";
+
+    /** SQL state 42S02 constant. */
+    const std::string STATE_42S02 = "42S02";
+
+    /** SQL state 42S11 constant. */
+    const std::string STATE_42S11 = "42S11";
+
+    /** SQL state 42S12 constant. */
+    const std::string STATE_42S12 = "42S12";
+
+    /** SQL state 42S21 constant. */
+    const std::string STATE_42S21 = "42S21";
+
+    /** SQL state 42S22 constant. */
+    const std::string STATE_42S22 = "42S22";
+
     /** SQL state HY000 constant. */
     const std::string STATE_HY000 = "HY000";
 
@@ -67,15 +106,24 @@ namespace
     /** SQL state HY003 constant. */
     const std::string STATE_HY003 = "HY003";
 
+    /** SQL state HY004 constant. */
+    const std::string STATE_HY004 = "HY004";
+
     /** SQL state HY009 constant. */
     const std::string STATE_HY009 = "HY009";
 
     /** SQL state HY010 constant. */
     const std::string STATE_HY010 = "HY010";
 
+    /** SQL state HY090 constant. */
+    const std::string STATE_HY090 = "HY090";
+
     /** SQL state HY092 constant. */
     const std::string STATE_HY092 = "HY092";
 
+    /** SQL state HY097 constant. */
+    const std::string STATE_HY097 = "HY097";
+
     /** SQL state HY105 constant. */
     const std::string STATE_HY105 = "HY105";
 
@@ -88,9 +136,6 @@ namespace
     /** SQL state HYT01 constant. */
     const std::string STATE_HYT01 = "HYT01";
 
-    /** SQL state HY090 constant. */
-    const std::string STATE_HY090 = "HY090";
-
     /** SQL state IM001 constant. */
     const std::string STATE_IM001 = "IM001";
 }
@@ -230,12 +275,45 @@ namespace ignite
                     case SqlState::S01S01_ERROR_IN_ROW:
                         return STATE_01S01;
 
+                    case SqlState::S01S02_OPTION_VALUE_CHANGED:
+                        return STATE_01S02;
+
+                    case SqlState::S07006_RESTRICTION_VIOLATION:
+                        return STATE_07006;
+
                     case SqlState::S22026_DATA_LENGTH_MISMATCH:
                         return STATE_22026;
 
+                    case SqlState::S23000_INTEGRITY_CONSTRAINT_VIOLATION:
+                        return STATE_23000;
+
                     case SqlState::S24000_INVALID_CURSOR_STATE:
                         return STATE_24000;
 
+                    case SqlState::S3F000_INVALID_SCHEMA_NAME:
+                        return STATE_3F000;
+
+                    case SqlState::S42000_SYNTAX_ERROR_OR_ACCESS_VIOLATION:
+                        return STATE_42000;
+
+                    case SqlState::S42S01_TABLE_OR_VIEW_ALREADY_EXISTS:
+                        return STATE_42S01;
+
+                    case SqlState::S42S02_TABLE_OR_VIEW_NOT_FOUND:
+                        return STATE_42S02;
+
+                    case SqlState::S42S11_INDEX_ALREADY_EXISTS:
+                        return STATE_42S11;
+
+                    case SqlState::S42S12_INDEX_NOT_FOUND:
+                        return STATE_42S12;
+
+                    case SqlState::S42S21_COLUMN_ALREADY_EXISTS:
+                        return STATE_42S21;
+
+                    case SqlState::S42S22_COLUMN_NOT_FOUND:
+                        return STATE_42S22;
+
                     case SqlState::S07009_INVALID_DESCRIPTOR_INDEX:
                         return STATE_07009;
 
@@ -248,6 +326,12 @@ namespace ignite
                     case SqlState::S08003_NOT_CONNECTED:
                         return STATE_08003;
 
+                    case SqlState::S08004_CONNECTION_REJECTED:
+                        return STATE_08004;
+
+                    case SqlState::S08S01_LINK_FAILURE:
+                        return STATE_08S01;
+
                     case SqlState::SHY000_GENERAL_ERROR:
                         return STATE_HY000;
 
@@ -269,6 +353,9 @@ namespace ignite
                     case SqlState::SHY092_OPTION_TYPE_OUT_OF_RANGE:
                         return STATE_HY092;
 
+                    case SqlState::SHY097_COLUMN_TYPE_OUT_OF_RANGE:
+                        return STATE_HY097;
+
                     case SqlState::SHY105_INVALID_PARAMETER_TYPE:
                         return STATE_HY105;
 
@@ -278,7 +365,7 @@ namespace ignite
                     case SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED:
                         return STATE_HYC00;
 
-                    case SqlState::SHYT01_CONNECTIOIN_TIMEOUT:
+                    case SqlState::SHYT01_CONNECTION_TIMEOUT:
                         return STATE_HYT01;
 
                     case SqlState::SIM001_FUNCTION_NOT_SUPPORTED:

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/src/message.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/message.cpp b/modules/platforms/cpp/odbc/src/message.cpp
index 9930290..3601591 100644
--- a/modules/platforms/cpp/odbc/src/message.cpp
+++ b/modules/platforms/cpp/odbc/src/message.cpp
@@ -206,7 +206,9 @@ namespace ignite
             writer.WriteObject<std::string>(sqlQuery);
         }
 
-        Response::Response(): status(ResponseStatus::FAILED), error()
+        Response::Response() :
+            status(ResponseStatus::UNKNOWN_ERROR),
+            error()
         {
             // No-op.
         }
@@ -216,17 +218,20 @@ namespace ignite
             // No-op.
         }
 
-        void Response::Read(impl::binary::BinaryReaderImpl& reader)
+        void Response::Read(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion& ver)
         {
-            status = reader.ReadInt8();
+            if (ver < ProtocolVersion::VERSION_2_1_5)
+                status = reader.ReadInt8();
+            else
+                status = reader.ReadInt32();
 
             if (status == ResponseStatus::SUCCESS)
-                ReadOnSuccess(reader);
+                ReadOnSuccess(reader, ver);
             else
                 utility::ReadString(reader, error);;
         }
 
-        void Response::ReadOnSuccess(impl::binary::BinaryReaderImpl&)
+        void Response::ReadOnSuccess(impl::binary::BinaryReaderImpl&, const ProtocolVersion&)
         {
             // No-op.
         }
@@ -244,7 +249,7 @@ namespace ignite
             // No-op.
         }
 
-        void HandshakeResponse::Read(impl::binary::BinaryReaderImpl& reader)
+        void HandshakeResponse::Read(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&)
         {
             accepted = reader.ReadBool();
 
@@ -270,7 +275,7 @@ namespace ignite
             // No-op.
         }
 
-        void QueryCloseResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader)
+        void QueryCloseResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&)
         {
             queryId = reader.ReadInt64();
         }
@@ -288,7 +293,7 @@ namespace ignite
             // No-op.
         }
 
-        void QueryExecuteResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader)
+        void QueryExecuteResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&)
         {
             queryId = reader.ReadInt64();
 
@@ -300,7 +305,8 @@ namespace ignite
         QueryExecuteBatchResponse::QueryExecuteBatchResponse():
             affectedRows(0),
             errorSetIdx(-1),
-            errorMessage()
+            errorMessage(),
+            errorCode(1)
         {
             // No-op.
         }
@@ -310,7 +316,7 @@ namespace ignite
             // No-op.
         }
 
-        void QueryExecuteBatchResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader)
+        void QueryExecuteBatchResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion& ver)
         {
             bool success = reader.ReadBool();
             affectedRows = reader.ReadInt64();
@@ -319,6 +325,9 @@ namespace ignite
             {
                 errorSetIdx = reader.ReadInt64();
                 errorMessage = reader.ReadObject<std::string>();
+
+                if (ver >= ProtocolVersion::VERSION_2_1_5)
+                    errorCode = reader.ReadInt32();
             }
         }
 
@@ -332,7 +341,7 @@ namespace ignite
             // No-op.
         }
 
-        void QueryFetchResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader)
+        void QueryFetchResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&)
         {
             queryId = reader.ReadInt64();
 
@@ -349,7 +358,7 @@ namespace ignite
             // No-op.
         }
 
-        void QueryGetColumnsMetaResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader)
+        void QueryGetColumnsMetaResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&)
         {
             meta::ReadColumnMetaVector(reader, meta);
         }
@@ -364,7 +373,7 @@ namespace ignite
             // No-op.
         }
 
-        void QueryGetTablesMetaResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader)
+        void QueryGetTablesMetaResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&)
         {
             meta::ReadTableMetaVector(reader, meta);
         }
@@ -379,7 +388,7 @@ namespace ignite
             // No-op.
         }
 
-        void QueryGetParamsMetaResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader)
+        void QueryGetParamsMetaResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader, const ProtocolVersion&)
         {
             utility::ReadByteArray(reader, typeIds);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/modules/platforms/cpp/odbc/src/query/batch_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/batch_query.cpp b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
index 46447c0..fc8fda4 100644
--- a/modules/platforms/cpp/odbc/src/query/batch_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
@@ -18,6 +18,7 @@
 #include "ignite/odbc/connection.h"
 #include "ignite/odbc/message.h"
 #include "ignite/odbc/log.h"
+#include "ignite/odbc/odbc_error.h"
 #include "ignite/odbc/query/batch_query.h"
 
 namespace ignite
@@ -160,9 +161,15 @@ namespace ignite
                 {
                     connection.SyncMessage(req, rsp);
                 }
+                catch (const OdbcError& err)
+                {
+                    diag.AddStatusRecord(err);
+
+                    return SqlResult::AI_ERROR;
+                }
                 catch (const IgniteError& err)
                 {
-                    diag.AddStatusRecord(SqlState::SHYT01_CONNECTIOIN_TIMEOUT, err.GetText());
+                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
 
                     return SqlResult::AI_ERROR;
                 }
@@ -171,7 +178,7 @@ namespace ignite
                 {
                     LOG_MSG("Error: " << rsp.GetError());
 
-                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, rsp.GetError());
+                    diag.AddStatusRecord(ResponseStatusToSqlState(rsp.GetStatus()), rsp.GetError());
 
                     return SqlResult::AI_ERROR;
                 }
@@ -186,7 +193,7 @@ namespace ignite
                     setsProcessed += rsp.GetErrorSetIdx();
                     LOG_MSG("setsProcessed: " << setsProcessed);
 
-                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, rsp.GetErrorMessage(),
+                    diag.AddStatusRecord(ResponseStatusToSqlState(rsp.GetErrorCode()), rsp.GetErrorMessage(),
                         static_cast<int32_t>(setsProcessed), 0);
 
                     return SqlResult::AI_SUCCESS_WITH_INFO;

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/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 b9c08f5..0910612 100644
--- a/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
@@ -21,6 +21,7 @@
 #include "ignite/odbc/connection.h"
 #include "ignite/odbc/message.h"
 #include "ignite/odbc/log.h"
+#include "ignite/odbc/odbc_error.h"
 #include "ignite/odbc/query/column_metadata_query.h"
 
 namespace
@@ -297,9 +298,15 @@ namespace ignite
                 {
                     connection.SyncMessage(req, rsp);
                 }
+                catch (const OdbcError& err)
+                {
+                    diag.AddStatusRecord(err);
+
+                    return SqlResult::AI_ERROR;
+                }
                 catch (const IgniteError& err)
                 {
-                    diag.AddStatusRecord(SqlState::SHYT01_CONNECTIOIN_TIMEOUT, err.GetText());
+                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
 
                     return SqlResult::AI_ERROR;
                 }
@@ -307,7 +314,7 @@ namespace ignite
                 if (rsp.GetStatus() != ResponseStatus::SUCCESS)
                 {
                     LOG_MSG("Error: " << rsp.GetError());
-                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, rsp.GetError());
+                    diag.AddStatusRecord(ResponseStatusToSqlState(rsp.GetStatus()), rsp.GetError());
 
                     return SqlResult::AI_ERROR;
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/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 245e0bd..80fcc69 100644
--- a/modules/platforms/cpp/odbc/src/query/data_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/data_query.cpp
@@ -18,6 +18,7 @@
 #include "ignite/odbc/connection.h"
 #include "ignite/odbc/message.h"
 #include "ignite/odbc/log.h"
+#include "ignite/odbc/odbc_error.h"
 #include "ignite/odbc/query/data_query.h"
 #include "ignite/odbc/query/batch_query.h"
 
@@ -193,9 +194,15 @@ namespace ignite
                 {
                     connection.SyncMessage(req, rsp);
                 }
+                catch (const OdbcError& err)
+                {
+                    diag.AddStatusRecord(err);
+
+                    return SqlResult::AI_ERROR;
+                }
                 catch (const IgniteError& err)
                 {
-                    diag.AddStatusRecord(SqlState::SHYT01_CONNECTIOIN_TIMEOUT, err.GetText());
+                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
 
                     return SqlResult::AI_ERROR;
                 }
@@ -204,7 +211,7 @@ namespace ignite
                 {
                     LOG_MSG("Error: " << rsp.GetError());
 
-                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, rsp.GetError());
+                    diag.AddStatusRecord(ResponseStatusToSqlState(rsp.GetStatus()), rsp.GetError());
 
                     return SqlResult::AI_ERROR;
                 }
@@ -241,9 +248,15 @@ namespace ignite
                 {
                     connection.SyncMessage(req, rsp);
                 }
+                catch (const OdbcError& err)
+                {
+                    diag.AddStatusRecord(err);
+
+                    return SqlResult::AI_ERROR;
+                }
                 catch (const IgniteError& err)
                 {
-                    diag.AddStatusRecord(SqlState::SHYT01_CONNECTIOIN_TIMEOUT, err.GetText());
+                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
 
                     return SqlResult::AI_ERROR;
                 }
@@ -254,7 +267,7 @@ namespace ignite
                 {
                     LOG_MSG("Error: " << rsp.GetError());
 
-                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, rsp.GetError());
+                    diag.AddStatusRecord(ResponseStatusToSqlState(rsp.GetStatus()), rsp.GetError());
 
                     return SqlResult::AI_ERROR;
                 }
@@ -273,9 +286,15 @@ namespace ignite
                 {
                     connection.SyncMessage(req, rsp);
                 }
+                catch (const OdbcError& err)
+                {
+                    diag.AddStatusRecord(err);
+
+                    return SqlResult::AI_ERROR;
+                }
                 catch (const IgniteError& err)
                 {
-                    diag.AddStatusRecord(SqlState::SHYT01_CONNECTIOIN_TIMEOUT, err.GetText());
+                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
 
                     return SqlResult::AI_ERROR;
                 }
@@ -284,7 +303,7 @@ namespace ignite
                 {
                     LOG_MSG("Error: " << rsp.GetError());
 
-                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, rsp.GetError());
+                    diag.AddStatusRecord(ResponseStatusToSqlState(rsp.GetStatus()), rsp.GetError());
 
                     return SqlResult::AI_ERROR;
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/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 e66b281..93f1f79 100644
--- a/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
@@ -21,6 +21,7 @@
 #include "ignite/odbc/connection.h"
 #include "ignite/odbc/message.h"
 #include "ignite/odbc/log.h"
+#include "ignite/odbc/odbc_error.h"
 #include "ignite/odbc/query/table_metadata_query.h"
 
 namespace
@@ -223,9 +224,15 @@ namespace ignite
                 {
                     connection.SyncMessage(req, rsp);
                 }
+                catch (const OdbcError& err)
+                {
+                    diag.AddStatusRecord(err);
+
+                    return SqlResult::AI_ERROR;
+                }
                 catch (const IgniteError& err)
                 {
-                    diag.AddStatusRecord(SqlState::SHYT01_CONNECTIOIN_TIMEOUT, err.GetText());
+                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
 
                     return SqlResult::AI_ERROR;
                 }
@@ -234,7 +241,7 @@ namespace ignite
                 {
                     LOG_MSG("Error: " << rsp.GetError());
 
-                    diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, rsp.GetError());
+                    diag.AddStatusRecord(ResponseStatusToSqlState(rsp.GetStatus()), rsp.GetError());
 
                     return SqlResult::AI_ERROR;
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/fc34091c/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 a74a413..36c1a0b 100644
--- a/modules/platforms/cpp/odbc/src/statement.cpp
+++ b/modules/platforms/cpp/odbc/src/statement.cpp
@@ -29,6 +29,7 @@
 #include "ignite/odbc/message.h"
 #include "ignite/odbc/statement.h"
 #include "ignite/odbc/log.h"
+#include "ignite/odbc/odbc_error.h"
 
 namespace ignite
 {
@@ -1104,9 +1105,15 @@ namespace ignite
             {
                 connection.SyncMessage(req, rsp);
             }
+            catch (const OdbcError& err)
+            {
+                AddStatusRecord(err);
+
+                return SqlResult::AI_ERROR;
+            }
             catch (const IgniteError& err)
             {
-                AddStatusRecord(SqlState::SHYT01_CONNECTIOIN_TIMEOUT, err.GetText());
+                AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
 
                 return SqlResult::AI_ERROR;
             }
@@ -1115,7 +1122,7 @@ namespace ignite
             {
                 LOG_MSG("Error: " << rsp.GetError());
 
-                AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, rsp.GetError());
+                AddStatusRecord(ResponseStatusToSqlState(rsp.GetStatus()), rsp.GetError());
 
                 return SqlResult::AI_ERROR;
             }


Mime
View raw message