You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/09/22 08:17:32 UTC
[11/19] ignite git commit: IGNITE-6294: ODBC: implemented SQLSTATE
management. This closes #2716.
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/4b4acd39
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4b4acd39
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4b4acd39
Branch: refs/heads/ignite-6181-2
Commit: 4b4acd39899bc02c6c4836e6848daed83b02dca6
Parents: ea0dcc4
Author: Igor Sapego <ig...@gmail.com>
Authored: Thu Sep 21 20:02:33 2017 +0300
Committer: devozerov <pp...@gmail.com>
Committed: Thu Sep 21 20:02:33 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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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/4b4acd39/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;
}