You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/08/01 09:26:21 UTC

[38/47] ignite git commit: IGNITE-5621: Support BINARY and VARBINARY SQL types for C++

IGNITE-5621: Support BINARY and VARBINARY SQL types for C++

(cherry picked from commit 96b43e5)


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

Branch: refs/heads/master
Commit: 97813a8280d54c9b4ce08dca954e05fa62393cbe
Parents: 3085b20
Author: Igor Sapego <is...@gridgain.com>
Authored: Fri Jul 28 19:30:35 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Fri Jul 28 19:32:43 2017 +0300

----------------------------------------------------------------------
 .../core-test/config/cache-query-default.xml    |  29 +++
 .../cpp/core-test/src/cache_query_test.cpp      | 215 ++++++++++++++++++-
 .../ignite/cache/query/query_fields_row.h       |  28 +++
 .../ignite/cache/query/query_sql_fields.h       |  13 +-
 .../ignite/impl/cache/query/query_argument.h    |  63 ++++++
 .../impl/cache/query/query_fields_row_impl.h    |  29 +++
 6 files changed, 373 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core-test/config/cache-query-default.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/config/cache-query-default.xml b/modules/platforms/cpp/core-test/config/cache-query-default.xml
index 16f601d..42ac80f 100644
--- a/modules/platforms/cpp/core-test/config/cache-query-default.xml
+++ b/modules/platforms/cpp/core-test/config/cache-query-default.xml
@@ -160,6 +160,35 @@
                         </list>
                     </property>
                 </bean>
+
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="ByteArrayCache"/>
+                    <property name="cacheMode" value="PARTITIONED"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="writeSynchronizationMode" value="FULL_SYNC"/>
+
+                    <property name="affinity">
+                        <bean class="org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction">
+                            <property name="partitions" value="256"/>
+                        </bean>
+                    </property>
+
+                    <!-- Configure type metadata to enable queries. -->
+                    <property name="queryEntities">
+                        <list>
+                            <bean class="org.apache.ignite.cache.QueryEntity">
+                                <property name="keyType" value="java.lang.Integer"/>
+                                <property name="valueType" value="ByteArrayType"/>
+                                <property name="fields">
+                                    <map>
+                                        <entry key="intVal" value="java.lang.Integer"/>
+                                        <entry key="arrayVal" value="[B"/>
+                                    </map>
+                                </property>
+                            </bean>
+                        </list>
+                    </property>
+                </bean>
             </list>
         </property>
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core-test/src/cache_query_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cache_query_test.cpp b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
index e763e08..4993279 100644
--- a/modules/platforms/cpp/core-test/src/cache_query_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
@@ -47,7 +47,7 @@ using ignite::impl::binary::BinaryUtils;
 /**
  * Person class for query tests.
  */
