This is an automated email from the ASF dual-hosted git repository.

isapego pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 75ac16f6507 IGNITE-16873 C++ Thin SqlFieldsQuery setting partitions 
(#10088)
75ac16f6507 is described below

commit 75ac16f6507cb250b6709e8998a8ebf041c8f359
Author: Igor Sapego <[email protected]>
AuthorDate: Tue Jun 14 12:28:23 2022 +0400

    IGNITE-16873 C++ Thin SqlFieldsQuery setting partitions (#10088)
---
 .../thin-client-test/src/sql_fields_query_test.cpp |  16 ++
 modules/platforms/cpp/thin-client/CMakeLists.txt   |   1 +
 .../ignite/thin/cache/query/query_sql_fields.h     |  57 +++++-
 .../cpp/thin-client/src/impl/data_channel.cpp      |  65 +++----
 .../cpp/thin-client/src/impl/data_channel.h        |  44 +----
 .../platforms/cpp/thin-client/src/impl/message.cpp |  91 +++++----
 .../platforms/cpp/thin-client/src/impl/message.h   | 127 ++++++-------
 .../cpp/thin-client/src/impl/protocol_context.cpp  | 123 +++++++++++++
 .../cpp/thin-client/src/impl/protocol_context.h    | 205 +++++++++++++++++++++
 .../cpp/thin-client/src/impl/protocol_version.h    |   4 +
 10 files changed, 551 insertions(+), 182 deletions(-)

diff --git 
a/modules/platforms/cpp/thin-client-test/src/sql_fields_query_test.cpp 
b/modules/platforms/cpp/thin-client-test/src/sql_fields_query_test.cpp
index 838e8309d38..4220db89700 100644
--- a/modules/platforms/cpp/thin-client-test/src/sql_fields_query_test.cpp
+++ b/modules/platforms/cpp/thin-client-test/src/sql_fields_query_test.cpp
@@ -129,6 +129,16 @@ BOOST_AUTO_TEST_CASE(SqlFieldsQuerySetGet)
     qry.SetEnforceJoinOrder(true);
     qry.SetLazy(true);
 
+    qry.SetUpdateBatchSize(42);
+
+    std::vector<int32_t> parts;
+    parts.push_back(1);
+    parts.push_back(4);
+    parts.push_back(90);
+    parts.push_back(12432);
+
+    qry.SetPartitions(parts);
+
     BOOST_CHECK_EQUAL(qry.GetSql(), sql);
     BOOST_CHECK_EQUAL(qry.GetTimeout(), 1000);
     BOOST_CHECK_EQUAL(qry.GetMaxRows(), 100);
@@ -140,6 +150,12 @@ BOOST_AUTO_TEST_CASE(SqlFieldsQuerySetGet)
     BOOST_CHECK(qry.IsDistributedJoins());
     BOOST_CHECK(qry.IsEnforceJoinOrder());
     BOOST_CHECK(qry.IsLazy());
+
+    BOOST_CHECK_EQUAL(qry.GetUpdateBatchSize(), 42);
+
+    std::vector<int32_t> partsOut = qry.GetPartitions();
+
+    BOOST_CHECK_EQUAL_COLLECTIONS(parts.begin(), parts.end(), 
partsOut.begin(), partsOut.end());
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/platforms/cpp/thin-client/CMakeLists.txt 
b/modules/platforms/cpp/thin-client/CMakeLists.txt
index f6a742f97e3..f7f73a592bd 100644
--- a/modules/platforms/cpp/thin-client/CMakeLists.txt
+++ b/modules/platforms/cpp/thin-client/CMakeLists.txt
@@ -24,6 +24,7 @@ include_directories(include src)
 set(SOURCES src/impl/data_channel.cpp
         src/impl/utility.cpp
         src/impl/protocol_version.cpp
+        src/impl/protocol_context.cpp
         src/impl/ignite_node.cpp
         src/impl/ignite_client_impl.cpp
         src/impl/data_router.cpp
diff --git 
a/modules/platforms/cpp/thin-client/include/ignite/thin/cache/query/query_sql_fields.h
 
b/modules/platforms/cpp/thin-client/include/ignite/thin/cache/query/query_sql_fields.h
index e9e0843a801..fde76a87e12 100644
--- 
a/modules/platforms/cpp/thin-client/include/ignite/thin/cache/query/query_sql_fields.h
+++ 
b/modules/platforms/cpp/thin-client/include/ignite/thin/cache/query/query_sql_fields.h
@@ -70,6 +70,8 @@ namespace ignite
                         enforceJoinOrder(false),
                         lazy(false),
                         collocated(false),
+                        parts(),
+                        updateBatchSize(1),
                         args()
                     {
                         // No-op.
@@ -91,6 +93,8 @@ namespace ignite
                         enforceJoinOrder(other.enforceJoinOrder),
                         lazy(other.lazy),
                         collocated(other.collocated),
+                        parts(other.parts),
+                        updateBatchSize(other.updateBatchSize),
                         args()
                     {
                         args.reserve(other.args.size());
@@ -147,6 +151,7 @@ namespace ignite
                             swap(enforceJoinOrder, other.enforceJoinOrder);
                             swap(lazy, other.lazy);
                             swap(collocated, other.collocated);
+                            swap(parts, other.parts);
                             swap(args, other.args);
                         }
                     }
@@ -387,10 +392,54 @@ namespace ignite
                         this->collocated = collocated;
                     }
 
+                    /**
+                     * Get partitions for the query.
+                     *
+                     * The query will be executed only on nodes which are 
primary for specified partitions.
+                     *
+                     * @return Partitions for the query.
+                     */
+                    const std::vector<int32_t>& GetPartitions() const
+                    {
+                        return parts;
+                    }
+
+                    /**
+                     * Set partitions for the query.
+                     *
+                     * The query will be executed only on nodes which are 
primary for specified partitions.
+                     *
+                     * @param partitions Partitions for the query.
+                     */
+                    void SetPartitions(const std::vector<int32_t>& partitions)
+                    {
+                        this->parts = partitions;
+                    }
+
+                    /**
+                     * Set batch size for update queries.
+                     *
+                     * @param size Batch size for update queries.
+                     */
+                    void SetUpdateBatchSize(int32_t size)
+                    {
+                        updateBatchSize = size;
+                    }
+
+                    /**
+                     * Get batch size for update queries.
+                     *
+                     * @return Batch size for update queries.
+                     */
+                    int32_t GetUpdateBatchSize() const
+                    {
+                        return updateBatchSize;
+                    }
+
                     /**
                      * Add argument for the query.
                      *
-                     * @tparam T Type of argument. Should be should be 
copy-constructable and assignable. BinaryType
+                     * @tparam T Type of argument. Should be 
copy-constructable and assignable. BinaryType
                      * class template should be specialized for this type.
                      *
                      * @param arg Argument.
@@ -458,6 +507,12 @@ namespace ignite
                     /** Collocated flag. */
                     bool collocated;
 
+                    /** Partitions. */
+                    std::vector<int32_t> parts;
+
+                    /** Max rows to fetch. */
+                    int32_t updateBatchSize;
+
                     /** Arguments. */
                     std::vector<impl::thin::CopyableWritable*> args;
                 };
diff --git a/modules/platforms/cpp/thin-client/src/impl/data_channel.cpp 
b/modules/platforms/cpp/thin-client/src/impl/data_channel.cpp
index 9c7194a79ee..4990727a97e 100644
--- a/modules/platforms/cpp/thin-client/src/impl/data_channel.cpp
+++ b/modules/platforms/cpp/thin-client/src/impl/data_channel.cpp
@@ -31,26 +31,6 @@ namespace ignite
     {
         namespace thin
         {
-            const ProtocolVersion DataChannel::VERSION_1_2_0(1, 2, 0);
-            const ProtocolVersion DataChannel::VERSION_1_3_0(1, 3, 0);
-            const ProtocolVersion DataChannel::VERSION_1_4_0(1, 4, 0);
-            const ProtocolVersion DataChannel::VERSION_1_5_0(1, 5, 0);
-            const ProtocolVersion DataChannel::VERSION_1_6_0(1, 6, 0);
-            const ProtocolVersion DataChannel::VERSION_1_7_0(1, 7, 0);
-            const ProtocolVersion DataChannel::VERSION_DEFAULT(VERSION_1_7_0);
-
-            DataChannel::VersionSet::value_type supportedArray[] = {
-                DataChannel::VERSION_1_7_0,
-                DataChannel::VERSION_1_6_0,
-                DataChannel::VERSION_1_5_0,
-                DataChannel::VERSION_1_4_0,
-                DataChannel::VERSION_1_3_0,
-                DataChannel::VERSION_1_2_0,
-            };
-
-            const DataChannel::VersionSet 
DataChannel::supportedVersions(supportedArray,
-                supportedArray + (sizeof(supportedArray) / 
sizeof(supportedArray[0])));
-
             DataChannel::DataChannel(
                 uint64_t id,
                 const network::EndPoint& addr,
@@ -67,7 +47,7 @@ namespace ignite
                 node(addr),
                 config(cfg),
                 typeMgr(typeMgr),
-                currentVersion(VERSION_DEFAULT),
+                protocolContext(),
                 reqIdCounter(0),
                 responseMutex(),
                 userThreadPool(userThreadPool)
@@ -82,7 +62,7 @@ namespace ignite
 
             void DataChannel::StartHandshake()
             {
-                DoHandshake(VERSION_DEFAULT);
+                DoHandshake(ProtocolContext::VERSION_LATEST);
             }
 
             void DataChannel::Close(const IgniteError* err)
@@ -123,7 +103,7 @@ namespace ignite
                 // Space for RequestSize + OperationCode + RequestID.
                 outStream.Reserve(4 + 2 + 8);
 
-                req.Write(writer, currentVersion);
+                req.Write(writer, protocolContext);
 
                 int64_t reqId = GenerateRequestId();
                 req.SetId(reqId);
@@ -232,12 +212,12 @@ namespace ignite
 
             bool DataChannel::DoHandshake(const ProtocolVersion& propVer)
             {
-                currentVersion = propVer;
+                ProtocolContext context(propVer);
 
-                return Handshake(propVer);
+                return Handshake(context);
             }
 
-            bool DataChannel::Handshake(const ProtocolVersion& propVer)
+            bool DataChannel::Handshake(const ProtocolContext& context)
             {
                 // Allocating 4 KB just in case.
                 enum {
@@ -251,17 +231,19 @@ namespace ignite
                 int32_t lenPos = outStream.Reserve(4);
                 writer.WriteInt8(MessageType::HANDSHAKE);
 
-                writer.WriteInt16(propVer.GetMajor());
-                writer.WriteInt16(propVer.GetMinor());
-                writer.WriteInt16(propVer.GetMaintenance());
+                const ProtocolVersion& ver = context.GetVersion();
+
+                writer.WriteInt16(ver.GetMajor());
+                writer.WriteInt16(ver.GetMinor());
+                writer.WriteInt16(ver.GetMaintenance());
 
                 writer.WriteInt8(ClientType::THIN_CLIENT);
 
-                if (propVer >= VERSION_1_7_0) {
-                    // Use features for any new changes in protocol.
-                    int8_t features[] = {0};
+                if 
(context.IsFeatureSupported(VersionFeature::BITMAP_FEATURES))
+                {
+                    std::vector<int8_t> features = 
ProtocolContext::GetSupportedFeaturesMask();
 
-                    writer.WriteInt8Array(features, 0);
+                    writer.WriteInt8Array(&features[0], 
static_cast<int32_t>(features.size()));
                 }
 
                 writer.WriteString(config.GetUser());
@@ -298,7 +280,9 @@ namespace ignite
 
                     int32_t errorCode = reader.ReadInt32();
 
-                    bool shouldRetry = IsVersionSupported(resVer) && resVer != 
currentVersion;
+                    bool shouldRetry = 
ProtocolContext::IsVersionSupported(resVer) &&
+                        resVer != protocolContext.GetVersion();
+
                     if (shouldRetry)
                         shouldRetry = DoHandshake(resVer);
 
@@ -317,7 +301,7 @@ namespace ignite
                     return;
                 }
 
-                if (currentVersion >= VERSION_1_7_0)
+                if 
(protocolContext.IsFeatureSupported(VersionFeature::BITMAP_FEATURES))
                 {
                     int32_t len = reader.ReadInt8Array(0, 0);
                     std::vector<int8_t> features;
@@ -327,9 +311,11 @@ namespace ignite
                         features.resize(static_cast<size_t>(len));
                         reader.ReadInt8Array(features.data(), len);
                     }
+
+                    protocolContext.SetFeatures(features);
                 }
 
-                if (currentVersion >= VERSION_1_4_0)
+                if 
(protocolContext.IsFeatureSupported(VersionFeature::PARTITION_AWARENESS))
                 {
                     Guid nodeGuid = reader.ReadGuid();
 
@@ -340,11 +326,6 @@ namespace ignite
                 stateHandler.OnHandshakeSuccess(id);
             }
 
-            bool DataChannel::IsVersionSupported(const ProtocolVersion& ver)
-            {
-                return supportedVersions.find(ver) != supportedVersions.end();
-            }
-
             void DataChannel::DeserializeMessage(const network::DataBuffer 
&data, Response &msg)
             {
                 interop::InteropInputStream inStream(data.GetInputStream());
@@ -354,7 +335,7 @@ namespace ignite
 
                 binary::BinaryReaderImpl reader(&inStream);
 
-                msg.Read(reader, currentVersion);
+                msg.Read(reader, protocolContext);
             }
 
             void DataChannel::FailPendingRequests(const IgniteError* err)
diff --git a/modules/platforms/cpp/thin-client/src/impl/data_channel.h 
b/modules/platforms/cpp/thin-client/src/impl/data_channel.h
index 5e09b50d0d5..b2d44dfbac0 100644
--- a/modules/platforms/cpp/thin-client/src/impl/data_channel.h
+++ b/modules/platforms/cpp/thin-client/src/impl/data_channel.h
@@ -34,6 +34,7 @@
 #include <ignite/impl/binary/binary_writer_impl.h>
 
 #include "impl/protocol_version.h"
+#include "impl/protocol_context.h"
 #include "impl/ignite_node.h"
 #include "impl/response_status.h"
 #include "impl/channel_state_handler.h"
@@ -66,9 +67,6 @@ namespace ignite
             class DataChannel
             {
             public:
-                /** Version set type. */
-                typedef std::set<ProtocolVersion> VersionSet;
-
                 /** Shared pointer to DataBuffer Promise. */
                 typedef 
common::concurrent::SharedPointer<common::Promise<network::DataBuffer> > 
SP_PromiseDataBuffer;
 
@@ -78,27 +76,6 @@ namespace ignite
                 /** Notification handler map. */
                 typedef std::map< int64_t, NotificationHandlerHolder > 
NotificationHandlerMap;
 
-                /** Version 1.2.0. */
-                static const ProtocolVersion VERSION_1_2_0;
-
-                /** Version 1.3.0. */
-                static const ProtocolVersion VERSION_1_3_0;
-
-                /** Version 1.4.0. Added: Partition awareness support, IEP-23. 
*/
-                static const ProtocolVersion VERSION_1_4_0;
-
-                /** Version 1.5.0. Transaction support. */
-                static const ProtocolVersion VERSION_1_5_0;
-
-                /** Version 1.6.0. Expiration Policy Configuration. */
-                static const ProtocolVersion VERSION_1_6_0;
-
-                /** Version 1.7.0. Features introduced. */
-                static const ProtocolVersion VERSION_1_7_0;
-
-                /** Current version. */
-                static const ProtocolVersion VERSION_DEFAULT;
-
                 /**
                  * Constructor.
                  *
@@ -252,11 +229,11 @@ namespace ignite
                  * Synchronously send handshake request message and receive 
handshake response. Uses provided timeout.
                  * Does not try to restore connection on fail.
                  *
-                 * @param propVer Proposed protocol version.
+                 * @param context Current protocol context.
                  * @return @c true if accepted.
                  * @throw IgniteError on error.
                  */
-                bool Handshake(const ProtocolVersion& propVer);
+                bool Handshake(const ProtocolContext& context);
 
                 /**
                  * Handle handshake response.
@@ -265,17 +242,6 @@ namespace ignite
                  */
                 void OnHandshakeResponse(const network::DataBuffer& msg);
 
-                /**
-                 * Check if the version is supported.
-                 *
-                 * @param ver Version.
-                 * @return True if the version is supported.
-                 */
-                static bool IsVersionSupported(const ProtocolVersion& ver);
-
-                /** Set of supported versions. */
-                const static VersionSet supportedVersions;
-
                 /** State handler. */
                 ChannelStateHandler& stateHandler;
 
@@ -297,8 +263,8 @@ namespace ignite
                 /** Metadata manager. */
                 binary::BinaryTypeManager& typeMgr;
 
-                /** Protocol version. */
-                ProtocolVersion currentVersion;
+                /** Protocol context. */
+                ProtocolContext protocolContext;
 
                 /** Request ID counter. */
                 int64_t reqIdCounter;
diff --git a/modules/platforms/cpp/thin-client/src/impl/message.cpp 
b/modules/platforms/cpp/thin-client/src/impl/message.cpp
index 15982b92eaf..9ab59bcc77e 100644
--- a/modules/platforms/cpp/thin-client/src/impl/message.cpp
+++ b/modules/platforms/cpp/thin-client/src/impl/message.cpp
@@ -38,12 +38,12 @@ namespace ignite
                 // No-op.
             }
 
-            void ResourceCloseRequest::Write(binary::BinaryWriterImpl& writer, 
const ProtocolVersion&) const
+            void ResourceCloseRequest::Write(binary::BinaryWriterImpl& writer, 
const ProtocolContext&) const
             {
                 writer.WriteInt64(id);
             }
 
-            void CachePartitionsRequest::Write(binary::BinaryWriterImpl& 
writer, const ProtocolVersion&) const
+            void CachePartitionsRequest::Write(binary::BinaryWriterImpl& 
writer, const ProtocolContext&) const
             {
                 writer.WriteInt32(static_cast<int32_t>(cacheIds.size()));
 
@@ -57,7 +57,7 @@ namespace ignite
                 // No-op.
             }
 
-            void 
GetOrCreateCacheWithNameRequest::Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion&) const
+            void 
GetOrCreateCacheWithNameRequest::Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext&) const
             {
                 writer.WriteString(name);
             }
@@ -68,7 +68,7 @@ namespace ignite
                 // No-op.
             }
 
-            void CreateCacheWithNameRequest::Write(binary::BinaryWriterImpl& 
writer, const ProtocolVersion&) const
+            void CreateCacheWithNameRequest::Write(binary::BinaryWriterImpl& 
writer, const ProtocolContext&) const
             {
                 writer.WriteString(name);
             }
@@ -85,9 +85,9 @@ namespace ignite
                 // No-op.
             }
 
-            void Response::Read(binary::BinaryReaderImpl& reader, const 
ProtocolVersion& ver)
+            void Response::Read(binary::BinaryReaderImpl& reader, const 
ProtocolContext& context)
             {
-                if (ver >= DataChannel::VERSION_1_4_0)
+                if 
(context.IsFeatureSupported(VersionFeature::PARTITION_AWARENESS))
                 {
                     flags = reader.ReadInt16();
 
@@ -98,7 +98,7 @@ namespace ignite
                     {
                         status = ResponseStatus::SUCCESS;
 
-                        ReadOnSuccess(reader, ver);
+                        ReadOnSuccess(reader, context);
 
                         return;
                     }
@@ -107,7 +107,7 @@ namespace ignite
                 status = reader.ReadInt32();
 
                 if (status == ResponseStatus::SUCCESS)
-                    ReadOnSuccess(reader, ver);
+                    ReadOnSuccess(reader, context);
                 else
                     reader.ReadString(error);
             }
@@ -133,7 +133,7 @@ namespace ignite
                 // No-op.
             }
 
-            void 
CachePartitionsResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, const 
ProtocolVersion&)
+            void 
CachePartitionsResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, const 
ProtocolContext&)
             {
                 topologyVersion.Read(reader);
 
@@ -157,17 +157,17 @@ namespace ignite
                 // No-op.
             }
 
