You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2016/09/05 13:18:28 UTC

[01/20] ignite git commit: Fixed GridQueryParsingTest.

Repository: ignite
Updated Branches:
  refs/heads/ignite-3611-1 [created] 1cdca9ec9


Fixed GridQueryParsingTest.


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

Branch: refs/heads/ignite-3611-1
Commit: 12fd4976f482ebc43831754645e34042c9073b2d
Parents: d6449ff
Author: sboikov <sb...@gridgain.com>
Authored: Thu Aug 25 12:29:04 2016 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Thu Aug 25 12:29:04 2016 +0300

----------------------------------------------------------------------
 .../internal/processors/query/h2/sql/GridQueryParsingTest.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/12fd4976/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
index ce1f241..1d54bbf 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
@@ -301,7 +301,7 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
     private static String normalizeSql(String sql) {
         return sql.toLowerCase()
             .replaceAll("/\\*(?:.|\r|\n)*?\\*/", " ")
-            .replaceAll("\\s*on\\s+1\\s*=\\s*1\\s*", " ")
+            .replaceAll("\\s*on\\s+1\\s*=\\s*1\\s*", " on true ")
             .replaceAll("\\s+", " ")
             .replaceAll("\\( +", "(")
             .replaceAll(" +\\)", ")")


[03/20] ignite git commit: IGNITE-2208 - Queries with object arguments doesn't work wth BinaryMarshaller.

Posted by vo...@apache.org.
IGNITE-2208 - Queries with object arguments doesn't work wth BinaryMarshaller.


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

Branch: refs/heads/ignite-3611-1
Commit: ae7765329fd6f7d50d13183d13626f39c5682334
Parents: 12f5329
Author: dkarachentsev <dk...@gridgain.com>
Authored: Fri Sep 2 18:01:12 2016 +0300
Committer: dkarachentsev <dk...@gridgain.com>
Committed: Fri Sep 2 18:01:12 2016 +0300

----------------------------------------------------------------------
 .../internal/binary/BinaryMarshaller.java       |   7 +
 .../processors/cache/IgniteCacheProxy.java      |  41 ++
 .../cache/query/GridCacheSqlQuery.java          |  11 +-
 .../GridCacheQueryTransformerSelfTest.java      |   9 +-
 .../query/h2/opt/GridH2ValueCacheObject.java    |   9 -
 ...niteBinaryObjectLocalQueryArgumentsTest.java |  28 ++
 ...aryObjectQueryArgumentsOffheapLocalTest.java |  28 ++
 ...teBinaryObjectQueryArgumentsOffheapTest.java |  30 ++
 .../IgniteBinaryObjectQueryArgumentsTest.java   | 469 ++++++++++++++++++-
 .../query/h2/sql/GridQueryParsingTest.java      |   4 +-
 .../IgniteCacheQuerySelfTestSuite.java          |   9 +
 11 files changed, 610 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMarshaller.java
index 29a1fca..39015e5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryMarshaller.java
@@ -136,4 +136,11 @@ public class BinaryMarshaller extends AbstractMarshaller {
     @Override public void onUndeploy(ClassLoader ldr) {
         impl.context().onUndeploy(ldr);
     }
+
+    /**
+     * @return GridBinaryMarshaller instance.
+     */
+    public GridBinaryMarshaller binaryMarshaller() {
+        return impl;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
index 9b26c1d..8b2e605 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java
@@ -63,6 +63,7 @@ import org.apache.ignite.internal.AsyncSupportAdapter;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.binary.BinaryUtils;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.query.CacheQuery;
 import org.apache.ignite.internal.processors.cache.query.CacheQueryFuture;
@@ -688,6 +689,8 @@ public class IgniteCacheProxy<K, V> extends AsyncSupportAdapter<IgniteCache<K, V
 
             validate(qry);
 
+            convertToBinary(qry);
+
             final CacheOperationContext opCtxCall = ctx.operationContextPerCall();
 
             if (qry instanceof ContinuousQuery)
@@ -764,6 +767,44 @@ public class IgniteCacheProxy<K, V> extends AsyncSupportAdapter<IgniteCache<K, V
     }
 
     /**
+     * Convert query arguments to BinaryObjects if binary marshaller used.
+     *
+     * @param qry Query.
+     */
+    private void convertToBinary(final Query qry) {
+        if (ctx.binaryMarshaller()) {
+            if (qry instanceof SqlQuery) {
+                final SqlQuery sqlQry = (SqlQuery) qry;
+
+                convertToBinary(sqlQry.getArgs());
+            } else if (qry instanceof SpiQuery) {
+                final SpiQuery spiQry = (SpiQuery) qry;
+
+                convertToBinary(spiQry.getArgs());
+            } else if (qry instanceof SqlFieldsQuery) {
+                final SqlFieldsQuery fieldsQry = (SqlFieldsQuery) qry;
+
+                convertToBinary(fieldsQry.getArgs());
+            }
+        }
+    }
+
+    /**
+     * Converts query arguments to BinaryObjects if binary marshaller used.
+     *
+     * @param args Arguments.
+     */
+    private void convertToBinary(final Object[] args) {
+        if (args == null)
+            return;
+
+        for (int i = 0; i < args.length; i++) {
+            if (args[i] != null && !BinaryUtils.isBinaryType(args[i].getClass()))
+                args[i] = ctx.toCacheObject(args[i]);
+        }
+    }
+
+    /**
      * @return {@code true} If this is a replicated cache and we are on a data node.
      */
     private boolean isReplicatedDataNode() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlQuery.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlQuery.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlQuery.java
index 0733827..bcb37c5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlQuery.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheSqlQuery.java
@@ -22,6 +22,7 @@ import java.util.LinkedHashMap;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.GridDirectTransient;
 import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.A;
@@ -153,7 +154,13 @@ public class GridCacheSqlQuery implements Message {
 
         assert paramsBytes != null;
 
-        params = m.unmarshal(paramsBytes, U.resolveClassLoader(ctx.config()));
+        final ClassLoader ldr = U.resolveClassLoader(ctx.config());
+
+        if (m instanceof BinaryMarshaller)
+            // To avoid deserializing of enum types.
+            params = ((BinaryMarshaller)m).binaryMarshaller().unmarshal(paramsBytes, ldr);
+        else
+            params = m.unmarshal(paramsBytes, ldr);
     }
 
     /** {@inheritDoc} */
@@ -271,4 +278,4 @@ public class GridCacheSqlQuery implements Message {
 
         return cp;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryTransformerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryTransformerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryTransformerSelfTest.java
index 6b13e05..e7e173b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryTransformerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/query/GridCacheQueryTransformerSelfTest.java
@@ -66,9 +66,14 @@ public class GridCacheQueryTransformerSelfTest extends GridCommonAbstractTest {
     @Override protected void beforeTestsStarted() throws Exception {
         startGridsMultiThreaded(3);
 
-        Ignition.setClientMode(true);
+        try {
+            Ignition.setClientMode(true);
 
-        startGrid();
+            startGrid();
+        }
+        finally {
+            Ignition.setClientMode(false);
+        }
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2ValueCacheObject.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2ValueCacheObject.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2ValueCacheObject.java
index 29f9675..fd0e6ed 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2ValueCacheObject.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2ValueCacheObject.java
@@ -21,8 +21,6 @@ import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.sql.Types;
 import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.binary.BinaryObject;
-import org.apache.ignite.internal.binary.BinaryEnumObjectImpl;
 import org.apache.ignite.internal.processors.cache.CacheObject;
 import org.apache.ignite.internal.processors.cache.CacheObjectContext;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
@@ -146,13 +144,6 @@ public class GridH2ValueCacheObject extends Value {
             return c1.compareTo(o2);
         }
 
-        if (o1 instanceof BinaryEnumObjectImpl && o2 instanceof Enum) {
-            final BinaryEnumObjectImpl bo1 = (BinaryEnumObjectImpl)o1;
-
-            if (bo1.isTypeEquals(o2.getClass()))
-                return Integer.compare(bo1.enumOrdinal(), ((Enum)o2).ordinal());
-        }
-
         // Group by types.
         if (o1.getClass() != o2.getClass()) {
             if (o1Comparable != o2Comparable)

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectLocalQueryArgumentsTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectLocalQueryArgumentsTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectLocalQueryArgumentsTest.java
new file mode 100644
index 0000000..7e35e51
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectLocalQueryArgumentsTest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.cache;
+
+/**
+ *
+ */
+public class IgniteBinaryObjectLocalQueryArgumentsTest extends IgniteBinaryObjectQueryArgumentsTest {
+    /** {@inheritDoc} */
+    @Override protected boolean isLocal() {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsOffheapLocalTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsOffheapLocalTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsOffheapLocalTest.java
new file mode 100644
index 0000000..560d258
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsOffheapLocalTest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.cache;
+
+/**
+ *
+ */
+public class IgniteBinaryObjectQueryArgumentsOffheapLocalTest extends IgniteBinaryObjectQueryArgumentsOffheapTest {
+    /** {@inheritDoc} */
+    @Override protected boolean isLocal() {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsOffheapTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsOffheapTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsOffheapTest.java
new file mode 100644
index 0000000..d1428ae
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsOffheapTest.java
@@ -0,0 +1,30 @@
+/*
+ * 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.cache;
+
+import org.apache.ignite.cache.CacheMemoryMode;
+
+/**
+ *
+ */
+public class IgniteBinaryObjectQueryArgumentsOffheapTest extends IgniteBinaryObjectQueryArgumentsTest {
+    /** {@inheritDoc} */
+    @Override protected CacheMemoryMode memoryMode() {
+        return CacheMemoryMode.OFFHEAP_TIERED;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsTest.java
index 5676ddd..8a0c5c8 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteBinaryObjectQueryArgumentsTest.java
@@ -17,15 +17,27 @@
 
 package org.apache.ignite.internal.processors.cache;
 
-import java.util.Arrays;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
 import javax.cache.Cache;
-import org.apache.ignite.IgniteBinary;
+
 import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheMemoryMode;
 import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
@@ -43,12 +55,64 @@ public class IgniteBinaryObjectQueryArgumentsTest extends GridCommonAbstractTest
     /** */
     private static final int NODES = 3;
 
+    /** */
+    public static final String PRIM_CACHE = "prim-cache";
+
+    /** */
+    public static final String STR_CACHE = "str-cache";
+
+    /** */
+    public static final String ENUM_CACHE = "enum-cache";
+
+    /** */
+    public static final String UUID_CACHE = "uuid-cache";
+
+    /** */
+    public static final String DATE_CACHE = "date-cache";
+
+    /** */
+    public static final String TIMESTAMP_CACHE = "timestamp-cache";
+
+    /** */
+    public static final String BIG_DECIMAL_CACHE = "decimal-cache";
+
+    /** */
+    public static final String OBJECT_CACHE = "obj-cache";
+
+    /** */
+    public static final String FIELD_CACHE = "field-cache";
+
     /** {@inheritDoc} */
     @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
         IgniteConfiguration cfg = super.getConfiguration(gridName);
 
         ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(IP_FINDER);
 
+        cfg.setCacheConfiguration(getCacheConfigurations());
+
+        cfg.setMarshaller(null);
+
+        return cfg;
+    }
+
+    /**
+     * @return {@code True} If query is local.
+     */
+    protected boolean isLocal() {
+        return false;
+    }
+
+    /**
+     * @return Memory mode.
+     */
+    protected CacheMemoryMode memoryMode() {
+        return CacheMemoryMode.ONHEAP_TIERED;
+    }
+
+    /**
+     * @return Cache config.
+     */
+    protected CacheConfiguration getCacheConfiguration(final String cacheName) {
         CacheConfiguration ccfg = new CacheConfiguration();
         ccfg.setWriteSynchronizationMode(FULL_SYNC);
 
@@ -57,11 +121,64 @@ public class IgniteBinaryObjectQueryArgumentsTest extends GridCommonAbstractTest
         person.setValueType(Person.class.getName());
         person.addQueryField("name", String.class.getName(), null);
 
-        ccfg.setQueryEntities(Arrays.asList(person));
+        ccfg.setQueryEntities(Collections.singletonList(person));
 
-        cfg.setCacheConfiguration(ccfg);
+        ccfg.setMemoryMode(memoryMode());
 
-        cfg.setMarshaller(null);
+        ccfg.setName(cacheName);
+
+        return ccfg;
+    }
+
+    /**
+     * @return Cache configurations.
+     */
+    private CacheConfiguration[] getCacheConfigurations() {
+        final ArrayList<CacheConfiguration> ccfgs = new ArrayList<>();
+
+        ccfgs.add(getCacheConfiguration(OBJECT_CACHE));
+        ccfgs.addAll(getCacheConfigurations(STR_CACHE, String.class, Person.class));
+        ccfgs.addAll(getCacheConfigurations(PRIM_CACHE, Integer.class, Person.class));
+        ccfgs.addAll(getCacheConfigurations(ENUM_CACHE, EnumKey.class, Person.class));
+        ccfgs.addAll(getCacheConfigurations(UUID_CACHE, UUID.class, Person.class));
+        ccfgs.addAll(getCacheConfigurations(DATE_CACHE, Date.class, Person.class));
+        ccfgs.addAll(getCacheConfigurations(TIMESTAMP_CACHE, Timestamp.class, Person.class));
+        ccfgs.addAll(getCacheConfigurations(BIG_DECIMAL_CACHE, BigDecimal.class, Person.class));
+        ccfgs.add(getCacheConfiguration(FIELD_CACHE, Integer.class, SearchValue.class));
+
+        return ccfgs.toArray(new CacheConfiguration[ccfgs.size()]);
+    }
+
+    /**
+     *
+     * @param cacheName Cache name.
+     * @param key Key type.
+     * @param val Value type.
+     * @return Configurations.
+     */
+    private List<CacheConfiguration> getCacheConfigurations(final String cacheName, final Class<?> key, final Class<?> val) {
+        final List<CacheConfiguration> res = new ArrayList<>();
+
+        res.add(getCacheConfiguration(cacheName, key, val));
+        res.add(getCacheConfiguration(cacheName + "-val", val, key));
+
+        return res;
+    }
+
+    /**
+     * @param cacheName Cache name.
+     * @param key Key type.
+     * @param val Value type
+     * @return Configuration.
+     */
+    @SuppressWarnings("unchecked")
+    private CacheConfiguration getCacheConfiguration(final String cacheName, final Class<?> key, final Class<?> val) {
+        CacheConfiguration cfg = new CacheConfiguration();
+
+        cfg.setName(cacheName);
+
+        cfg.setMemoryMode(memoryMode());
+        cfg.setIndexedTypes(key, val);
 
         return cfg;
     }
@@ -70,7 +187,9 @@ public class IgniteBinaryObjectQueryArgumentsTest extends GridCommonAbstractTest
     @Override protected void beforeTestsStarted() throws Exception {
         super.beforeTestsStarted();
 
-        startGridsMultiThreaded(NODES);
+        final int nodes = isLocal() ? 1 : NODES;
+
+        startGridsMultiThreaded(nodes);
     }
 
     /** {@inheritDoc} */
@@ -84,31 +203,210 @@ public class IgniteBinaryObjectQueryArgumentsTest extends GridCommonAbstractTest
      * @throws Exception If failed.
      */
     public void testObjectArgument() throws Exception {
-        IgniteCache<TestKey, Person> cache = ignite(0).cache(null);
+        testKeyQuery(OBJECT_CACHE, new TestKey(1), new TestKey(2));
+    }
 
-        for (int i = 0; i < 100; i++)
-            cache.put(new TestKey(i), new Person("name-" + i));
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPrimitiveObjectArgument() throws Exception {
+        testKeyValQuery(PRIM_CACHE, 1, 2);
+    }
 
-        SqlQuery<TestKey, Person> qry = new SqlQuery<>(Person.class, "where _key=?");
+    /**
+     * @throws Exception If failed.
+     */
+    public void testStringObjectArgument() throws Exception {
+        testKeyValQuery(STR_CACHE, "str1", "str2");
+    }
 
-        IgniteBinary binary = ignite(0).binary();
+    /**
+     * @throws Exception If failed.
+     */
+    public void testEnumObjectArgument() throws Exception {
+       testKeyValQuery(ENUM_CACHE, EnumKey.KEY1, EnumKey.KEY2);
+    }
 
-        for (int i = 0; i < 100; i++) {
-            Object key = new TestKey(i);
+    /**
+     * @throws Exception If failed.
+     */
+    public void testUuidObjectArgument() throws Exception {
+        final UUID uuid1 = UUID.randomUUID();
+        UUID uuid2 = UUID.randomUUID();
 
-            if (i % 2 == 0)
-                key = binary.toBinary(key);
+        while (uuid1.equals(uuid2))
+            uuid2 = UUID.randomUUID();
 
-            qry.setArgs(key);
+        testKeyValQuery(UUID_CACHE, uuid1, uuid2);
+    }
 
-            List<Cache.Entry<TestKey, Person>> res = cache.query(qry).getAll();
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDateObjectArgument() throws Exception {
+        testKeyValQuery(DATE_CACHE, new Date(0), new Date(1));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTimestampArgument() throws Exception {
+        testKeyValQuery(TIMESTAMP_CACHE, new Timestamp(0), new Timestamp(1));
+    }
 
-            assertEquals(1, res.size());
 
-            Person p = res.get(0).getValue();
+    /**
+     * @throws Exception If failed.
+     */
+    public void testBigDecimalArgument() throws Exception {
+        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
 
-            assertEquals("name-" + i, p.name);
+        final BigDecimal bd1 = new BigDecimal(rnd.nextDouble());
+        BigDecimal bd2 = new BigDecimal(rnd.nextDouble());
+
+        while (bd1.equals(bd2))
+            bd2 = new BigDecimal(rnd.nextDouble());
+
+        testKeyValQuery(BIG_DECIMAL_CACHE, bd1, bd2);
+    }
+
+    /**
+     * Test simple queries.
+     *
+     * @param cacheName Cache name.
+     * @param key1 Key 1.
+     * @param key2 Key 2.
+     * @param <T> Key type.
+     */
+    private <T> void testKeyValQuery(final String cacheName, final T key1, final T key2) {
+        testKeyQuery(cacheName, key1, key2);
+        testValQuery(cacheName + "-val", key1, key2);
+    }
+
+    /**
+     * Test simple query by key.
+     *
+     * @param cacheName Cache name.
+     * @param key1 Key 1.
+     * @param key2 Key 2.
+     * @param <T> Key type.
+     */
+    private <T> void testKeyQuery(final String cacheName, final T key1, final T key2) {
+        final IgniteCache<T, Person> cache = ignite(0).cache(cacheName);
+
+        final Person p1 = new Person("p1");
+        final Person p2 = new Person("p2");
+
+        cache.put(key1, p1);
+        cache.put(key2, p2);
+
+        final SqlQuery<T, Person> qry = new SqlQuery<>(Person.class, "where _key=?");
+
+        final SqlFieldsQuery fieldsQry = new SqlFieldsQuery("select * from Person where _key=?");
+
+        qry.setLocal(isLocal());
+        fieldsQry.setLocal(isLocal());
+
+        qry.setArgs(key1);
+        fieldsQry.setArgs(key1);
+
+        final List<Cache.Entry<T, Person>> res = cache.query(qry).getAll();
+        final List<List<?>> fieldsRes = cache.query(fieldsQry).getAll();
+
+        assertEquals(1, res.size());
+        assertEquals(1, fieldsRes.size());
+
+        assertEquals(p1, res.get(0).getValue());
+        assertEquals(key1, res.get(0).getKey());
+
+        assertTrue(fieldsRes.get(0).size() >= 2);
+        assertEquals(key1, fieldsRes.get(0).get(0));
+        assertEquals(p1, fieldsRes.get(0).get(1));
+    }
+
+    /**
+     * Test simple query by value.
+     *
+     * @param cacheName Cache name.
+     * @param val1 Value 1.
+     * @param val2 Value 2.
+     * @param <T> Value type.
+     */
+    private <T> void testValQuery(final String cacheName, final T val1, final T val2) {
+        final IgniteCache<Person, T> cache = ignite(0).cache(cacheName);
+
+        final Class<?> valType = val1.getClass();
+
+        final Person p1 = new Person("p1");
+        final Person p2 = new Person("p2");
+
+        cache.put(p1, val1);
+        cache.put(p2, val2);
+
+        final SqlQuery<Person, T> qry = new SqlQuery<>(valType, "where _val=?");
+
+        final SqlFieldsQuery fieldsQry = new SqlFieldsQuery("select * from " + valType.getSimpleName() + " where _val=?");
+
+        qry.setLocal(isLocal());
+        fieldsQry.setLocal(isLocal());
+
+        qry.setArgs(val1);
+        fieldsQry.setArgs(val1);
+
+        final List<Cache.Entry<Person, T>> res = cache.query(qry).getAll();
+        final List<List<?>> fieldsRes = cache.query(fieldsQry).getAll();
+
+        assertEquals(1, res.size());
+        assertEquals(1, fieldsRes.size());
+
+        assertEquals(p1, res.get(0).getKey());
+        assertEquals(val1, res.get(0).getValue());
+
+        assertTrue(fieldsRes.get(0).size() >= 2);
+        assertEquals(p1, fieldsRes.get(0).get(0));
+        assertEquals(val1, fieldsRes.get(0).get(1));
+    }
+
+    /**
+     * @throws Exception
+     */
+    public void testFieldSearch() throws Exception {
+        final IgniteCache<Integer, SearchValue> cache = ignite(0).cache(FIELD_CACHE);
+
+        final Map<Integer, SearchValue> map = new HashMap<>();
+
+        for (int i = 0; i < 10; i++) {
+            map.put(i,
+                new SearchValue(
+                    UUID.randomUUID(),
+                    String.valueOf(i),
+                    new BigDecimal(i * 0.1),
+                    i,
+                    new Date(i),
+                    new Timestamp(i),
+                    new Person(String.valueOf("name-" + i)),
+                    i % 2 == 0 ? EnumKey.KEY1 : EnumKey.KEY2)
+            );
         }
+
+        cache.putAll(map);
+
+        SqlQuery<Integer, SearchValue> qry = new SqlQuery<>(SearchValue.class,
+            "where uuid=? and str=? and decimal=? and integer=? and date=? and ts=? and person=? and enumKey=?");
+
+        final int k = ThreadLocalRandom.current().nextInt(10);
+
+        final SearchValue val = map.get(k);
+
+        qry.setLocal(isLocal());
+        qry.setArgs(val.uuid, val.str, val.decimal, val.integer, val.date, val.ts, val.person, val.enumKey);
+
+        final List<Cache.Entry<Integer, SearchValue>> res = cache.query(qry).getAll();
+
+        assertEquals(1, res.size());
+
+        assertEquals(val.integer, res.get(0).getKey());
+        assertEquals(val, res.get(0).getValue());
     }
 
     /**
@@ -124,6 +422,27 @@ public class IgniteBinaryObjectQueryArgumentsTest extends GridCommonAbstractTest
         public Person(String name) {
             this.name = name;
         }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(final Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            final Person person = (Person) o;
+
+            return name != null ? name.equals(person.name) : person.name == null;
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return name != null ? name.hashCode() : 0;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(Person.class, this);
+        }
     }
 
     /**
@@ -158,4 +477,114 @@ public class IgniteBinaryObjectQueryArgumentsTest extends GridCommonAbstractTest
             return id;
         }
     }
+
+    /**
+     *
+     */
+    private enum EnumKey {
+        /** */
+        KEY1,
+
+        /** */
+        KEY2
+    }
+
+    /**
+     *
+     */
+    private static class SearchValue {
+        /** */
+        @QuerySqlField
+        private UUID uuid;
+
+        /** */
+        @QuerySqlField
+        private String str;
+
+        /** */
+        @QuerySqlField
+        private BigDecimal decimal;
+
+        /** */
+        @QuerySqlField
+        private Integer integer;
+
+        /** */
+        @QuerySqlField
+        private Date date;
+
+        /** */
+        @QuerySqlField
+        private Timestamp ts;
+
+        /** */
+        @QuerySqlField
+        private Person person;
+
+        /** */
+        @QuerySqlField
+        private EnumKey enumKey;
+
+        /**
+         *
+         * @param uuid UUID.
+         * @param str String.
+         * @param decimal Decimal.
+         * @param integer Integer.
+         * @param date Date.
+         * @param ts Timestamp.
+         * @param person Person.
+         * @param enumKey Enum.
+         */
+        public SearchValue(
+            final UUID uuid,
+            final String str,
+            final BigDecimal decimal,
+            final Integer integer,
+            final Date date,
+            final Timestamp ts,
+            final Person person,
+            final EnumKey enumKey
+        ) {
+            this.uuid = uuid;
+            this.str = str;
+            this.decimal = decimal;
+            this.integer = integer;
+            this.date = date;
+            this.ts = ts;
+            this.person = person;
+            this.enumKey = enumKey;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(final Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            final SearchValue that = (SearchValue) o;
+
+            if (uuid != null ? !uuid.equals(that.uuid) : that.uuid != null) return false;
+            if (str != null ? !str.equals(that.str) : that.str != null) return false;
+            if (decimal != null ? !decimal.equals(that.decimal) : that.decimal != null) return false;
+            if (integer != null ? !integer.equals(that.integer) : that.integer != null) return false;
+            if (date != null ? !date.equals(that.date) : that.date != null) return false;
+            if (ts != null ? !ts.equals(that.ts) : that.ts != null) return false;
+            if (person != null ? !person.equals(that.person) : that.person != null) return false;
+            return enumKey == that.enumKey;
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            int res = uuid != null ? uuid.hashCode() : 0;
+            res = 31 * res + (str != null ? str.hashCode() : 0);
+            res = 31 * res + (decimal != null ? decimal.hashCode() : 0);
+            res = 31 * res + (integer != null ? integer.hashCode() : 0);
+            res = 31 * res + (date != null ? date.hashCode() : 0);
+            res = 31 * res + (ts != null ? ts.hashCode() : 0);
+            res = 31 * res + (person != null ? person.hashCode() : 0);
+            res = 31 * res + (enumKey != null ? enumKey.hashCode() : 0);
+            return res;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
index 1d54bbf..cf000e9 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
@@ -301,7 +301,7 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
     private static String normalizeSql(String sql) {
         return sql.toLowerCase()
             .replaceAll("/\\*(?:.|\r|\n)*?\\*/", " ")
-            .replaceAll("\\s*on\\s+1\\s*=\\s*1\\s*", " on true ")
+            .replaceAll("\\s*on\\s+1\\s*=\\s*1\\s*", " ")
             .replaceAll("\\s+", " ")
             .replaceAll("\\( +", "(")
             .replaceAll(" +\\)", ")")
@@ -366,4 +366,4 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
         @QuerySqlField(index = true)
         public String street = "Nevskiy";
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ae776532/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 3652acd..e7f55a1 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -24,6 +24,10 @@ import org.apache.ignite.internal.processors.cache.GridCacheQueryInternalKeysSel
 import org.apache.ignite.internal.processors.cache.GridCacheQuerySerializationSelfTest;
 import org.apache.ignite.internal.processors.cache.GridCacheReduceQueryMultithreadedSelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectFieldsQuerySelfTest;
+import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectLocalQueryArgumentsTest;
+import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectQueryArgumentsOffheapLocalTest;
+import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectQueryArgumentsOffheapTest;
+import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectQueryArgumentsTest;
 import org.apache.ignite.internal.processors.cache.IgniteBinaryWrappedObjectFieldsQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheCollocatedQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheDuplicateEntityConfigurationSelfTest;
@@ -118,6 +122,11 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
         suite.addTestSuite(IgniteCacheQueryNoRebalanceSelfTest.class);
         suite.addTestSuite(GridCacheQueryTransformerSelfTest.class);
 
+        suite.addTestSuite(IgniteBinaryObjectQueryArgumentsTest.class);
+        suite.addTestSuite(IgniteBinaryObjectQueryArgumentsOffheapTest.class);
+        suite.addTestSuite(IgniteBinaryObjectQueryArgumentsOffheapLocalTest.class);
+        suite.addTestSuite(IgniteBinaryObjectLocalQueryArgumentsTest.class);
+
         return suite;
     }
 }


[09/20] ignite git commit: IGNITE-3801: ODBC: Added tests for OUTER JOIN. This closes #1027.

Posted by vo...@apache.org.
IGNITE-3801: ODBC: Added tests for OUTER JOIN. This closes #1027.


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

Branch: refs/heads/ignite-3611-1
Commit: d06eaa2344a753e08d1e3cb00e6b4ab83c6a9a01
Parents: c992213
Author: isapego <is...@gridgain.com>
Authored: Sun Sep 4 16:52:04 2016 +0300
Committer: thatcoach <pp...@list.ru>
Committed: Sun Sep 4 16:52:04 2016 +0300

----------------------------------------------------------------------
 modules/platforms/cpp/odbc-test/Makefile.am     |   1 +
 .../cpp/odbc-test/project/vs/odbc-test.vcxproj  |   1 +
 .../project/vs/odbc-test.vcxproj.filters        |   3 +
 .../cpp/odbc-test/src/sql_outer_join_test.cpp   | 498 +++++++++++++++++++
 .../odbc-test/src/sql_test_suite_fixture.cpp    |   6 +-
 .../cpp/odbc/src/config/connection_info.cpp     |   4 +-
 6 files changed, 507 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d06eaa23/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 1ca85a7..c3dd86a 100644
--- a/modules/platforms/cpp/odbc-test/Makefile.am
+++ b/modules/platforms/cpp/odbc-test/Makefile.am
@@ -70,6 +70,7 @@ ignite_odbc_tests_SOURCES = \
     src/sql_operators_test.cpp \
     src/sql_value_expressions_test.cpp \
     src/sql_types_test.cpp \
+    src/sql_outer_join_test.cpp \
     ../odbc/src/cursor.cpp \
     ../odbc/src/config/connection_info.cpp \
     ../odbc/src/app/application_data_buffer.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/d06eaa23/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 cb5735f..b85f1e6 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
@@ -170,6 +170,7 @@
     <ClCompile Include="..\..\src\parser_test.cpp" />
     <ClCompile Include="..\..\src\row_test.cpp" />
     <ClCompile Include="..\..\src\sql_aggregate_functions_test.cpp" />
+    <ClCompile Include="..\..\src\sql_outer_join_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" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/d06eaa23/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 270bdd6..ee5df76 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
@@ -106,6 +106,9 @@
     <ClCompile Include="..\..\src\sql_value_expressions_test.cpp">
       <Filter>Code</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\sql_outer_join_test.cpp">
+      <Filter>Code</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\test_type.h">

http://git-wip-us.apache.org/repos/asf/ignite/blob/d06eaa23/modules/platforms/cpp/odbc-test/src/sql_outer_join_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/sql_outer_join_test.cpp b/modules/platforms/cpp/odbc-test/src/sql_outer_join_test.cpp
new file mode 100644
index 0000000..426041b
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/src/sql_outer_join_test.cpp
@@ -0,0 +1,498 @@
+/*
+ * 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 _MSC_VER
+#   define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include "sql_test_suite_fixture.h"
+#include "test_utils.h"
+
+using namespace ignite;
+
+using namespace boost::unit_test;
+
+BOOST_FIXTURE_TEST_SUITE(SqlOuterJoinTestSuite, ignite::SqlTestSuiteFixture)
+
+// Checking that left outer joins are supported.
+// Corresponds to SQL_OJ_LEFT flag.
+BOOST_AUTO_TEST_CASE(TestOuterJoinLeft)
+{
+    TestType in1;
+    TestType in2;
+
+    in1.i32Field = 20;
+    in2.i32Field = 30;
+
+    in1.i16Field = 40;
+    in2.i16Field = 20;
+
+    testCache.Put(1, in1);
+    testCache.Put(2, in2);
+
+    SQLINTEGER columns[2];
+    SQLLEN columnsLen[2];
+
+    SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &columns[0], 0, &columnsLen[0]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 2, SQL_C_SLONG, &columns[1], 0, &columnsLen[1]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    SQLCHAR request[] = "SELECT T1.i32Field, T2.i16Field FROM "
+        "{oj TestType T1 LEFT OUTER JOIN TestType T2 ON T1.i32Field = T2.i16Field}";
+
+    ret = SQLExecDirect(stmt, request, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 20);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 20);
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 30);
+
+    BOOST_CHECK_EQUAL(columnsLen[1], SQL_NULL_DATA);
+
+    ret = SQLFetch(stmt);
+    BOOST_CHECK(ret == SQL_NO_DATA);
+}
+
+// Checking that the column names in the ON clause of the outer join do not
+// have to be in the same order as their respective table names in the OUTER
+// JOIN clause. Corresponds to SQL_OJ_NOT_ORDERED flag. 
+BOOST_AUTO_TEST_CASE(TestOuterJoinOrdering)
+{
+    TestType in1;
+    TestType in2;
+
+    in1.i32Field = 20;
+    in2.i32Field = 30;
+
+    in1.i16Field = 40;
+    in2.i16Field = 20;
+
+    testCache.Put(1, in1);
+    testCache.Put(2, in2);
+
+    SQLINTEGER columns[2];
+    SQLLEN columnsLen[2];
+
+    SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &columns[0], 0, &columnsLen[0]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 2, SQL_C_SLONG, &columns[1], 0, &columnsLen[1]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    SQLCHAR request[] = "SELECT T1.i32Field, T2.i16Field FROM "
+        "{oj TestType T1 LEFT OUTER JOIN TestType T2 ON T2.i16Field = T1.i32Field}";
+
+    ret = SQLExecDirect(stmt, request, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 20);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 20);
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 30);
+
+    BOOST_CHECK_EQUAL(columnsLen[1], SQL_NULL_DATA);
+
+    ret = SQLFetch(stmt);
+    BOOST_CHECK(ret == SQL_NO_DATA);
+}
+
+// Checking that the comparison operator in the ON clause can be any of the ODBC
+// comparison operators. Corresponds to SQL_OJ_ALL_COMPARISON_OPS flag.
+// Operator '<'.
+BOOST_AUTO_TEST_CASE(TestOuterJoinOpsLess)
+{
+    TestType in1;
+    TestType in2;
+
+    in1.i32Field = 20;
+    in2.i32Field = 30;
+
+    in1.i16Field = 40;
+    in2.i16Field = 20;
+
+    testCache.Put(1, in1);
+    testCache.Put(2, in2);
+
+    SQLINTEGER columns[2];
+    SQLLEN columnsLen[2];
+
+    SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &columns[0], 0, &columnsLen[0]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 2, SQL_C_SLONG, &columns[1], 0, &columnsLen[1]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    SQLCHAR request[] = "SELECT T1.i32Field, T2.i16Field FROM "
+        "{oj TestType T1 LEFT OUTER JOIN TestType T2 ON T2.i16Field < T1.i32Field}";
+
+    ret = SQLExecDirect(stmt, request, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 20);
+
+    BOOST_CHECK_EQUAL(columnsLen[1], SQL_NULL_DATA);
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 30);
+
+    BOOST_CHECK_EQUAL(columnsLen[1], SQL_NULL_DATA);
+
+    ret = SQLFetch(stmt);
+    BOOST_CHECK(ret == SQL_NO_DATA);
+}
+
+// Checking that the comparison operator in the ON clause can be any of the ODBC
+// comparison operators. Corresponds to SQL_OJ_ALL_COMPARISON_OPS flag.
+// Operator '>'.
+BOOST_AUTO_TEST_CASE(TestOuterJoinOpsGreater)
+{
+    TestType in1;
+    TestType in2;
+
+    in1.i32Field = 20;
+    in2.i32Field = 30;
+
+    in1.i16Field = 40;
+    in2.i16Field = 20;
+
+    testCache.Put(1, in1);
+    testCache.Put(2, in2);
+
+    SQLINTEGER columns[2];
+    SQLLEN columnsLen[2];
+
+    SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &columns[0], 0, &columnsLen[0]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 2, SQL_C_SLONG, &columns[1], 0, &columnsLen[1]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    SQLCHAR request[] = "SELECT T1.i32Field, T2.i16Field FROM "
+        "{oj TestType T1 LEFT OUTER JOIN TestType T2 ON T2.i16Field > T1.i32Field}";
+
+    ret = SQLExecDirect(stmt, request, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 20);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 40);
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 30);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 40);
+
+    ret = SQLFetch(stmt);
+    BOOST_CHECK(ret == SQL_NO_DATA);
+}
+
+// Checking that the comparison operator in the ON clause can be any of the ODBC
+// comparison operators. Corresponds to SQL_OJ_ALL_COMPARISON_OPS flag.
+// Operator '<='.
+BOOST_AUTO_TEST_CASE(TestOuterJoinOpsLessOrEqual)
+{
+    TestType in1;
+    TestType in2;
+
+    in1.i32Field = 20;
+    in2.i32Field = 30;
+
+    in1.i16Field = 40;
+    in2.i16Field = 20;
+
+    testCache.Put(1, in1);
+    testCache.Put(2, in2);
+
+    SQLINTEGER columns[2];
+    SQLLEN columnsLen[2];
+
+    SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &columns[0], 0, &columnsLen[0]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 2, SQL_C_SLONG, &columns[1], 0, &columnsLen[1]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    SQLCHAR request[] = "SELECT T1.i32Field, T2.i16Field FROM "
+        "{oj TestType T1 LEFT OUTER JOIN TestType T2 ON T2.i16Field <= T1.i32Field}";
+
+    ret = SQLExecDirect(stmt, request, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 20);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 20);
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 30);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 20);
+
+    ret = SQLFetch(stmt);
+    BOOST_CHECK(ret == SQL_NO_DATA);
+}
+
+// Checking that the comparison operator in the ON clause can be any of the ODBC
+// comparison operators. Corresponds to SQL_OJ_ALL_COMPARISON_OPS flag.
+// Operator '>='.
+BOOST_AUTO_TEST_CASE(TestOuterJoinOpsGreaterOrEqual)
+{
+    TestType in1;
+    TestType in2;
+
+    in1.i32Field = 20;
+    in2.i32Field = 30;
+
+    in1.i16Field = 40;
+    in2.i16Field = 20;
+
+    testCache.Put(1, in1);
+    testCache.Put(2, in2);
+
+    SQLINTEGER columns[2];
+    SQLLEN columnsLen[2];
+
+    SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &columns[0], 0, &columnsLen[0]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 2, SQL_C_SLONG, &columns[1], 0, &columnsLen[1]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    SQLCHAR request[] = "SELECT T1.i32Field, T2.i16Field FROM "
+        "{oj TestType T1 LEFT OUTER JOIN TestType T2 ON T2.i16Field >= T1.i32Field}";
+
+    ret = SQLExecDirect(stmt, request, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 20);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 40);
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 20);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 20);
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 30);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 40);
+
+    ret = SQLFetch(stmt);
+    BOOST_CHECK(ret == SQL_NO_DATA);
+}
+
+// Checking that the comparison operator in the ON clause can be any of the ODBC
+// comparison operators. Corresponds to SQL_OJ_ALL_COMPARISON_OPS flag.
+// Operator '!='.
+BOOST_AUTO_TEST_CASE(TestOuterJoinOpsNotEqual)
+{
+    TestType in1;
+    TestType in2;
+
+    in1.i32Field = 20;
+    in2.i32Field = 30;
+
+    in1.i16Field = 40;
+    in2.i16Field = 20;
+
+    testCache.Put(1, in1);
+    testCache.Put(2, in2);
+
+    SQLINTEGER columns[2];
+    SQLLEN columnsLen[2];
+
+    SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &columns[0], 0, &columnsLen[0]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLBindCol(stmt, 2, SQL_C_SLONG, &columns[1], 0, &columnsLen[1]);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    SQLCHAR request[] = "SELECT T1.i32Field, T2.i16Field FROM "
+        "{oj TestType T1 LEFT OUTER JOIN TestType T2 ON T2.i16Field != T1.i32Field}";
+
+    ret = SQLExecDirect(stmt, request, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 20);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 40);
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 30);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 40);
+
+    ret = SQLFetch(stmt);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    BOOST_CHECK_NE(columnsLen[0], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[0], 30);
+
+    BOOST_CHECK_NE(columnsLen[1], SQL_NULL_DATA);
+    BOOST_CHECK_EQUAL(columns[1], 20);
+
+    ret = SQLFetch(stmt);
+    BOOST_CHECK(ret == SQL_NO_DATA);
+}
+
+BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/d06eaa23/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp b/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
index 69b4bfa..657b854 100644
--- a/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
+++ b/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
@@ -117,17 +117,17 @@ namespace ignite
         ret = SQLBindCol(stmt, 1, type, column, bufSize, resSize);
 
         if (!SQL_SUCCEEDED(ret))
-            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)) ;
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
 
         ret = SQLExecDirect(stmt, reinterpret_cast<SQLCHAR*>(const_cast<char*>(request)), SQL_NTS);
 
         if (!SQL_SUCCEEDED(ret))
-            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)) ;
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
 
         ret = SQLFetch(stmt);
 
         if (!SQL_SUCCEEDED(ret))
-            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)) ;
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
 
         ret = SQLFetch(stmt);
         BOOST_CHECK(ret == SQL_NO_DATA) ;

http://git-wip-us.apache.org/repos/asf/ignite/blob/d06eaa23/modules/platforms/cpp/odbc/src/config/connection_info.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/connection_info.cpp b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
index 744a88e..ca8d1a0 100644
--- a/modules/platforms/cpp/odbc/src/config/connection_info.cpp
+++ b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
@@ -298,9 +298,7 @@ namespace ignite
 #ifdef SQL_OJ_CAPABILITIES
                 // Bitmask enumerating the types of outer joins supported by the 
                 // driver and data source.
-                intParams[SQL_OJ_CAPABILITIES] = SQL_OJ_LEFT | SQL_OJ_RIGHT |
-                    SQL_OJ_FULL | SQL_OJ_NESTED | SQL_OJ_INNER |
-                    SQL_OJ_ALL_COMPARISON_OPS;
+                intParams[SQL_OJ_CAPABILITIES] = SQL_OJ_LEFT | SQL_OJ_NOT_ORDERED | SQL_OJ_ALL_COMPARISON_OPS;
 #endif // SQL_OJ_CAPABILITIES
 
 #ifdef SQL_POS_OPERATIONS


[18/20] ignite git commit: IGNITE-3819: ODBC: Improved error logging. This closes #1024.

Posted by vo...@apache.org.
IGNITE-3819: ODBC: Improved error logging. This closes #1024.


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

Branch: refs/heads/ignite-3611-1
Commit: e3533010b584ba986196f9c7dbc36359aebd829e
Parents: df8163f
Author: Igor Sapego <is...@gridgain.com>
Authored: Mon Sep 5 15:02:07 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Sep 5 15:02:07 2016 +0300

----------------------------------------------------------------------
 .../processors/odbc/OdbcRequestHandler.java     | 31 +++++++++++++++-----
 1 file changed, 23 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e3533010/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
index 3f7d505..69bbc74 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
@@ -28,6 +28,7 @@ import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
 import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
 import org.apache.ignite.lang.IgniteProductVersion;
 
@@ -97,16 +98,16 @@ public class OdbcRequestHandler {
                     return executeQuery(reqId, (OdbcQueryExecuteRequest)req);
 
                 case FETCH_SQL_QUERY:
-                    return fetchQuery((OdbcQueryFetchRequest)req);
+                    return fetchQuery(reqId, (OdbcQueryFetchRequest)req);
 
                 case CLOSE_SQL_QUERY:
-                    return closeQuery((OdbcQueryCloseRequest)req);
+                    return closeQuery(reqId, (OdbcQueryCloseRequest)req);
 
                 case GET_COLUMNS_META:
-                    return getColumnsMeta((OdbcQueryGetColumnsMetaRequest)req);
+                    return getColumnsMeta(reqId, (OdbcQueryGetColumnsMetaRequest)req);
 
                 case GET_TABLES_META:
-                    return getTablesMeta((OdbcQueryGetTablesMetaRequest)req);
+                    return getTablesMeta(reqId, (OdbcQueryGetTablesMetaRequest)req);
             }
 
             return new OdbcResponse(OdbcResponse.STATUS_FAILED, "Unsupported ODBC request: " + req);
@@ -189,6 +190,8 @@ public class OdbcRequestHandler {
         catch (Exception e) {
             qryCursors.remove(qryId);
 
+            U.error(log, "Failed to execute SQL query [reqId=" + reqId + ", req=" + req + ']', e);
+
             return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage());
         }
     }
@@ -196,10 +199,11 @@ public class OdbcRequestHandler {
     /**
      * {@link OdbcQueryCloseRequest} command handler.
      *
+     * @param reqId Request ID.
      * @param req Execute query request.
      * @return Response.
      */
-    private OdbcResponse closeQuery(OdbcQueryCloseRequest req) {
+    private OdbcResponse closeQuery(long reqId, OdbcQueryCloseRequest req) {
         try {
             QueryCursor cur = qryCursors.get(req.queryId()).get1();
 
@@ -217,6 +221,8 @@ public class OdbcRequestHandler {
         catch (Exception e) {
             qryCursors.remove(req.queryId());
 
+            U.error(log, "Failed to close SQL query [reqId=" + reqId + ", req=" + req.queryId() + ']', e);
+
             return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage());
         }
     }
@@ -224,10 +230,11 @@ public class OdbcRequestHandler {
     /**
      * {@link OdbcQueryFetchRequest} command handler.
      *
+     * @param reqId Request ID.
      * @param req Execute query request.
      * @return Response.
      */
-    private OdbcResponse fetchQuery(OdbcQueryFetchRequest req) {
+    private OdbcResponse fetchQuery(long reqId, OdbcQueryFetchRequest req) {
         try {
             Iterator cur = qryCursors.get(req.queryId()).get2();
 
@@ -244,6 +251,8 @@ public class OdbcRequestHandler {
             return new OdbcResponse(res);
         }
         catch (Exception e) {
+            U.error(log, "Failed to fetch SQL query result [reqId=" + reqId + ", req=" + req + ']', e);
+
             return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage());
         }
     }
@@ -251,10 +260,11 @@ public class OdbcRequestHandler {
     /**
      * {@link OdbcQueryGetColumnsMetaRequest} command handler.
      *
+     * @param reqId Request ID.
      * @param req Get columns metadata request.
      * @return Response.
      */
-    private OdbcResponse getColumnsMeta(OdbcQueryGetColumnsMetaRequest req) {
+    private OdbcResponse getColumnsMeta(long reqId, OdbcQueryGetColumnsMetaRequest req) {
         try {
             List<OdbcColumnMeta> meta = new ArrayList<>();
 
@@ -298,6 +308,8 @@ public class OdbcRequestHandler {
             return new OdbcResponse(res);
         }
         catch (Exception e) {
+            U.error(log, "Failed to get columns metadata [reqId=" + reqId + ", req=" + req + ']', e);
+
             return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage());
         }
     }
@@ -305,10 +317,11 @@ public class OdbcRequestHandler {
     /**
      * {@link OdbcQueryGetTablesMetaRequest} command handler.
      *
+     * @param reqId Request ID.
      * @param req Get tables metadata request.
      * @return Response.
      */
-    private OdbcResponse getTablesMeta(OdbcQueryGetTablesMetaRequest req) {
+    private OdbcResponse getTablesMeta(long reqId, OdbcQueryGetTablesMetaRequest req) {
         try {
             List<OdbcTableMeta> meta = new ArrayList<>();
 
@@ -340,6 +353,8 @@ public class OdbcRequestHandler {
             return new OdbcResponse(res);
         }
         catch (Exception e) {
+            U.error(log, "Failed to get tables metadata [reqId=" + reqId + ", req=" + req + ']', e);
+
             return new OdbcResponse(OdbcResponse.STATUS_FAILED, e.getMessage());
         }
     }


[12/20] ignite git commit: IGNITE-3829: Additional fix.

Posted by vo...@apache.org.
IGNITE-3829: Additional fix.


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

Branch: refs/heads/ignite-3611-1
Commit: 3aa13f716934a6ccfe49f8bf99ec3b654e263900
Parents: fc2fe7b
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Mon Sep 5 10:19:48 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Sep 5 10:19:48 2016 +0300

----------------------------------------------------------------------
 .../cache/binary/CacheObjectBinaryProcessorImpl.java     | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3aa13f71/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
index ecd27f7..82e67ac 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
@@ -709,10 +709,15 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
             if (meta != null) {
                 String name = meta.affinityKeyFieldName();
 
-                affKeyFields.putIfAbsent(meta.typeId(), new T1<>(meta.field(name)));
+                if (name != null) {
+                    BinaryField field = meta.field(name);
 
-                if (name != null)
-                    return po.field(name);
+                    affKeyFields.putIfAbsent(meta.typeId(), new T1<>(field));
+
+                    return field.value(po);
+                }
+                else
+                    affKeyFields.putIfAbsent(meta.typeId(), new T1<BinaryField>(null));
             }
             else if (po instanceof BinaryObjectEx) {
                 int typeId = ((BinaryObjectEx)po).typeId();


[17/20] ignite git commit: IGNITE-3743: ODBC: Added procedure call escape sequence support. This closes #1008.

Posted by vo...@apache.org.
IGNITE-3743: ODBC: Added procedure call escape sequence support. This closes #1008.


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

Branch: refs/heads/ignite-3611-1
Commit: df8163f1ad3a390bb8d51b0eb2f378b5b3663025
Parents: 42963e6
Author: Andrey V. Mashenkov <an...@gmail.com>
Authored: Mon Sep 5 14:15:59 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Sep 5 14:15:59 2016 +0300

----------------------------------------------------------------------
 .../processors/odbc/escape/OdbcEscapeType.java  |   4 +
 .../processors/odbc/escape/OdbcEscapeUtils.java |   5 +
 .../odbc/OdbcEscapeSequenceSelfTest.java        | 125 +++++++++++++++++++
 3 files changed, 134 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/df8163f1/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeType.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeType.java
index 3bf0324..c7e3234 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeType.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeType.java
@@ -27,6 +27,9 @@ public enum OdbcEscapeType {
     /** Outer join. */
     OUTER_JOIN("oj", true, false),
 
+    /** Stored procedure call */
+    CALL("call", true, false),
+
     /** Date. */
     DATE("d", true, false),
 
@@ -47,6 +50,7 @@ public enum OdbcEscapeType {
         SCALAR_FUNCTION, // Assume that scalar functions are very frequent.
         DATE, TIMESTAMP, // Date and timestamp are relatively frequent as well; also TS must go before T.
         OUTER_JOIN,      // Joins are less frequent,
+        CALL,            // Procedure calls are less frequent than joins.
         LIKE, TIME, GUID // LIKE, TIME and GUID are even less frequent.
     };
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/df8163f1/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
index 48d4296..88afc52 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
@@ -278,6 +278,11 @@ public class OdbcEscapeUtils {
             case OUTER_JOIN:
                 return parseExpression(text, startPos0, len0);
 
+            case CALL: {
+                String val = parseExpression(text, startPos0, len0);
+
+                return "CALL " + val;
+            }
             default:
                 throw new IgniteException("Unsupported escape sequence token [text=" +
                     substring(text, startPos, len) + ", token=" + token.type().body() + ']');

http://git-wip-us.apache.org/repos/asf/ignite/blob/df8163f1/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
index 3fec7d3..26221ea 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
@@ -540,6 +540,131 @@ public class OdbcEscapeSequenceSelfTest extends GridCommonAbstractTest {
         checkFail("{fn func(arg')}");
     }
 
+
+    /**
+     * Test escape sequence series.
+     */
+    public void testSimpleCallProc() throws Exception {
+        check(
+            "CALL test()",
+            "{call test()}"
+        );
+
+        check(
+            "select CALL test()",
+            "select {call test()}"
+        );
+
+        check(
+            "select CALL test() from table;",
+            "select {call test()} from table;"
+        );
+
+        check(
+            "CALL func(field1) CALL func(field2)",
+            "{call func(field1)} {call func(field2)}"
+        );
+
+        check(
+            "select CALL func(field1), CALL func(field2)",
+            "select {call func(field1)}, {call func(field2)}"
+        );
+
+        check(
+            "select CALL func(field1), CALL func(field2) from table;",
+            "select {call func(field1)}, {call func(field2)} from table;"
+        );
+    }
+
+    /**
+     * Test simple nested escape sequences. Depth = 2.
+     */
+    public void testNestedCallProc() throws Exception {
+        check(
+            "CALL func1(field1, CALL func2(field2))",
+            "{call func1(field1, {call func2(field2)})}"
+        );
+
+        check(
+            "select CALL func1(field1, CALL func2(field2))",
+            "select {call func1(field1, {call func2(field2)})}"
+        );
+
+        check(
+            "select CALL func1(field1, CALL func2(field2), field3) from SomeTable;",
+            "select {call func1(field1, {call func2(field2)}, field3)} from SomeTable;"
+        );
+    }
+
+    /**
+     * Test nested escape sequences. Depth > 2.
+     */
+    public void testDeepNestedCallProc() {
+        check(
+            "CALL func1(CALL func2(CALL func3(field1)))",
+            "{call func1({call func2({call func3(field1)})})}"
+        );
+
+        check(
+            "CALL func1(CALL func2(CALL func3(CALL func4(field1))))",
+            "{call func1({call func2({call func3({call func4(field1)})})})}"
+        );
+
+        check(
+            "select CALL func1(field1, CALL func2(CALL func3(field2), field3))",
+            "select {call func1(field1, {call func2({call func3(field2)}, field3)})}"
+        );
+
+        check(
+            "select CALL func1(field1, CALL func2(CALL func3(field2), field3)) from SomeTable;",
+            "select {call func1(field1, {call func2({call func3(field2)}, field3)})} from SomeTable;"
+        );
+    }
+
+    /**
+     * Test series of nested escape sequences.
+     */
+    public void testNestedCallProcMixed() {
+        check(
+            "CALL func1(CALL func2(field1), CALL func3(field2))",
+            "{call func1({call func2(field1)}, {call func3(field2)})}"
+        );
+
+        check(
+            "select CALL func1(CALL func2(field1), CALL func3(field2)) from table;",
+            "select {call func1({call func2(field1)}, {call func3(field2)})} from table;"
+        );
+
+        check(
+            "CALL func1(CALL func2(CALL func3(field1))) CALL func1(CALL func2(field2))",
+            "{call func1({call func2({call func3(field1)})})} {call func1({call func2(field2)})}"
+        );
+    }
+
+    /**
+     * Test invalid escape sequence.
+     */
+    public void testFailedOnInvalidCallProcSequence() {
+        checkFail("{callfunc1()}");
+
+        checkFail("select {call func1(field1, {call func2(field2), field3)} from SomeTable;");
+
+        checkFail("select {call func1(field1, call func2(field2)}, field3)} from SomeTable;");
+    }
+
+    /**
+     * Test escape sequences with additional whitespace characters
+     */
+    public void testCallProcEscapeSequenceWithWhitespaces() throws Exception {
+        check("CALL func1()", "{ call func1()}");
+
+        check("CALL func1()", "{    call  func1()}");
+
+        check("CALL func1()", "{ \n call\nfunc1()}");
+
+        checkFail("{ \n func1()}");
+    }
+
     /**
      * Check parsing logic.
      *


[19/20] ignite git commit: IGNITE-3741: ODBC: Added character escape support to expression parser. This closes #1004.

Posted by vo...@apache.org.
IGNITE-3741: ODBC: Added character escape support to expression parser. This closes #1004.


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

Branch: refs/heads/ignite-3611-1
Commit: 008cf64429f40635e396a71f2c0aaf184077ff2b
Parents: e353301
Author: Andrey V. Mashenkov <an...@gmail.com>
Authored: Mon Sep 5 15:17:53 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Sep 5 15:17:53 2016 +0300

----------------------------------------------------------------------
 .../processors/odbc/escape/OdbcEscapeType.java  |  9 ++-
 .../processors/odbc/escape/OdbcEscapeUtils.java | 53 ++++++------
 .../odbc/OdbcEscapeSequenceSelfTest.java        | 85 +++++++++++++++++++-
 3 files changed, 119 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/008cf644/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeType.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeType.java
index c7e3234..44d8361 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeType.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeType.java
@@ -42,8 +42,11 @@ public enum OdbcEscapeType {
     /** GUID. */
     GUID("guid", true, false),
 
-    /** LIKE clause. */
-    LIKE("\'", false, true);
+    /** LIKE escape character clause. */
+    ESCAPE_WO_TOKEN("\'", false, false),
+
+    /** LIKE escape character clause. */
+    ESCAPE("escape", true, false);
 
     /** Values in convenient order. */
     private static final OdbcEscapeType[] VALS = new OdbcEscapeType[] {
@@ -51,7 +54,7 @@ public enum OdbcEscapeType {
         DATE, TIMESTAMP, // Date and timestamp are relatively frequent as well; also TS must go before T.
         OUTER_JOIN,      // Joins are less frequent,
         CALL,            // Procedure calls are less frequent than joins.
-        LIKE, TIME, GUID // LIKE, TIME and GUID are even less frequent.
+        ESCAPE_WO_TOKEN, ESCAPE, TIME, GUID // LIKE, TIME and GUID are even less frequent.
     };
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/008cf644/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
index 88afc52..bbf19c7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/escape/OdbcEscapeUtils.java
@@ -76,12 +76,9 @@ public class OdbcEscapeUtils {
         while (curPos < text.length()) {
             char curChar = text.charAt(curPos);
 
-            if (curChar == '\'') {
-                if (!insideLiteral)
-                    insideLiteral = true;
-                else if (text.charAt(curPos - 1) != '\\')
-                    insideLiteral = false;
-            }
+            if (curChar == '\'')
+                /* Escaped quote in odbc is two successive singe quotes. They'll flip flag twice without side-effect. */
+                insideLiteral = !insideLiteral;
             else if (!insideLiteral) {
                 if (curChar == '{') {
                     if (openPos == -1) {
@@ -173,11 +170,7 @@ public class OdbcEscapeUtils {
 
             OdbcEscapeToken token = parseToken(text, startPos, len);
 
-            if (token.type().standard())
-                return parseStandardExpression(text, startPos, len, token);
-            else
-                throw new IgniteException("Unsupported escape sequence token [text=" +
-                    substring(text, startPos, len) + ", token=" + token.type().body() + ']');
+            return parseEscapeSequence(text, startPos, len, token);
         }
         else {
             // Nothing to escape, return original string.
@@ -209,20 +202,17 @@ public class OdbcEscapeUtils {
 
         for (OdbcEscapeType typ : OdbcEscapeType.sortedValues()) {
             if (text.startsWith(typ.body(), pos)) {
-                pos += typ.body().length();
+                if (typ.standard())
+                    pos += typ.body().length();
 
-                if (typ == OdbcEscapeType.LIKE)
-                    throw new IgniteException("LIKE escape sequence is not supported yet.");
-                else {
-                    empty = (startPos + len == pos + 1);
+                empty = (startPos + len == pos + 1);
 
-                    if (!empty && typ.standard()) {
-                        char charAfter = text.charAt(pos);
+                if (!empty && typ.standard()) {
+                    char charAfter = text.charAt(pos);
 
-                        if (!Character.isWhitespace(charAfter))
-                            throw new IgniteException("Unexpected escape sequence token: " +
-                                substring(text, startPos, len));
-                    }
+                    if (!Character.isWhitespace(charAfter))
+                        throw new IgniteException("Unexpected escape sequence token: " +
+                            substring(text, startPos, len));
                 }
 
                 curTyp = typ;
@@ -249,7 +239,7 @@ public class OdbcEscapeUtils {
      * @param token Token.
      * @return Result.
      */
-    private static String parseStandardExpression(String text, int startPos, int len, OdbcEscapeToken token) {
+    private static String parseEscapeSequence(String text, int startPos, int len, OdbcEscapeToken token) {
         assert validSubstring(text, startPos, len);
 
         // Get expression borders.
@@ -283,6 +273,11 @@ public class OdbcEscapeUtils {
 
                 return "CALL " + val;
             }
+
+            case ESCAPE:
+            case ESCAPE_WO_TOKEN:
+                return parseLikeEscCharacterExpression(text, startPos0, len0);
+
             default:
                 throw new IgniteException("Unsupported escape sequence token [text=" +
                     substring(text, startPos, len) + ", token=" + token.type().body() + ']');
@@ -302,6 +297,18 @@ public class OdbcEscapeUtils {
     }
 
     /**
+     * Parse LIKE escape character expression.
+     *
+     * @param text Text.
+     * @param startPos Start position.
+     * @param len Length.
+     * @return Parsed expression.
+     */
+    private static String parseLikeEscCharacterExpression(String text, int startPos, int len) {
+        return "ESCAPE " + substring(text, startPos, len).trim();
+    }
+
+    /**
      * Parse expression and validate against ODBC specification with regex pattern.
      *
      * @param text Text.

http://git-wip-us.apache.org/repos/asf/ignite/blob/008cf644/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
index 26221ea..5303c6e 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcEscapeSequenceSelfTest.java
@@ -528,9 +528,10 @@ public class OdbcEscapeSequenceSelfTest extends GridCommonAbstractTest {
             "select '{' + {fn func()} + '}' from table;"
         );
 
+        // quoted two single quotes should be interpret as apostrophe
         check(
-            "select '{\\'{fn test()}\\'}' from table;",
-            "select '{\\'{fn test()}\\'}' from table;"
+            "select '{''{fn test()}''}' from table;",
+            "select '{''{fn test()}''}' from table;"
         );
 
         checkFail("'{fn test()}");
@@ -666,6 +667,86 @@ public class OdbcEscapeSequenceSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Test escape sequence series.
+     */
+    public void testLikeEscapeSequence() throws Exception {
+        check(
+            "ESCAPE '\\'",
+            "{'\\'}"
+        );
+
+        check(
+            "ESCAPE '\\'",
+            "{escape '\\'}"
+        );
+
+        check(
+            "ESCAPE ''",
+            "{''}"
+        );
+
+        check(
+            "ESCAPE ''",
+            "{escape ''}"
+        );
+
+        check(
+            "select * from t where value LIKE '\\%AAA%' ESCAPE '\\'",
+            "select * from t where value LIKE '\\%AAA%' {'\\'}"
+        );
+
+        check(
+            "select * from t where value LIKE '\\%AAA%' ESCAPE '\\'",
+            "select * from t where value LIKE '\\%AAA%' {escape '\\'}"
+        );
+
+        check(
+            "select * from t where value LIKE '\\%AAA%' ESCAPE '\\' ORDER BY id;",
+            "select * from t where value LIKE '\\%AAA%' {'\\'} ORDER BY id;"
+        );
+
+        check(
+            "select * from t where value LIKE '\\%AAA%' ESCAPE '\\' ORDER BY id;",
+            "select * from t where value LIKE '\\%AAA%' {escape '\\'} ORDER BY id;"
+        );
+
+        check(
+            "select * from t where value LIKE '\\%AAA''s%' ESCAPE '\\'",
+            "select * from t where value LIKE '\\%AAA''s%' {escape '\\'}"
+        );
+    }
+
+    /**
+     * Test escape sequences with additional whitespace characters
+     */
+    public void testLikeEscapeSequenceWithWhitespaces() throws Exception {
+        check("ESCAPE '\\'", "{ '\\' }");
+        check("ESCAPE '\\'", "{ escape '\\'}");
+
+        check("ESCAPE '\\'", "{   '\\' }");
+        check("ESCAPE '\\'", "{   escape   '\\' }");
+
+        check("ESCAPE '\\'", "{ \n '\\' }");
+        check("ESCAPE '\\'", "{ \n escape\n'\\' }");
+    }
+
+    /**
+     * Test invalid escape sequence.
+     */
+    public void testLikeOnInvalidLikeEscapeSequence() {
+        checkFail("LIKE 'AAA's'");
+        checkFail("LIKE 'AAA\'s'");
+
+        checkFail("LIKE '\\%AAA%' {escape'\\' }");
+
+        checkFail("LIKE '\\%AAA%' {'\\' ORDER BY id");
+        checkFail("LIKE '\\%AAA%' {escape '\\' ORDER BY id;");
+
+        checkFail("LIKE '\\%AAA%' '\\'} ORDER BY id");
+        checkFail("LIKE '\\%AAA%' escape '\\'} ORDER BY id;");
+    }
+
+    /**
      * Check parsing logic.
      *
      * @param exp Expected result.


[16/20] ignite git commit: IGNITE-3817: Fixed binary object re-build with missing schema.

Posted by vo...@apache.org.
IGNITE-3817: Fixed binary object re-build with missing schema.


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

Branch: refs/heads/ignite-3611-1
Commit: 42963e6c99e9b282972e6ad67a813a8038cf580f
Parents: 40d4b6a
Author: Alexander Paschenko <ap...@gridgain.com>
Authored: Mon Sep 5 14:10:39 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Sep 5 14:10:39 2016 +0300

----------------------------------------------------------------------
 .../binary/builder/BinaryObjectBuilderImpl.java       |  2 +-
 .../binary/BinaryObjectBuilderAdditionalSelfTest.java | 14 ++++++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/42963e6c/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
index 16c51b0..086da5c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
@@ -199,7 +199,7 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder {
 
             Map<String, Integer> fieldsMeta = null;
 
-            if (reader != null) {
+            if (reader != null && BinaryUtils.hasSchema(flags)) {
                 BinarySchema schema = reader.schema();
 
                 Map<Integer, Object> assignedFldsById;

http://git-wip-us.apache.org/repos/asf/ignite/blob/42963e6c/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectBuilderAdditionalSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectBuilderAdditionalSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectBuilderAdditionalSelfTest.java
index f999ad3..24806cb 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectBuilderAdditionalSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectBuilderAdditionalSelfTest.java
@@ -56,6 +56,7 @@ import org.apache.ignite.internal.binary.builder.BinaryBuilderEnum;
 import org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl;
 import org.apache.ignite.internal.binary.mutabletest.GridBinaryMarshalerAwareTestClass;
 import org.apache.ignite.internal.binary.mutabletest.GridBinaryTestClasses;
+import org.apache.ignite.internal.binary.test.GridBinaryTestClass2;
 import org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl;
 import org.apache.ignite.internal.processors.cache.binary.IgniteBinaryImpl;
 import org.apache.ignite.internal.util.lang.GridMapEntry;
@@ -1389,6 +1390,19 @@ public class BinaryObjectBuilderAdditionalSelfTest extends GridCommonAbstractTes
     }
 
     /**
+     * Ensure that object w/o schema can be re-built.
+     */
+    public void testBuildFromObjectWithoutSchema() {
+        BinaryObjectBuilderImpl binBuilder = wrap(new GridBinaryTestClass2());
+
+        BinaryObject binObj = binBuilder.build();
+
+        BinaryObjectBuilderImpl binBuilder2 = wrap(binObj);
+
+        binBuilder2.build();
+    }
+
+    /**
      * @param obj Object.
      * @return Object in binary format.
      */


[14/20] ignite git commit: IGNITE-2974: ODBC: Added "socketSendBufferSize" and "socketReceiveBufferSize" configuration parameters. This closes #994.

Posted by vo...@apache.org.
IGNITE-2974: ODBC: Added "socketSendBufferSize" and "socketReceiveBufferSize" configuration parameters. This closes #994.


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

Branch: refs/heads/ignite-3611-1
Commit: d65228e42ec9c84182b8c9c9c8d06a0056d5eed2
Parents: a760918
Author: Andrey V. Mashenkov <an...@gmail.com>
Authored: Mon Sep 5 11:20:26 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Sep 5 11:20:26 2016 +0300

----------------------------------------------------------------------
 .../ignite/configuration/OdbcConfiguration.java | 64 ++++++++++++++++++++
 .../internal/processors/odbc/OdbcProcessor.java |  8 +--
 .../odbc/OdbcProcessorValidationSelfTest.java   | 21 ++++++-
 3 files changed, 86 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d65228e4/modules/core/src/main/java/org/apache/ignite/configuration/OdbcConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/OdbcConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/OdbcConfiguration.java
index 3746995..c098e09 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/OdbcConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/OdbcConfiguration.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.configuration;
 
+import org.apache.ignite.internal.util.typedef.internal.S;
+
 /**
  * ODBC configuration.
  */
@@ -30,12 +32,21 @@ public class OdbcConfiguration {
     /** Default maximum TCP port range value. */
     public static final int DFLT_TCP_PORT_TO = 10810;
 
+    /** Default socket send and receive buffer size. */
+    public static final int DFLT_SOCK_BUF_SIZE = 0;
+
     /** Default max number of open cursors per connection. */
     public static final int DFLT_MAX_OPEN_CURSORS = 128;
 
     /** Endpoint address. */
     private String endpointAddr;
 
+    /** Socket send buffer size. */
+    private int sockSndBufSize = DFLT_SOCK_BUF_SIZE;
+
+    /** Socket receive buffer size. */
+    private int sockRcvBufSize = DFLT_SOCK_BUF_SIZE;
+
     /** Max number of opened cursors per connection. */
     private int maxOpenCursors = DFLT_MAX_OPEN_CURSORS;
 
@@ -57,6 +68,8 @@ public class OdbcConfiguration {
 
         endpointAddr = cfg.getEndpointAddress();
         maxOpenCursors = cfg.getMaxOpenCursors();
+        sockRcvBufSize = cfg.getSocketReceiveBufferSize();
+        sockSndBufSize = cfg.getSocketSendBufferSize();
     }
 
     /**
@@ -115,4 +128,55 @@ public class OdbcConfiguration {
 
         return this;
     }
+
+    /**
+     * Gets socket send buffer size. When set to zero, operation system default will be used.
+     * <p>
+     * Defaults to {@link #DFLT_SOCK_BUF_SIZE}
+     *
+     * @return Socket send buffer size in bytes.
+     */
+    public int getSocketSendBufferSize() {
+        return sockSndBufSize;
+    }
+
+    /**
+     * Sets socket send buffer size. See {@link #getSocketSendBufferSize()} for more information.
+     *
+     * @param sockSndBufSize Socket send buffer size in bytes.
+     * @return This instance for chaining.
+     */
+    public OdbcConfiguration setSocketSendBufferSize(int sockSndBufSize) {
+        this.sockSndBufSize = sockSndBufSize;
+
+        return this;
+    }
+
+    /**
+     * Gets socket receive buffer size. When set to zero, operation system default will be used.
+     * <p>
+     * Defaults to {@link #DFLT_SOCK_BUF_SIZE}.
+     *
+     * @return Socket receive buffer size in bytes.
+     */
+    public int getSocketReceiveBufferSize() {
+        return sockRcvBufSize;
+    }
+
+    /**
+     * Sets socket receive buffer size. See {@link #getSocketReceiveBufferSize()} for more information.
+     *
+     * @param sockRcvBufSize Socket receive buffer size in bytes.
+     * @return This instance for chaining.
+     */
+    public OdbcConfiguration setSocketReceiveBufferSize(int sockRcvBufSize) {
+        this.sockRcvBufSize = sockRcvBufSize;
+
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(OdbcConfiguration.class, this);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d65228e4/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java
index ead8901..adfdc22 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProcessor.java
@@ -46,9 +46,6 @@ public class OdbcProcessor extends GridProcessorAdapter {
     /** Default TCP direct buffer flag. */
     private static final boolean DFLT_TCP_DIRECT_BUF = false;
 
-    /** Default socket send and receive buffer size. */
-    private static final int DFLT_SOCK_BUF_SIZE = 32 * 1024;
-
     /** Busy lock. */
     private final GridSpinBusyLock busyLock = new GridSpinBusyLock();
 
@@ -113,11 +110,10 @@ public class OdbcProcessor extends GridProcessorAdapter {
                             .tcpNoDelay(DFLT_TCP_NODELAY)
                             .directBuffer(DFLT_TCP_DIRECT_BUF)
                             .byteOrder(ByteOrder.nativeOrder())
-                            .socketSendBufferSize(DFLT_SOCK_BUF_SIZE)
-                            .socketReceiveBufferSize(DFLT_SOCK_BUF_SIZE)
+                            .socketSendBufferSize(odbcCfg.getSocketSendBufferSize())
+                            .socketReceiveBufferSize(odbcCfg.getSocketReceiveBufferSize())
                             .filters(new GridNioCodecFilter(new OdbcBufferedParser(), log, false))
                             .directMode(false)
-                            .idleTimeout(Long.MAX_VALUE)
                             .build();
 
                         srv0.start();

http://git-wip-us.apache.org/repos/asf/ignite/blob/d65228e4/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcProcessorValidationSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcProcessorValidationSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcProcessorValidationSelfTest.java
index 751f0ae..bb08c6c 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcProcessorValidationSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/odbc/OdbcProcessorValidationSelfTest.java
@@ -94,7 +94,7 @@ public class OdbcProcessorValidationSelfTest extends GridCommonAbstractTest {
     /**
      * Test start with invalid address format.
      *
-     * @throws Exception
+     * @throws Exception If failed.
      */
     public void testAddressInvalidFormat() throws Exception {
         check(new OdbcConfiguration().setEndpointAddress("127.0.0.1:"), false);
@@ -115,6 +115,25 @@ public class OdbcProcessorValidationSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Test connection parameters: sendBufferSize, receiveBufferSize, connectionTimeout.
+     *
+     * @throws Exception If failed.
+     */
+    public void testConnectionParams() throws Exception {
+        check(new OdbcConfiguration().setEndpointAddress("127.0.0.1:9998..10000")
+            .setSocketSendBufferSize(4 * 1024), true);
+
+        check(new OdbcConfiguration().setEndpointAddress("127.0.0.1:9998..10000")
+            .setSocketReceiveBufferSize(4 * 1024), true);
+
+        check(new OdbcConfiguration().setEndpointAddress("127.0.0.1:9998..10000")
+            .setSocketSendBufferSize(-64 * 1024), false);
+
+        check(new OdbcConfiguration().setEndpointAddress("127.0.0.1:9998..10000")
+            .setSocketReceiveBufferSize(-64 * 1024), false);
+    }
+
+    /**
      * Perform check.
      *
      * @param odbcCfg ODBC configuration.


[11/20] ignite git commit: IGNITE-3646: IGFS: Added test for symlinked mkdirs on local secondary file system. This closes #1013.

Posted by vo...@apache.org.
IGNITE-3646: IGFS: Added test for symlinked mkdirs on local secondary file system. This closes #1013.


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

Branch: refs/heads/ignite-3611-1
Commit: fc2fe7bf1905675258d40932a4ff649156c17488
Parents: f8ae674
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Sun Sep 4 17:12:35 2016 +0300
Committer: thatcoach <pp...@list.ru>
Committed: Sun Sep 4 17:12:35 2016 +0300

----------------------------------------------------------------------
 ...SecondaryFileSystemDualAbstractSelfTest.java | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/fc2fe7bf/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
index df7d782..8baaf4a 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
@@ -61,7 +61,9 @@ public abstract class IgfsLocalSecondaryFileSystemDualAbstractSelfTest extends I
     private final File fileLinkSrc = new File(FS_WORK_DIR + File.separatorChar + "file");
 
 
-    /** Constructor.
+    /**
+     * Constructor.
+     *
      * @param mode IGFS mode.
      */
     public IgfsLocalSecondaryFileSystemDualAbstractSelfTest(IgfsMode mode) {
@@ -172,6 +174,22 @@ public abstract class IgfsLocalSecondaryFileSystemDualAbstractSelfTest extends I
      *
      * @throws Exception If failed.
      */
+    public void testMkdirsInsideSymlink() throws Exception {
+        if (U.isWindows())
+            return;
+
+        createSymlinks();
+
+        igfs.mkdirs(SUBSUBDIR);
+
+        assertTrue(Files.isDirectory(dirLinkDest.toPath().resolve("subdir/subsubdir")));
+        assertTrue(Files.isDirectory(dirLinkSrc.toPath().resolve("subdir/subsubdir")));
+    }
+
+    /**
+     *
+     * @throws Exception If failed.
+     */
     public void testUsedSpaceSize() throws Exception {
         final int DIRS_COUNT = 5;
         final int DIRS_MAX_DEEP = 3;


[07/20] ignite git commit: IGNITE-2946: CPP: Optimized GetNext() method for cursors. This closes #992.

Posted by vo...@apache.org.
IGNITE-2946: CPP: Optimized GetNext() method for cursors. This closes #992.


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

Branch: refs/heads/ignite-3611-1
Commit: e9c797fd964727882ad6f40f2a452b17ae7c857e
Parents: e3c4868
Author: isapego <is...@gridgain.com>
Authored: Sun Sep 4 16:47:40 2016 +0300
Committer: thatcoach <pp...@list.ru>
Committed: Sun Sep 4 16:47:40 2016 +0300

----------------------------------------------------------------------
 .../query/PlatformAbstractQueryCursor.java      |  11 +-
 .../cache/query/PlatformFieldsQueryCursor.java  |   6 +
 .../ignite/impl/binary/binary_reader_impl.h     |   2 +-
 .../common/include/ignite/common/concurrent.h   |   5 +-
 .../cpp/core-test/src/cache_query_test.cpp      | 243 +++++++++++++------
 modules/platforms/cpp/core/Makefile.am          |   1 +
 modules/platforms/cpp/core/include/Makefile.am  |   1 +
 .../include/ignite/cache/query/query_cursor.h   |   6 +-
 .../ignite/cache/query/query_fields_cursor.h    |   4 +-
 .../ignite/impl/cache/query/query_batch.h       | 148 +++++++++++
 .../impl/cache/query/query_fields_row_impl.h    |  30 +--
 .../ignite/impl/cache/query/query_impl.h        |  30 ++-
 .../platforms/cpp/core/project/vs/core.vcxproj  |   2 +
 .../cpp/core/project/vs/core.vcxproj.filters    |   6 +
 .../core/src/impl/cache/query/query_batch.cpp   |  52 ++++
 .../core/src/impl/cache/query/query_impl.cpp    | 180 ++++++++------
 .../Impl/Cache/Query/FieldsQueryCursor.cs       |   3 +
 17 files changed, 537 insertions(+), 193 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformAbstractQueryCursor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformAbstractQueryCursor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformAbstractQueryCursor.java
index 7422757..ab52b52 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformAbstractQueryCursor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformAbstractQueryCursor.java
@@ -70,13 +70,12 @@ public abstract class PlatformAbstractQueryCursor<T> extends PlatformAbstractTar
                 try {
                     int cntPos = writer.reserveInt();
 
-                    int cnt;
+                    int cnt = 0;
 
-                    for (cnt = 0; cnt < batchSize; cnt++) {
-                        if (iter.hasNext())
-                            write(writer, iter.next());
-                        else
-                            break;
+                    while (cnt < batchSize && iter.hasNext()) {
+                        write(writer, iter.next());
+
+                        cnt++;
                     }
 
                     writer.writeInt(cntPos, cnt);

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformFieldsQueryCursor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformFieldsQueryCursor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformFieldsQueryCursor.java
index a4cdae6..25f86f2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformFieldsQueryCursor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/query/PlatformFieldsQueryCursor.java
@@ -41,9 +41,15 @@ public class PlatformFieldsQueryCursor extends PlatformAbstractQueryCursor<List<
     @Override protected void write(BinaryRawWriterEx writer, List vals) {
         assert vals != null;
 
+        int rowSizePos = writer.reserveInt();
+
         writer.writeInt(vals.size());
 
         for (Object val : vals)
             writer.writeObjectDetached(val);
+
+        int rowEndPos = writer.out().position();
+        
+        writer.writeInt(rowSizePos, rowEndPos - rowSizePos);
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
index d9f1e1a..8c4b464 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_reader_impl.h
@@ -943,7 +943,7 @@ namespace ignite
                  *
                  * @return Stream.
                  */
-                impl::interop::InteropInputStream* GetStream();
+                interop::InteropInputStream* GetStream();
             private:
                 /** Underlying stream. */
                 interop::InteropInputStream* stream;

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/common/include/ignite/common/concurrent.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/common/concurrent.h b/modules/platforms/cpp/common/include/ignite/common/concurrent.h
index 9a475da..465e02e 100644
--- a/modules/platforms/cpp/common/include/ignite/common/concurrent.h
+++ b/modules/platforms/cpp/common/include/ignite/common/concurrent.h
@@ -167,10 +167,9 @@ namespace ignite
                  *
                  * @param other Instance to copy.
                  */
-                SharedPointer(const SharedPointer& other)
+                SharedPointer(const SharedPointer& other) :
+                    impl(other.impl)
                 {
-                    impl = other.impl;
-
                     if (impl)
                         impl->Increment();
                 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/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 168f3f9..b8cd612 100644
--- a/modules/platforms/cpp/core-test/src/cache_query_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
@@ -212,63 +212,6 @@ namespace ignite
     }
 }
 
-/** Node started during the test. */
-Ignite grid = Ignite();
-
-/** Cache accessor. */
-Cache<int, QueryPerson> GetCache()
-{
-    return grid.GetCache<int, QueryPerson>("cache");
-}
-
-/**
- * Test setup fixture.
- */
-struct CacheQueryTestSuiteFixture {
-    /**
-     * Constructor.
-     */
-    CacheQueryTestSuiteFixture()
-    {
-        IgniteConfiguration cfg;
-        
-        cfg.jvmOpts.push_back("-Xdebug");
-        cfg.jvmOpts.push_back("-Xnoagent");
-        cfg.jvmOpts.push_back("-Djava.compiler=NONE");
-        cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005");
-        cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError");
-
-#ifdef IGNITE_TESTS_32
-        cfg.jvmInitMem = 256;
-        cfg.jvmMaxMem = 768;
-#else
-        cfg.jvmInitMem = 1024;
-        cfg.jvmMaxMem = 4096;
-#endif
-
-        char* cfgPath = getenv("IGNITE_NATIVE_TEST_CPP_CONFIG_PATH");
-
-        cfg.springCfgPath = std::string(cfgPath).append("/").append("cache-query.xml");
-
-        IgniteError err;
-
-        Ignite grid0 = Ignition::Start(cfg, &err);
-
-        if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
-            BOOST_ERROR(err.GetText());
-
-        grid = grid0;
-    }
-
-    /**
-     * Destructor.
-     */
-    ~CacheQueryTestSuiteFixture()
-    {
-        Ignition::Stop(grid.GetName(), true);
-    }
-};
-
 /**
  * Ensure that HasNext() fails.
  *
@@ -522,6 +465,131 @@ void CheckMultipleGetAll(Cursor& cur, int key1, const std::string& name1,
     }
 }
 
+/**
+ * Test setup fixture.
+ */
+struct CacheQueryTestSuiteFixture
+{
+    Ignite StartNode(const char* name)
+    {
+        IgniteConfiguration cfg;
+
+        cfg.jvmOpts.push_back("-Xdebug");
+        cfg.jvmOpts.push_back("-Xnoagent");
+        cfg.jvmOpts.push_back("-Djava.compiler=NONE");
+        cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005");
+        cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError");
+
+#ifdef IGNITE_TESTS_32
+        cfg.jvmInitMem = 256;
+        cfg.jvmMaxMem = 768;
+#else
+        cfg.jvmInitMem = 1024;
+        cfg.jvmMaxMem = 4096;
+#endif
+
+        cfg.springCfgPath.assign(getenv("IGNITE_NATIVE_TEST_CPP_CONFIG_PATH")).append("/cache-query.xml");
+
+        IgniteError err;
+
+        Ignite grid0 = Ignition::Start(cfg, name, &err);
+
+        if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
+            BOOST_ERROR(err.GetText());
+
+        return grid0;
+    }
+
+    void CheckFieldsQueryPages(int32_t pageSize, int32_t pagesNum, int32_t additionalNum)
+    {
+        // Test simple query.
+        Cache<int, QueryPerson> cache = GetPersonCache();
+
+        // Test query with two fields of different type.
+        SqlFieldsQuery qry("select name, age from QueryPerson");
+
+        QueryFieldsCursor cursor = cache.Query(qry);
+        CheckEmpty(cursor);
+
+        const int32_t entryCnt = pageSize * pagesNum + additionalNum; // Number of entries.
+
+        qry.SetPageSize(pageSize);
+
+        for (int i = 0; i < entryCnt; i++)
+        {
+            std::stringstream stream;
+
+            stream << "A" << i;
+
+            cache.Put(i, QueryPerson(stream.str(), i * 10, BinaryUtils::MakeDateLocal(1970 + i),
+                BinaryUtils::MakeTimestampLocal(2016, 1, 1, i / 60, i % 60)));
+        }
+
+        cursor = cache.Query(qry);
+
+        IgniteError error;
+
+        for (int i = 0; i < entryCnt; i++)
+        {
+            std::stringstream stream;
+
+            stream << "A" << i;
+
+            std::string expected_name = stream.str();
+            int expected_age = i * 10;
+
+            BOOST_REQUIRE(cursor.HasNext(error));
+            BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+            QueryFieldsRow row = cursor.GetNext(error);
+            BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+            BOOST_REQUIRE(row.HasNext(error));
+            BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+            std::string name = row.GetNext<std::string>(error);
+            BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+            BOOST_REQUIRE(name == expected_name);
+
+            int age = row.GetNext<int>(error);
+            BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+            BOOST_REQUIRE(age == expected_age);
+
+            BOOST_REQUIRE(!row.HasNext());
+        }
+
+        CheckEmpty(cursor);
+    }
+
+    /**
+     * Constructor.
+     */
+    CacheQueryTestSuiteFixture() : 
+        grid(StartNode("Node1"))
+    {
+        // No-op.
+    }
+
+    /**
+     * Destructor.
+     */
+    ~CacheQueryTestSuiteFixture()
+    {
+        Ignition::StopAll(true);
+    }
+
+    /** Person cache accessor. */
+    Cache<int, QueryPerson> GetPersonCache()
+    {
+        return grid.GetCache<int, QueryPerson>("cache");
+    }
+
+    /** Node started during the test. */
+    Ignite grid;
+};
+
 BOOST_FIXTURE_TEST_SUITE(CacheQueryTestSuite, CacheQueryTestSuiteFixture)
 
 /**
@@ -529,7 +597,7 @@ BOOST_FIXTURE_TEST_SUITE(CacheQueryTestSuite, CacheQueryTestSuiteFixture)
  */
 BOOST_AUTO_TEST_CASE(TestSqlQuery)
 {    
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with no results.
     SqlQuery qry("QueryPerson", "age < 20");
@@ -585,7 +653,7 @@ BOOST_AUTO_TEST_CASE(TestSqlQuery)
  */
 BOOST_AUTO_TEST_CASE(TestTextQuery)
 {
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with no results.
     TextQuery qry("QueryPerson", "A1");
@@ -631,7 +699,7 @@ BOOST_AUTO_TEST_CASE(TestTextQuery)
 BOOST_AUTO_TEST_CASE(TestScanQuery)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with no results.
     ScanQuery qry;
@@ -667,7 +735,7 @@ BOOST_AUTO_TEST_CASE(TestScanQuery)
 BOOST_AUTO_TEST_CASE(TestScanQueryPartitioned)
 {
     // Populate cache with data.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     int32_t partCnt = 256;   // Defined in configuration explicitly.   
     int32_t entryCnt = 1000; // Should be greater than partCnt.
@@ -716,7 +784,7 @@ BOOST_AUTO_TEST_CASE(TestScanQueryPartitioned)
 BOOST_AUTO_TEST_CASE(TestFieldsQuerySingle)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with two fields of different type.
     SqlFieldsQuery qry("select age, name from QueryPerson");
@@ -761,7 +829,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQuerySingle)
 BOOST_AUTO_TEST_CASE(TestFieldsQueryExceptions)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with two fields of different type.
     SqlFieldsQuery qry("select age, name from QueryPerson");
@@ -806,7 +874,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQueryExceptions)
 BOOST_AUTO_TEST_CASE(TestFieldsQueryTwo)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with two fields of different type.
     SqlFieldsQuery qry("select age, name from QueryPerson");
@@ -869,7 +937,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQueryTwo)
 BOOST_AUTO_TEST_CASE(TestFieldsQuerySeveral)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with two fields of different type.
     SqlFieldsQuery qry("select name, age from QueryPerson");
@@ -935,7 +1003,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQuerySeveral)
 BOOST_AUTO_TEST_CASE(TestFieldsQueryDateLess)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with field of type 'Date'.
     SqlFieldsQuery qry("select birthday from QueryPerson where birthday<'1990-01-01'");
@@ -996,7 +1064,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQueryDateLess)
 BOOST_AUTO_TEST_CASE(TestFieldsQueryDateMore)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with field of type 'Date'.
     SqlFieldsQuery qry("select birthday from QueryPerson where birthday>'2070-01-01'");
@@ -1057,7 +1125,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQueryDateMore)
 BOOST_AUTO_TEST_CASE(TestFieldsQueryDateEqual)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with field of type 'Date'.
     SqlFieldsQuery qry("select birthday from QueryPerson where birthday='2032-01-01'");
@@ -1109,7 +1177,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQueryDateEqual)
 BOOST_AUTO_TEST_CASE(TestFieldsQueryTimestampLess)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with field of type 'Timestamp'.
     SqlFieldsQuery qry("select recordCreated from QueryPerson where recordCreated<'2016-01-01 01:00:00'");
@@ -1170,7 +1238,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQueryTimestampLess)
 BOOST_AUTO_TEST_CASE(TestFieldsQueryTimestampMore)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with field of type 'Timestamp'.
     SqlFieldsQuery qry("select recordCreated from QueryPerson where recordCreated>'2016-01-01 15:30:00'");
@@ -1233,7 +1301,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQueryTimestampMore)
 BOOST_AUTO_TEST_CASE(TestFieldsQueryTimestampEqual)
 {
     // Test simple query.
-    Cache<int, QueryPerson> cache = GetCache();
+    Cache<int, QueryPerson> cache = GetPersonCache();
 
     // Test query with field of type 'Timestamp'.
     SqlFieldsQuery qry("select recordCreated from QueryPerson where recordCreated='2016-01-01 09:18:00'");
@@ -1279,4 +1347,37 @@ BOOST_AUTO_TEST_CASE(TestFieldsQueryTimestampEqual)
     CheckEmpty(cursor);
 }
 
+/**
+ * Test fields query with several pages.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQueryPagesSeveral)
+{
+    CheckFieldsQueryPages(32, 8, 1);
+}
+
+/**
+ * Test fields query with page size 1.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQueryPageSingle)
+{
+    CheckFieldsQueryPages(1, 100, 0);
+}
+
+/**
+ * Test fields query with page size 0.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQueryPageZero)
+{
+    try
+    {
+        CheckFieldsQueryPages(0, 100, 0);
+
+        BOOST_FAIL("Exception expected.");
+    }
+    catch (IgniteError&)
+    {
+        // Expected.
+    }
+}
+
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/core/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/Makefile.am b/modules/platforms/cpp/core/Makefile.am
index 2b73476..bbb7720 100644
--- a/modules/platforms/cpp/core/Makefile.am
+++ b/modules/platforms/cpp/core/Makefile.am
@@ -59,6 +59,7 @@ libignite_la_SOURCES = \
     src/impl/handle_registry.cpp \
     src/impl/cache/query/query_impl.cpp \
     src/impl/cache/cache_impl.cpp \
+    src/impl/cache/query/query_batch.cpp \
     src/impl/interop/interop_external_memory.cpp \
     src/impl/interop/interop_target.cpp \
     src/impl/transactions/transaction_impl.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/core/include/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/Makefile.am b/modules/platforms/cpp/core/include/Makefile.am
index f7159ae..fb84bc5 100644
--- a/modules/platforms/cpp/core/include/Makefile.am
+++ b/modules/platforms/cpp/core/include/Makefile.am
@@ -27,6 +27,7 @@ nobase_include_HEADERS = \
     ignite/impl/cache/query/query_fields_row_impl.h \
     ignite/impl/cache/query/query_impl.h \
     ignite/impl/cache/cache_impl.h \
+    ignite/impl/cache/query/query_batch.h \
     ignite/impl/interop/interop_target.h \
     ignite/impl/interop/interop_external_memory.h \
     ignite/impl/handle_registry.h \

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
index 4c46662..61c6813 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
@@ -112,7 +112,7 @@ namespace ignite
                     impl::cache::query::QueryCursorImpl* impl0 = impl.Get();
 
                     if (impl0)
-                        return impl0->HasNext(&err);
+                        return impl0->HasNext(err);
                     else
                     {
                         err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, 
@@ -160,7 +160,7 @@ namespace ignite
                     if (impl0) {
                         impl::Out2Operation<K, V> outOp;
 
-                        impl0->GetNext(outOp, &err);
+                        impl0->GetNext(outOp, err);
 
                         if (err.GetCode() == IgniteError::IGNITE_SUCCESS) 
                         {
@@ -215,7 +215,7 @@ namespace ignite
                     if (impl0) {
                         impl::OutQueryGetAllOperation<K, V> outOp(&res);
 
-                        impl0->GetAll(outOp, &err);
+                        impl0->GetAll(outOp, err);
                     }
                     else
                         err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
index 3946e1c..36e5f5c 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
@@ -108,7 +108,7 @@ namespace ignite
                     impl::cache::query::QueryCursorImpl* impl0 = impl.Get();
 
                     if (impl0)
-                        return impl0->HasNext(&err);
+                        return impl0->HasNext(err);
                     else
                     {
                         err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, 
@@ -153,7 +153,7 @@ namespace ignite
                     impl::cache::query::QueryCursorImpl* impl0 = impl.Get();
 
                     if (impl0)
-                        return impl0->GetNextRow(&err);
+                        return impl0->GetNextRow(err);
                     else
                     {
                         err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_batch.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_batch.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_batch.h
new file mode 100644
index 0000000..15d6edb
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_batch.h
@@ -0,0 +1,148 @@
+/*
+ * 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_CACHE_QUERY_BATCH
+#define _IGNITE_CACHE_QUERY_BATCH
+
+#include <cassert>
+
+#include "ignite/ignite_error.h"
+#include "ignite/impl/ignite_environment.h"
+#include "ignite/impl/operations.h"
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace cache
+        {
+            namespace query
+            {
+                class QueryFieldsRowImpl;
+
+                /**
+                 * Query batch.
+                 */
+                class IGNITE_IMPORT_EXPORT QueryBatch
+                {
+                    typedef common::concurrent::SharedPointer<interop::InteropMemory> MemorySharedPtr;
+
+                public:
+                    /**
+                     * Constructor.
+                     *
+                     * @param env Environment.
+                     * @param mem Batch memory.
+                     */
+                    QueryBatch(IgniteEnvironment& env, MemorySharedPtr mem) :
+                        env(env),
+                        mem(mem),
+                        stream(mem.Get()),
+                        reader(&stream),
+                        size(reader.ReadInt32()),
+                        pos(0)
+                    {
+                        // No-op.
+                    }
+
+                    /**
+                     * Destructor.
+                     */
+                    ~QueryBatch()
+                    {
+                        // No-op.
+                    }
+
+                    /**
+                     * Check whether batch is empty.
+                     *
+                     * @return True if empty.
+                     */
+                    bool IsEmpty() const
+                    {
+                        return size == 0;
+                    }
+
+                    /**
+                     * Get the number of the unread rows in the batch.
+                     *
+                     * @return Number of the unread rows in the batch.
+                     */
+                    int32_t Left() const
+                    {
+                        return size - pos;
+                    }
+
+                    /**
+                     * Check whether next result exists.
+                     *
+                     * @param err Error.
+                     * @return True if exists.
+                     */
+                    int32_t Size()
+                    {
+                        return size;
+                    }
+
+                    /**
+                     * Get next object.
+                     * 
+                     * @param op Operation.
+                     */
+                    void GetNext(OutputOperation& op)
+                    {
+                        assert(Left() > 0);
+
+                        op.ProcessOutput(reader);
+
+                        ++pos;
+                    }
+
+                    /**
+                     * Get next row.
+                     *
+                     * @return Output row.
+                     */
+                    QueryFieldsRowImpl* GetNextRow();
+
+                private:
+                    /** Environment. */
+                    IgniteEnvironment& env;
+
+                    /** Memomy containing the batch. */
+                    MemorySharedPtr mem;
+
+                    /** Stream. */
+                    interop::InteropInputStream stream;
+
+                    /** Reader. */
+                    binary::BinaryReaderImpl reader;
+
+                    /** Result batch size. */
+                    int32_t size;
+
+                    /** Position in memory. */
+                    int32_t pos;
+
+                    IGNITE_NO_COPY_ASSIGNMENT(QueryBatch);
+                };
+            }
+        }
+    }
+}
+
+#endif // _IGNITE_CACHE_QUERY_BATCH

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/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 233c2d4..82cebd5 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
@@ -18,16 +18,9 @@
 #ifndef _IGNITE_IMPL_CACHE_QUERY_CACHE_QUERY_FIELDS_ROW_IMPL
 #define _IGNITE_IMPL_CACHE_QUERY_CACHE_QUERY_FIELDS_ROW_IMPL
 
-#include <vector>
-#include <memory>
-
 #include <ignite/common/concurrent.h>
 #include <ignite/ignite_error.h>
 
-#include "ignite/cache/cache_entry.h"
-#include "ignite/impl/cache/query/query_impl.h"
-#include "ignite/impl/operations.h"
-
 namespace ignite
 {
     namespace impl
@@ -45,23 +38,18 @@ namespace ignite
                     typedef common::concurrent::SharedPointer<interop::InteropMemory> SP_InteropMemory;
 
                     /**
-                     * Default constructor.
-                     */
-                    QueryFieldsRowImpl() : mem(0), stream(0), reader(0), size(0), 
-                        processed(0)
-                    {
-                        // No-op.
-                    }
-
-                    /**
                      * Constructor.
                      *
                      * @param mem Memory containig row data.
                      */
-                    QueryFieldsRowImpl(SP_InteropMemory mem) : mem(mem), stream(mem.Get()), 
-                        reader(&stream), size(reader.ReadInt32()), processed(0)
+                    QueryFieldsRowImpl(SP_InteropMemory mem, int32_t rowBegin, int32_t columnNum) :
+                        mem(mem),
+                        stream(mem.Get()),
+                        reader(&stream),
+                        columnNum(columnNum),
+                        processed(0)
                     {
-                        // No-op.
+                        stream.Position(rowBegin);
                     }
 
                     /**
@@ -89,7 +77,7 @@ namespace ignite
                     bool HasNext(IgniteError& err)
                     {
                         if (IsValid())
-                            return processed < size;
+                            return processed < columnNum;
                         else
                         {
                             err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
@@ -165,7 +153,7 @@ namespace ignite
                     binary::BinaryReaderImpl reader;
 
                     /** Number of elements in a row. */
-                    int32_t size;
+                    int32_t columnNum;
 
                     /** Number of elements that have been read by now. */
                     int32_t processed;

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
index 0f17c32..4083c7c 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
@@ -22,6 +22,7 @@
 
 #include "ignite/impl/ignite_environment.h"
 #include "ignite/impl/operations.h"
+#include "ignite/impl/cache/query/query_batch.h"
 
 namespace ignite
 {
@@ -58,7 +59,7 @@ namespace ignite
                      * @param err Error.
                      * @return True if exists.
                      */
-                    bool HasNext(IgniteError* err);
+                    bool HasNext(IgniteError& err);
 
                     /**
                      * Get next object.
@@ -66,7 +67,7 @@ namespace ignite
                      * @param op Operation.
                      * @param err Error.
                      */
-                    void GetNext(OutputOperation& op, IgniteError* err);
+                    void GetNext(OutputOperation& op, IgniteError& err);
 
                     /**
                      * Get next row.
@@ -74,7 +75,7 @@ namespace ignite
                      * @param err Error.
                      * @return Output row.
                      */
-                    QueryFieldsRowImpl* GetNextRow(IgniteError* err);
+                    QueryFieldsRowImpl* GetNextRow(IgniteError& err);
 
                     /**
                      * Get all cursor entries.
@@ -82,7 +83,7 @@ namespace ignite
                      * @param op Operation.
                      * @param err Error.
                      */
-                    void GetAll(OutputOperation& op, IgniteError* err);
+                    void GetAll(OutputOperation& op, IgniteError& err);
 
                 private:
                     /** Environment. */
@@ -91,15 +92,18 @@ namespace ignite
                     /** Handle to Java object. */
                     jobject javaRef;
 
+                    /** Current result batch. */
+                    QueryBatch* batch;
+
+                    /** Whether cursor has no more elements available. */
+                    bool endReached;
+
                     /** Whether iteration methods were called. */
                     bool iterCalled;
 
                     /** Whether GetAll() method was called. */
                     bool getAllCalled;
 
-                    /** Whether next entry is available. */
-                    bool hasNext;
-
                     IGNITE_NO_COPY_ASSIGNMENT(QueryCursorImpl);
 
                     /**
@@ -108,7 +112,15 @@ namespace ignite
                      * @param err Error.
                      * @return True in case of success, false if an error is thrown.
                      */
-                    bool CreateIteratorIfNeeded(IgniteError* err);
+                    bool CreateIteratorIfNeeded(IgniteError& err);
+
+                   /**
+                     * Get next result batch if update is needed.
+                     *
+                     * @param err Error.
+                     * @return True if operation has been successful.
+                     */
+                    bool GetNextBatchIfNeeded(IgniteError& err);
 
                     /**
                      * Check whether Java-side iterator has next element.
@@ -116,7 +128,7 @@ namespace ignite
                      * @param err Error.
                      * @return True if the next element is available.
                      */
-                    bool IteratorHasNext(IgniteError* err);
+                    bool IteratorHasNext(IgniteError& err);
                 };
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/core/project/vs/core.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/project/vs/core.vcxproj b/modules/platforms/cpp/core/project/vs/core.vcxproj
index 0797c31..ca14a1d 100644
--- a/modules/platforms/cpp/core/project/vs/core.vcxproj
+++ b/modules/platforms/cpp/core/project/vs/core.vcxproj
@@ -209,6 +209,7 @@
     <ClInclude Include="..\..\include\ignite\ignition.h" />
     <ClInclude Include="..\..\include\ignite\impl\binary\binary_type_updater_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\cache\cache_impl.h" />
+    <ClInclude Include="..\..\include\ignite\impl\cache\query\query_batch.h" />
     <ClInclude Include="..\..\include\ignite\impl\cache\query\query_fields_row_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\cache\query\query_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\ignite_environment.h" />
@@ -229,6 +230,7 @@
     <ClCompile Include="..\..\src\ignition.cpp" />
     <ClCompile Include="..\..\src\impl\binary\binary_type_updater_impl.cpp" />
     <ClCompile Include="..\..\src\impl\cache\cache_impl.cpp" />
+    <ClCompile Include="..\..\src\impl\cache\query\query_batch.cpp" />
     <ClCompile Include="..\..\src\impl\cache\query\query_impl.cpp" />
     <ClCompile Include="..\..\src\impl\ignite_environment.cpp" />
     <ClCompile Include="..\..\src\impl\ignite_impl.cpp" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/project/vs/core.vcxproj.filters b/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
index c90b697..c5fb532 100644
--- a/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
+++ b/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
@@ -43,6 +43,9 @@
     <ClCompile Include="..\..\src\impl\interop\interop_target.cpp">
       <Filter>Code\impl\interop</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\impl\cache\query\query_batch.cpp">
+      <Filter>Code\impl\cache\query</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\ignite\impl\cache\cache_impl.h">
@@ -138,6 +141,9 @@
     <ClInclude Include="..\..\include\ignite\impl\interop\interop_target.h">
       <Filter>Code\impl\interop</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\include\ignite\impl\cache\query\query_batch.h">
+      <Filter>Code\impl\cache\query</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Code">

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/core/src/impl/cache/query/query_batch.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/cache/query/query_batch.cpp b/modules/platforms/cpp/core/src/impl/cache/query/query_batch.cpp
new file mode 100644
index 0000000..44086af
--- /dev/null
+++ b/modules/platforms/cpp/core/src/impl/cache/query/query_batch.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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 "ignite/impl/cache/query/query_batch.h"
+#include "ignite/impl/cache/query/query_fields_row_impl.h"
+
+namespace ignite
+{
+    namespace impl
+    {
+        namespace cache
+        {
+            namespace query
+            {
+                QueryFieldsRowImpl* QueryBatch::GetNextRow()
+                {
+                    assert(Left() > 0);
+
+                    int32_t rowBegin = stream.Position();
+
+                    int32_t rowLen = reader.ReadInt32();
+                    int32_t columnNum = reader.ReadInt32();
+
+                    int32_t dataPos = stream.Position();
+
+                    assert(rowLen >= 4);
+
+                    ++pos;
+
+                    stream.Position(rowBegin + rowLen);
+
+                    return new QueryFieldsRowImpl(mem, dataPos, columnNum);
+                }
+
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp b/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
index 880e8b1..73d9924 100644
--- a/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
@@ -35,30 +35,41 @@ namespace ignite
                 /** Operation: get all entries. */
                 const int32_t OP_GET_ALL = 1;
 
+                /** Operation: get multiple entries. */
+                const int32_t OP_GET_BATCH = 2;
+
                 /** Operation: get single entry. */
                 const int32_t OP_GET_SINGLE = 3;
 
                 QueryCursorImpl::QueryCursorImpl(SharedPointer<IgniteEnvironment> env, jobject javaRef) :
-                    env(env), javaRef(javaRef), iterCalled(false), getAllCalled(false), hasNext(false)
+                    env(env),
+                    javaRef(javaRef),
+                    batch(0),
+                    endReached(false),
+                    iterCalled(false),
+                    getAllCalled(false)
                 {
                     // No-op.
                 }
 
                 QueryCursorImpl::~QueryCursorImpl()
                 {
-                    // 1. Close the cursor.
+                    // 1. Releasing memory.
+                    delete batch;
+
+                    // 2. Close the cursor.
                     env.Get()->Context()->QueryCursorClose(javaRef);
 
-                    // 2. Release Java reference.
+                    // 3. Release Java reference.
                     JniContext::Release(javaRef);
                 }
 
-                bool QueryCursorImpl::HasNext(IgniteError* err)
+                bool QueryCursorImpl::HasNext(IgniteError& err)
                 {
                     // Check whether GetAll() was called earlier.
                     if (getAllCalled) 
                     {
-                        *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, 
+                        err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, 
                             "Cannot use HasNext() method because GetAll() was called.");
 
                         return false;
@@ -67,16 +78,21 @@ namespace ignite
                     // Create iterator in Java if needed.
                     if (!CreateIteratorIfNeeded(err))
                         return false;
-                    
-                    return hasNext;
+
+                    // Get next results batch if the end in the current batch
+                    // has been reached.
+                    if (!GetNextBatchIfNeeded(err))
+                        return false;
+
+                    return !endReached;
                 }
 
-                void QueryCursorImpl::GetNext(OutputOperation& op, IgniteError* err)
+                void QueryCursorImpl::GetNext(OutputOperation& op, IgniteError& err)
                 {
                     // Check whether GetAll() was called earlier.
                     if (getAllCalled) 
                     {
-                        *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, 
+                        err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, 
                             "Cannot use GetNext() method because GetAll() was called.");
 
                         return;
@@ -86,75 +102,52 @@ namespace ignite
                     if (!CreateIteratorIfNeeded(err))
                         return;
 
-                    if (hasNext)
-                    {
-                        JniErrorInfo jniErr;
-
-                        SharedPointer<InteropMemory> inMem = env.Get()->AllocateMemory();
-                        
-                        env.Get()->Context()->TargetOutStream(
-                            javaRef, OP_GET_SINGLE, inMem.Get()->PointerLong(), &jniErr);
-
-                        IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
-
-                        if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
-                        {
-                            InteropInputStream in(inMem.Get());
-
-                            binary::BinaryReaderImpl reader(&in);
-
-                            op.ProcessOutput(reader);
+                    // Get next results batch if the end in the current batch
+                    // has been reached.
+                    if (!GetNextBatchIfNeeded(err))
+                        return;
 
-                            hasNext = IteratorHasNext(err);
-                        }
-                    }
-                    else
+                    if (endReached)
                     {
                         // Ensure we do not overwrite possible previous error.
-                        if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
-                            *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "No more elements available.");
+                        if (err.GetCode() == IgniteError::IGNITE_SUCCESS)
+                            err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "No more elements available.");
+
+                        return;
                     }
+
+                    batch->GetNext(op);
                 }
 
-                QueryFieldsRowImpl* QueryCursorImpl::GetNextRow(IgniteError* err)
+                QueryFieldsRowImpl* QueryCursorImpl::GetNextRow(IgniteError& err)
                 {
                     // Create iterator in Java if needed.
                     if (!CreateIteratorIfNeeded(err))
-                        return NULL;
-
-                    if (hasNext)
-                    {
-                        JniErrorInfo jniErr;
-
-                        SharedPointer<InteropMemory> inMem = env.Get()->AllocateMemory();
+                        return 0;
 
-                        env.Get()->Context()->TargetOutStream(javaRef, OP_GET_SINGLE, inMem.Get()->PointerLong(), &jniErr);
+                    // Get next results batch if the end in the current batch
+                    // has been reached.
+                    if (!GetNextBatchIfNeeded(err))
+                        return 0;
 
-                        IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
-
-                        if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
-                        {
-                            hasNext = IteratorHasNext(err);
-
-                            return new QueryFieldsRowImpl(inMem);
-                        }
-                    }
-                    else
+                    if (endReached)
                     {
                         // Ensure we do not overwrite possible previous error.
-                        if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
-                            *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "No more elements available.");
+                        if (err.GetCode() == IgniteError::IGNITE_SUCCESS)
+                            err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "No more elements available.");
+
+                        return 0;
                     }
 
-                    return NULL;
+                    return batch->GetNextRow();
                 }
 
-                void QueryCursorImpl::GetAll(OutputOperation& op, IgniteError* err)
+                void QueryCursorImpl::GetAll(OutputOperation& op, IgniteError& err)
                 {
                     // Check whether any of iterator methods were called.
                     if (iterCalled)
                     {
-                        *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+                        err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
                             "Cannot use GetAll() method because an iteration method was called.");
 
                         return;
@@ -163,7 +156,7 @@ namespace ignite
                     // Check whether GetAll was called before.
                     if (getAllCalled)
                     {
-                        *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+                        err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
                             "Cannot use GetNext() method because GetAll() was called.");
 
                         return;
@@ -176,7 +169,7 @@ namespace ignite
 
                     env.Get()->Context()->TargetOutStream(javaRef, OP_GET_ALL, inMem.Get()->PointerLong(), &jniErr);
 
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
 
                     if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
                     {
@@ -190,38 +183,71 @@ namespace ignite
                     }
                 }
 
-                bool QueryCursorImpl::CreateIteratorIfNeeded(IgniteError* err)
+                bool QueryCursorImpl::CreateIteratorIfNeeded(IgniteError& err)
                 {
-                    if (!iterCalled)
-                    {
-                        JniErrorInfo jniErr;
+                    if (iterCalled)
+                        return true;
 
-                        env.Get()->Context()->QueryCursorIterator(javaRef, &jniErr);
+                    JniErrorInfo jniErr;
 
-                        IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+                    env.Get()->Context()->QueryCursorIterator(javaRef, &jniErr);
 
-                        if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
-                        {
-                            iterCalled = true;
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+
+                    if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
+                        iterCalled = true;
+
+                    return iterCalled;
+                }
+
+                bool QueryCursorImpl::GetNextBatchIfNeeded(IgniteError& err)
+                {
+                    assert(iterCalled);
+
+                    if (endReached || (batch && batch->Left() > 0))
+                        return true;
+
+                    endReached = !IteratorHasNext(err);
+
+                    if (endReached)
+                        return true;
+
+                    JniErrorInfo jniErr;
+
+                    SharedPointer<InteropMemory> inMem = env.Get()->AllocateMemory();
+
+                    env.Get()->Context()->TargetOutStream(
+                        javaRef, OP_GET_BATCH, inMem.Get()->PointerLong(), &jniErr);
+
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+
+                    if (jniErr.code != IGNITE_JNI_ERR_SUCCESS)
+                        return false;
+
+                    delete batch;
+
+                    // Needed for exception safety.
+                    batch = 0;
+
+                    batch = new QueryBatch(*env.Get(), inMem);
+
+                    endReached = batch->IsEmpty();
 
-                            hasNext = IteratorHasNext(err);
-                        }
-                        else
-                            return false;
-                    }
-                    
                     return true;
                 }
 
-                bool QueryCursorImpl::IteratorHasNext(IgniteError* err)
+                bool QueryCursorImpl::IteratorHasNext(IgniteError& err)
                 {
                     JniErrorInfo jniErr;
 
                     bool res = env.Get()->Context()->QueryCursorIteratorHasNext(javaRef, &jniErr);
 
-                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, &err);
+
+                    if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
+                        return res;
 
-                    return jniErr.code == IGNITE_JNI_ERR_SUCCESS && res;
+                    return false;
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e9c797fd/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs
index d33fdce..d928418 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs
@@ -52,6 +52,9 @@ namespace Apache.Ignite.Core.Impl.Cache.Query
         [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
         protected override T Read(BinaryReader reader)
         {
+            // Reading and skipping row size in bytes.
+            reader.ReadInt();
+
             int cnt = reader.ReadInt();
 
             return _readerFunc(reader, cnt);


[15/20] ignite git commit: IGNITE-3834: Fixed a problem with BinaryMarshaller handles resolution.

Posted by vo...@apache.org.
IGNITE-3834: Fixed a problem with BinaryMarshaller handles resolution.


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

Branch: refs/heads/ignite-3611-1
Commit: 40d4b6ac6a71ed541d20018cf7deb2fb9b9bbb9b
Parents: d65228e
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Mon Sep 5 11:35:26 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Sep 5 11:35:26 2016 +0300

----------------------------------------------------------------------
 .../internal/binary/BinaryReaderHandles.java    |  2 +-
 .../binary/BinaryMarshallerSelfTest.java        | 38 ++++++++++++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/40d4b6ac/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandles.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandles.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandles.java
index fddb8aa..881060f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandles.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderHandles.java
@@ -57,7 +57,7 @@ public class BinaryReaderHandles {
                 return null;
 
             case MODE_SINGLE:
-                return (T)data;
+                 return pos == singlePos ? (T)data : null;
 
             default:
                 assert mode == MODE_MULTIPLE;

http://git-wip-us.apache.org/repos/asf/ignite/blob/40d4b6ac/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
index f4c1bf7..b347ec0 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
@@ -2896,6 +2896,21 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * @throws Exception If failed.
+     */
+    public void testSingleHandle() throws Exception {
+        SingleHandleA a = new SingleHandleA(new SingleHandleB());
+
+        BinaryObjectImpl bo = marshal(a, binaryMarshaller());
+
+        Map<String, BinaryObject> map = bo.field("map");
+
+        BinaryObject innerBo = map.get("key");
+
+        assertEquals(SingleHandleB.class, innerBo.deserialize().getClass());
+    }
+
+    /**
      *
      */
     private static interface SomeItf {
@@ -4847,4 +4862,27 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
             return value;
         }
     }
+
+    /**
+     */
+    private static class SingleHandleA {
+        /** */
+        private SingleHandleB b;
+
+        /** */
+        private Map<Object, SingleHandleB> map = new HashMap<>();
+
+        /**
+         * @param b B.
+         */
+        SingleHandleA(SingleHandleB b) {
+            this.b = b;
+
+            map.put("key", b);
+        }
+    }
+
+    /**
+     */
+    private static class SingleHandleB {}
 }


[04/20] ignite git commit: IGNITE-3827: Removed double marshalling of keys in DataStreamerImpl.addData(Map) method.

Posted by vo...@apache.org.
IGNITE-3827: Removed double marshalling of keys in DataStreamerImpl.addData(Map) method.


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

Branch: refs/heads/ignite-3611-1
Commit: 7a84ab6a9163ca31fbcfcc6d7ff27e06bf9babef
Parents: fbbcaf4
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Fri Sep 2 18:05:16 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Fri Sep 2 18:05:16 2016 +0300

----------------------------------------------------------------------
 .../datastreamer/DataStreamerImpl.java          | 23 ++++++++------------
 1 file changed, 9 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/7a84ab6a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
index e565cba..a3bae24 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
@@ -87,7 +87,6 @@ import org.apache.ignite.internal.util.future.IgniteFinishedFutureImpl;
 import org.apache.ignite.internal.util.lang.GridPeerDeployAware;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
-import org.apache.ignite.internal.util.typedef.C1;
 import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.A;
@@ -513,23 +512,19 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
 
             activeFuts.add(resFut);
 
-            Collection<KeyCacheObject> keys = null;
+            Collection<KeyCacheObject> keys =
+                new GridConcurrentHashSet<>(entries.size(), U.capacity(entries.size()), 1);
 
-            if (entries.size() > 1) {
-                keys = new GridConcurrentHashSet<>(entries.size(), U.capacity(entries.size()), 1);
+            Collection<DataStreamerEntry> entries0 = new ArrayList<>(entries.size());
 
-                for (Map.Entry<K, V> entry : entries)
-                    keys.add(cacheObjProc.toCacheKeyObject(cacheObjCtx, null, entry.getKey(), true));
-            }
+            for (Map.Entry<K, V> entry : entries) {
+                KeyCacheObject key = cacheObjProc.toCacheKeyObject(cacheObjCtx, null, entry.getKey(), true);
+                CacheObject val = cacheObjProc.toCacheObject(cacheObjCtx, entry.getValue(), true);
 
-            Collection<? extends DataStreamerEntry> entries0 = F.viewReadOnly(entries, new C1<Entry<K, V>, DataStreamerEntry>() {
-                @Override public DataStreamerEntry apply(Entry<K, V> e) {
-                    KeyCacheObject key = cacheObjProc.toCacheKeyObject(cacheObjCtx, null, e.getKey(), true);
-                    CacheObject val = cacheObjProc.toCacheObject(cacheObjCtx, e.getValue(), true);
+                keys.add(key);
 
-                    return new DataStreamerEntry(key, val);
-                }
-            });
+                entries0.add(new DataStreamerEntry(key, val));
+            }
 
             load0(entries0, resFut, keys, 0);
 


[08/20] ignite git commit: IGNITE-3760: ODBC: Added tests for supported SQL92 string functions. This closes #1006.

Posted by vo...@apache.org.
IGNITE-3760: ODBC: Added tests for supported SQL92 string functions. This closes #1006.


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

Branch: refs/heads/ignite-3611-1
Commit: c992213274ec5872ef7ce359efa51e26003424ad
Parents: e9c797f
Author: isapego <is...@gridgain.com>
Authored: Sun Sep 4 16:49:42 2016 +0300
Committer: thatcoach <pp...@list.ru>
Committed: Sun Sep 4 16:49:42 2016 +0300

----------------------------------------------------------------------
 .../odbc-test/src/sql_string_functions_test.cpp | 63 ++++++++++++++++++++
 .../cpp/odbc/src/config/connection_info.cpp     |  4 +-
 2 files changed, 65 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/c9922132/modules/platforms/cpp/odbc-test/src/sql_string_functions_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/sql_string_functions_test.cpp b/modules/platforms/cpp/odbc-test/src/sql_string_functions_test.cpp
index d1ce194..c85f80c 100644
--- a/modules/platforms/cpp/odbc-test/src/sql_string_functions_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/sql_string_functions_test.cpp
@@ -288,4 +288,67 @@ BOOST_AUTO_TEST_CASE(TestStringFunctionUcase)
     CheckSingleResult<std::string>("SELECT {fn UCASE(strField)} FROM TestType", "HELLO WORLD!");
 }
 
+BOOST_AUTO_TEST_CASE(Test92StringFunctionLower)
+{
+    TestType in;
+    in.strField = "Hello World!";
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<std::string>("SELECT LOWER(strField) FROM TestType", "hello world!");
+}
+
+BOOST_AUTO_TEST_CASE(Test92StringFunctionUpper)
+{
+    TestType in;
+    in.strField = "Hello World!";
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<std::string>("SELECT UPPER(strField) FROM TestType", "HELLO WORLD!");
+}
+
+BOOST_AUTO_TEST_CASE(Test92StringFunctionSubstring)
+{
+    TestType in;
+    in.strField = "Hello Ignite!";
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<std::string>("SELECT SUBSTRING(strField, 7) FROM TestType", "Ignite!");
+    CheckSingleResult<std::string>("SELECT SUBSTRING(strField, 7, 6) FROM TestType", "Ignite");
+    CheckSingleResult<std::string>("SELECT SUBSTRING(strField FROM 7) FROM TestType", "Ignite!");
+    CheckSingleResult<std::string>("SELECT SUBSTRING(strField FROM 7 FOR 6) FROM TestType", "Ignite");
+}
+
+BOOST_AUTO_TEST_CASE(Test92StringFunctionTrimBoth)
+{
+    TestType in;
+    in.strField = "    Lorem ipsum  ";
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<std::string>("SELECT TRIM(BOTH FROM strField) FROM TestType", "Lorem ipsum");
+}
+
+BOOST_AUTO_TEST_CASE(Test92StringFunctionTrimLeading)
+{
+    TestType in;
+    in.strField = "    Lorem ipsum  ";
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<std::string>("SELECT TRIM(LEADING FROM strField) FROM TestType", "Lorem ipsum  ");
+}
+
+BOOST_AUTO_TEST_CASE(Test92StringFunctionTrimTrailing)
+{
+    TestType in;
+    in.strField = "    Lorem ipsum  ";
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<std::string>("SELECT TRIM(TRAILING FROM strField) FROM TestType", "    Lorem ipsum");
+}
+
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/c9922132/modules/platforms/cpp/odbc/src/config/connection_info.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/connection_info.cpp b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
index cff48cf..744a88e 100644
--- a/modules/platforms/cpp/odbc/src/config/connection_info.cpp
+++ b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
@@ -315,8 +315,8 @@ namespace ignite
 
 #ifdef SQL_SQL92_STRING_FUNCTIONS
                 // Bitmask enumerating the string scalar functions.
-                intParams[SQL_SQL92_STRING_FUNCTIONS] = SQL_SSF_CONVERT | SQL_SSF_LOWER | SQL_SSF_UPPER |
-                    SQL_SSF_SUBSTRING | SQL_SSF_TRANSLATE;
+                intParams[SQL_SQL92_STRING_FUNCTIONS] = SQL_SSF_LOWER | SQL_SSF_UPPER | SQL_SSF_SUBSTRING |
+                    SQL_SSF_TRIM_BOTH | SQL_SSF_TRIM_LEADING | SQL_SSF_TRIM_TRAILING;
 #endif // SQL_SQL92_STRING_FUNCTIONS
 
 #ifdef SQL_SQL92_DATETIME_FUNCTIONS


[10/20] ignite git commit: IGNITE-3651 IGFS: Implemented "usedSpaceSize()" operation for local secondary file system. This closes #1009.

Posted by vo...@apache.org.
IGNITE-3651 IGFS: Implemented "usedSpaceSize()" operation for local secondary file system. This closes #1009.


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

Branch: refs/heads/ignite-3611-1
Commit: f8ae67456703e63e3afc9bb5c21d81d576d59448
Parents: d06eaa23
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Sun Sep 4 17:09:08 2016 +0300
Committer: thatcoach <pp...@list.ru>
Committed: Sun Sep 4 17:09:08 2016 +0300

----------------------------------------------------------------------
 .../local/LocalIgfsSecondaryFileSystem.java     | 15 ++++-
 .../local/LocalFileSystemSizeVisitor.java       | 60 ++++++++++++++++++++
 ...SecondaryFileSystemDualAbstractSelfTest.java | 43 ++++++++++++++
 3 files changed, 117 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f8ae6745/modules/core/src/main/java/org/apache/ignite/igfs/secondary/local/LocalIgfsSecondaryFileSystem.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/igfs/secondary/local/LocalIgfsSecondaryFileSystem.java b/modules/core/src/main/java/org/apache/ignite/igfs/secondary/local/LocalIgfsSecondaryFileSystem.java
index 519f472..36080f2 100644
--- a/modules/core/src/main/java/org/apache/ignite/igfs/secondary/local/LocalIgfsSecondaryFileSystem.java
+++ b/modules/core/src/main/java/org/apache/ignite/igfs/secondary/local/LocalIgfsSecondaryFileSystem.java
@@ -27,6 +27,7 @@ import org.apache.ignite.igfs.IgfsPathNotFoundException;
 import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystem;
 import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystemPositionedReadable;
 import org.apache.ignite.internal.processors.igfs.secondary.local.LocalFileSystemIgfsFile;
+import org.apache.ignite.internal.processors.igfs.secondary.local.LocalFileSystemSizeVisitor;
 import org.apache.ignite.internal.processors.igfs.secondary.local.LocalIgfsSecondaryFileSystemPositionedReadable;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -42,6 +43,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.LinkOption;
+import java.nio.file.Path;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Collection;
 import java.util.Collections;
@@ -301,7 +303,18 @@ public class LocalIgfsSecondaryFileSystem implements IgfsSecondaryFileSystem, Li
 
     /** {@inheritDoc} */
     @Override public long usedSpaceSize() {
-        throw new UnsupportedOperationException("usedSpaceSize operation is not yet supported.");
+        Path p = fileForPath(new IgfsPath("/")).toPath();
+
+        try {
+            LocalFileSystemSizeVisitor visitor = new LocalFileSystemSizeVisitor();
+
+            Files.walkFileTree(p, visitor);
+
+            return visitor.size();
+        }
+        catch (IOException e) {
+            throw new IgfsException("Failed to calculate used space size.", e);
+        }
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8ae6745/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemSizeVisitor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemSizeVisitor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemSizeVisitor.java
new file mode 100644
index 0000000..222b749
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/secondary/local/LocalFileSystemSizeVisitor.java
@@ -0,0 +1,60 @@
+/*
+ * 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.igfs.secondary.local;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+
+/**
+ * File visitor to get occupied file system size.
+ */
+public class LocalFileSystemSizeVisitor implements FileVisitor<Path> {
+    /** File size accumulator. */
+    private long size;
+
+    /** {@inheritDoc} */
+    @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+        return FileVisitResult.CONTINUE;
+    }
+
+    /** {@inheritDoc} */
+    @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+        size += attrs.size();
+        return FileVisitResult.CONTINUE;
+    }
+
+    /** {@inheritDoc} */
+    @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
+        return FileVisitResult.CONTINUE;
+    }
+
+    /** {@inheritDoc} */
+    @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+        return FileVisitResult.CONTINUE;
+    }
+
+    /**
+     * @return Total size of visited files.
+     */
+    public long size() {
+        return size;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f8ae6745/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
index 1d1ce8d..df7d782 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsLocalSecondaryFileSystemDualAbstractSelfTest.java
@@ -24,6 +24,7 @@ import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystem;
 import org.apache.ignite.igfs.secondary.local.LocalIgfsSecondaryFileSystem;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteBiInClosure;
 import org.jetbrains.annotations.Nullable;
 
 import java.io.File;
@@ -32,6 +33,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.util.Collection;
+import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * Abstract test for Hadoop 1.0 file system stack.
@@ -170,6 +172,47 @@ public abstract class IgfsLocalSecondaryFileSystemDualAbstractSelfTest extends I
      *
      * @throws Exception If failed.
      */
+    public void testUsedSpaceSize() throws Exception {
+        final int DIRS_COUNT = 5;
+        final int DIRS_MAX_DEEP = 3;
+        final int FILES_COUNT = 10;
+        final AtomicLong totalSize = new AtomicLong();
+
+        IgniteBiInClosure<Integer, IgfsPath> createHierarchy = new IgniteBiInClosure<Integer, IgfsPath>() {
+            @Override public void apply(Integer level, IgfsPath levelDir) {
+                try {
+                    for (int i = 0; i < FILES_COUNT; ++i) {
+                        IgfsPath filePath = new IgfsPath(levelDir, "file" + Integer.toString(i));
+
+                        createFile(igfs, filePath, true, chunk);
+
+                        totalSize.getAndAdd(chunk.length);
+                    }
+
+                    if (level < DIRS_MAX_DEEP) {
+                        for (int dir = 0; dir < DIRS_COUNT; dir++) {
+                            IgfsPath dirPath = new IgfsPath(levelDir, "dir" + Integer.toString(dir));
+
+                            igfs.mkdirs(dirPath);
+
+                            apply(level + 1, dirPath);
+                        }
+                    }
+                } catch (Exception e) {
+                    fail(e.getMessage());
+                }
+            }
+        };
+
+        createHierarchy.apply(1, new IgfsPath("/dir"));
+
+        assertEquals(totalSize.get(), igfs.metrics().secondarySpaceSize());
+    }
+
+    /**
+     *
+     * @throws Exception If failed.
+     */
     private void createSymlinks() throws Exception {
         assert dirLinkDest.mkdir();
 


[13/20] ignite git commit: IGNITE-3750: ODBC: Added tests for date/time types. This closes #1002.

Posted by vo...@apache.org.
IGNITE-3750: ODBC: Added tests for date/time types. This closes #1002.


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

Branch: refs/heads/ignite-3611-1
Commit: a760918757bee71ab28495496f94e9067ef17888
Parents: 3aa13f7
Author: Igor Sapego <is...@gridgain.com>
Authored: Mon Sep 5 10:36:38 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Sep 5 10:36:38 2016 +0300

----------------------------------------------------------------------
 .../processors/odbc/OdbcMessageParser.java      |  10 +-
 modules/platforms/cpp/odbc-test/Makefile.am     |   1 +
 .../odbc-test/include/sql_test_suite_fixture.h  |   6 +
 .../cpp/odbc-test/project/vs/odbc-test.vcxproj  |   1 +
 .../project/vs/odbc-test.vcxproj.filters        |   3 +
 .../cpp/odbc-test/src/queries_test.cpp          |   1 +
 .../src/sql_date_time_functions_test.cpp        | 213 +++++++++++++++++++
 .../odbc-test/src/sql_test_suite_fixture.cpp    |  17 ++
 modules/platforms/cpp/odbc/src/column.cpp       |  14 +-
 .../cpp/odbc/src/config/connection_info.cpp     |  16 +-
 10 files changed, 261 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a7609187/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
index a751eb2..3accf74 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
@@ -232,8 +232,14 @@ public class OdbcMessageParser {
 
                     writer.writeInt(row.size());
 
-                    for (Object obj : row)
-                        writer.writeObjectDetached(obj);
+                    for (Object obj : row) {
+                        if (obj instanceof java.sql.Timestamp)
+                            writer.writeTimestamp((java.sql.Timestamp)obj);
+                        else if (obj instanceof java.util.Date)
+                            writer.writeDate((java.util.Date)obj);
+                        else
+                            writer.writeObjectDetached(obj);
+                    }
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/a7609187/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 c3dd86a..a22e247 100644
--- a/modules/platforms/cpp/odbc-test/Makefile.am
+++ b/modules/platforms/cpp/odbc-test/Makefile.am
@@ -70,6 +70,7 @@ ignite_odbc_tests_SOURCES = \
     src/sql_operators_test.cpp \
     src/sql_value_expressions_test.cpp \
     src/sql_types_test.cpp \
+    src/sql_date_time_functions_test.cpp \
     src/sql_outer_join_test.cpp \
     ../odbc/src/cursor.cpp \
     ../odbc/src/config/connection_info.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/a7609187/modules/platforms/cpp/odbc-test/include/sql_test_suite_fixture.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/sql_test_suite_fixture.h b/modules/platforms/cpp/odbc-test/include/sql_test_suite_fixture.h
index 9e482da..6d26818 100644
--- a/modules/platforms/cpp/odbc-test/include/sql_test_suite_fixture.h
+++ b/modules/platforms/cpp/odbc-test/include/sql_test_suite_fixture.h
@@ -186,6 +186,12 @@ namespace ignite
 
     template<>
     void SqlTestSuiteFixture::CheckSingleResult<double>(const char* request);
+
+    template<>
+    void SqlTestSuiteFixture::CheckSingleResult<Date>(const char* request);
+
+    template<>
+    void SqlTestSuiteFixture::CheckSingleResult<Timestamp>(const char* request);
 }
 
 #endif //_IGNITE_ODBC_TEST_SQL_TEST_SUIT_FIXTURE

http://git-wip-us.apache.org/repos/asf/ignite/blob/a7609187/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 b85f1e6..98a1e58 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
@@ -171,6 +171,7 @@
     <ClCompile Include="..\..\src\row_test.cpp" />
     <ClCompile Include="..\..\src\sql_aggregate_functions_test.cpp" />
     <ClCompile Include="..\..\src\sql_outer_join_test.cpp" />
+    <ClCompile Include="..\..\src\sql_date_time_functions_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" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/a7609187/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 ee5df76..f348ee7 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
@@ -109,6 +109,9 @@
     <ClCompile Include="..\..\src\sql_outer_join_test.cpp">
       <Filter>Code</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\sql_date_time_functions_test.cpp">
+      <Filter>Code</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\test_type.h">

http://git-wip-us.apache.org/repos/asf/ignite/blob/a7609187/modules/platforms/cpp/odbc-test/src/queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/queries_test.cpp b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
index 4ba3a63..7c10527 100644
--- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
@@ -121,6 +121,7 @@ struct QueriesTestSuiteFixture
         cfg.jvmOpts.push_back("-Djava.compiler=NONE");
         cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005");
         cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError");
+        cfg.jvmOpts.push_back("-Duser.timezone=GMT");
 
 #ifdef IGNITE_TESTS_32
         cfg.jvmInitMem = 256;

http://git-wip-us.apache.org/repos/asf/ignite/blob/a7609187/modules/platforms/cpp/odbc-test/src/sql_date_time_functions_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/sql_date_time_functions_test.cpp b/modules/platforms/cpp/odbc-test/src/sql_date_time_functions_test.cpp
new file mode 100644
index 0000000..f89cc3d
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/src/sql_date_time_functions_test.cpp
@@ -0,0 +1,213 @@
+/*
+ * 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 _MSC_VER
+#   define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include "sql_test_suite_fixture.h"
+
+using namespace ignite;
+
+using namespace boost::unit_test;
+
+BOOST_FIXTURE_TEST_SUITE(SqlDateTimeFunctionTestSuite, ignite::SqlTestSuiteFixture)
+
+BOOST_AUTO_TEST_CASE(TestCurrentDate)
+{
+    CheckSingleResult<Date>("SELECT {fn CURRENT_DATE()}");
+}
+
+BOOST_AUTO_TEST_CASE(TestCurdate)
+{
+    CheckSingleResult<Date>("SELECT {fn CURDATE()}");
+}
+
+BOOST_AUTO_TEST_CASE(TestCurrentTime)
+{
+    CheckSingleResult<Timestamp>("SELECT {fn CURRENT_TIME()}");
+}
+
+BOOST_AUTO_TEST_CASE(TestCurtime)
+{
+    CheckSingleResult<Timestamp>("SELECT {fn CURTIME()}");
+}
+
+BOOST_AUTO_TEST_CASE(TestCurrentTimestamp)
+{
+    CheckSingleResult<Timestamp>("SELECT {fn CURRENT_TIMESTAMP()}");
+}
+
+BOOST_AUTO_TEST_CASE(TestDayname)
+{
+    TestType in;
+
+    in.dateField = impl::binary::BinaryUtils::MakeDateGmt(2016, 8, 29);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<std::string>("SELECT {fn DAYNAME(dateField)} FROM TestType", "Monday");
+}
+
+BOOST_AUTO_TEST_CASE(TestDayofmonth)
+{
+    TestType in;
+
+    in.dateField = impl::binary::BinaryUtils::MakeDateGmt(2016, 8, 29);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn DAYOFMONTH(dateField)} FROM TestType", 29);
+    CheckSingleResult<int32_t>("SELECT {fn DAY_OF_MONTH(dateField)} FROM TestType", 29);
+}
+
+BOOST_AUTO_TEST_CASE(TestDayofweek)
+{
+    TestType in;
+
+    in.dateField = impl::binary::BinaryUtils::MakeDateGmt(2016, 8, 29);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn DAYOFWEEK(dateField)} FROM TestType", 2);
+    CheckSingleResult<int32_t>("SELECT {fn DAY_OF_WEEK(dateField)} FROM TestType", 2);
+}
+
+BOOST_AUTO_TEST_CASE(TestDayofyear)
+{
+    TestType in;
+
+    in.dateField = impl::binary::BinaryUtils::MakeDateGmt(2016, 8, 29);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn DAYOFYEAR(dateField)} FROM TestType", 242);
+    CheckSingleResult<int32_t>("SELECT {fn DAY_OF_YEAR(dateField)} FROM TestType", 242);
+}
+
+BOOST_AUTO_TEST_CASE(TestExtract)
+{
+    TestType in;
+
+    in.timestampField = impl::binary::BinaryUtils::MakeTimestampGmt(2016, 2, 24, 13, 45, 23, 580695103);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn EXTRACT(YEAR FROM timestampField)} FROM TestType", 2016);
+    CheckSingleResult<int32_t>("SELECT {fn EXTRACT(MONTH FROM timestampField)} FROM TestType", 2);
+    CheckSingleResult<int32_t>("SELECT {fn EXTRACT(DAY FROM timestampField)} FROM TestType", 24);
+    CheckSingleResult<int32_t>("SELECT {fn EXTRACT(HOUR FROM timestampField)} FROM TestType", 13);
+    CheckSingleResult<int32_t>("SELECT {fn EXTRACT(MINUTE FROM timestampField)} FROM TestType", 45);
+    CheckSingleResult<int32_t>("SELECT {fn EXTRACT(SECOND FROM timestampField)} FROM TestType", 23);
+}
+
+BOOST_AUTO_TEST_CASE(TestHour)
+{
+    TestType in;
+
+    in.timestampField = impl::binary::BinaryUtils::MakeTimestampGmt(2016, 2, 24, 13, 45, 23, 580695103);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn HOUR(timestampField)} FROM TestType", 13);
+}
+
+BOOST_AUTO_TEST_CASE(TestMinute)
+{
+    TestType in;
+
+    in.timestampField = impl::binary::BinaryUtils::MakeTimestampGmt(2016, 2, 24, 13, 45, 23, 580695103);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn MINUTE(timestampField)} FROM TestType", 45);
+}
+
+BOOST_AUTO_TEST_CASE(TestMonth)
+{
+    TestType in;
+
+    in.timestampField = impl::binary::BinaryUtils::MakeTimestampGmt(2016, 2, 24, 13, 45, 23, 580695103);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn MONTH(timestampField)} FROM TestType", 2);
+}
+
+BOOST_AUTO_TEST_CASE(TestMonthname)
+{
+    TestType in;
+
+    in.timestampField = impl::binary::BinaryUtils::MakeTimestampGmt(2016, 2, 24, 13, 45, 23, 580695103);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<std::string>("SELECT {fn MONTHNAME(timestampField)} FROM TestType", "February");
+}
+
+BOOST_AUTO_TEST_CASE(TestNow)
+{
+    CheckSingleResult<Timestamp>("SELECT {fn NOW()}");
+}
+
+BOOST_AUTO_TEST_CASE(TestQuarter)
+{
+    TestType in;
+
+    in.timestampField = impl::binary::BinaryUtils::MakeTimestampGmt(2016, 2, 24, 13, 45, 23, 580695103);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn QUARTER(timestampField)} FROM TestType", 1);
+}
+
+BOOST_AUTO_TEST_CASE(TestSecond)
+{
+    TestType in;
+
+    in.timestampField = impl::binary::BinaryUtils::MakeTimestampGmt(2016, 2, 24, 13, 45, 23, 580695103);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn SECOND(timestampField)} FROM TestType", 23);
+}
+
+BOOST_AUTO_TEST_CASE(TestWeek)
+{
+    TestType in;
+
+    in.timestampField = impl::binary::BinaryUtils::MakeTimestampGmt(2016, 2, 24, 13, 45, 23, 580695103);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn WEEK(timestampField)} FROM TestType", 9);
+}
+
+BOOST_AUTO_TEST_CASE(TestYear)
+{
+    TestType in;
+
+    in.timestampField = impl::binary::BinaryUtils::MakeTimestampGmt(2016, 2, 24, 13, 45, 23, 580695103);
+
+    testCache.Put(1, in);
+
+    CheckSingleResult<int32_t>("SELECT {fn YEAR(timestampField)} FROM TestType", 2016);
+}
+
+BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/a7609187/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp b/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
index 657b854..e9a8fc5 100644
--- a/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
+++ b/modules/platforms/cpp/odbc-test/src/sql_test_suite_fixture.cpp
@@ -34,6 +34,7 @@ namespace ignite
         cfg.jvmOpts.push_back("-Djava.compiler=NONE");
         cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005");
         cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError");
+        cfg.jvmOpts.push_back("-Duser.timezone=GMT");
 
 #ifdef IGNITE_TESTS_32
         cfg.jvmInitMem = 256;
@@ -268,4 +269,20 @@ namespace ignite
 
         CheckSingleResult0(request, SQL_C_DOUBLE, &res, 0, 0);
     }
+
+    template<>
+    void SqlTestSuiteFixture::CheckSingleResult<Date>(const char* request)
+    {
+        SQL_DATE_STRUCT res;
+
+        CheckSingleResult0(request, SQL_C_DATE, &res, 0, 0);
+    }
+
+    template<>
+    void SqlTestSuiteFixture::CheckSingleResult<Timestamp>(const char* request)
+    {
+        SQL_TIMESTAMP_STRUCT res;
+
+        CheckSingleResult0(request, SQL_C_TIMESTAMP, &res, 0, 0);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/a7609187/modules/platforms/cpp/odbc/src/column.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/column.cpp b/modules/platforms/cpp/odbc/src/column.cpp
index ec779ac..b076a12 100644
--- a/modules/platforms/cpp/odbc/src/column.cpp
+++ b/modules/platforms/cpp/odbc/src/column.cpp
@@ -58,7 +58,7 @@ namespace
      * complex type.
      * @return Column type header.
      */
-    int8_t ReadColumnHeader(ignite::impl::interop::InteropInputStream& stream)
+    int8_t ReadColumnHeader(InteropInputStream& stream)
     {
         using namespace ignite::impl::binary;
 
@@ -130,10 +130,10 @@ namespace ignite
             // No-op.
         }
 
-        Column::Column(ignite::impl::binary::BinaryReaderImpl& reader) :
+        Column::Column(BinaryReaderImpl& reader) :
             type(0), startPos(-1), endPos(-1), offset(0), size(0)
         {
-            ignite::impl::interop::InteropInputStream* stream = reader.GetStream();
+            InteropInputStream* stream = reader.GetStream();
 
             if (!stream)
                 return;
@@ -294,12 +294,8 @@ namespace ignite
             size = sizeTmp;
         }
 
-        SqlResult Column::ReadToBuffer(ignite::impl::binary::BinaryReaderImpl& reader,
-            app::ApplicationDataBuffer& dataBuf)
+        SqlResult Column::ReadToBuffer(BinaryReaderImpl& reader, app::ApplicationDataBuffer& dataBuf)
         {
-            using namespace ignite::impl::binary;
-            using namespace ignite::impl::interop;
-
             if (!IsValid())
                 return SQL_RESULT_ERROR;
 
@@ -310,7 +306,7 @@ namespace ignite
                 return SQL_RESULT_NO_DATA;
             }
 
-            ignite::impl::interop::InteropInputStream* stream = reader.GetStream();
+            InteropInputStream* stream = reader.GetStream();
 
             if (!stream)
                 return SQL_RESULT_ERROR;

http://git-wip-us.apache.org/repos/asf/ignite/blob/a7609187/modules/platforms/cpp/odbc/src/config/connection_info.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/connection_info.cpp b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
index ca8d1a0..ee2c22b 100644
--- a/modules/platforms/cpp/odbc/src/config/connection_info.cpp
+++ b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
@@ -254,7 +254,11 @@ namespace ignite
 #ifdef SQL_TIMEDATE_FUNCTIONS
                 // Bitmask enumerating the scalar date and time functions supported
                 // by the driver and associated data source.
-                intParams[SQL_TIMEDATE_FUNCTIONS] = 0;
+                intParams[SQL_TIMEDATE_FUNCTIONS] = SQL_FN_TD_CURRENT_DATE | SQL_FN_TD_CURRENT_TIME |
+                    SQL_FN_TD_CURRENT_TIMESTAMP | SQL_FN_TD_CURDATE | SQL_FN_TD_CURTIME | SQL_FN_TD_DAYNAME |
+                    SQL_FN_TD_DAYOFMONTH | SQL_FN_TD_DAYOFWEEK | SQL_FN_TD_DAYOFYEAR | SQL_FN_TD_EXTRACT |
+                    SQL_FN_TD_HOUR | SQL_FN_TD_MINUTE | SQL_FN_TD_MONTH | SQL_FN_TD_MONTHNAME | SQL_FN_TD_NOW |
+                    SQL_FN_TD_QUARTER | SQL_FN_TD_SECOND | SQL_FN_TD_WEEK | SQL_FN_TD_YEAR;
 #endif // SQL_TIMEDATE_FUNCTIONS
 
 #ifdef SQL_TIMEDATE_ADD_INTERVALS
@@ -272,15 +276,7 @@ namespace ignite
 #ifdef SQL_DATETIME_LITERALS
                 // Bitmask enumerating the SQL-92 datetime literals supported by
                 // the data source.
-                intParams[SQL_DATETIME_LITERALS] = SQL_DL_SQL92_INTERVAL_HOUR |
-                    SQL_DL_SQL92_DATE | SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND |
-                    SQL_DL_SQL92_TIME | SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND |
-                    SQL_DL_SQL92_TIMESTAMP | SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE |
-                    SQL_DL_SQL92_INTERVAL_YEAR | SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND |
-                    SQL_DL_SQL92_INTERVAL_MONTH | SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR |
-                    SQL_DL_SQL92_INTERVAL_DAY | SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE |
-                    SQL_DL_SQL92_INTERVAL_MINUTE | SQL_DL_SQL92_INTERVAL_SECOND |
-                    SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH;
+                intParams[SQL_DATETIME_LITERALS] =  SQL_DL_SQL92_DATE | SQL_DL_SQL92_TIME | SQL_DL_SQL92_TIMESTAMP;
 #endif // SQL_DATETIME_LITERALS
 
 #ifdef SQL_SYSTEM_FUNCTIONS


[02/20] ignite git commit: Merge remote-tracking branch 'remotes/community/ignite-1.6.6' into ignite-1.6.7

Posted by vo...@apache.org.
Merge remote-tracking branch 'remotes/community/ignite-1.6.6' into ignite-1.6.7


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

Branch: refs/heads/ignite-3611-1
Commit: 12f532986677c30a716f73aeaa7d3587dd701f55
Parents: 70e69cb 12fd497
Author: sboikov <sb...@gridgain.com>
Authored: Thu Sep 1 17:05:15 2016 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Thu Sep 1 17:05:15 2016 +0300

----------------------------------------------------------------------
 .../internal/processors/query/h2/sql/GridQueryParsingTest.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------



[20/20] ignite git commit: WIP.

Posted by vo...@apache.org.
WIP.


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

Branch: refs/heads/ignite-3611-1
Commit: 1cdca9ec941de26bbcd1671fd7fbc7302a052d7d
Parents: 008cf64
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Mon Sep 5 16:18:10 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Sep 5 16:18:10 2016 +0300

----------------------------------------------------------------------
 .../internal/processors/igfs/IgfsImpl.java      | 73 +++++++++++---------
 1 file changed, 39 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1cdca9ec/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
index c704e00..3b25c82 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
@@ -17,7 +17,6 @@
 
 package org.apache.ignite.internal.processors.igfs;
 
-import java.util.Set;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
@@ -68,7 +67,6 @@ import org.apache.ignite.internal.processors.igfs.client.IgfsClientUpdateCallabl
 import org.apache.ignite.internal.processors.task.GridInternal;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
-import org.apache.ignite.internal.util.typedef.C1;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.A;
@@ -791,7 +789,7 @@ public final class IgfsImpl implements IgfsEx {
 
                 IgfsMode mode = resolveMode(path);
 
-                Collection<String> files = new HashSet<>();
+                Collection<IgfsPath> files = new HashSet<>();
 
                 if (IgfsUtils.isDualMode(mode)) {
                     assert secondaryFs != null;
@@ -799,8 +797,10 @@ public final class IgfsImpl implements IgfsEx {
                     try {
                         Collection<IgfsPath> children = secondaryFs.listPaths(path);
 
-                        for (IgfsPath child : children)
-                            files.add(child.name());
+                        files.addAll(children);
+
+                        if (!modeRslvr.hasPrimaryChild(path))
+                            return files;
                     }
                     catch (Exception e) {
                         U.error(log, "List paths in DUAL mode failed [path=" + path + ']', e);
@@ -809,20 +809,17 @@ public final class IgfsImpl implements IgfsEx {
                     }
                 }
 
-                if (!IgfsUtils.isDualMode(mode) || modeRslvr.hasPrimaryChild(path)) {
-                    IgniteUuid fileId = meta.fileId(path);
+                IgfsEntryInfo info = primaryInfoForListing(path);
 
-                    if (fileId != null)
-                        files.addAll(meta.directoryListing(fileId).keySet());
-                    else if (mode == PRIMARY)
-                        throw new IgfsPathNotFoundException("Failed to list files (path not found): " + path);
+                if (info != null) {
+                    // Perform the listing.
+                    for (String child : info.listing().keySet())
+                        files.add(new IgfsPath(path, child));
                 }
+                else if (mode == PRIMARY)
+                    throw new IgfsPathNotFoundException("Failed to list paths (path not found): " + path);
 
-                return F.viewReadOnly(files, new C1<String, IgfsPath>() {
-                    @Override public IgfsPath apply(String e) {
-                        return new IgfsPath(path, e);
-                    }
-                });
+                return files;
             }
         });
     }
@@ -841,7 +838,7 @@ public final class IgfsImpl implements IgfsEx {
 
                 IgfsMode mode = resolveMode(path);
 
-                Set<IgfsFile> files = new HashSet<>();
+                Collection<IgfsFile> files = new HashSet<>();
 
                 if (IgfsUtils.isDualMode(mode)) {
                     assert secondaryFs != null;
@@ -865,27 +862,22 @@ public final class IgfsImpl implements IgfsEx {
                     }
                 }
 
-                IgniteUuid fileId = meta.fileId(path);
-
-                if (fileId != null) {
-                    IgfsEntryInfo info = meta.info(fileId);
+                IgfsEntryInfo info = primaryInfoForListing(path);
 
-                    // Handle concurrent deletion.
-                    if (info != null) {
-                        if (info.isFile())
-                            // If this is a file, return its description.
-                            return Collections.<IgfsFile>singleton(new IgfsFileImpl(path, info,
-                                data.groupBlockSize()));
+                if (info != null) {
+                    if (info.isFile())
+                        // If this is a file, return its description.
+                        return Collections.<IgfsFile>singleton(new IgfsFileImpl(path, info,
+                            data.groupBlockSize()));
 
-                        // Perform the listing.
-                        for (Map.Entry<String, IgfsListingEntry> e : info.listing().entrySet()) {
-                            IgfsEntryInfo childInfo = meta.info(e.getValue().fileId());
+                    // Perform the listing.
+                    for (Map.Entry<String, IgfsListingEntry> e : info.listing().entrySet()) {
+                        IgfsEntryInfo childInfo = meta.info(e.getValue().fileId());
 
-                            if (childInfo != null) {
-                                IgfsPath childPath = new IgfsPath(path, e.getKey());
+                        if (childInfo != null) {
+                            IgfsPath childPath = new IgfsPath(path, e.getKey());
 
-                                files.add(new IgfsFileImpl(childPath, childInfo, data.groupBlockSize()));
-                            }
+                            files.add(new IgfsFileImpl(childPath, childInfo, data.groupBlockSize()));
                         }
                     }
                 }
@@ -897,6 +889,19 @@ public final class IgfsImpl implements IgfsEx {
         });
     }
 
+    /**
+     * Get primary file system info for listing operation.
+     *
+     * @param path Path.
+     * @return Info or {@code null} if not found.
+     * @throws IgniteCheckedException If failed.
+     */
+    private IgfsEntryInfo primaryInfoForListing(IgfsPath path) throws IgniteCheckedException {
+        IgniteUuid fileId = meta.fileId(path);
+
+        return fileId != null ? meta.info(fileId) : null;
+    }
+
     /** {@inheritDoc} */
     @Override public long usedSpaceSize() {
         return metrics().localSpaceSize();


[06/20] ignite git commit: IGNITE-3829: Optimized affinity key field name handling.

Posted by vo...@apache.org.
IGNITE-3829: Optimized affinity key field name handling.


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

Branch: refs/heads/ignite-3611-1
Commit: e3c4868d6737e5a0f0b90f99666242865add750c
Parents: 7bb961f
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Fri Sep 2 18:23:09 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Fri Sep 2 18:23:09 2016 +0300

----------------------------------------------------------------------
 .../binary/CacheObjectBinaryProcessorImpl.java  | 35 ++++++++++++++++----
 1 file changed, 28 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e3c4868d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
index 0337874..ecd27f7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
@@ -40,6 +40,7 @@ import org.apache.ignite.IgniteBinary;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.binary.BinaryBasicNameMapper;
+import org.apache.ignite.binary.BinaryField;
 import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.binary.BinaryObjectBuilder;
 import org.apache.ignite.binary.BinaryObjectException;
@@ -89,6 +90,7 @@ import org.apache.ignite.internal.util.lang.GridMapEntry;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.C1;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T1;
 import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.CU;
@@ -159,6 +161,9 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
     /** Metadata updates collected before metadata cache is initialized. */
     private final Map<Integer, BinaryMetadata> metaBuf = new ConcurrentHashMap<>();
 
+    /** Cached affinity key field names. */
+    private final ConcurrentHashMap<Integer, T1<BinaryField>> affKeyFields = new ConcurrentHashMap<>();
+
     /**
      * @param ctx Kernal context.
      */
@@ -684,22 +689,38 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
      * @return Affinity key.
      */
     public Object affinityKey(BinaryObject po) {
+        // Fast path for already cached field.
+        if (po instanceof BinaryObjectEx) {
+            int typeId = ((BinaryObjectEx)po).typeId();
+
+            T1<BinaryField> fieldHolder = affKeyFields.get(typeId);
+
+            if (fieldHolder != null) {
+                BinaryField field = fieldHolder.get();
+
+                return field != null ? field.value(po) : po;
+            }
+        }
+
+        // Slow path if affinity field is not cached yet.
         try {
             BinaryType meta = po instanceof BinaryObjectEx ? ((BinaryObjectEx)po).rawType() : po.type();
 
             if (meta != null) {
-                String affKeyFieldName = meta.affinityKeyFieldName();
+                String name = meta.affinityKeyFieldName();
+
+                affKeyFields.putIfAbsent(meta.typeId(), new T1<>(meta.field(name)));
 
-                if (affKeyFieldName != null)
-                    return po.field(affKeyFieldName);
+                if (name != null)
+                    return po.field(name);
             }
             else if (po instanceof BinaryObjectEx) {
-                int id = ((BinaryObjectEx)po).typeId();
+                int typeId = ((BinaryObjectEx)po).typeId();
 
-                String affKeyFieldName = binaryCtx.affinityKeyFieldName(id);
+                String name = binaryCtx.affinityKeyFieldName(typeId);
 
-                if (affKeyFieldName != null)
-                    return po.field(affKeyFieldName);
+                if (name != null)
+                    return po.field(name);
             }
         }
         catch (BinaryObjectException e) {


[05/20] ignite git commit: Merge remote-tracking branch 'upstream/ignite-1.6.7' into ignite-1.6.7

Posted by vo...@apache.org.
Merge remote-tracking branch 'upstream/ignite-1.6.7' into ignite-1.6.7


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

Branch: refs/heads/ignite-3611-1
Commit: 7bb961fd0a2e78334d33b6bc279c4edc323c246a
Parents: 7a84ab6 ae77653
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Fri Sep 2 18:05:54 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Fri Sep 2 18:05:54 2016 +0300

----------------------------------------------------------------------
 .../store/jdbc/dialect/SQLServerDialect.java    |   2 +-
 .../internal/binary/BinaryMarshaller.java       |   7 +
 .../processors/cache/IgniteCacheProxy.java      |  41 ++
 .../cache/query/GridCacheSqlQuery.java          |  11 +-
 .../processors/odbc/OdbcHandshakeRequest.java   |   8 +-
 .../processors/odbc/OdbcHandshakeResult.java    |  17 +-
 .../processors/odbc/OdbcMessageParser.java      |  22 +-
 .../processors/odbc/OdbcProtocolVersion.java    | 106 +++++
 .../processors/odbc/OdbcRequestHandler.java     |  17 +-
 .../GridCacheQueryTransformerSelfTest.java      |   9 +-
 .../query/h2/opt/GridH2ValueCacheObject.java    |   9 -
 ...niteBinaryObjectLocalQueryArgumentsTest.java |  28 ++
 ...aryObjectQueryArgumentsOffheapLocalTest.java |  28 ++
 ...teBinaryObjectQueryArgumentsOffheapTest.java |  30 ++
 .../IgniteBinaryObjectQueryArgumentsTest.java   | 469 ++++++++++++++++++-
 .../query/h2/sql/GridQueryParsingTest.java      |   2 +-
 .../IgniteCacheQuerySelfTestSuite.java          |   9 +
 .../cpp/common/include/ignite/common/utils.h    |  25 +
 .../cpp/common/os/win/src/common/utils.cpp      |  20 +
 modules/platforms/cpp/odbc-test/Makefile.am     |   1 +
 .../odbc-test/config/queries-test-noodbc.xml    | 103 ++++
 .../cpp/odbc-test/config/queries-test.xml       |  31 +-
 .../cpp/odbc-test/project/vs/odbc-test.vcxproj  |   2 +
 .../project/vs/odbc-test.vcxproj.filters        |   6 +
 .../cpp/odbc-test/src/configuration_test.cpp    | 156 ++++--
 .../cpp/odbc-test/src/queries_test.cpp          | 122 +++--
 .../odbc-test/src/sql_test_suite_fixture.cpp    |  14 +-
 modules/platforms/cpp/odbc/Makefile.am          |   2 +
 modules/platforms/cpp/odbc/include/Makefile.am  |   2 +
 .../cpp/odbc/include/ignite/odbc/common_types.h |   3 +
 .../include/ignite/odbc/config/configuration.h  | 207 +++++++-
 .../cpp/odbc/include/ignite/odbc/connection.h   |  47 +-
 .../ignite/odbc/diagnostic/diagnostic_record.h  |   2 +-
 .../cpp/odbc/include/ignite/odbc/dsn_config.h   |  61 +++
 .../cpp/odbc/include/ignite/odbc/parser.h       |   3 -
 .../odbc/include/ignite/odbc/protocol_version.h | 168 +++++++
 .../include/ignite/odbc/system/odbc_constants.h |   4 -
 .../odbc/system/ui/dsn_configuration_window.h   | 136 ++++++
 .../ignite/odbc/system/ui/custom_window.h       | 189 ++++++++
 .../win/include/ignite/odbc/system/ui/window.h  | 201 ++++++++
 .../odbc/os/win/src/system/ui/custom_window.cpp | 184 ++++++++
 .../src/system/ui/dsn_configuration_window.cpp  | 212 +++++++++
 .../cpp/odbc/os/win/src/system/ui/window.cpp    | 192 ++++++++
 .../cpp/odbc/os/win/src/system_dsn.cpp          | 218 +++++++++
 .../platforms/cpp/odbc/project/vs/odbc.vcxproj  |  27 +-
 .../cpp/odbc/project/vs/odbc.vcxproj.filters    |  36 ++
 .../cpp/odbc/src/config/configuration.cpp       | 266 ++++++-----
 modules/platforms/cpp/odbc/src/connection.cpp   |  66 ++-
 .../odbc/src/diagnostic/diagnostic_record.cpp   |   8 +-
 .../diagnostic/diagnostic_record_storage.cpp    |   2 +-
 modules/platforms/cpp/odbc/src/dsn_config.cpp   | 111 +++++
 modules/platforms/cpp/odbc/src/entry_points.cpp |   8 -
 modules/platforms/cpp/odbc/src/odbc.cpp         |  83 +---
 .../platforms/cpp/odbc/src/protocol_version.cpp | 131 ++++++
 .../commands/cache/VisorCacheStopCommand.scala  |   5 +-
 55 files changed, 3435 insertions(+), 434 deletions(-)
----------------------------------------------------------------------