-class IGNITE_IMPORT_EXPORT QueryPerson
+class QueryPerson
 {
 public:
     /**
@@ -203,7 +203,7 @@ private:
 /**
  * Relation class for query tests.
  */
-class IGNITE_IMPORT_EXPORT QueryRelation
+class QueryRelation
 {
 public:
     /**
@@ -257,6 +257,40 @@ private:
     int32_t someVal;
 };
 
+/**
+ * Byte array test type.
+ */
+struct ByteArrayType
+{
+    /**
+     * Test constructor.
+     *
+     * @param val Init value.
+     */
+    ByteArrayType(int32_t val) :
+        intVal(val),
+        arrayVal(val + 1, val + 1)
+    {
+        // No-op.
+    }
+
+    /**
+     * Default constructor.
+     */
+    ByteArrayType() :
+        intVal(0),
+        arrayVal()
+    {
+        // No-op.
+    }
+
+    /** Int field. */
+    int32_t intVal;
+
+    /** Array field. */
+    std::vector<int8_t> arrayVal;
+};
+
 namespace ignite
 {
     namespace binary
@@ -300,7 +334,7 @@ namespace ignite
             IGNITE_BINARY_IS_NULL_FALSE(QueryRelation)
             IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(QueryRelation)
 
-            static void Write(BinaryWriter& writer, QueryRelation obj)
+            static void Write(BinaryWriter& writer, const QueryRelation& obj)
             {
                 writer.WriteInt32("personId", obj.GetPersonId());
                 writer.WriteInt32("someVal", obj.GetHobbyId());
@@ -314,6 +348,32 @@ namespace ignite
                 dst = QueryRelation(personId, someVal);
             }
         IGNITE_BINARY_TYPE_END
+
+        /**
+         * Binary type definition for ByteArrayType.
+         */
+        IGNITE_BINARY_TYPE_START(ByteArrayType)
+            IGNITE_BINARY_GET_TYPE_ID_AS_HASH(ByteArrayType)
+            IGNITE_BINARY_GET_TYPE_NAME_AS_IS(ByteArrayType)
+            IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+            IGNITE_BINARY_IS_NULL_FALSE(ByteArrayType)
+            IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ByteArrayType)
+
+            static void Write(BinaryWriter& writer, const ByteArrayType& obj)
+            {
+                writer.WriteInt32("intVal", obj.intVal);
+                writer.WriteInt8Array("arrayVal", &obj.arrayVal[0], static_cast<int32_t>(obj.arrayVal.size()));
+            }
+
+            static void Read(BinaryReader& reader, ByteArrayType& dst)
+            {
+                dst.intVal = reader.ReadInt32("intVal");
+                int32_t arrayValSize = reader.ReadInt8Array("arrayVal", 0, 0);
+
+                dst.arrayVal.resize(static_cast<size_t>(arrayValSize));
+                reader.ReadInt8Array("arrayVal", &dst.arrayVal[0], arrayValSize);
+            }
+        IGNITE_BINARY_TYPE_END
     }
 }
 
@@ -1956,4 +2016,153 @@ BOOST_AUTO_TEST_CASE(TestFieldsQuerySetSchema)
     CheckEmpty(cursor);
 }
 