-            void CacheValueResponse::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolVersion&)
+            void CacheValueResponse::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolContext&)
             {
                 value.Read(reader);
             }
 
-            void BinaryTypeGetRequest::Write(binary::BinaryWriterImpl& writer, 
const ProtocolVersion&) const
+            void BinaryTypeGetRequest::Write(binary::BinaryWriterImpl& writer, 
const ProtocolContext&) const
             {
                 writer.WriteInt32(typeId);
             }
 
-            void BinaryTypePutRequest::Write(binary::BinaryWriterImpl& writer, 
const ProtocolVersion&) const
+            void BinaryTypePutRequest::Write(binary::BinaryWriterImpl& writer, 
const ProtocolContext&) const
             {
                 writer.WriteInt32(snapshot.GetTypeId());
                 writer.WriteString(snapshot.GetTypeName());
@@ -196,7 +196,7 @@ namespace ignite
                 writer.WriteInt32(0);
             }
 
-            void 
BinaryTypeGetResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, const 
ProtocolVersion&)
+            void 
BinaryTypeGetResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, const 
ProtocolContext&)
             {
                 int32_t typeId = reader.ReadInt32();
 
@@ -230,12 +230,12 @@ namespace ignite
                 // Ignoring schemas for now.
             }
 
-            void DestroyCacheRequest::Write(binary::BinaryWriterImpl& writer, 
const ProtocolVersion&) const
+            void DestroyCacheRequest::Write(binary::BinaryWriterImpl& writer, 
const ProtocolContext&) const
             {
                 writer.WriteInt32(cacheId);
             }
 
