IGNITE-7855: ODBC: implemented streaming mode. This closes #4669.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4a2d867d Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4a2d867d Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4a2d867d Branch: refs/heads/ignite-gg-14206 Commit: 4a2d867d779c352f8968c5a48bf52834deb010f1 Parents: 8ad6805 Author: Igor Sapego <igors...@gmail.com> Authored: Thu Sep 27 11:25:48 2018 +0300 Committer: devozerov <voze...@gridgain.com> Committed: Thu Sep 27 11:25:48 2018 +0300 ---------------------------------------------------------------------- .../odbc/ClientListenerNioListener.java | 2 +- .../odbc/ClientListenerResponseSender.java | 29 + .../odbc/jdbc/JdbcConnectionContext.java | 3 +- .../odbc/jdbc/JdbcRequestHandler.java | 5 +- .../odbc/jdbc/JdbcResponseSender.java | 31 - .../odbc/odbc/OdbcConnectionContext.java | 33 +- .../processors/odbc/odbc/OdbcMessageParser.java | 32 + .../processors/odbc/odbc/OdbcQuery.java | 94 +++ .../processors/odbc/odbc/OdbcRequest.java | 25 +- .../odbc/odbc/OdbcRequestHandler.java | 321 +++++++--- .../odbc/odbc/OdbcStreamingBatchRequest.java | 102 ++++ .../odbc/odbc/OdbcStreamingBatchResult.java | 74 +++ .../processors/query/SqlClientContext.java | 2 +- .../ignite/impl/interop/interop_memory.h | 7 + .../binary/src/impl/interop/interop_memory.cpp | 5 + modules/platforms/cpp/common/Makefile.am | 2 +- .../platforms/cpp/common/include/Makefile.am | 1 + .../include/ignite/common/default_allocator.h | 6 - .../cpp/common/include/ignite/common/expected.h | 300 ++++++++++ .../cpp/common/include/ignite/common/utils.h | 9 + .../cpp/common/project/vs/common.vcxproj | 1 + .../common/project/vs/common.vcxproj.filters | 3 + .../cpp/core-test/src/teamcity_boost.cpp | 2 +- modules/platforms/cpp/odbc-test/Makefile.am | 10 +- .../cpp/odbc-test/include/odbc_test_suite.h | 2 +- .../cpp/odbc-test/include/test_utils.h | 10 +- .../cpp/odbc-test/project/vs/odbc-test.vcxproj | 14 +- .../project/vs/odbc-test.vcxproj.filters | 18 + .../cpp/odbc-test/src/api_robustness_test.cpp | 22 +- .../cpp/odbc-test/src/attributes_test.cpp | 13 +- .../cpp/odbc-test/src/authentication_test.cpp | 2 +- .../cpp/odbc-test/src/connection_test.cpp | 4 +- .../platforms/cpp/odbc-test/src/errors_test.cpp | 2 +- .../cpp/odbc-test/src/meta_queries_test.cpp | 4 +- .../cpp/odbc-test/src/queries_ssl_test.cpp | 2 +- .../cpp/odbc-test/src/queries_test.cpp | 4 +- .../cpp/odbc-test/src/sql_get_info_test.cpp | 2 +- .../cpp/odbc-test/src/sql_parsing_test.cpp | 372 ++++++++++++ .../odbc-test/src/sql_test_suite_fixture.cpp | 6 +- .../cpp/odbc-test/src/streaming_test.cpp | 589 +++++++++++++++++++ .../odbc-test/src/teamcity/teamcity_boost.cpp | 2 +- .../platforms/cpp/odbc-test/src/test_utils.cpp | 13 + .../platforms/cpp/odbc-test/src/types_test.cpp | 2 +- modules/platforms/cpp/odbc/Makefile.am | 7 + modules/platforms/cpp/odbc/include/Makefile.am | 10 + .../odbc/config/connection_string_parser.h | 4 +- .../cpp/odbc/include/ignite/odbc/connection.h | 52 +- .../cpp/odbc/include/ignite/odbc/message.h | 124 +++- .../cpp/odbc/include/ignite/odbc/odbc_error.h | 36 +- .../ignite/odbc/query/column_metadata_query.h | 2 +- .../ignite/odbc/query/foreign_keys_query.h | 2 +- .../include/ignite/odbc/query/internal_query.h | 189 ++++++ .../ignite/odbc/query/primary_keys_query.h | 2 +- .../cpp/odbc/include/ignite/odbc/query/query.h | 10 +- .../ignite/odbc/query/special_columns_query.h | 2 +- .../include/ignite/odbc/query/streaming_query.h | 151 +++++ .../ignite/odbc/query/table_metadata_query.h | 2 +- .../include/ignite/odbc/query/type_info_query.h | 2 +- .../odbc/include/ignite/odbc/sql/sql_command.h | 87 +++ .../odbc/include/ignite/odbc/sql/sql_lexer.h | 117 ++++ .../odbc/include/ignite/odbc/sql/sql_parser.h | 68 +++ .../ignite/odbc/sql/sql_set_streaming_command.h | 198 +++++++ .../odbc/include/ignite/odbc/sql/sql_token.h | 159 +++++ .../odbc/include/ignite/odbc/sql/sql_utils.h | 62 ++ .../cpp/odbc/include/ignite/odbc/statement.h | 30 + .../ignite/odbc/streaming/streaming_batch.h | 115 ++++ .../ignite/odbc/streaming/streaming_context.h | 136 +++++ .../src/system/ui/dsn_configuration_window.cpp | 19 +- .../platforms/cpp/odbc/project/vs/odbc.vcxproj | 17 + .../cpp/odbc/project/vs/odbc.vcxproj.filters | 57 ++ .../src/config/connection_string_parser.cpp | 4 +- modules/platforms/cpp/odbc/src/connection.cpp | 7 +- modules/platforms/cpp/odbc/src/message.cpp | 62 +- .../cpp/odbc/src/query/batch_query.cpp | 3 +- .../cpp/odbc/src/query/streaming_query.cpp | 93 +++ .../platforms/cpp/odbc/src/sql/sql_lexer.cpp | 236 ++++++++ .../platforms/cpp/odbc/src/sql/sql_parser.cpp | 97 +++ .../odbc/src/sql/sql_set_streaming_command.cpp | 200 +++++++ .../platforms/cpp/odbc/src/sql/sql_utils.cpp | 55 ++ modules/platforms/cpp/odbc/src/statement.cpp | 134 ++++- .../cpp/odbc/src/streaming/streaming_batch.cpp | 76 +++ .../odbc/src/streaming/streaming_context.cpp | 158 +++++ 82 files changed, 4749 insertions(+), 218 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java index c9670c6..0eb6ac4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java @@ -286,7 +286,7 @@ public class ClientListenerNioListener extends GridNioServerListenerAdapter<byte switch (clientType) { case ODBC_CLIENT: - return new OdbcConnectionContext(ctx, busyLock, connId, maxCursors); + return new OdbcConnectionContext(ctx, ses, busyLock, connId, maxCursors); case JDBC_CLIENT: return new JdbcConnectionContext(ctx, ses, busyLock, connId, maxCursors); http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerResponseSender.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerResponseSender.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerResponseSender.java new file mode 100644 index 0000000..dcb2d3f --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerResponseSender.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.odbc; + +/** + * Client listener response result sender. + */ +public interface ClientListenerResponseSender { + /** + * Send response to the client. Used for asynchronous result send. + * @param resp Client listener response. + */ + public void send(ClientListenerResponse resp); +} http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java index 5e9a1b3..c80136d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcConnectionContext.java @@ -29,6 +29,7 @@ import org.apache.ignite.internal.processors.odbc.ClientListenerMessageParser; import org.apache.ignite.internal.processors.odbc.ClientListenerProtocolVersion; import org.apache.ignite.internal.processors.odbc.ClientListenerRequestHandler; import org.apache.ignite.internal.processors.odbc.ClientListenerResponse; +import org.apache.ignite.internal.processors.odbc.ClientListenerResponseSender; import org.apache.ignite.internal.processors.query.NestedTxMode; import org.apache.ignite.internal.util.GridSpinBusyLock; import org.apache.ignite.internal.util.nio.GridNioSession; @@ -174,7 +175,7 @@ public class JdbcConnectionContext extends ClientListenerAbstractConnectionConte parser = new JdbcMessageParser(ctx, ver); - JdbcResponseSender sender = new JdbcResponseSender() { + ClientListenerResponseSender sender = new ClientListenerResponseSender() { @Override public void send(ClientListenerResponse resp) { if (resp != null) { if (log.isDebugEnabled()) http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java index 97ce20a..d59788c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java @@ -52,6 +52,7 @@ import org.apache.ignite.internal.processors.odbc.ClientListenerProtocolVersion; import org.apache.ignite.internal.processors.odbc.ClientListenerRequest; import org.apache.ignite.internal.processors.odbc.ClientListenerRequestHandler; import org.apache.ignite.internal.processors.odbc.ClientListenerResponse; +import org.apache.ignite.internal.processors.odbc.ClientListenerResponseSender; import org.apache.ignite.internal.processors.odbc.odbc.OdbcQueryGetColumnsMetaRequest; import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor; import org.apache.ignite.internal.processors.query.GridQueryProperty; @@ -127,7 +128,7 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler { private final Object orderedBatchesMux = new Object(); /** Response sender. */ - private final JdbcResponseSender sender; + private final ClientListenerResponseSender sender; /** Automatic close of cursors. */ private final boolean autoCloseCursors; @@ -158,7 +159,7 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler { * @param protocolVer Protocol version. */ public JdbcRequestHandler(GridKernalContext ctx, GridSpinBusyLock busyLock, - JdbcResponseSender sender, int maxCursors, + ClientListenerResponseSender sender, int maxCursors, boolean distributedJoins, boolean enforceJoinOrder, boolean collocated, boolean replicatedOnly, boolean autoCloseCursors, boolean lazy, boolean skipReducerOnUpdate, NestedTxMode nestedTxMode, AuthorizationContext actx, ClientListenerProtocolVersion protocolVer) { http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResponseSender.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResponseSender.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResponseSender.java deleted file mode 100644 index 128bcee..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResponseSender.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.odbc.jdbc; - -import org.apache.ignite.internal.processors.odbc.ClientListenerResponse; - -/** - * JDBC response result sender. - */ -public interface JdbcResponseSender { - /** - * Send response to the client. Used for asynchronous result send. - * @param resp JDBC response. - */ - public void send(ClientListenerResponse resp); -} http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/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 d82dcc6..5592aab 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 @@ -18,6 +18,7 @@ package org.apache.ignite.internal.processors.odbc.odbc; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.binary.BinaryReaderExImpl; import org.apache.ignite.internal.processors.authentication.AuthorizationContext; @@ -26,7 +27,10 @@ import org.apache.ignite.internal.processors.odbc.ClientListenerMessageParser; import org.apache.ignite.internal.processors.odbc.ClientListenerProtocolVersion; import org.apache.ignite.internal.processors.odbc.ClientListenerRequestHandler; import org.apache.ignite.internal.processors.query.NestedTxMode; +import org.apache.ignite.internal.processors.odbc.ClientListenerResponse; +import org.apache.ignite.internal.processors.odbc.ClientListenerResponseSender; import org.apache.ignite.internal.util.GridSpinBusyLock; +import org.apache.ignite.internal.util.nio.GridNioSession; import java.util.HashSet; import java.util.Set; @@ -59,6 +63,9 @@ public class OdbcConnectionContext extends ClientListenerAbstractConnectionConte /** Supported versions. */ private static final Set<ClientListenerProtocolVersion> SUPPORTED_VERS = new HashSet<>(); + /** Session. */ + private final GridNioSession ses; + /** Shutdown busy lock. */ private final GridSpinBusyLock busyLock; @@ -71,6 +78,9 @@ public class OdbcConnectionContext extends ClientListenerAbstractConnectionConte /** Request handler. */ private OdbcRequestHandler handler = null; + /** Logger. */ + private final IgniteLogger log; + static { SUPPORTED_VERS.add(CURRENT_VER); SUPPORTED_VERS.add(VER_2_5_0); @@ -83,15 +93,19 @@ public class OdbcConnectionContext extends ClientListenerAbstractConnectionConte /** * Constructor. * @param ctx Kernal Context. + * @param ses Session. * @param busyLock Shutdown busy lock. - * @param connId + * @param connId Connection ID. * @param maxCursors Maximum allowed cursors. */ - public OdbcConnectionContext(GridKernalContext ctx, GridSpinBusyLock busyLock, long connId, int maxCursors) { + public OdbcConnectionContext(GridKernalContext ctx, GridNioSession ses, GridSpinBusyLock busyLock, long connId, int maxCursors) { super(ctx, connId); + this.ses = ses; this.busyLock = busyLock; this.maxCursors = maxCursors; + + log = ctx.log(getClass()); } /** {@inheritDoc} */ @@ -140,7 +154,20 @@ public class OdbcConnectionContext extends ClientListenerAbstractConnectionConte AuthorizationContext actx = authenticate(user, passwd); - handler = new OdbcRequestHandler(ctx, busyLock, maxCursors, distributedJoins, enforceJoinOrder, + ClientListenerResponseSender sender = new ClientListenerResponseSender() { + @Override public void send(ClientListenerResponse resp) { + if (resp != null) { + if (log.isDebugEnabled()) + log.debug("Async response: [resp=" + resp.status() + ']'); + + byte[] outMsg = parser.encode(resp); + + ses.send(outMsg); + } + } + }; + + handler = new OdbcRequestHandler(ctx, busyLock, sender, maxCursors, distributedJoins, enforceJoinOrder, replicatedOnly, collocated, lazy, skipReducerOnUpdate, actx, nestedTxMode, ver); parser = new OdbcMessageParser(ctx, ver); http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/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 5b4cebb..0e9b48a 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 @@ -17,6 +17,7 @@ package org.apache.ignite.internal.processors.odbc.odbc; +import java.util.ArrayList; import java.util.Collection; import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteLogger; @@ -138,6 +139,30 @@ public class OdbcMessageParser implements ClientListenerMessageParser { break; } + case OdbcRequest.STREAMING_BATCH: + { + String schema = reader.readString(); + + int num = reader.readInt(); + + ArrayList<OdbcQuery> queries = new ArrayList<>(num); + + for (int i = 0; i < num; ++i) + { + OdbcQuery qry = new OdbcQuery(); + qry.readBinary(reader); + + queries.add(qry); + } + + boolean last = reader.readBoolean(); + long order = reader.readLong(); + + res = new OdbcStreamingBatchRequest(schema, queries, last, order); + + break; + } + case OdbcRequest.QRY_FETCH: { long queryId = reader.readLong(); int pageSize = reader.readInt(); @@ -278,6 +303,13 @@ public class OdbcMessageParser implements ClientListenerMessageParser { writer.writeInt(res.errorCode()); } } + else if (res0 instanceof OdbcStreamingBatchResult) { + OdbcStreamingBatchResult res = (OdbcStreamingBatchResult) res0; + + writer.writeString(res.error()); + writer.writeInt(res.status()); + writer.writeLong(res.order()); + } else if (res0 instanceof OdbcQueryFetchResult) { OdbcQueryFetchResult res = (OdbcQueryFetchResult) res0; http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQuery.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQuery.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQuery.java new file mode 100644 index 0000000..d89cc0d --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcQuery.java @@ -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. + */ + +package org.apache.ignite.internal.processors.odbc.odbc; + +import org.apache.ignite.internal.binary.BinaryReaderExImpl; +import org.apache.ignite.internal.binary.BinaryWriterExImpl; +import org.apache.ignite.internal.processors.odbc.SqlListenerUtils; +import org.apache.ignite.internal.util.typedef.internal.S; + +/** + * ODBC SQL query with parameters. + */ +public class OdbcQuery { + /** Query SQL. */ + private String sql; + + /** Arguments. */ + private Object[] args; + + /** + * Default constructor is used for serialization. + */ + public OdbcQuery() { + // No-op. + } + + /** + * @return Query SQL string. + */ + public String sql() { + return sql; + } + + /** + * @return Query arguments. + */ + public Object[] args() { + return args; + } + + /** + * Writes fields to provided writer. + * + * @param writer Binary object writer. + */ + public void writeBinary(BinaryWriterExImpl writer) { + writer.writeString(sql); + + if (args == null || args.length == 0) + writer.writeInt(0); + else { + writer.writeInt(args.length); + + for (Object arg : args) + SqlListenerUtils.writeObject(writer, arg, false); + } + } + + /** + * Reads fields from provided reader. + * + * @param reader Binary object reader. + */ + public void readBinary(BinaryReaderExImpl reader) { + sql = reader.readString(); + + int argsNum = reader.readInt(); + + args = new Object[argsNum]; + + for (int i = 0; i < argsNum; ++i) + args[i] = SqlListenerUtils.readObject(reader, false); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(OdbcQuery.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequest.java index 9b9aa01..5b02cfe 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequest.java @@ -24,43 +24,46 @@ import org.apache.ignite.internal.processors.odbc.ClientListenerRequestNoId; */ public class OdbcRequest extends ClientListenerRequestNoId { /** Execute sql query. */ - public static final int QRY_EXEC = 2; + public static final byte QRY_EXEC = 2; /** Fetch query results. */ - public static final int QRY_FETCH = 3; + public static final byte QRY_FETCH = 3; /** Close query. */ - public static final int QRY_CLOSE = 4; + public static final byte QRY_CLOSE = 4; /** Get columns meta query. */ - public static final int META_COLS = 5; + public static final byte META_COLS = 5; /** Get columns meta query. */ - public static final int META_TBLS = 6; + public static final byte META_TBLS = 6; /** Get parameters meta. */ - public static final int META_PARAMS = 7; + public static final byte META_PARAMS = 7; /** Execute sql query with the batch of parameters. */ - public static final int QRY_EXEC_BATCH = 8; + public static final byte QRY_EXEC_BATCH = 8; /** Get next result set. */ - public static final int MORE_RESULTS = 9; + public static final byte MORE_RESULTS = 9; + + /** Process ordered streaming batch. */ + public static final byte STREAMING_BATCH = 10; /** Command. */ - private final int cmd; + private final byte cmd; /** * @param cmd Command type. */ - public OdbcRequest(int cmd) { + public OdbcRequest(byte cmd) { this.cmd = cmd; } /** * @return Command. */ - public int command() { + public byte command() { return cmd; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/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 16baeb9..6f3324d 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 @@ -25,15 +25,18 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.PriorityQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import javax.cache.configuration.Factory; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.cache.query.FieldsQueryCursor; import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.IgniteInterruptedCheckedException; import org.apache.ignite.internal.binary.BinaryWriterExImpl; import org.apache.ignite.internal.binary.GridBinaryMarshaller; import org.apache.ignite.internal.processors.authentication.AuthorizationContext; @@ -44,16 +47,21 @@ import org.apache.ignite.internal.processors.odbc.ClientListenerProtocolVersion; import org.apache.ignite.internal.processors.odbc.ClientListenerRequest; import org.apache.ignite.internal.processors.odbc.ClientListenerRequestHandler; import org.apache.ignite.internal.processors.odbc.ClientListenerResponse; +import org.apache.ignite.internal.processors.odbc.ClientListenerResponseSender; import org.apache.ignite.internal.processors.odbc.odbc.escape.OdbcEscapeUtils; import org.apache.ignite.internal.processors.query.GridQueryProperty; import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; import org.apache.ignite.internal.processors.query.IgniteSQLException; import org.apache.ignite.internal.processors.query.NestedTxMode; +import org.apache.ignite.internal.processors.query.QueryUtils; +import org.apache.ignite.internal.processors.query.SqlClientContext; import org.apache.ignite.internal.util.GridSpinBusyLock; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.X; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.util.worker.GridWorker; +import org.apache.ignite.lang.IgniteBiTuple; import static org.apache.ignite.internal.processors.odbc.odbc.OdbcRequest.META_COLS; import static org.apache.ignite.internal.processors.odbc.odbc.OdbcRequest.META_PARAMS; @@ -63,6 +71,7 @@ import static org.apache.ignite.internal.processors.odbc.odbc.OdbcRequest.QRY_CL import static org.apache.ignite.internal.processors.odbc.odbc.OdbcRequest.QRY_EXEC; import static org.apache.ignite.internal.processors.odbc.odbc.OdbcRequest.QRY_EXEC_BATCH; import static org.apache.ignite.internal.processors.odbc.odbc.OdbcRequest.QRY_FETCH; +import static org.apache.ignite.internal.processors.odbc.odbc.OdbcRequest.STREAMING_BATCH; /** * SQL query handler. @@ -74,6 +83,9 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { /** Kernel context. */ private final GridKernalContext ctx; + /** Client context. */ + private final SqlClientContext cliCtx; + /** Logger. */ private final IgniteLogger log; @@ -89,37 +101,29 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { /** Current queries cursors. */ private final ConcurrentHashMap<Long, OdbcQueryResults> qryResults = new ConcurrentHashMap<>(); - /** Distributed joins flag. */ - private final boolean distributedJoins; - - /** Enforce join order flag. */ - private final boolean enforceJoinOrder; - - /** Replicated only flag. */ - private final boolean replicatedOnly; - /** Nested transaction behaviour. */ private final NestedTxMode nestedTxMode; - /** Collocated flag. */ - private final boolean collocated; - - /** Lazy flag. */ - private final boolean lazy; - - /** Update on server flag. */ - private final boolean skipReducerOnUpdate; - /** Authentication context */ private final AuthorizationContext actx; /** Client version. */ private ClientListenerProtocolVersion ver; + /** Ordered batches queue. */ + private final PriorityQueue<OdbcStreamingBatchRequest> orderedBatchesQueue = new PriorityQueue<>(); + + /** Ordered batches mutex. */ + private final Object orderedBatchesMux = new Object(); + + /** Response sender. */ + private final ClientListenerResponseSender sender; + /** * Constructor. * @param ctx Context. * @param busyLock Shutdown latch. + * @param sender Results sender. * @param maxCursors Maximum allowed cursors. * @param distributedJoins Distributed joins flag. * @param enforceJoinOrder Enforce join order flag. @@ -131,18 +135,40 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { * @param actx Authentication context. * @param ver Client protocol version. */ - public OdbcRequestHandler(GridKernalContext ctx, GridSpinBusyLock busyLock, int maxCursors, - boolean distributedJoins, boolean enforceJoinOrder, boolean replicatedOnly, boolean collocated, boolean lazy, - boolean skipReducerOnUpdate, AuthorizationContext actx, NestedTxMode nestedTxMode, ClientListenerProtocolVersion ver) { + public OdbcRequestHandler( + GridKernalContext ctx, + GridSpinBusyLock busyLock, + ClientListenerResponseSender sender, + int maxCursors, + boolean distributedJoins, + boolean enforceJoinOrder, + boolean replicatedOnly, + boolean collocated, + boolean lazy, + boolean skipReducerOnUpdate, + AuthorizationContext actx, NestedTxMode nestedTxMode, ClientListenerProtocolVersion ver) { this.ctx = ctx; + + Factory<GridWorker> orderedFactory = new Factory<GridWorker>() { + @Override public GridWorker create() { + return new OrderedBatchWorker(); + } + }; + + this.cliCtx = new SqlClientContext( + ctx, + orderedFactory, + distributedJoins, + enforceJoinOrder, + collocated, + replicatedOnly, + lazy, + skipReducerOnUpdate + ); + this.busyLock = busyLock; + this.sender = sender; this.maxCursors = maxCursors; - this.distributedJoins = distributedJoins; - this.enforceJoinOrder = enforceJoinOrder; - this.replicatedOnly = replicatedOnly; - this.collocated = collocated; - this.lazy = lazy; - this.skipReducerOnUpdate = skipReducerOnUpdate; this.actx = actx; this.nestedTxMode = nestedTxMode; this.ver = ver; @@ -204,6 +230,9 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { case QRY_EXEC_BATCH: return executeBatchQuery((OdbcQueryExecuteBatchRequest)req); + case STREAMING_BATCH: + return dispatchBatchOrdered((OdbcStreamingBatchRequest)req); + case QRY_FETCH: return fetchQuery((OdbcQueryFetchRequest)req); @@ -247,8 +276,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { * or due to {@code IOException} during network operations. */ public void onDisconnect() { - if (busyLock.enterBusy()) - { + if (busyLock.enterBusy()) { if (worker != null) { worker.cancel(); @@ -260,10 +288,11 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { } } - try - { + try { for (OdbcQueryResults res : qryResults.values()) res.closeAll(); + + U.close(cliCtx, log); } finally { busyLock.leaveBusy(); @@ -281,21 +310,32 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { * @return Query instance. */ private SqlFieldsQueryEx makeQuery(String schema, String sql, Object[] args, int timeout, boolean autoCommit) { - SqlFieldsQueryEx qry = new SqlFieldsQueryEx(sql, null); + SqlFieldsQueryEx qry = makeQuery(schema, sql); qry.setArgs(args); - - qry.setDistributedJoins(distributedJoins); - qry.setEnforceJoinOrder(enforceJoinOrder); - qry.setReplicatedOnly(replicatedOnly); - qry.setCollocated(collocated); - qry.setLazy(lazy); - qry.setSchema(schema); - qry.setSkipReducerOnUpdate(skipReducerOnUpdate); - qry.setNestedTxMode(nestedTxMode); + qry.setTimeout(timeout, TimeUnit.SECONDS); qry.setAutoCommit(autoCommit); - qry.setTimeout(timeout, TimeUnit.SECONDS); + return qry; + } + + /** + * Make query considering handler configuration. + * @param schema Schema. + * @param sql SQL request. + * @return Query instance. + */ + private SqlFieldsQueryEx makeQuery(String schema, String sql) { + SqlFieldsQueryEx qry = new SqlFieldsQueryEx(sql, null); + + qry.setDistributedJoins(cliCtx.isDistributedJoins()); + qry.setEnforceJoinOrder(cliCtx.isEnforceJoinOrder()); + qry.setReplicatedOnly(cliCtx.isReplicatedOnly()); + qry.setCollocated(cliCtx.isCollocated()); + qry.setLazy(cliCtx.isLazy()); + qry.setSchema(F.isEmpty(schema) ? QueryUtils.DFLT_SCHEMA : schema); + qry.setSkipReducerOnUpdate(cliCtx.isSkipReducerOnUpdate()); + qry.setNestedTxMode(nestedTxMode); return qry; } @@ -317,6 +357,8 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { long qryId = QRY_ID_GEN.getAndIncrement(); + assert !cliCtx.isStream(); + try { String sql = OdbcEscapeUtils.parse(req.sqlQuery()); @@ -326,7 +368,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { SqlFieldsQuery qry = makeQuery(req.schema(), sql, req.arguments(), req.timeout(), req.autoCommit()); - List<FieldsQueryCursor<List<?>>> cursors = ctx.query().querySqlFields(qry, true, false); + List<FieldsQueryCursor<List<?>>> cursors = ctx.query().querySqlFields(null, qry, cliCtx, true, false); OdbcQueryResults results = new OdbcQueryResults(cursors, ver); @@ -390,7 +432,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { qry.addBatchedArgs(set); List<FieldsQueryCursor<List<?>>> qryCurs = - ctx.query().querySqlFields(qry, true, true); + ctx.query().querySqlFields(null, qry, cliCtx, true, true); long[] rowsAffected = new long[req.arguments().length]; @@ -409,6 +451,105 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { } /** + * @param req Ordered batch request. + * @return Response. + */ + private ClientListenerResponse dispatchBatchOrdered(OdbcStreamingBatchRequest req) { + synchronized (orderedBatchesMux) { + orderedBatchesQueue.add(req); + + orderedBatchesMux.notify(); + } + + if (!cliCtx.isStreamOrdered()) + processStreamingBatchOrdered(req); + + return null; + } + + /** + * @param req Ordered batch request. + */ + private void processStreamingBatchOrdered(OdbcStreamingBatchRequest req) { + try { + if (req.last()) + cliCtx.waitTotalProcessedOrderedRequests(req.order()); + + sender.send(processStreamingBatch(req)); + } catch (Exception e) { + U.error(null, "Error processing file batch", e); + + sender.send(new OdbcResponse(IgniteQueryErrorCode.UNKNOWN, "Server error: " + e)); + } + + synchronized (orderedBatchesMux) { + orderedBatchesQueue.poll(); + } + + cliCtx.orderedRequestProcessed(); + } + + /** + * @param req Request. + * @return Response. + */ + private ClientListenerResponse processStreamingBatch(OdbcStreamingBatchRequest req) { + assert cliCtx.isStream(); + + // Send back only the first error. Others will be written to the log. + IgniteBiTuple<Integer, String> firstErr = new IgniteBiTuple<>(); + + SqlFieldsQueryEx qry = null; + + for (OdbcQuery q : req.queries()) { + if (q.sql() != null) { // If we have a new query string in the batch, + if (qry != null) // then execute the previous sub-batch and create a new SqlFieldsQueryEx. + processStreamingBatch(qry, firstErr); + + qry = makeQuery(req.schemaName(), q.sql()); + } + + assert qry != null; + + qry.addBatchedArgs(q.args()); + } + + if (qry != null) + processStreamingBatch(qry, firstErr); + + if (req.last()) + cliCtx.disableStreaming(); + + if (firstErr.isEmpty()) + return new OdbcResponse(new OdbcStreamingBatchResult(req.order())); + else + { + assert firstErr.getKey() != null; + + return new OdbcResponse(new OdbcStreamingBatchResult(firstErr.getKey(), firstErr.getValue(), req.order())); + } + } + + /** + * Executes query and updates result counters. + * + * @param qry Query. + * @param err First error data - code and message. + */ + private void processStreamingBatch(SqlFieldsQueryEx qry, IgniteBiTuple<Integer, String> err) { + try { + assert cliCtx.isStream(); + + ctx.query().streamBatchedUpdateQuery(qry.getSchema(), cliCtx, qry.getSql(), qry.batchedArguments()); + } + catch (Exception e) { + U.error(log, "Failed to execute batch query [qry=" + qry +']', e); + + extractBatchError(e, null, err); + } + } + + /** * {@link OdbcQueryCloseRequest} command handler. * * @param req Execute query request. @@ -742,39 +883,41 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { * @param e Exception to convert. * @return resulting {@link OdbcResponse}. */ - private OdbcResponse exceptionToBatchResult(Exception e) { - int code; - String msg; - long[] rowsAffected = null; + private static OdbcResponse exceptionToBatchResult(Exception e) { + IgniteBiTuple<Integer, String> err = new IgniteBiTuple<>(); + List<Long> rowsAffected = new ArrayList<>(); + + extractBatchError(e, rowsAffected, err); + OdbcQueryExecuteBatchResult res = new OdbcQueryExecuteBatchResult( + U.toLongArray(rowsAffected), -1, err.get1(), err.get2()); + + return new OdbcResponse(res); + } + + /** + * Extract batching error from general exception. + * @param e Exception + * @param rowsAffected List containing the number of affected rows for every query in batch. + * @param err Error tuple containing error code and error message. + */ + private static void extractBatchError(Exception e, List<Long> rowsAffected, IgniteBiTuple<Integer, String> err) { if (e instanceof IgniteSQLException) { BatchUpdateException batchCause = X.cause(e, BatchUpdateException.class); if (batchCause != null) { - rowsAffected = batchCause.getLargeUpdateCounts(); - - msg = batchCause.getMessage(); - - code = batchCause.getErrorCode(); - } - else { - msg = OdbcUtils.tryRetrieveH2ErrorMessage(e); + if (rowsAffected != null) { + for (long cnt : batchCause.getLargeUpdateCounts()) + rowsAffected.add(cnt); + } - code = ((IgniteSQLException)e).statusCode(); + err.set(batchCause.getErrorCode(), batchCause.getMessage()); } + else + err.set(((IgniteSQLException)e).statusCode(), OdbcUtils.tryRetrieveH2ErrorMessage(e)); } - else { - msg = e.getMessage(); - - code = IgniteQueryErrorCode.UNKNOWN; - } - - if (rowsAffected == null) - rowsAffected = new long[0]; - - OdbcQueryExecuteBatchResult res = new OdbcQueryExecuteBatchResult(rowsAffected, -1, code, msg); - - return new OdbcResponse(res); + else + err.set(IgniteQueryErrorCode.UNKNOWN, e.getMessage()); } /** @@ -784,7 +927,45 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler { * @param e Exception to convert. * @return resulting {@link OdbcResponse}. */ - private OdbcResponse exceptionToResult(Exception e) { + private static OdbcResponse exceptionToResult(Exception e) { return new OdbcResponse(OdbcUtils.tryRetrieveSqlErrorCode(e), OdbcUtils.tryRetrieveH2ErrorMessage(e)); } + + /** + * Ordered batch worker. + */ + private class OrderedBatchWorker extends GridWorker { + /** + * Constructor. + */ + OrderedBatchWorker() { + super(ctx.igniteInstanceName(), "ordered-batch", OdbcRequestHandler.this.log); + } + + /** {@inheritDoc} */ + @Override protected void body() throws InterruptedException, IgniteInterruptedCheckedException { + long nextBatchOrder = 0; + + while (true) { + if (!cliCtx.isStream()) + return; + + OdbcStreamingBatchRequest req; + + synchronized (orderedBatchesMux) { + req = orderedBatchesQueue.peek(); + + if (req == null || req.order() != nextBatchOrder) { + orderedBatchesMux.wait(); + + continue; + } + } + + processStreamingBatchOrdered(req); + + nextBatchOrder++; + } + } + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcStreamingBatchRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcStreamingBatchRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcStreamingBatchRequest.java new file mode 100644 index 0000000..7f3ee22 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcStreamingBatchRequest.java @@ -0,0 +1,102 @@ +package org.apache.ignite.internal.processors.odbc.odbc; + +/* + * 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. + */ + +import java.util.List; +import org.apache.ignite.internal.util.tostring.GridToStringExclude; +import org.apache.ignite.internal.util.tostring.GridToStringInclude; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * ODBC query execute request with the batch of parameters. + */ +public class OdbcStreamingBatchRequest extends OdbcRequest implements java.lang.Comparable<OdbcStreamingBatchRequest> { + /** Schema name. */ + @GridToStringInclude(sensitive = true) + private String schemaName; + + /** Sql query. */ + @GridToStringExclude() + private List<OdbcQuery> queries; + + /** + * Last stream batch flag - whether open streamers on current connection + * must be flushed and closed after this batch. + */ + @GridToStringInclude(sensitive = true) + private boolean last; + + /** Order. */ + @GridToStringInclude(sensitive = true) + private long order; + + /** + * @param schema Schema. + * @param queries SQL queries list. + * @param last Last page flag. + * @param order Order. + */ + public OdbcStreamingBatchRequest(@Nullable String schema, List<OdbcQuery> queries, boolean last, long order) { + super(STREAMING_BATCH); + + this.schemaName = schema; + this.queries = queries; + this.last = last; + this.order = order; + } + + /** + * @return Schema name. + */ + @Nullable public String schemaName() { + return schemaName; + } + + /** + * @return Queries. + */ + public List<OdbcQuery> queries() { + return queries; + } + + /** + * @return Last stream batch flag. + */ + public boolean last() { + return last; + } + + /** + * @return Request order. + */ + public long order() { + return order; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(OdbcStreamingBatchRequest.class, this); + } + + /** {@inheritDoc} */ + @Override public int compareTo(@NotNull OdbcStreamingBatchRequest o) { + return Long.compare(order, o.order); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcStreamingBatchResult.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcStreamingBatchResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcStreamingBatchResult.java new file mode 100644 index 0000000..63831f7 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcStreamingBatchResult.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.odbc.odbc; + +import org.apache.ignite.internal.processors.odbc.ClientListenerResponse; +import org.jetbrains.annotations.Nullable; + +/** + * ODBC query execute with batch of parameters result. + */ +public class OdbcStreamingBatchResult { + /** Success status. */ + private int status; + + /** Error. */ + private String err; + + /** Order. */ + private final long order; + + /** + * @param order Order. + */ + public OdbcStreamingBatchResult(long order) { + this(ClientListenerResponse.STATUS_SUCCESS, null, order); + } + + /** + * @param status Response status. + * @param err Error, {@code null} if success is {@code true}. + * @param order Order. + */ + public OdbcStreamingBatchResult(int status, @Nullable String err, long order) { + this.status = status; + this.err = err; + this.order = order; + } + + /** + * @return Success flag. + */ + public int status() { + return status; + } + + /** + * @return Error. + */ + public String error() { + return err; + } + + /** + * @return Order. + */ + public long order() { + return order; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/core/src/main/java/org/apache/ignite/internal/processors/query/SqlClientContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/SqlClientContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/SqlClientContext.java index 42dbae6..1f2fe43 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/SqlClientContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/SqlClientContext.java @@ -30,7 +30,7 @@ import org.apache.ignite.internal.util.worker.GridWorker; import org.apache.ignite.thread.IgniteThread; /** - * Container for connection properties passed by various drivers (JDBC drivers, possibly ODBC) having notion of an + * Container for connection properties passed by various drivers (JDBC, ODBC drivers) having notion of an * <b>SQL connection</b> - Ignite basically does not have one.<p> * Also contains anything that a driver may need to share between threads processing queries of logically same client - * see JDBC thin driver http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/binary/include/ignite/impl/interop/interop_memory.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/binary/include/ignite/impl/interop/interop_memory.h b/modules/platforms/cpp/binary/include/ignite/impl/interop/interop_memory.h index 50b5328..9a1872b 100644 --- a/modules/platforms/cpp/binary/include/ignite/impl/interop/interop_memory.h +++ b/modules/platforms/cpp/binary/include/ignite/impl/interop/interop_memory.h @@ -192,6 +192,13 @@ namespace ignite int8_t* Data(); /** + * Get raw data pointer. + * + * @return Data pointer. + */ + const int8_t* Data() const; + + /** * Get capacity. * * @return Capacity. http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/binary/src/impl/interop/interop_memory.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/binary/src/impl/interop/interop_memory.cpp b/modules/platforms/cpp/binary/src/impl/interop/interop_memory.cpp index 04b27ae..645a5bc 100644 --- a/modules/platforms/cpp/binary/src/impl/interop/interop_memory.cpp +++ b/modules/platforms/cpp/binary/src/impl/interop/interop_memory.cpp @@ -110,6 +110,11 @@ namespace ignite return Data(memPtr); } + const int8_t* InteropMemory::Data() const + { + return Data(memPtr); + } + int32_t InteropMemory::Capacity() const { return Capacity(memPtr); http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/common/Makefile.am ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/Makefile.am b/modules/platforms/cpp/common/Makefile.am index 374f417..df9068d 100644 --- a/modules/platforms/cpp/common/Makefile.am +++ b/modules/platforms/cpp/common/Makefile.am @@ -46,9 +46,9 @@ libignite_common_la_SOURCES = \ os/linux/src/common/platform_utils.cpp \ os/linux/src/common/dynamic_load_os.cpp \ src/common/big_integer.cpp \ + src/common/bits.cpp \ src/common/concurrent.cpp \ src/common/decimal.cpp \ - src/common/bits.cpp \ src/common/utils.cpp \ src/date.cpp \ src/ignite_error.cpp \ http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/common/include/Makefile.am ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/include/Makefile.am b/modules/platforms/cpp/common/include/Makefile.am index a28d04f..8079579 100644 --- a/modules/platforms/cpp/common/include/Makefile.am +++ b/modules/platforms/cpp/common/include/Makefile.am @@ -24,6 +24,7 @@ nobase_include_HEADERS = \ ignite/common/concurrent.h \ ignite/common/decimal.h \ ignite/common/default_allocator.h \ + ignite/common/expected.h \ ignite/common/reference_impl.h \ ignite/common/dynamic_size_array.h \ ignite/common/fixed_size_array.h \ http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/common/include/ignite/common/default_allocator.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/include/ignite/common/default_allocator.h b/modules/platforms/cpp/common/include/ignite/common/default_allocator.h index 4350987..f7f99b4 100644 --- a/modules/platforms/cpp/common/include/ignite/common/default_allocator.h +++ b/modules/platforms/cpp/common/include/ignite/common/default_allocator.h @@ -18,13 +18,9 @@ #define _IGNITE_COMMON_DEFAULT_ALLOCATOR #include <stdint.h> -#include <cstring> #include <cassert> -#include <utility> - #include <ignite/common/common.h> -#include <ignite/common/fixed_size_array.h> namespace ignite { @@ -86,8 +82,6 @@ namespace ignite { p->~ValueType(); } - - private: }; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/common/include/ignite/common/expected.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/include/ignite/common/expected.h b/modules/platforms/cpp/common/include/ignite/common/expected.h new file mode 100644 index 0000000..6322c7a --- /dev/null +++ b/modules/platforms/cpp/common/include/ignite/common/expected.h @@ -0,0 +1,300 @@ +/* + * 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_COMMON_EXPECTED +#define _IGNITE_COMMON_EXPECTED + +#include <memory> + +#include <ignite/common/utils.h> + +namespace ignite +{ + namespace common + { + /** + * Helper class to construct Expected class with error value. + */ + template<typename E> + struct Unexpected + { + /** Value type. */ + typedef E ValueType; + + /** + * Constructor. + * + * @param e Error value reference. + */ + Unexpected(const ValueType& e) : err(e) + { + // No-op; + } + + /** Error. */ + const ValueType& err; + }; + + /** + * Operation result wrapper. + * + * Represents a type, which can accept one of two value types - expected + * result or error. + * + * @tparam R Result type. + * @tparam E Error type. + * @tparam AR Allocator type used for the Result type. + * @tparam AE Allocator type used for the Error type. + */ + template< + typename R, + typename E, + typename AR = std::allocator<R>, + typename AE = std::allocator<E> > + class Expected + { + public: + /** Result type. */ + typedef R ResultType; + + /** Error type. */ + typedef E ErrorType; + + /** Allocator type used for the ResultType. */ + typedef AR ResultAllocatorType; + + /** Allocator type used for the ErrorType. */ + typedef AE ErrorAllocatorType; + + /** + * Constructor. + * + * Creates new instance, containing expected value. + * @param res Result. + */ + Expected(const ResultType& res) : + ok(true) + { + ResultAllocatorType ral; + + ral.construct(AsResult(), res); + } + + /** + * Constructor. + * + * Creates new instance, containing error. + * @param err Result. + */ + explicit Expected(Unexpected<ErrorType> err) : + ok(false) + { + ErrorAllocatorType ral; + + ral.construct(AsError(), err.err); + } + + /** + * Copy constructor. + * + * @param other Other. + */ + Expected(const Expected& other) : + ok(other.ok) + { + if (ok) + { + ResultAllocatorType ral; + + ral.construct(AsResult(), *other.AsResult()); + } + else + { + ErrorAllocatorType ral; + + ral.construct(AsError(), *other.AsError()); + } + } + + /** + * Destructor. + */ + ~Expected() + { + if (ok) + { + ResultAllocatorType ral; + + ral.destroy(AsResult()); + } + else + { + ErrorAllocatorType ral; + + ral.destroy(AsError()); + } + } + + /** + * Check if the value is OK. + * + * @return @c false if the value is an error and @c true otherwise. + */ + bool IsOk() const + { + return ok; + } + + /** + * Get result. Constant accesser. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + const ResultType& GetResult() const + { + if (!ok) + throw *AsError(); + + return *AsResult(); + } + + /** + * Get result. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + ResultType& GetResult() + { + if (!ok) + throw *AsError(); + + return *AsResult(); + } + + /** + * Get result. Constant accesser. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + const ResultType& operator*() const + { + return GetResult(); + } + + /** + * Get result. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + ResultType& operator*() + { + return GetResult(); + } + + /** + * Get result. Constant accesser. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + const ResultType& operator->() const + { + return GetResult(); + } + + /** + * Get result. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + ResultType& operator->() + { + return GetResult(); + } + + /** + * Get error. + * + * @return Error if it was set before. If there is no error, default + * constructed error is returned (which is expected to be "No error"). + */ + const ErrorType& GetError() const + { + static ErrorType noError; + + if (ok) + return noError; + + return *AsError(); + } + + private: + /** + * Get storage as an result. + * + * @return Storage pointer as an result pointer. + */ + ResultType* AsResult() + { + return reinterpret_cast<ResultType*>(&storage); + } + + /** + * Get storage as an result. + * + * @return Storage pointer as an result pointer. + */ + const ResultType* AsResult() const + { + return reinterpret_cast<const ResultType*>(&storage); + } + + /** + * Get storage as an error. + * + * @return Storage pointer as an error pointer. + */ + ErrorType* AsError() + { + return reinterpret_cast<ErrorType*>(&storage); + } + + /** + * Get storage as an error. + * + * @return Storage pointer as an error pointer. + */ + const ErrorType* AsError() const + { + return reinterpret_cast<const ErrorType*>(&storage); + } + + /** Storage. */ + int8_t storage[sizeof(typename Bigger<ResultType, ErrorType>::type)]; + + /** Result flag. Set to @c false if the value is an error. */ + bool ok; + }; + } +} + +#endif // _IGNITE_COMMON_EXPECTED \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/common/include/ignite/common/utils.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/include/ignite/common/utils.h b/modules/platforms/cpp/common/include/ignite/common/utils.h index 4edbf4b..29e36f5 100644 --- a/modules/platforms/cpp/common/include/ignite/common/utils.h +++ b/modules/platforms/cpp/common/include/ignite/common/utils.h @@ -489,6 +489,15 @@ namespace ignite }; /** + * Returns the bigger type. + */ + template<typename T1, typename T2> + struct Bigger + { + typedef typename Conditional<(sizeof(T1) > sizeof(T2)), T1, T2>::type type; + }; + + /** * Utility class to bind class instance with member function. */ template<typename R, typename T> http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/common/project/vs/common.vcxproj ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/project/vs/common.vcxproj b/modules/platforms/cpp/common/project/vs/common.vcxproj index bce1c2f..8f3bbe7 100644 --- a/modules/platforms/cpp/common/project/vs/common.vcxproj +++ b/modules/platforms/cpp/common/project/vs/common.vcxproj @@ -171,6 +171,7 @@ <ClInclude Include="..\..\include\ignite\common\decimal.h" /> <ClInclude Include="..\..\include\ignite\common\default_allocator.h" /> <ClInclude Include="..\..\include\ignite\common\dynamic_size_array.h" /> + <ClInclude Include="..\..\include\ignite\common\expected.h" /> <ClInclude Include="..\..\include\ignite\common\fixed_size_array.h" /> <ClInclude Include="..\..\include\ignite\common\bits.h" /> <ClInclude Include="..\..\include\ignite\common\lazy.h" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/common/project/vs/common.vcxproj.filters ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/project/vs/common.vcxproj.filters b/modules/platforms/cpp/common/project/vs/common.vcxproj.filters index 2d1a8b8..ee10799 100644 --- a/modules/platforms/cpp/common/project/vs/common.vcxproj.filters +++ b/modules/platforms/cpp/common/project/vs/common.vcxproj.filters @@ -82,6 +82,9 @@ <ClInclude Include="..\..\include\ignite\common\lazy.h"> <Filter>Code\common</Filter> </ClInclude> + <ClInclude Include="..\..\include\ignite\common\expected.h"> + <Filter>Code\common</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\src\date.cpp"> http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/core-test/src/teamcity_boost.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/core-test/src/teamcity_boost.cpp b/modules/platforms/cpp/core-test/src/teamcity_boost.cpp index 45c666d..5f0441c 100644 --- a/modules/platforms/cpp/core-test/src/teamcity_boost.cpp +++ b/modules/platforms/cpp/core-test/src/teamcity_boost.cpp @@ -19,7 +19,7 @@ #include <sstream> -#include <boost/test/unit_test_suite_impl.hpp> +#include <boost/test/unit_test_suite.hpp> #include <boost/test/results_collector.hpp> #include <boost/test/utils/basic_cstring/io.hpp> #include <boost/test/unit_test_log.hpp> http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/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 14dae7c..c5dc54e 100644 --- a/modules/platforms/cpp/odbc-test/Makefile.am +++ b/modules/platforms/cpp/odbc-test/Makefile.am @@ -47,7 +47,9 @@ ignite_odbc_tests_LDADD = \ -ldl \ -lodbc \ -lpthread \ - -lboost_regex + -lboost_thread \ + -lboost_system \ + -lboost_chrono ignite_odbc_tests_LDFLAGS = \ -static-libtool-libs @@ -87,6 +89,8 @@ ignite_odbc_tests_SOURCES = \ src/types_test.cpp \ src/transaction_test.cpp \ src/authentication_test.cpp \ + src/sql_parsing_test.cpp \ + src/streaming_test.cpp \ ../odbc/src/log.cpp \ ../odbc/src/cursor.cpp \ ../odbc/src/diagnostic/diagnostic_record.cpp \ @@ -97,6 +101,10 @@ ignite_odbc_tests_SOURCES = \ ../odbc/src/config/connection_string_parser.cpp \ ../odbc/src/app/application_data_buffer.cpp \ ../odbc/src/ssl/ssl_mode.cpp \ + ../odbc/src/sql/sql_parser.cpp \ + ../odbc/src/sql/sql_lexer.cpp \ + ../odbc/src/sql/sql_set_streaming_command.cpp \ + ../odbc/src/sql/sql_utils.cpp \ ../odbc/src/row.cpp \ ../odbc/src/protocol_version.cpp \ ../odbc/src/column.cpp \ http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/odbc-test/include/odbc_test_suite.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/include/odbc_test_suite.h b/modules/platforms/cpp/odbc-test/include/odbc_test_suite.h index 94733c5..7a33c6a 100644 --- a/modules/platforms/cpp/odbc-test/include/odbc_test_suite.h +++ b/modules/platforms/cpp/odbc-test/include/odbc_test_suite.h @@ -70,7 +70,7 @@ namespace ignite /** * Start additional with the specified name and config. - * + * * @param cfg Config path. * @param name Instance name. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/odbc-test/include/test_utils.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/include/test_utils.h b/modules/platforms/cpp/odbc-test/include/test_utils.h index 9faf89d..a1de23e 100644 --- a/modules/platforms/cpp/odbc-test/include/test_utils.h +++ b/modules/platforms/cpp/odbc-test/include/test_utils.h @@ -110,9 +110,17 @@ namespace ignite_test ignite::Ignite StartNode(const char* cfgFile, const char* name); /** + * Start node with the config for the current platform. + * + * @param cfg Basic config path. Changed to platform config if needed. + * @param name Instance name. + */ + ignite::Ignite StartPlatformNode(const char* cfg, const char* name); + + /** * Remove all the LFS artifacts. */ void ClearLfs(); } -#endif // _IGNITE_ODBC_TEST_TEST_UTILS \ No newline at end of file +#endif // _IGNITE_ODBC_TEST_TEST_UTILS http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/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 3410ec5..0147e8a 100644 --- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj +++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj @@ -98,7 +98,7 @@ </ClCompile> <Link> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(JAVA_HOME)\lib\jvm.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_unit_test_framework-vc100-mt-gd-1_58.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_regex-vc100-mt-gd-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(JAVA_HOME)\lib\jvm.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_unit_test_framework-vc100-mt-gd-1_58.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_thread-vc100-mt-gd-1_58.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_system-vc100-mt-gd-1_58.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_chrono-vc100-mt-gd-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> @@ -112,7 +112,7 @@ </ClCompile> <Link> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>$(JAVA_HOME)\lib\jvm.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_unit_test_framework-vc100-mt-gd-1_58.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_regex-vc100-mt-gd-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(JAVA_HOME)\lib\jvm.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_unit_test_framework-vc100-mt-gd-1_58.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_thread-vc100-mt-gd-1_58.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_system-vc100-mt-gd-1_58.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_chrono-vc100-mt-gd-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> <SubSystem>Console</SubSystem> </Link> </ItemDefinitionGroup> @@ -131,7 +131,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> - <AdditionalDependencies>$(JAVA_HOME)\lib\jvm.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_unit_test_framework-vc100-mt-1_58.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_regex-vc100-mt-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(JAVA_HOME)\lib\jvm.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_unit_test_framework-vc100-mt-1_58.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_thread-vc100-mt-1_58.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_system-vc100-mt-1_58.lib;$(BOOST_HOME)\lib32-msvc-10.0\libboost_chrono-vc100-mt-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -149,7 +149,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> - <AdditionalDependencies>$(JAVA_HOME)\lib\jvm.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_unit_test_framework-vc100-mt-1_58.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_regex-vc100-mt-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(JAVA_HOME)\lib\jvm.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_unit_test_framework-vc100-mt-1_58.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_thread-vc100-mt-1_58.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_system-vc100-mt-1_58.lib;$(BOOST_HOME)\lib64-msvc-10.0\libboost_chrono-vc100-mt-1_58.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> @@ -168,6 +168,10 @@ <ClCompile Include="..\..\..\odbc\src\protocol_version.cpp" /> <ClCompile Include="..\..\..\odbc\src\result_page.cpp" /> <ClCompile Include="..\..\..\odbc\src\row.cpp" /> + <ClCompile Include="..\..\..\odbc\src\sql\sql_lexer.cpp" /> + <ClCompile Include="..\..\..\odbc\src\sql\sql_parser.cpp" /> + <ClCompile Include="..\..\..\odbc\src\sql\sql_set_streaming_command.cpp" /> + <ClCompile Include="..\..\..\odbc\src\sql\sql_utils.cpp" /> <ClCompile Include="..\..\..\odbc\src\ssl\ssl_mode.cpp" /> <ClCompile Include="..\..\..\odbc\src\utility.cpp" /> <ClCompile Include="..\..\src\api_robustness_test.cpp" /> @@ -190,6 +194,7 @@ <ClCompile Include="..\..\src\sql_get_info_test.cpp" /> <ClCompile Include="..\..\src\sql_outer_join_test.cpp" /> <ClCompile Include="..\..\src\sql_date_time_functions_test.cpp" /> + <ClCompile Include="..\..\src\sql_parsing_test.cpp" /> <ClCompile Include="..\..\src\sql_test_suite_fixture.cpp" /> <ClCompile Include="..\..\src\sql_numeric_functions_test.cpp" /> <ClCompile Include="..\..\src\sql_operators_test.cpp" /> @@ -198,6 +203,7 @@ <ClCompile Include="..\..\src\sql_esc_convert_function_test.cpp" /> <ClCompile Include="..\..\src\sql_types_test.cpp" /> <ClCompile Include="..\..\src\sql_value_expressions_test.cpp" /> + <ClCompile Include="..\..\src\streaming_test.cpp" /> <ClCompile Include="..\..\src\teamcity\teamcity_boost.cpp" /> <ClCompile Include="..\..\src\teamcity\teamcity_messages.cpp" /> <ClCompile Include="..\..\src\test_utils.cpp" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/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 3065df0..1d54f07 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 @@ -172,6 +172,24 @@ <ClCompile Include="..\..\..\odbc\src\nested_tx_mode.cpp"> <Filter>Externals</Filter> </ClCompile> + <ClCompile Include="..\..\src\sql_parsing_test.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\..\odbc\src\sql\sql_lexer.cpp"> + <Filter>Externals</Filter> + </ClCompile> + <ClCompile Include="..\..\..\odbc\src\sql\sql_parser.cpp"> + <Filter>Externals</Filter> + </ClCompile> + <ClCompile Include="..\..\..\odbc\src\sql\sql_set_streaming_command.cpp"> + <Filter>Externals</Filter> + </ClCompile> + <ClCompile Include="..\..\..\odbc\src\sql\sql_utils.cpp"> + <Filter>Externals</Filter> + </ClCompile> + <ClCompile Include="..\..\src\streaming_test.cpp"> + <Filter>Code</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\include\test_type.h"> http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp index 5f807c9..4259667 100644 --- a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp @@ -58,14 +58,13 @@ struct ApiRobustnessTestSuiteFixture : public odbc::OdbcTestSuite { static Ignite StartAdditionalNode(const char* name) { - return StartTestNode("queries-test.xml", name); + return StartPlatformNode("queries-test.xml", name); } /** * Constructor. */ ApiRobustnessTestSuiteFixture() : - grid(), testCache(0) { grid = StartAdditionalNode("NodeMain"); @@ -82,8 +81,6 @@ struct ApiRobustnessTestSuiteFixture : public odbc::OdbcTestSuite { Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache"); - SQLRETURN ret; - const int64_t recordsNum = 100; for (int i = 0; i < recordsNum; ++i) @@ -98,7 +95,7 @@ struct ApiRobustnessTestSuiteFixture : public odbc::OdbcTestSuite int32_t i32Field = -1; // Binding column. - ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &i32Field, 0, 0); + SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &i32Field, 0, 0); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); @@ -126,7 +123,7 @@ struct ApiRobustnessTestSuiteFixture : public odbc::OdbcTestSuite /** * Destructor. */ - ~ApiRobustnessTestSuiteFixture() + virtual ~ApiRobustnessTestSuiteFixture() { // No-op. } @@ -457,7 +454,7 @@ BOOST_AUTO_TEST_CASE(TestSQLBindCol) ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt); //Unsupported data types - for(int i = 0; i < sizeof(unsupportedC)/sizeof(unsupportedC[0]); ++i) + for (size_t i = 0; i < sizeof(unsupportedC)/sizeof(unsupportedC[0]); ++i) { ret = SQLBindCol(stmt, 1, unsupportedC[i], &ind1, sizeof(ind1), &len1); BOOST_REQUIRE_EQUAL(ret, SQL_ERROR); @@ -506,16 +503,16 @@ BOOST_AUTO_TEST_CASE(TestSQLBindParameter) SQLBindParameter(stmt, 2, SQL_PARAM_INPUT_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 100, 100, &ind1, sizeof(ind1), &len1); CheckSQLStatementDiagnosticError("HY105"); - //Unsupported data types - for(int i = 0; i < sizeof(unsupportedSql)/sizeof(unsupportedSql[0]); ++i) + for (size_t i = 0; i < sizeof(unsupportedSql)/sizeof(unsupportedSql[0]); ++i) { - ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, unsupportedSql[i], 100, 100, &ind1, sizeof(ind1), &len1); + ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, + unsupportedSql[i], 100, 100, &ind1, sizeof(ind1), &len1); + BOOST_REQUIRE_EQUAL(ret, SQL_ERROR); CheckSQLStatementDiagnosticError("HYC00"); } - // Size is null. SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 100, 100, &ind1, 0, &len1); @@ -1092,9 +1089,8 @@ BOOST_AUTO_TEST_CASE(TestSQLDiagnosticRecords) Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache"); SQLHANDLE hnd; - SQLRETURN ret; - ret = SQLAllocHandle(SQL_HANDLE_DESC, dbc, &hnd); + SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_DESC, dbc, &hnd); BOOST_REQUIRE_EQUAL(ret, SQL_ERROR); CheckSQLConnectionDiagnosticError("IM001"); http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/odbc-test/src/attributes_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/src/attributes_test.cpp b/modules/platforms/cpp/odbc-test/src/attributes_test.cpp index 05c1c7f..69bca67 100644 --- a/modules/platforms/cpp/odbc-test/src/attributes_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/attributes_test.cpp @@ -58,18 +58,9 @@ struct AttributesTestSuiteFixture : odbc::OdbcTestSuite /** * Constructor. */ - AttributesTestSuiteFixture() : - grid() + AttributesTestSuiteFixture() { - const char* config = NULL; - -#ifdef IGNITE_TESTS_32 - config = "queries-test-32.xml"; -#else - config = "queries-test.xml"; -#endif - - grid = StartNode(config, "NodeMain"); + grid = StartPlatformNode("queries-test.xml", "NodeMain"); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/odbc-test/src/authentication_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/src/authentication_test.cpp b/modules/platforms/cpp/odbc-test/src/authentication_test.cpp index c746d5e..b93def6 100644 --- a/modules/platforms/cpp/odbc-test/src/authentication_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/authentication_test.cpp @@ -56,7 +56,7 @@ struct AuthenticationTestSuiteFixture : odbc::OdbcTestSuite { static Ignite StartAdditionalNode(const char* name) { - return StartTestNode("queries-auth.xml", name); + return StartPlatformNode("queries-auth.xml", name); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/odbc-test/src/connection_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/src/connection_test.cpp b/modules/platforms/cpp/odbc-test/src/connection_test.cpp index 709ef61..e9d0fb2 100644 --- a/modules/platforms/cpp/odbc-test/src/connection_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/connection_test.cpp @@ -85,8 +85,8 @@ struct ConnectionTestSuiteFixture: odbc::OdbcTestSuite /** * Extract code from ODBC error message. * - * @param err Error. - * @return Code. + * @param err Error message. + * @return Error code. */ static std::string ExtractErrorCode(const std::string& err) { http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/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 index 9c640ba..7d330b9 100644 --- a/modules/platforms/cpp/odbc-test/src/errors_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/errors_test.cpp @@ -64,7 +64,7 @@ struct ErrorTestSuiteFixture : odbc::OdbcTestSuite { static Ignite StartAdditionalNode(const char* name) { - return StartTestNode("queries-test.xml", name); + return StartPlatformNode("queries-test.xml", name); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp index 5cacb96..82dbf3a 100644 --- a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp @@ -65,7 +65,7 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite */ static Ignite StartAdditionalNode(const char* name) { - return StartTestNode("queries-test.xml", name); + return StartPlatformNode("queries-test.xml", name); } /** @@ -129,7 +129,7 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite cache1(0), cache2(0) { - grid = StartTestNode("queries-test.xml", "NodeMain"); + grid = StartPlatformNode("queries-test.xml", "NodeMain"); cache1 = grid.GetCache<int64_t, TestType>("cache"); cache2 = grid.GetCache<int64_t, ComplexType>("cache2"); http://git-wip-us.apache.org/repos/asf/ignite/blob/4a2d867d/modules/platforms/cpp/odbc-test/src/queries_ssl_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/src/queries_ssl_test.cpp b/modules/platforms/cpp/odbc-test/src/queries_ssl_test.cpp index 861bef1..3ff2f56 100644 --- a/modules/platforms/cpp/odbc-test/src/queries_ssl_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/queries_ssl_test.cpp @@ -47,7 +47,7 @@ struct SslQueriesTestSuiteFixture : odbc::OdbcTestSuite { static Ignite StartAdditionalNode(const char* name) { - return StartTestNode("queries-ssl.xml", name); + return StartPlatformNode("queries-ssl.xml", name); } /**