+/**
+ * Test query for byte arrays.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQueryByteArraySelect)
+{
+    Cache<int32_t, ByteArrayType> byteArrayCache = grid.GetCache<int32_t, ByteArrayType>("ByteArrayCache");
+
+    int32_t entryCnt = 100; // Number of entries.
+
+    for (int32_t i = 0; i < entryCnt; i++)
+        byteArrayCache.Put(i, ByteArrayType(i));
+
+    SqlFieldsQuery qry("select intVal, arrayVal, intVal + 1 from ByteArrayType where _key=42");
+
+    QueryFieldsCursor cursor = byteArrayCache.Query(qry);
+
+    BOOST_REQUIRE(cursor.HasNext());
+
+    QueryFieldsRow row = cursor.GetNext();
+
+    BOOST_REQUIRE(row.HasNext());
+
+    int32_t intVal1 = row.GetNext<int32_t>();
+
+    BOOST_CHECK_EQUAL(intVal1, 42);
+
+    BOOST_REQUIRE(row.HasNext());
+
+    std::vector<int8_t> arrayVal;
+    int32_t arrayValSize = row.GetNextInt8Array(0, 0);
+
+    arrayVal.resize(static_cast<size_t>(arrayValSize));
+    row.GetNextInt8Array(&arrayVal[0], arrayValSize);
+
+    BOOST_CHECK_EQUAL(arrayValSize, 43);
+
+    for (int32_t i = 0; i < arrayValSize; ++i)
+        BOOST_CHECK_EQUAL(arrayVal[i], 43);
+
+    BOOST_REQUIRE(row.HasNext());
+
+    int32_t intVal2 = row.GetNext<int32_t>();
+
+    BOOST_CHECK_EQUAL(intVal2, 43);
+
+    BOOST_REQUIRE(!row.HasNext());
+
+    CheckEmpty(cursor);
+}
+
+/**
+ * Test query for byte arrays.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQueryByteArrayInsert)
+{
+    Cache<int32_t, ByteArrayType> byteArrayCache = grid.GetCache<int32_t, ByteArrayType>("ByteArrayCache");
+
+    SqlFieldsQuery qry("insert into ByteArrayType(_key, intVal, arrayVal) values (?, ?, ?)");
+
+    int32_t entryCnt = 100; // Number of entries.
+
+    for (int32_t i = 0; i < entryCnt; i++)
+    {
+        int32_t key = i;
+        int32_t intVal = i;
+        std::vector<int8_t> arrayVal(i + 1, i + 1);
+
+        qry.AddArgument(key);
+        qry.AddArgument(intVal);
+        qry.AddInt8ArrayArgument(&arrayVal[0], i + 1);
+
+        byteArrayCache.Query(qry);
+
+        qry.ClearArguments();
+    }
+
+    ByteArrayType val = byteArrayCache.Get(42);
+
+    BOOST_CHECK_EQUAL(val.intVal, 42);
+    BOOST_CHECK_EQUAL(val.arrayVal.size(), 43);
+
+    for (int32_t i = 0; i < 43; ++i)
+        BOOST_CHECK_EQUAL(val.arrayVal[i], 43);
+}
+
+/**
+ * Test query for byte arrays.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQueryByteArrayInsertSelect)
+{
+    Cache<int32_t, ByteArrayType> byteArrayCache = grid.GetCache<int32_t, ByteArrayType>("ByteArrayCache");
+
+    SqlFieldsQuery qry("insert into ByteArrayType(_key, intVal, arrayVal) values (?, ?, ?)");
+
+    int32_t entryCnt = 100; // Number of entries.
+
+    for (int32_t i = 0; i < entryCnt; i++)
+    {
+        int32_t key = i;
+        int32_t intVal = i;
+        std::vector<int8_t> arrayVal(i + 1, i + 1);
+
+        qry.AddArgument(key);
+        qry.AddArgument(intVal);
+        qry.AddInt8ArrayArgument(&arrayVal[0], i + 1);
+
+        byteArrayCache.Query(qry);
+
+        qry.ClearArguments();
+    }
+
+    qry = SqlFieldsQuery("select intVal, arrayVal, intVal + 1 from ByteArrayType where _key=42");
+
+    QueryFieldsCursor cursor = byteArrayCache.Query(qry);
+
+    BOOST_REQUIRE(cursor.HasNext());
+
+    QueryFieldsRow row = cursor.GetNext();
+
+    BOOST_REQUIRE(row.HasNext());
+
+    int32_t intVal1 = row.GetNext<int32_t>();
+
+    BOOST_CHECK_EQUAL(intVal1, 42);
+
+    BOOST_REQUIRE(row.HasNext());
+
+    std::vector<int8_t> arrayVal;
+    int32_t arrayValSize = row.GetNextInt8Array(0, 0);
+
+    arrayVal.resize(static_cast<size_t>(arrayValSize));
+    row.GetNextInt8Array(&arrayVal[0], arrayValSize);
+
+    BOOST_CHECK_EQUAL(arrayValSize, 43);
+
+    for (int32_t i = 0; i < arrayValSize; ++i)
+        BOOST_CHECK_EQUAL(arrayVal[i], 43);
+
+    BOOST_REQUIRE(row.HasNext());
+
+    int32_t intVal2 = row.GetNext<int32_t>();
+
+    BOOST_CHECK_EQUAL(intVal2, 43);
+
+    BOOST_REQUIRE(!row.HasNext());
+
+    CheckEmpty(cursor);
+}
+
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
index d3ac2de..8ed587c 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
@@ -172,6 +172,34 @@ namespace ignite
                 }
 
                 /**
+                 * Get next entry assuming it's an array of 8-byte signed
+                 * integers. Maps to "byte[]" type in Java.
+                 *
+                 * This method should only be used on the valid instance.
+                 *
+                 * @param dst Array to store data to.
+                 * @param len Expected length of array.
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 *
+                 * @throw IgniteError class instance in case of failure.
+                 */
+                int32_t GetNextInt8Array(int8_t* dst, int32_t len)
+                {
+                    impl::cache::query::QueryFieldsRowImpl* impl0 = impl.Get();
+
+                    if (impl0)
+                        return impl0->GetNextInt8Array(dst, len);
+                    else
+                    {
+                        throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+                            "Instance is not usable (did you check for error?).");
+                    }
+                }
+
+                /**
                  * Check if the instance is valid.
                  *
                  * Invalid instance can be returned if some of the previous

http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
index bf8d7ac..96d794d 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
@@ -139,7 +139,7 @@ namespace ignite
                         using std::swap;
 
                         swap(sql, other.sql);
-                        swap(sql, other.schema);
+                        swap(schema, other.schema);
                         swap(pageSize, other.pageSize);
                         swap(loc, other.loc);
                         swap(distributedJoins, other.distributedJoins);
@@ -274,6 +274,17 @@ namespace ignite
                 }
 
                 /**
+                 * Add array of bytes as an argument.
+                 *
+                 * @param src Array pointer.
+                 * @param len Array length in bytes.
+                 */
+                void AddInt8ArrayArgument(const int8_t* src, int32_t len)
+                {
+                    args.push_back(new impl::cache::query::QueryInt8ArrayArgument(src, len));
+                }
+
+                /**
                  * Remove all added arguments.
                  */
                 void ClearArguments()