-            void 
GetCacheNamesResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, const 
ProtocolVersion&)
+            void 
GetCacheNamesResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, const 
ProtocolContext&)
             {
                 int32_t len = reader.ReadInt32();
 
@@ -250,7 +250,7 @@ namespace ignite
                 }
             }
 
-            void BoolResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&)
+            void BoolResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&)
             {
                 value = reader.ReadBool();
             }
@@ -262,9 +262,9 @@ namespace ignite
                 // No-op.
             }
 
-            void CacheGetSizeRequest::Write(binary::BinaryWriterImpl& writer, 
const ProtocolVersion& ver) const
+            void CacheGetSizeRequest::Write(binary::BinaryWriterImpl& writer, 
const ProtocolContext& context) const
             {
-                CacheRequest<MessageType::CACHE_GET_SIZE>::Write(writer, ver);
+                CacheRequest<MessageType::CACHE_GET_SIZE>::Write(writer, 
context);
 
                 if (peekModes & ignite::thin::cache::CachePeekMode::ALL)
                 {
@@ -303,18 +303,18 @@ namespace ignite
                 stream->Synchronize();
             }
 
-            void Int64Response::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolVersion&)
+            void Int64Response::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolContext&)
             {
                 value = reader.ReadInt64();
             }
 
-            void Int32Response::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolVersion&)
+            void Int32Response::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolContext&)
             {
                 value = reader.ReadInt32();
             }
 
 
-            void ScanQueryResponse::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolVersion&)
+            void ScanQueryResponse::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolContext&)
             {
                 ignite::binary::BinaryRawReader rawReader(&reader);
 
@@ -330,9 +330,9 @@ namespace ignite
                 // No-op.
             }
 
-            void ScanQueryRequest::Write(binary::BinaryWriterImpl &writer, 
const ProtocolVersion &ver) const
+            void ScanQueryRequest::Write(binary::BinaryWriterImpl &writer, 
const ProtocolContext& context) const
             {
-                CacheRequest::Write(writer, ver);
+                CacheRequest::Write(writer, context);
 
                 // TODO: IGNITE-16995 Implement a RemoteFilter for ScanQuery
                 writer.WriteNull();
@@ -352,9 +352,9 @@ namespace ignite
                 // No-op.
             }
 
-            void SqlFieldsQueryRequest::Write(binary::BinaryWriterImpl& 
writer, const ProtocolVersion& ver) const
+            void SqlFieldsQueryRequest::Write(binary::BinaryWriterImpl& 
writer, const ProtocolContext& context) const
             {
-                CacheRequest<MessageType::QUERY_SQL_FIELDS>::Write(writer, 
ver);
+                CacheRequest<MessageType::QUERY_SQL_FIELDS>::Write(writer, 
context);
 
                 if (qry.schema.empty())
                     writer.WriteNull();
@@ -366,10 +366,12 @@ namespace ignite
                 writer.WriteString(qry.sql);
                 writer.WriteInt32(static_cast<int32_t>(qry.args.size()));
 
-                std::vector<impl::thin::CopyableWritable*>::const_iterator it;
+                {
+                    std::vector<impl::thin::CopyableWritable*>::const_iterator 
it;
 
-                for (it = qry.args.begin(); it != qry.args.end(); ++it)
-                    (*it)->Write(writer);
+                    for (it = qry.args.begin(); it != qry.args.end(); ++it)
+                        (*it)->Write(writer);
+                }
 
                 writer.WriteInt8(0); // Statement type - Any
 
@@ -381,9 +383,24 @@ namespace ignite
                 writer.WriteBool(qry.lazy);
                 writer.WriteInt64(qry.timeout);
                 writer.WriteBool(true); // Include field names
+
+                if 
(context.IsFeatureSupported(BitmaskFeature::QRY_PARTITIONS_BATCH_SIZE))
+                {
+                    if (qry.parts.empty())
+                        writer.WriteInt32(-1);
+                    else
+                    {
+                        
writer.WriteInt32(static_cast<int32_t>(qry.parts.size()));
+
+                        for (std::vector<int32_t>::const_iterator it = 
qry.parts.begin(); it != qry.parts.end(); ++it)
+                            writer.WriteInt32(*it);
+                    }
+
+                    writer.WriteInt32(qry.updateBatchSize);
+                }
             }
 