http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_argument.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_argument.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_argument.h
index f2f55bc..e9e7e51 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_argument.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_argument.h
@@ -129,6 +129,69 @@ namespace ignite
                     /** Value. */
                     T val;
                 };
+
+                /**
+                 * Query bytes array argument class.
+                 */
+                class QueryInt8ArrayArgument : public QueryArgumentBase
+                {
+                public:
+                    /**
+                     * Constructor.
+                     *
+                     * @param src Array.
+                     * @param len Array length.
+                     */
+                    QueryInt8ArrayArgument(const int8_t* src, int32_t len) :
+                        val(src, src + len)
+                    {
+                        // No-op.
+                    }
+
+                    /**
+                     * Copy constructor.
+                     *
+                     * @param other Other instance.
+                     */
+                    QueryInt8ArrayArgument(const QueryInt8ArrayArgument& other) :
+                        val(other.val)
+                    {
+                        // No-op.
+                    }
+
+                    /**
+                     * Assignment operator.
+                     *
+                     * @param other Other instance.
+                     * @return *this.
+                     */
+                    QueryInt8ArrayArgument& operator=(const QueryInt8ArrayArgument& other)
+                    {
+                        if (this != &other)
+                            val = other.val;
+
+                        return *this;
+                    }
+
+                    virtual ~QueryInt8ArrayArgument()
+                    {
+                        // No-op.
+                    }
+
+                    virtual QueryArgumentBase* Copy() const
+                    {
+                        return new QueryInt8ArrayArgument(*this);
+                    }
+
+                    virtual void Write(ignite::binary::BinaryRawWriter& writer)
+                    {
+                        writer.WriteInt8Array(&val[0], static_cast<int32_t>(val.size()));
+                    }
+
+                private:
+                    /** Value. */
+                    std::vector<int8_t> val;
+                };
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
index 82cebd5..63e0523 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
@@ -127,6 +127,35 @@ namespace ignite
                     }
 
                     /**
+                     * Get next entry assuming it's an array of 8-byte signed
+                     * integers. Maps to "byte[]" type in Java.
+                     *
+                     * @param dst Array to store data to.
+                     * @param len Expected length of array.
+                     * @return Actual amount of elements read. If "len" argument is less than actual
+                     *     array size or resulting array is set to null, nothing will be written
+                     *     to resulting array and returned value will contain required array length.
+                     *     -1 will be returned in case array in stream was null.
+                     */
+                    int32_t GetNextInt8Array(int8_t* dst, int32_t len)
+                    {
+                        if (IsValid()) {
+
+                            int32_t actualLen = reader.ReadInt8Array(dst, len);
+
+                            if (actualLen == 0 || dst && len >= actualLen)
+                                ++processed;
+
+                            return actualLen;
+                        }
+                        else
+                        {
+                            throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+                                "Instance is not usable (did you check for error?).");
+                        }
+                    }
+
+                    /**
                      * Check if the instance is valid.
                      *
                      * Invalid instance can be returned if some of the previous