-            void 
SqlFieldsQueryResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, const 
ProtocolVersion&)
+            void 
SqlFieldsQueryResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, const 
ProtocolContext&)
             {
                 ignite::binary::BinaryRawReader rawReader(&reader);
 
@@ -401,14 +418,14 @@ namespace ignite
                 cursorPage.Get()->Read(reader);
             }
 
-            void 
QueryCursorGetPageResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&)
+            void 
QueryCursorGetPageResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&)
             {
                 cursorPage.Get()->Read(reader);
             }
 
-            void ContinuousQueryRequest::Write(binary::BinaryWriterImpl& 
writer, const ProtocolVersion& ver) const
+            void ContinuousQueryRequest::Write(binary::BinaryWriterImpl& 
writer, const ProtocolContext& context) const
             {
-                CacheRequest<MessageType::QUERY_CONTINUOUS>::Write(writer, 
ver);
+                CacheRequest<MessageType::QUERY_CONTINUOUS>::Write(writer, 
context);
 
                 writer.WriteInt32(pageSize);
                 writer.WriteInt64(timeInterval);
@@ -418,12 +435,12 @@ namespace ignite
                 writer.WriteNull();
             }
 
-            void 
ContinuousQueryResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, const 
ProtocolVersion&)
+            void 
ContinuousQueryResponse::ReadOnSuccess(binary::BinaryReaderImpl& reader, const 
ProtocolContext&)
             {
                 queryId = reader.ReadInt64();
             }
 
-            void ComputeTaskExecuteRequest::Write(binary::BinaryWriterImpl& 
writer, const ProtocolVersion&) const
+            void ComputeTaskExecuteRequest::Write(binary::BinaryWriterImpl& 
writer, const ProtocolContext&) const
             {
                 // To be changed when Cluster API is implemented.
                 int32_t nodesNum = 0;
@@ -435,17 +452,17 @@ namespace ignite
                 arg.Write(writer);
             }
 
-            void 
ComputeTaskExecuteResponse::ReadOnSuccess(binary::BinaryReaderImpl&reader, 
const ProtocolVersion&)
+            void 
ComputeTaskExecuteResponse::ReadOnSuccess(binary::BinaryReaderImpl&reader, 
const ProtocolContext&)
             {
                 taskId = reader.ReadInt64();
             }
 
-            void 
ComputeTaskFinishedNotification::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolVersion&)
+            void 
ComputeTaskFinishedNotification::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolContext&)
             {
                 result.Read(reader);
             }
 
-            void 
ClientCacheEntryEventNotification::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolVersion&)
+            void 
ClientCacheEntryEventNotification::ReadOnSuccess(binary::BinaryReaderImpl& 
reader, const ProtocolContext&)
             {
                 ignite::binary::BinaryRawReader reader0(&reader);
                 query.ReadAndProcessEvents(reader0);
diff --git a/modules/platforms/cpp/thin-client/src/impl/message.h 
b/modules/platforms/cpp/thin-client/src/impl/message.h
index c5ca32e8517..09973fb53b9 100644
--- a/modules/platforms/cpp/thin-client/src/impl/message.h
+++ b/modules/platforms/cpp/thin-client/src/impl/message.h
@@ -35,7 +35,7 @@
 #include "impl/affinity/affinity_topology_version.h"
 #include "impl/affinity/partition_awareness_group.h"
 #include "impl/cache/query/cursor_page.h"
-#include "impl/protocol_version.h"
+#include "impl/protocol_context.h"
 
 namespace ignite
 {
@@ -254,9 +254,8 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
                  */
-                virtual void Write(binary::BinaryWriterImpl&, const 
ProtocolVersion&) const
+                virtual void Write(binary::BinaryWriterImpl&, const 
ProtocolContext&) const
                 {
                     // No-op.
                 }
@@ -344,7 +343,7 @@ namespace ignite
                  *
                  * @param writer Writer.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion&) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext&) const;
 
             private:
                 /** Resource ID. */
@@ -376,7 +375,7 @@ namespace ignite
                  * Write request using provided writer.
                  * @param writer Writer.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion&) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext&) const;
 
             private:
                 /** Cache IDs. */
@@ -407,9 +406,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const;
 
             private:
                 /** Name. */
@@ -440,9 +439,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const;
 
             private:
                 /** Name. */
@@ -477,9 +476,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const;
 
             private:
                 /** Cache ID. */
@@ -533,7 +532,7 @@ namespace ignite
                  * Write request using provided writer.
                  * @param writer Writer.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion&) const
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext&) const
                 {
                     writer.WriteInt32(cacheId);
 
@@ -589,9 +588,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const;
 
             private:
                 /** Peek modes. */
@@ -632,11 +631,11 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const
                 {
-                    CacheRequest<OpCode>::Write(writer, ver);
+                    CacheRequest<OpCode>::Write(writer, context);
 
                     value.Write(writer);
                 }
@@ -680,11 +679,11 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const
                 {
-                    CacheRequest<OpCode>::Write(writer, ver);
+                    CacheRequest<OpCode>::Write(writer, context);
 
                     val1.Write(writer);
                     val2.Write(writer);
@@ -735,11 +734,11 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const
                 {
-                    CacheRequest<OpCode>::Write(writer, ver);
+                    CacheRequest<OpCode>::Write(writer, context);
 
                     val1.Write(writer);
                     val2.Write(writer);
@@ -791,9 +790,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion&) const {
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext&) const
+                {
                     writer.WriteInt8(concurrency);
                     writer.WriteInt8(isolation);
                     writer.WriteInt64(timeout);
@@ -844,9 +843,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion&) const {
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext&) const
+                {
                     writer.WriteInt32(txId);
                     writer.WriteBool(commited);
                 }
@@ -887,9 +886,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const;
 
             private:
                 /** Cache ID. */
@@ -924,9 +923,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const;
 
             private:
                 /** Cache ID. */
@@ -958,9 +957,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const;
 
             private:
                 /** Query. */
@@ -997,7 +996,7 @@ namespace ignite
                  * Write request using provided writer.
                  * @param writer Writer.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion&) const
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext&) const
                 {
                     writer.WriteInt64(cursorId);
                 }
@@ -1032,9 +1031,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const;
 
             private:
                 /** Query. */
@@ -1075,9 +1074,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const;
 
             private:
                 /** Page size. */
@@ -1125,9 +1124,9 @@ namespace ignite
                 /**
                  * Write request using provided writer.
                  * @param writer Writer.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolVersion& ver) const;
+                virtual void Write(binary::BinaryWriterImpl& writer, const 
ProtocolContext& context) const;
 
             private:
                 /** Flags. */
@@ -1161,10 +1160,11 @@ namespace ignite
 
                 /**
                  * Read response using provided reader.
+                 *
                  * @param reader Reader.
-                 * @param ver Protocol version.
+                 * @param context Protocol context.
                  */
-                virtual void Read(binary::BinaryReaderImpl& reader, const 
ProtocolVersion& ver);
+                virtual void Read(binary::BinaryReaderImpl& reader, const 
ProtocolContext& context);
 
                 /**
                  * Get request processing status.
@@ -1215,7 +1215,7 @@ namespace ignite
                 /**
                  * Read data if response status is ResponseStatus::SUCCESS.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl&, const 
ProtocolVersion&)
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl&, const 
ProtocolContext&)
                 {
                     // No-op.
                 }
@@ -1256,7 +1256,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
                 /**
                  * Get version.
@@ -1309,7 +1309,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Value. */
@@ -1346,7 +1346,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Cache ID. */
@@ -1383,7 +1383,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Cache ID. */
@@ -1428,7 +1428,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Value. */
@@ -1473,7 +1473,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Value. */
@@ -1518,7 +1518,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Value. */
@@ -1573,7 +1573,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Cursor ID. */
@@ -1641,7 +1641,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Cursor ID. */
@@ -1691,7 +1691,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Cursor Page. */
@@ -1735,7 +1735,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Query ID. */
@@ -1779,7 +1779,7 @@ namespace ignite
                  *
                  * @param reader Reader.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion&);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext&);
 
             private:
                 /** Task ID. */
@@ -1812,8 +1812,9 @@ namespace ignite
                  * Read notification data.
                  *
                  * @param reader Reader.
+                 * @param context Protocol context.
                  */
-                virtual void Read(binary::BinaryReaderImpl& reader, const 
ProtocolVersion& ver)
+                virtual void Read(binary::BinaryReaderImpl& reader, const 
ProtocolContext& context)
                 {
                     flags = reader.ReadInt16();
 
@@ -1832,7 +1833,7 @@ namespace ignite
                         return;
                     }
 
-                    ReadOnSuccess(reader, ver);
+                    ReadOnSuccess(reader, context);
                 }
 
                 /**
@@ -1847,9 +1848,9 @@ namespace ignite
                  * Read data if response status is ResponseStatus::SUCCESS.
                  *
                  * @param reader Reader.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion& ver) = 0;
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext& context) = 0;
             };
 
             /**
@@ -1907,9 +1908,9 @@ namespace ignite
                  * Read data if response status is ResponseStatus::SUCCESS.
                  *
                  * @param reader Reader.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion& ver);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext& context);
 
             private:
                 /** Result. */
@@ -1943,9 +1944,9 @@ namespace ignite
                  * Read data if response status is ResponseStatus::SUCCESS.
                  *
                  * @param reader Reader.
-                 * @param ver Version.
+                 * @param context Protocol context.
                  */
-                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolVersion& ver);
+                virtual void ReadOnSuccess(binary::BinaryReaderImpl& reader, 
const ProtocolContext& context);
 
             private:
                 /** Result. */
diff --git a/modules/platforms/cpp/thin-client/src/impl/protocol_context.cpp 
b/modules/platforms/cpp/thin-client/src/impl/protocol_context.cpp
new file mode 100644
index 00000000000..0a6c4f18b3f
--- /dev/null
+++ b/modules/platforms/cpp/thin-client/src/impl/protocol_context.cpp
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+#include "impl/protocol_context.h"
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace thin
+        {
+            const ProtocolVersion VERSION_1_2_0(1, 2, 0);
+            const ProtocolVersion VERSION_1_3_0(1, 3, 0);
+            const ProtocolVersion VERSION_1_4_0(1, 4, 0);
+            const ProtocolVersion VERSION_1_5_0(1, 5, 0);
+            const ProtocolVersion VERSION_1_6_0(1, 6, 0);
+            const ProtocolVersion VERSION_1_7_0(1, 7, 0);
+
+            VersionSet::value_type supportedArray[] = {
+                VERSION_1_7_0,
+                VERSION_1_6_0,
+                VERSION_1_5_0,
+                VERSION_1_4_0,
+                VERSION_1_3_0,
+                VERSION_1_2_0,
+            };
+
+            const VersionSet supportedVersions(supportedArray,
+                supportedArray + (sizeof(supportedArray) / 
sizeof(supportedArray[0])));
+
+            VersionFeature::Type 
VersionFeature::PARTITION_AWARENESS(VERSION_1_4_0);
+            VersionFeature::Type 
VersionFeature::BITMAP_FEATURES(VERSION_1_7_0);
+
+            const ProtocolVersion 
ProtocolContext::VERSION_LATEST(VERSION_1_7_0);
+
+            ProtocolContext::ProtocolContext() :
+                ver(VERSION_LATEST),
+                features()
+            {
+                SetAllFeatures(features);
+            }
+
+            ProtocolContext::~ProtocolContext()
+            {
+                // No-op.
+            }
+
+            ProtocolContext::ProtocolContext(const ProtocolVersion& ver) :
+                ver(ver),
+                features()
+            {
+                if (IsFeatureSupported(VersionFeature::BITMAP_FEATURES))
+                    SetAllFeatures(features);
+            }
+
+            bool ProtocolContext::IsFeatureSupported(BitmaskFeature::Type 
feature) const
+            {
+                return TestFeature(features, feature);
+            }
+
+            void ProtocolContext::SetFeatures(const std::vector<int8_t>& 
bitmask)
+            {
+                features = bitmask;
+            }
+
+            bool ProtocolContext::IsVersionSupported(const ProtocolVersion& 
ver)
+            {
+                return supportedVersions.find(ver) != supportedVersions.end();
+            }
+
+            std::vector<int8_t> ProtocolContext::GetSupportedFeaturesMask()
+            {
+                std::vector<int8_t> features((BitmaskFeature::MAX_SUPPORTED + 
7) / 8, 0);
+
+                SetAllFeatures(features);
+
+                return features;
+            }
+
+            void ProtocolContext::SetAllFeatures(std::vector<int8_t> &features)
+            {
+                SetFeature(features, 
BitmaskFeature::QRY_PARTITIONS_BATCH_SIZE);
+            }
+
+            void ProtocolContext::SetFeature(std::vector<int8_t>& features, 
BitmaskFeature::Type feature)
+            {
+                size_t byteN = feature / 8;
+                size_t bitN = feature % 8;
+
+                if (features.size() <= byteN)
+                    features.resize(byteN + 1, 0);
+
+                features[byteN] |= static_cast<int8_t>(1U << bitN);
+            }
+
+            bool ProtocolContext::TestFeature(const std::vector<int8_t> 
&features, BitmaskFeature::Type feature)
+            {
+                size_t byteN = feature / 8;
+                size_t bitN = feature % 8;
+
+                if (features.size() <= byteN)
+                    return false;
+
+                return (features[byteN] & static_cast<int8_t>(1U << bitN)) != 
0;
+            }
+        }
+    }
+}
+
diff --git a/modules/platforms/cpp/thin-client/src/impl/protocol_context.h 
b/modules/platforms/cpp/thin-client/src/impl/protocol_context.h
new file mode 100644
index 00000000000..ffde1fb20f8
--- /dev/null
+++ b/modules/platforms/cpp/thin-client/src/impl/protocol_context.h
@@ -0,0 +1,205 @@
+/*
+ * 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_IMPL_THIN_PROTOCOL_CONTEXT
+#define _IGNITE_IMPL_THIN_PROTOCOL_CONTEXT
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "impl/protocol_version.h"
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace thin
+        {
+            /**
+             * Bitmask feature.
+             */
+            struct BitmaskFeature
+            {
+                enum Type
+                {
+                    /** Additional SqlFieldsQuery properties: partitions, 
updateBatchSize. */
+                    QRY_PARTITIONS_BATCH_SIZE = 7,
+
+                    /** Max number of supported bitmask features. */
+                    MAX_SUPPORTED
+                };
+            };
+
+            /**
+             * Version feature.
+             */
+            struct VersionFeature
+            {
+                class Type
+                {
+                public:
+                    /**
+                     * Constructor.
+                     *
+                     * @param ver Version for the feature;
+                     */
+                    explicit Type(const ProtocolVersion& ver) :
+                        ver(ver)
+                    {
+                        // No-op.
+                    }
+
+                    /**
+                     * Get version.
+                     *
+                     * @return Version.
+                     */
+                    const ProtocolVersion& GetVersion() const
+                    {
+                        return ver;
+                    }
+
+                private:
+                    /** Version. */
+                    const ProtocolVersion ver;
+                };
+
+                /** Partition awareness. */
+                static Type PARTITION_AWARENESS;
+
+                /** Bitmap features. */
+                static Type BITMAP_FEATURES;
+            };
+
+            /** Protocol context. */
+            class ProtocolContext
+            {
+            public:
+                /** The latest supported version. */
+                static const ProtocolVersion VERSION_LATEST;
+
+                /**
+                 * Default constructor.
+                 *
+                 * Constructs a protocol context with the latest version and 
all features set. Basically, max number of
+                 * supported features context.
+                 */
+                ProtocolContext();
+
+                /**
+                 * Constructor.
+                 *
+                 * Constructs a protocol context with specified version and 
all features set.
+                 *
+                 * @param ver Version part.
+                 */
+                explicit ProtocolContext(const ProtocolVersion& ver);
+
+                /**
+                 * Destructor.
+                 */
+                ~ProtocolContext();
+
+                /**
+                 * Get protocol version.
+                 *
+                 * @return Protocol version.
+                 */
+                const ProtocolVersion& GetVersion() const
+                {
+                    return ver;
+                }
+
+                /**
+                 * Check if the feature supported.
+                 *
+                 * @param feature Version feature to check.
+                 * @return @c true if the feature is supported.
+                 */
+                bool IsFeatureSupported(const VersionFeature::Type& feature) 
const
+                {
+                    return ver >= feature.GetVersion();
+                }
+
+                /**
+                 * Check if the feature supported.
+                 *
+                 * @param feature Bitmask feature to check.
+                 * @return @true if the feature is supported.
+                 */
+                bool IsFeatureSupported(BitmaskFeature::Type feature) const;
+
+                /**
+                 * Set features bitmask.
+                 *
+                 * @param bitmask Features bitmask.
+                 */
+                void SetFeatures(const std::vector<int8_t>& bitmask);
+
+                /**
+                 * Check wheather protocol version is supported by the current 
implementation of C++ client.
+                 *
+                 * @param ver Protocol version to check.
+                 * @return @c true if supported.
+                 */
+                static bool IsVersionSupported(const ProtocolVersion& ver);
+
+                /**
+                 * Get supported features mask.
+                 *
+                 * @return Supported features mask.
+                 */
+                static std::vector<int8_t> GetSupportedFeaturesMask();
+
+            private:
+                /**
+                 * Set feature in feature bitmask.
+                 *
+                 * @param features Features bitmask.
+                 * @param feature Feature to set.
+                 */
+                static void SetFeature(std::vector<int8_t>& features, 
BitmaskFeature::Type feature);
+
+                /**
+                 * Set all possible features in feature bitmask.
+                 *
+                 * @param features Features bitmask.
+                 */
+                static void SetAllFeatures(std::vector<int8_t>& features);
+
+                /**
+                 * Check if feature is in feature bitmask.
+                 *
+                 * @param features Features bitmask.
+                 * @param feature Feature to check.
+                 *
+                 * @return @c true if it is supported.
+                 */
+                static bool TestFeature(const std::vector<int8_t>& features, 
BitmaskFeature::Type feature);
+
+                /** Protocol version. */
+                const ProtocolVersion ver;
+
+                /** Features mask. */
+                std::vector<int8_t> features;
+            };
+        }
+    }
+}
+
+#endif //_IGNITE_IMPL_THIN_PROTOCOL_CONTEXT
\ No newline at end of file
diff --git a/modules/platforms/cpp/thin-client/src/impl/protocol_version.h 
b/modules/platforms/cpp/thin-client/src/impl/protocol_version.h
index c3361f5e0ee..55cdd97db56 100644
--- a/modules/platforms/cpp/thin-client/src/impl/protocol_version.h
+++ b/modules/platforms/cpp/thin-client/src/impl/protocol_version.h
@@ -19,6 +19,7 @@
 #define _IGNITE_IMPL_THIN_PROTOCOL_VERSION
 
 #include <stdint.h>
+#include <set>
 
 #include <string>
 
@@ -155,6 +156,9 @@ namespace ignite
                 /** Maintenance part. */
                 int16_t vmaintenance;
             };
+
+            /** Version set type. */
+            typedef std::set<ProtocolVersion> VersionSet;
         }
     }
 }

Reply via email to