ignite-437: test for bigQuery sql

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

Branch: refs/heads/ignite-gg-9829
Commit: fe743909cf483d00ab5189049523ed3353bf5a3d
Parents: 2f458d2
Author: Artem Shutak <ashu...@gridgain.com>
Authored: Wed Apr 8 19:55:29 2015 +0300
Committer: Artem Shutak <ashu...@gridgain.com>
Committed: Wed Apr 8 19:55:29 2015 +0300

----------------------------------------------------------------------
 .../h2/sql/AbstractH2CompareQueryTest.java      | 341 ++++++++
 .../query/h2/sql/BaseH2CompareQueryTest.java    | 823 +++++++++++++++++
 .../query/h2/sql/H2CompareBigQueryTest.java     | 707 +++++++++++++++
 .../query/h2/sql/IgniteVsH2QueryTest.java       | 875 -------------------
 .../IgniteCacheQuerySelfTestSuite.java          |   5 +-
 .../processors/query/h2/sql/bigQuery.sql        |  55 ++
 6 files changed, 1929 insertions(+), 877 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/fe743909/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
----------------------------------------------------------------------
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
new file mode 100644
index 0000000..c74493f
--- /dev/null
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
@@ -0,0 +1,341 @@
+/*
+ * 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.query.h2.sql;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.cache.query.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.marshaller.optimized.*;
+import org.apache.ignite.spi.discovery.tcp.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;
+import org.apache.ignite.testframework.junits.common.*;
+import org.jetbrains.annotations.*;
+
+import java.sql.*;
+import java.util.*;
+
+/**
+ * Abstract test framework to compare query results from h2 database instance 
and mixed ignite caches (replicated and partitioned)
+ * which have the same data models and data content. 
+ */
+public abstract class AbstractH2CompareQueryTest extends 
GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new 
TcpDiscoveryVmIpFinder(true);
+
+    /** Partitioned cache. */
+    protected static IgniteCache pCache;
+
+    /** Replicated cache. */
+    protected static IgniteCache rCache;
+    
+    /** H2 db connection. */
+    protected static Connection conn;
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration c = super.getConfiguration(gridName);
+
+        TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+        disco.setIpFinder(IP_FINDER);
+
+        c.setDiscoverySpi(disco);
+
+        c.setMarshaller(new OptimizedMarshaller(true));
+
+        c.setCacheConfiguration(createCache("part", CacheMode.PARTITIONED),
+            createCache("repl", CacheMode.REPLICATED)
+        );
+
+        return c;
+    }
+
+    /**
+     * Creates new cache configuration.
+     *
+     * @param name Cache name.
+     * @param mode Cache mode.
+     * @return Cache configuration.
+     */
+    private CacheConfiguration createCache(String name, CacheMode mode) {
+        CacheConfiguration<?,?> cc = defaultCacheConfiguration();
+
+        cc.setName(name);
+        cc.setCacheMode(mode);
+        
cc.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+        cc.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+
+        setIndexedTypes(cc, mode);
+
+        return cc;
+    }
+
+    /**
+     * @param cc Cache configuration.
+     * @param mode Cache Mode.
+     */
+    protected abstract void setIndexedTypes(CacheConfiguration<?, ?> cc, 
CacheMode mode) ;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        Ignite ignite = startGrids(4);
+
+        pCache = ignite.cache("part");
+        
+        rCache = ignite.cache("repl");
+
+        awaitPartitionMapExchange();
+        
+        conn = openH2Connection(false);
+
+        initializeH2Schema();
+
+        initCacheAndDbData();
+
+        checkAllDataEquals();
+    }
+    
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        super.afterTestsStopped();
+        
+        conn.close();
+        
+        stopAllGrids();
+    }
+
+    /**
+     * Populate cache and h2 database with test data.
+     */
+    protected abstract void initCacheAndDbData() throws SQLException;
+
+    /**
+     * @throws Exception If failed.
+     */
+    protected abstract void checkAllDataEquals() throws Exception;
+
+    /**
+     * Initialize h2 database schema.
+     *
+     * @throws SQLException If exception.
+     */
+    protected abstract void initializeH2Schema() throws SQLException;
+
+    /**
+     * Gets connection from a pool.
+     *
+     * @param autocommit {@code true} If connection should use autocommit mode.
+     * @return Pooled connection.
+     * @throws SQLException In case of error.
+     */
+    private Connection openH2Connection(boolean autocommit) throws 
SQLException {
+        System.setProperty("h2.serializeJavaObject", "false");
+        
+        String dbName = "test";
+        
+        Connection conn = DriverManager.getConnection("jdbc:h2:mem:" + dbName 
+ ";DB_CLOSE_DELAY=-1");
+
+        conn.setAutoCommit(autocommit);
+
+        return conn;
+    }
+
+    /**
+     * Execute given sql query on h2 database and on partitioned ignite cache 
and compare results.
+     *
+     * @param sql SQL query.
+     * @param args SQL arguments.
+     * then results will compare as ordered queries.
+     * @return Result set after SQL query execution. 
+     * @throws SQLException If exception.
+     */
+    protected final List<List<?>> compareQueryRes0(String sql, @Nullable 
Object... args) throws SQLException {
+        return compareQueryRes0(pCache, sql, args, Ordering.RANDOM);
+    }
+
+    /**
+     * Execute given sql query on h2 database and on ignite cache and compare 
results. 
+     * Expected that results are not ordered.
+     *
+     * @param cache Ignite cache.
+     * @param sql SQL query.
+     * @param args SQL arguments.
+     * then results will compare as ordered queries.
+     * @return Result set after SQL query execution. 
+     * @throws SQLException If exception.
+     */
+    protected final List<List<?>> compareQueryRes0(IgniteCache cache, String 
sql, @Nullable Object... args) throws SQLException {
+        return compareQueryRes0(cache, sql, args, Ordering.RANDOM);
+    }
+
+    /**
+     * Execute given sql query on h2 database and on partitioned ignite cache 
and compare results.
+     * Expected that results are ordered.
+     *
+     * @param sql SQL query.
+     * @param args SQL arguments.
+     * then results will compare as ordered queries.
+     * @return Result set after SQL query execution.
+     * @throws SQLException If exception.
+     */
+    protected final List<List<?>> compareOrderedQueryRes0(String sql, 
@Nullable Object... args) throws SQLException {
+        return compareQueryRes0(pCache, sql, args, Ordering.ORDERED);
+    }
+
+    /**
+     * Execute given sql query on h2 database and on ignite cache and compare 
results.
+     *
+     * @param cache Ignite cache.
+     * @param sql SQL query.
+     * @param args SQL arguments.
+     * @param ordering Expected ordering of SQL results. If {@link 
Ordering#ORDERED}
+     * then results will compare as ordered queries.
+     * @return Result set after SQL query execution.
+     * @throws SQLException If exception.
+     */    
+    @SuppressWarnings("unchecked")
+    protected final List<List<?>> compareQueryRes0(IgniteCache cache, String 
sql, @Nullable Object[] args, Ordering ordering) throws SQLException {
+        if (args == null)
+            args = new Object[] {null};
+        
+        info("Sql query:\n" + sql + "\nargs=" + Arrays.toString(args));
+
+        List<List<?>> h2Res = executeH2Query(sql, args);
+
+        List<List<?>> cacheRes = cache.query(new 
SqlFieldsQuery(sql).setArgs(args)).getAll();
+
+        assertRsEquals(h2Res, cacheRes, ordering);
+        
+        return h2Res;
+    }
+
+    /**
+     * Execute SQL query on h2 database.
+     *
+     * @param sql SQL query.
+     * @param args SQL arguments.
+     * @return Result of SQL query on h2 database.
+     * @throws SQLException If exception.
+     */
+    private List<List<?>> executeH2Query(String sql, Object[] args) throws 
SQLException {
+        List<List<?>> res = new ArrayList<>();
+        ResultSet rs = null;
+
+        try(PreparedStatement st = conn.prepareStatement(sql)) {
+            for (int idx = 0; idx < args.length; idx++)
+                st.setObject(idx + 1, args[idx]);
+
+            rs = st.executeQuery();
+
+            int colCnt = rs.getMetaData().getColumnCount();
+
+            while (rs.next()) {
+                List<Object> row = new ArrayList<>(colCnt);
+                
+                for (int i = 1; i <= colCnt; i++)
+                    row.add(rs.getObject(i));
+                
+                res.add(row);
+            }
+        }
+        finally {
+            U.closeQuiet(rs);
+        }
+
+        return res;
+    }
+
+    /**
+     * Assert equals of result sets according to expected ordering.
+     *
+     * @param rs1 Expected result set.
+     * @param rs2 Actual result set.
+     * @param ordering Expected ordering of SQL results. If {@link 
Ordering#ORDERED}
+     * then results will compare as ordered queries.
+     */
+    private void assertRsEquals(List<List<?>> rs1, List<List<?>> rs2, Ordering 
ordering) {
+        assertEquals("Rows count has to be equal.", rs1.size(), rs2.size());
+        
+        switch (ordering){
+            case ORDERED:
+                for (int rowNum = 0; rowNum < rs1.size(); rowNum++) {
+                    List<?> row1 = rs1.get(rowNum);
+                    List<?> row2 = rs2.get(rowNum);
+
+                    assertEquals("Columns count have to be equal.", 
row1.size(), row2.size());
+
+                    for (int colNum = 0; colNum < row1.size(); colNum++)
+                        assertEquals("Row=" + rowNum + ", column=" + colNum, 
row1.get(colNum), row2.get(colNum));
+                }
+
+                break;
+            case RANDOM:
+                Map<List<?>, Integer> rowsWithCnt1 = 
extractUniqueRowsWithCounts(rs1);
+                Map<List<?>, Integer> rowsWithCnt2 = 
extractUniqueRowsWithCounts(rs2);
+                
+                assertEquals("Unique rows count has to be equal.", 
rowsWithCnt1.size(), rowsWithCnt2.size());
+
+                for (Map.Entry<List<?>, Integer> entry1 : 
rowsWithCnt1.entrySet()) {
+                    List<?> row = entry1.getKey();
+                    Integer cnt1 = entry1.getValue();
+
+                    Integer cnt2 = rowsWithCnt2.get(row);
+
+                    assertEquals("Row has different occurance number.\nRow=" + 
row, cnt1, cnt2);
+                }
+                
+                break;
+            default: 
+                throw new IllegalStateException();
+        }
+    }
+
+    /**
+     * @param rs Result set.
+     * @return Map of unique rows at the result set to number of occuriances 
at the result set.
+     */
+    private Map<List<?>, Integer> 
extractUniqueRowsWithCounts(Iterable<List<?>> rs) {
+        Map<List<?>, Integer> res = new HashMap<>();
+
+        for (List<?> row : rs) {
+            Integer cnt = res.get(row);
+            
+            if (cnt == null)
+                cnt = 0;
+            
+            res.put(row, cnt + 1);
+        }
+        return res;
+    }
+    
+    /**
+     * Ordering type.
+     */
+    protected enum Ordering {
+        /** Random. */
+        RANDOM, 
+        /** Ordered. */
+        ORDERED
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/fe743909/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/BaseH2CompareQueryTest.java
----------------------------------------------------------------------
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/BaseH2CompareQueryTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/BaseH2CompareQueryTest.java
new file mode 100644
index 0000000..eea834d
--- /dev/null
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/BaseH2CompareQueryTest.java
@@ -0,0 +1,823 @@
+/*
+ * 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.query.h2.sql;
+
+import org.apache.ignite.cache.*;
+import org.apache.ignite.cache.affinity.*;
+import org.apache.ignite.cache.query.annotations.*;
+import org.apache.ignite.configuration.*;
+
+import java.io.*;
+import java.sql.*;
+import java.sql.Date;
+import java.util.*;
+
+/**
+ * Base set of queries to compare query results from h2 database instance and 
mixed ignite caches (replicated and partitioned)
+ * which have the same data models and data content.
+ */
+public class BaseH2CompareQueryTest extends AbstractH2CompareQueryTest {
+    /** Org count. */
+    public static final int ORG_CNT = 30;
+    
+    /** Address count. */
+    public static final int ADDR_CNT = 10;
+    
+    /** Person count. */
+    public static final int PERS_CNT = 50;
+    
+    /** Product count. */
+    public static final int PROD_CNT = 100;
+
+    /** Purchase count. */
+    public static final int PURCH_CNT = PROD_CNT * 5;
+
+    /** {@inheritDoc} */
+    @Override protected void setIndexedTypes(CacheConfiguration<?, ?> cc, 
CacheMode mode) {
+        if (mode == CacheMode.PARTITIONED)
+            cc.setIndexedTypes(
+                Integer.class, Organization.class,
+                AffinityKey.class, Person.class,
+                AffinityKey.class, Purchase.class
+            );
+        else if (mode == CacheMode.REPLICATED)
+            cc.setIndexedTypes(
+                Integer.class, Product.class,
+                Integer.class, Address.class
+            );
+        else
+            throw new IllegalStateException("mode: " + mode);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override protected void initCacheAndDbData() throws SQLException {
+        int idGen = 0;
+
+        // Organizations.
+        List<Organization> organizations = new ArrayList<>();
+
+        for (int i = 0; i < ORG_CNT; i++) {
+            int id = idGen++;
+
+            Organization org = new Organization(id, "Org" + id);
+
+            organizations.add(org);
+
+            pCache.put(org.id, org);
+
+            insertInDb(org);
+        }
+        
+       // Adresses.
+        List<Address> addreses = new ArrayList<>();
+
+        for (int i = 0; i < ADDR_CNT; i++) {
+            int id = idGen++;
+
+            Address addr = new Address(id, "Addr" + id);
+
+            addreses.add(addr);
+
+            rCache.put(addr.id, addr);
+
+            insertInDb(addr);
+        }
+
+        // Persons.
+        List<Person> persons = new ArrayList<>();
+
+        for (int i = 0; i < PERS_CNT; i++) {
+            int id = idGen++;
+
+            Person person = new Person(id, organizations.get(i % 
organizations.size()),
+                "name" + id, "lastName" + id, id * 100.0, addreses.get(i % 
addreses.size()));
+
+            // Add a Person without lastname.
+            if (id == organizations.size() + 1)
+                person.lastName = null;
+
+            persons.add(person);
+
+            pCache.put(person.key(), person);
+
+            insertInDb(person);
+        }
+
+        // Products.
+        List<Product> products = new ArrayList<>();
+
+        for (int i = 0; i < PROD_CNT; i++) {
+            int id = idGen++;
+
+            Product product = new Product(id, "Product" + id, id*1000);
+
+            products.add(product);
+
+            rCache.put(product.id, product);
+
+            insertInDb(product);
+        }
+
+        // Purchases.
+        for (int i = 0; i < PURCH_CNT; i++) {
+            int id = idGen++;
+
+            Person person = persons.get(i % persons.size());
+            
+            Purchase purchase = new Purchase(id, products.get(i % 
products.size()), person.orgId, person);
+
+            pCache.put(purchase.key(), purchase);
+
+            insertInDb(purchase);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void checkAllDataEquals() throws Exception {
+        compareQueryRes0("select _key, _val, id, name from 
\"part\".Organization");
+
+        compareQueryRes0("select _key, _val, id, firstName, lastName, orgId, 
salary from \"part\".Person");
+
+        compareQueryRes0("select _key, _val, id, personId, productId, 
organizationId from \"part\".Purchase");
+
+        compareQueryRes0(rCache, "select _key, _val, id, name, price from 
\"repl\".Product");
+    }
+
+    /**
+     * *
+     * @throws Exception
+     */
+    public void testAllExamples() throws Exception {
+//        compareQueryRes0("select ? limit ? offset ?");
+
+//        compareQueryRes0("select cool1()");
+//        compareQueryRes0("select cool1() z");
+//
+//        compareQueryRes0("select b,a from table0('aaa', 100)");
+//        compareQueryRes0("select * from table0('aaa', 100)");
+//        compareQueryRes0("select * from table0('aaa', 100) t0");
+//        compareQueryRes0("select x.a, y.b from table0('aaa', 100) x natural 
join table0('bbb', 100) y");
+//        compareQueryRes0("select * from table0('aaa', 100) x join 
table0('bbb', 100) y on x.a=y.a and x.b = 'bbb'");
+//        compareQueryRes0("select * from table0('aaa', 100) x left join 
table0('bbb', 100) y on x.a=y.a and x.b = 'bbb'");
+//        compareQueryRes0("select * from table0('aaa', 100) x left join 
table0('bbb', 100) y on x.a=y.a where x.b = 'bbb'");
+//        compareQueryRes0("select * from table0('aaa', 100) x left join 
table0('bbb', 100) y where x.b = 'bbb'");
+
+        final String addStreet = "Addr" + ORG_CNT + 1;
+        
+        List<List<?>> res = compareQueryRes0("select avg(old) from 
\"part\".Person left join \"repl\".Address " +
+            " on Person.addrId = Address.id where lower(Address.street) = 
lower(?)", addStreet);
+        
+        assertNotSame(0, res);
+
+        compareQueryRes0("select avg(old) from \"part\".Person join 
\"repl\".Address on Person.addrId = Address.id " +
+            "where lower(Address.street) = lower(?)", addStreet);
+
+        compareQueryRes0("select avg(old) from \"part\".Person left join 
\"repl\".Address where Person.addrId = Address.id " +
+            "and lower(Address.street) = lower(?)", addStreet);
+
+        compareQueryRes0("select avg(old) from \"part\".Person, 
\"repl\".Address where Person.addrId = Address.id " +
+            "and lower(Address.street) = lower(?)", addStreet);
+
+        compareQueryRes0("select firstName, date from \"part\".Person");
+        compareQueryRes0("select distinct firstName, date from 
\"part\".Person");
+        
+        final String star = " _key, _val, id, firstName, lastName, orgId, 
salary, addrId, old, date ";
+        
+        compareQueryRes0("select " + star + " from \"part\".Person p");
+        compareQueryRes0("select " + star + " from \"part\".Person");
+        compareQueryRes0("select distinct " + star + " from \"part\".Person");
+        compareQueryRes0("select p.firstName, date from \"part\".Person p");
+        
+        compareQueryRes0("select p._key, p._val, p.id, p.firstName, 
p.lastName, p.orgId, p.salary, p.addrId, p.old, " +
+            " p.date, a._key, a._val, a.id, a.street" +
+            " from \"part\".Person p, \"repl\".Address a");
+//        compareQueryRes0("select p.* from \"part\".Person p, 
\"repl\".Address a");
+//        compareQueryRes0("select person.* from \"part\".Person, 
\"repl\".Address a");
+//        compareQueryRes0("select p.*, street from \"part\".Person p, 
\"repl\".Address a");
+        compareQueryRes0("select p.firstName, a.street from \"part\".Person p, 
\"repl\".Address a");
+        compareQueryRes0("select distinct p.firstName, a.street from 
\"part\".Person p, \"repl\".Address a");
+        compareQueryRes0("select distinct firstName, street from 
\"part\".Person, \"repl\".Address group by firstName, street ");
+        compareQueryRes0("select distinct firstName, street from 
\"part\".Person, \"repl\".Address");
+        // TODO uncomment and investigate (Rows count has to be equal.: 
Expected :2500, Actual :900)
+//        compareQueryRes0("select p1.firstName, a2.street from 
\"part\".Person p1, \"repl\".Address a1, \"part\".Person p2, \"repl\".Address 
a2");
+
+        //TODO look at it (org.h2.jdbc.JdbcSQLException: Feature not 
supported: "VARCHAR +" // at H2)
+//        compareQueryRes0("select p.firstName n, a.street s from 
\"part\".Person p, \"repl\".Address a");
+        compareQueryRes0("select p.firstName, 1 as i, 'aaa' s from 
\"part\".Person p");
+
+//        compareQueryRes0("select p.firstName + 'a', 1 * 3 as i, 'aaa' s, 
-p.old, -p.old as old from \"part\".Person p");
+//        compareQueryRes0("select p.firstName || 'a' + p.firstName, (p.old * 
3) % p.old - p.old / p.old, p.firstName = 'aaa', " +
+//            " p.firstName is p.firstName, p.old > 0, p.old >= 0, p.old < 0, 
p.old <= 0, p.old <> 0, p.old is not p.old, " +
+//            " p.old is null, p.old is not null " +
+//            " from \"part\".Person p");
+
+        compareQueryRes0("select p.firstName from \"part\".Person p where 
firstName <> 'ivan'");
+        compareQueryRes0("select p.firstName from \"part\".Person p where 
firstName like 'i%'");
+        compareQueryRes0("select p.firstName from \"part\".Person p where 
firstName regexp 'i%'");
+        compareQueryRes0("select p.firstName from \"part\".Person p, 
\"repl\".Address a where p.firstName <> 'ivan' and a.id > 10 or not (a.id = 
100)");
+
+        compareQueryRes0("select case p.firstName when 'a' then 1 when 'a' 
then 2 end as a from \"part\".Person p");
+        compareQueryRes0("select case p.firstName when 'a' then 1 when 'a' 
then 2 else -1 end as a from \"part\".Person p");
+
+        compareQueryRes0("select abs(p.old)  from \"part\".Person p");
+        compareQueryRes0("select cast(p.old as numeric(10, 2)) from 
\"part\".Person p");
+        compareQueryRes0("select cast(p.old as numeric(10, 2)) z from 
\"part\".Person p");
+        compareQueryRes0("select cast(p.old as numeric(10, 2)) as z from 
\"part\".Person p");
+
+        // TODO alanyse
+//        compareQueryRes0("select " + star + " from \"part\".Person p where 
p.firstName in ('a', 'b', '_' + RAND())"); // test ConditionIn
+        compareQueryRes0("select " + star + " from \"part\".Person p where 
p.firstName in ('a', 'b', 'c')"); // test ConditionInConstantSet
+        compareQueryRes0("select " + star + " from \"part\".Person p where 
p.firstName in (select a.street from \"repl\".Address a)"); // test 
ConditionInConstantSet
+
+        compareQueryRes0("select (select a.street from \"repl\".Address a 
where a.id = p.addrId) from \"part\".Person p"); // test ConditionInConstantSet
+
+        compareQueryRes0("select p.firstName, ? from \"part\".Person p where 
firstName regexp ? and p.old < ?", 10, "Iv*n", 40);
+
+        compareQueryRes0("select count(*) as a from \"part\".Person");
+        compareQueryRes0("select count(*) as a, count(p.*), count(p.firstName) 
from \"part\".Person p");
+        compareQueryRes0("select count(distinct p.firstName) from 
\"part\".Person p");
+
+        compareQueryRes0("select p.firstName, avg(p.old), max(p.old) from 
\"part\".Person p group by p.firstName");
+        compareQueryRes0("select p.firstName n, avg(p.old) a, max(p.old) m 
from \"part\".Person p group by p.firstName");
+        compareQueryRes0("select p.firstName n, avg(p.old) a, max(p.old) m 
from \"part\".Person p group by n");
+
+        compareQueryRes0("select p.firstName n, avg(p.old) a, max(p.old) m 
from \"part\".Person p group by p.addrId, p.firstName");
+        compareQueryRes0("select p.firstName n, avg(p.old) a, max(p.old) m 
from \"part\".Person p group by p.firstName, p.addrId");
+        compareQueryRes0("select p.firstName n, max(p.old) + min(p.old) / 
count(distinct p.old) from \"part\".Person p group by p.firstName");
+        compareQueryRes0("select p.firstName n, max(p.old) maxOld, min(p.old) 
minOld from \"part\".Person p group by p.firstName having maxOld > 10 and 
min(p.old) < 1");
+
+        compareQueryRes0("select p.firstName n, avg(p.old) a, max(p.old) m 
from \"part\".Person p group by p.firstName order by n");
+        compareQueryRes0("select p.firstName n, avg(p.old) a, max(p.old) m 
from \"part\".Person p group by p.firstName order by p.firstName");
+        compareQueryRes0("select p.firstName n, avg(p.old) a, max(p.old) m 
from \"part\".Person p group by p.firstName order by p.firstName, m");
+        compareQueryRes0("select p.firstName n, avg(p.old) a, max(p.old) m 
from \"part\".Person p group by p.firstName order by p.firstName, max(p.old) 
desc");
+        compareQueryRes0("select p.firstName n, avg(p.old) a, max(p.old) m 
from \"part\".Person p group by p.firstName order by p.firstName nulls first");
+        compareQueryRes0("select p.firstName n, avg(p.old) a, max(p.old) m 
from \"part\".Person p group by p.firstName order by p.firstName nulls last");
+        compareQueryRes0("select p.firstName n from \"part\".Person p order by 
p.old + 10");
+        compareQueryRes0("select p.firstName n from \"part\".Person p order by 
p.old + 10, p.firstName");
+        compareQueryRes0("select p.firstName n from \"part\".Person p order by 
p.old + 10, p.firstName desc");
+
+        compareQueryRes0("select p.firstName n from \"part\".Person p, (select 
a.street from \"repl\".Address a where a.street is not null) ");
+        compareQueryRes0("select street from \"part\".Person p, (select 
a.street from \"repl\".Address a where a.street is not null) ");
+        compareQueryRes0("select addr.street from \"part\".Person p, (select 
a.street from \"repl\".Address a where a.street is not null) addr");
+
+        compareQueryRes0("select p.firstName n from \"part\".Person p order by 
p.old + 10");
+
+        compareQueryRes0("select 'foo' as bar union select 'foo' as bar");
+        compareQueryRes0("select 'foo' as bar union all select 'foo' as bar");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testParamSubstitution() throws Exception {
+        compareQueryRes0("select ? from \"part\".Person", "Some arg");
+    }
+
+    /**
+     * @throws SQLException If failed.
+     */
+    public void testAggregateOrderBy() throws SQLException {
+        compareOrderedQueryRes0("select firstName name, count(*) cnt from 
\"part\".Person group by name order by cnt desc");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNullParamSubstitution() throws Exception {
+        List<List<?>> rs1 = compareQueryRes0("select id from \"part\".Person 
where lastname is ?", null);
+
+        // Ensure we find something.
+        assertNotSame(0, rs1.size());
+    }
+
+    /**
+     *
+     */
+    public void testUnion() throws SQLException {
+        String base = "select _val v from \"part\".Person";
+
+        compareQueryRes0(base + " union all " + base);
+        compareQueryRes0(base + " union " + base);
+
+        base = "select firstName||lastName name, salary from \"part\".Person";
+
+        assertEquals(10, compareOrderedQueryRes0(base + " union all " + base + 
" order by salary desc").size());
+        assertEquals(5, compareOrderedQueryRes0(base + " union " + base + " 
order by salary desc").size());
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testEmptyResult() throws Exception {
+        compareQueryRes0("select id from \"part\".Person where 0 = 1");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSqlQueryWithAggregation() throws Exception {
+        compareQueryRes0("select avg(salary) from \"part\".Person, 
\"part\".Organization where Person.orgId = Organization.id and "
+            + "lower(Organization.name) = lower(?)", "Org1");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSqlFieldsQuery() throws Exception {
+        compareQueryRes0("select concat(firstName, ' ', lastName) from 
\"part\".Person");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSqlFieldsQueryWithJoin() throws Exception {
+        compareQueryRes0("select concat(firstName, ' ', lastName), "
+            + "Organization.name from \"part\".Person, \"part\".Organization 
where "
+            + "Person.orgId = Organization.id");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testOrdered() throws Exception {
+        compareOrderedQueryRes0("select firstName, lastName" +
+                " from \"part\".Person" +
+                " order by lastName, firstName"
+        );
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSimpleJoin() throws Exception {
+        // Have expected results.
+        compareQueryRes0("select id, firstName, lastName" +
+            "  from \"part\".Person" +
+            "  where Person.id = ?", 3);
+
+        // Ignite cache return 0 results...
+        compareQueryRes0("select pe.firstName" +
+            "  from \"part\".Person pe join \"part\".Purchase pu on pe.id = 
pu.personId " +
+            "  where pe.id = ?", 3);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSimpleReplicatedSelect() throws Exception {
+        compareQueryRes0(rCache, "select id, name from \"repl\".Product");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void _testCrossCache() throws Exception {
+        //TODO Investigate (should be 20 results instead of 0).
+        compareQueryRes0("select firstName, lastName" +
+            "  from \"part\".Person, \"part\".Purchase" +
+            "  where Person.id = Purchase.personId");
+
+        //TODO Investigate.
+        compareQueryRes0("select concat(firstName, ' ', lastName), 
Product.name " +
+            "  from \"part\".Person, \"part\".Purchase, \"repl\".Product " +
+            "  where Person.id = Purchase.personId and Purchase.productId = 
Product.id" +
+            "  group by Product.id");
+
+        //TODO Investigate.
+        compareQueryRes0("select concat(firstName, ' ', lastName), count 
(Product.id) " +
+            "  from \"part\".Person, \"part\".Purchase, \"repl\".Product " +
+            "  where Person.id = Purchase.personId and Purchase.productId = 
Product.id" +
+            "  group by Product.id");
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void initializeH2Schema() throws SQLException {
+        Statement st = conn.createStatement();
+
+        st.execute("CREATE SCHEMA \"part\"");
+        st.execute("CREATE SCHEMA \"repl\"");
+
+        st.execute("create table \"part\".ORGANIZATION" +
+            "  (_key int not null," +
+            "  _val other not null," +
+            "  id int unique," +
+            "  name varchar(255))");
+
+        st.execute("create table \"part\".PERSON" +
+            "  (_key other not null ," +
+            "   _val other not null ," +
+            "  id int unique, " +
+            "  firstName varchar(255), " +
+            "  lastName varchar(255)," +
+            "  orgId int not null," +
+            "  salary double," +
+            "  addrId int," +
+            "  old int," +
+            "  date Date )");
+
+        st.execute("create table \"repl\".PRODUCT" +
+            "  (_key int not null ," +
+            "   _val other not null ," +
+            "  id int unique, " +
+            "  name varchar(255), " +
+            "  price int)");
+
+        st.execute("create table \"part\".PURCHASE" +
+            "  (_key other not null ," +
+            "   _val other not null ," +
+            "  id int unique, " +
+            "  personId int, " +
+            "  organizationId int, " +
+            "  productId int)");
+
+        st.execute("create table \"repl\".ADDRESS" +
+            "  (_key int not null ," +
+            "   _val other not null ," +
+            "  id int unique, " +
+            "  street varchar(255))");
+
+        conn.commit();
+    }
+    
+    /**
+     * Insert {@link Organization} at h2 database.
+     *
+     * @param org Organization.
+     * @throws SQLException If exception.
+     */
+    private void insertInDb(Organization org) throws SQLException {
+        try(PreparedStatement st = conn.prepareStatement(
+            "insert into \"part\".ORGANIZATION (_key, _val, id, name) 
values(?, ?, ?, ?)")) {
+            st.setObject(1, org.id);
+            st.setObject(2, org);
+            st.setObject(3, org.id);
+            st.setObject(4, org.name);
+
+            st.executeUpdate();
+        }
+    }
+
+    /**
+     * Insert {@link Person} at h2 database.
+     *
+     * @param p Person.
+     * @throws SQLException If exception.
+     */
+    private void insertInDb(Person p) throws SQLException {
+        try(PreparedStatement st = conn.prepareStatement("insert into 
\"part\".PERSON " +
+            "(_key, _val, id, firstName, lastName, orgId, salary, addrId, old, 
date) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
+            st.setObject(1, p.key());
+            st.setObject(2, p);
+            st.setObject(3, p.id);
+            st.setObject(4, p.firstName);
+            st.setObject(5, p.lastName);
+            st.setObject(6, p.orgId);
+            st.setObject(7, p.salary);
+            st.setObject(8, p.addrId);
+            st.setObject(9, p.old);
+            st.setObject(10, p.date);
+
+            st.executeUpdate();
+        }
+    }
+
+    /**
+     * Insert {@link Product} at h2 database.
+     *
+     * @param p Product.
+     * @throws SQLException If exception.
+     */
+    private void insertInDb(Product p) throws SQLException {
+        try(PreparedStatement st = conn.prepareStatement(
+            "insert into \"repl\".PRODUCT (_key, _val, id, name, price) 
values(?, ?, ?, ?, ?)")) {
+            st.setObject(1, p.id);
+            st.setObject(2, p);
+            st.setObject(3, p.id);
+            st.setObject(4, p.name);
+            st.setObject(5, p.price);
+
+            st.executeUpdate();
+        }
+    }
+
+    /**
+     * Insert {@link Purchase} at h2 database.
+     *
+     * @param p Purchase.
+     * @throws SQLException If exception.
+     */
+    private void insertInDb(Purchase p) throws SQLException {
+        try(PreparedStatement st = conn.prepareStatement(
+            "insert into \"part\".PURCHASE (_key, _val, id, personId, 
productId, organizationId) values(?, ?, ?, ?, ?, ?)")) {
+            st.setObject(1, p.key());
+            st.setObject(2, p);
+            st.setObject(3, p.id);
+            st.setObject(4, p.personId);
+            st.setObject(5, p.productId);
+            st.setObject(6, p.organizationId);
+
+            st.executeUpdate();
+        }
+    }
+    
+    /**
+     * Insert {@link Address} at h2 database.
+     *
+     * @param a Address.
+     * @throws SQLException If exception.
+     */
+    private void insertInDb(Address a) throws SQLException {
+        try(PreparedStatement st = conn.prepareStatement(
+            "insert into \"repl\".ADDRESS (_key, _val, id, street) values(?, 
?, ?, ?)")) {
+            st.setObject(1, a.id);
+            st.setObject(2, a);
+            st.setObject(3, a.id);
+            st.setObject(4, a.street);
+
+            st.executeUpdate();
+        }
+    }
+
+    @QuerySqlFunction
+    public static int cool1() {
+        return 1;
+    }
+
+    @QuerySqlFunction
+    public static ResultSet table0(Connection c, String a, int b) throws 
SQLException {
+        return c.createStatement().executeQuery("select '" + a + "' as a, " +  
b + " as b");
+    }
+
+    /**
+     * Person class. Stored at partitioned cache.
+     */
+    private static class Person implements Serializable {
+        /** Person ID (indexed). */
+        @QuerySqlField(index = true)
+        private int id;
+
+        /** Organization ID (indexed). */
+        @QuerySqlField(index = true)
+        private int orgId;
+
+        /** First name (not-indexed). */
+        @QuerySqlField
+        private String firstName;
+
+        /** Last name (not indexed). */
+        @QuerySqlField
+        private String lastName;
+
+        /** Salary (indexed). */
+        @QuerySqlField(index = true)
+        private double salary;
+
+        /** Address Id (indexed). */
+        @QuerySqlField(index = true)
+        private int addrId;
+
+        /** Date. */
+        @QuerySqlField(index = true)
+        public Date date = new Date(System.currentTimeMillis());
+
+        /** Old. */
+        @QuerySqlField(index = true)
+        public int old = 17;
+
+
+        /**
+         * Constructs person record.
+         *
+         * @param org Organization.
+         * @param firstName First name.
+         * @param lastName Last name.
+         * @param salary Salary.
+         */
+        Person(int id, Organization org, String firstName, String lastName, 
double salary, Address addr) {
+            this.id = id;
+            this.firstName = firstName;
+            this.lastName = lastName;
+            this.salary = salary;
+            orgId = org.id;
+            addrId = addr.id;
+        }
+
+        /**
+         * @return Custom affinity key to guarantee that person is always 
collocated with organization.
+         */
+        public AffinityKey<Integer> key() {
+            return new AffinityKey<>(id, orgId);
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            return this == o || o instanceof Person && id == ((Person)o).id;
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return "Person [firstName=" + firstName +
+                ", lastName=" + lastName +
+                ", id=" + id +
+                ", orgId=" + orgId +
+                ", salary=" + salary + 
+                ", addrId=" + addrId + ']';
+        }
+    }
+
+    /**
+     * Organization class. Stored at partitioned cache.
+     */
+    private static class Organization implements Serializable {
+        /** Organization ID (indexed). */
+        @QuerySqlField(index = true)
+        private int id;
+
+        /** Organization name (indexed). */
+        @QuerySqlField(index = true)
+        private String name;
+
+        /**
+         * Create Organization.
+         *
+         * @param id Organization ID.
+         * @param name Organization name.
+         */
+        Organization(int id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            return this == o || o instanceof Organization && id == 
((Organization)o).id;
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return "Organization [id=" + id + ", name=" + name + ']';
+        }
+    }
+
+    /**
+     * Product class. Stored at replicated cache.
+     */
+    private static class Product implements Serializable {
+        /** Primary key. */
+        @QuerySqlField(index = true)
+        private int id;
+
+        /** Product name. */
+        @QuerySqlField
+        private String name;
+
+        /** Product price */
+        @QuerySqlField
+        private int price;
+
+        /**
+         * Create Product.
+         *
+         * @param id Product ID.
+         * @param name Product name.
+         * @param price Product price.
+         */
+        Product(int id, String name, int price) {
+            this.id = id;
+            this.name = name;
+            this.price = price;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            return this == o || o instanceof Product && id == ((Product)o).id;
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return "Product [id=" + id + ", name=" + name + ", price=" + price 
+ ']';
+        }
+    }
+
+    /**
+     * Purchase class. Stored at partitioned cache.
+     */
+    private static class Purchase implements Serializable {
+        /** Primary key. */
+        @QuerySqlField(index = true)
+        private int id;
+
+        /** Product ID. */
+        @QuerySqlField
+        private int productId;
+
+        /** Person ID. */
+        @QuerySqlField
+        private int personId;
+        
+        /** Organization id. */
+        @QuerySqlField
+        private int organizationId;
+
+        /**
+         * Create Purchase.
+         *  @param id Purchase ID.
+         * @param product Purchase product.
+         * @param organizationId Organization Id.
+         * @param person Purchase person.
+         */
+        Purchase(int id, Product product, int organizationId, Person person) {
+            this.id = id;
+            productId = product.id;
+            personId = person.id;
+            this.organizationId = organizationId;
+        }
+
+        /**
+         * @return Custom affinity key to guarantee that purchase is always 
collocated with person.
+         */
+        public AffinityKey<Integer> key() {
+            return new AffinityKey<>(id, organizationId);
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            return this == o || o instanceof Purchase && id == 
((Purchase)o).id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return "Purchase [id=" + id + ", productId=" + productId + ", 
personId=" + personId + ']';
+        }
+    }
+
+    /**
+     * Address class. Stored at replicated cache.
+     */
+    private static class Address implements Serializable {
+        @QuerySqlField(index = true)
+        private int id;
+
+        @QuerySqlField(index = true)
+        private String street;
+
+        Address(int id, String street) {
+            this.id = id;
+            this.street = street;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            return this == o || o instanceof Address && id == ((Address)o).id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return "Address [id=" + id + ", street=" + street + ']';
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/fe743909/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/H2CompareBigQueryTest.java
----------------------------------------------------------------------
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/H2CompareBigQueryTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/H2CompareBigQueryTest.java
new file mode 100644
index 0000000..c5a2cad
--- /dev/null
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/H2CompareBigQueryTest.java
@@ -0,0 +1,707 @@
+/*
+ * 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.query.h2.sql;
+
+import org.apache.ignite.cache.*;
+import org.apache.ignite.cache.affinity.*;
+import org.apache.ignite.cache.query.annotations.*;
+import org.apache.ignite.configuration.*;
+
+import java.io.*;
+import java.sql.Date;
+import java.sql.*;
+import java.util.*;
+import java.util.concurrent.atomic.*;
+
+/**
+ * Executes one big query (and subqueries of the big query) to compare query 
results from h2 database instance and 
+ * mixed ignite caches (replicated and partitioned) which have the same data 
models and data content.
+ * 
+ * 
+ * <pre> 
+ *
+ *  -------------------------------------> rootOrderId (virtual) 
<--------------------------
+ *  |                                                                |         
            |
+ *  |                                                                |         
            |
+ *  |                                ---------------------           |         
            |
+ *  |  ------------------            --part.ReplaceOrder--           |         
            |
+ *  |  --part.CustOrder--            ---------------------           |         
            |
+ *  |  ------------------            -  id  PK           -           |         
            |
+ *  |  -  orderId  PK   - <--  <---> -  orderId          -           |         
            |
+ *  -- -  rootOrderId   -   |        -  rootOrderId      - -----------         
            |
+ *     -  origOrderId   -   |        -  refOrderId       -   // = origOrderId  
            |
+ *     -  date          -   |        -  date             -                     
            |
+ *     -  alias         -   |        -  alias            -                     
            |
+ *     -  archSeq       -   |        -  archSeq          -          
-------------------    |
+ *     ------------------   |        ---------------------          
----repl.Exec------    |
+ *                          |                                       
-------------------    |
+ *     -----------------    |                                       -  
rootOrderId PK - ----
+ *     ---part.Cancel---    |                                       -  date    
       -
+ *     -----------------    |        ---------------------          -  
execShares int -
+ *     -  id       PK  -    |        --part.OrderParams---          -  price   
   int -
+ *     -  refOrderId   - ---|        ---------------------          -  lastMkt 
   int -
+ *     -  date         -    |        -  id  PK           -          
-------------------
+ *     -----------------    -------  - orderId           -
+ *                                   - date              -
+ *                                   - parentAlgo        -
+ *                                   ---------------------
+ *  </pre>
+ *
+ */
+public class H2CompareBigQueryTest extends AbstractH2CompareQueryTest {
+    /** Root order count. */
+    private static final int ROOT_ORDER_CNT = 1000;
+
+    /** Dates count. */
+    private static final int DATES_CNT = 5;
+    
+    /** Full the big query. */
+    private String bigQry = getBigQry();
+
+    /**
+     * Extracts the big query from file.
+     *  
+     * @return Big query.
+     */
+    private String getBigQry() {
+        String res = "";
+
+        Reader isr = new 
InputStreamReader(getClass().getResourceAsStream("bigQuery.sql"));
+        
+        try(BufferedReader reader = new BufferedReader(isr)) {
+            for(String line; (line = reader.readLine()) != null; )
+                if (!line.startsWith("--")) // Skip commented lines.
+                    res += line + '\n';
+        }
+        catch (Throwable e) {
+            e.printStackTrace();
+            
+            fail();
+        }
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void setIndexedTypes(CacheConfiguration<?, ?> cc, 
CacheMode mode) {
+        if (mode == CacheMode.PARTITIONED)
+            cc.setIndexedTypes(
+                Integer.class, CustOrder.class,
+                AffinityKey.class, ReplaceOrder.class,
+                AffinityKey.class, OrderParams.class,
+                AffinityKey.class, Cancel.class
+            );
+        else if (mode == CacheMode.REPLICATED)
+            cc.setIndexedTypes(
+                Integer.class, Exec.class
+            );
+        else
+            throw new IllegalStateException("mode: " + mode);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override protected void initCacheAndDbData() throws SQLException {
+        final AtomicInteger idGen = new AtomicInteger();
+
+        final Iterable<Integer> rootOrderIds = new ArrayList<Integer>(){{
+            for (int i = 0; i < ROOT_ORDER_CNT; i++)
+                add(idGen.incrementAndGet());
+        }};
+
+        final Date curDate = new Date(new java.util.Date().getTime());
+
+        final List<Date> dates = new ArrayList<Date>(){{
+            for (int i = 0; i < DATES_CNT; i++)
+                add(new Date(curDate.getTime() - i * 24 * 60 * 60 * 1000)); // 
Minus i days.
+        }};
+
+        final Iterable<CustOrder> orders = new ArrayList<CustOrder>(){{
+            for (int rootOrderId : rootOrderIds) {
+                // Generate 1 - 5 orders for 1 root order.
+                for (int i = 0; i < rootOrderId % 5; i++) {
+                    int orderId = idGen.incrementAndGet();
+                    
+                    CustOrder order = new CustOrder(orderId, rootOrderId, 
dates.get(orderId % dates.size()) , 
+                        orderId % 2 == 0 ? "CUSTOM" : "OTHER", orderId);
+
+                    add(order);
+
+                    pCache.put(order.orderId, order);
+
+                    insertInDb(order);
+                }                
+            }
+        }};
+
+        final Collection<OrderParams> params = new ArrayList<OrderParams>(){{
+            for (CustOrder o : orders) {
+                OrderParams op = new OrderParams(idGen.incrementAndGet(), 
o.orderId, o.date, 
+                    o.orderId % 2 == 0 ? "Algo 1" : "Algo 2");
+
+                add(op);
+
+                pCache.put(op.key(), op);
+
+                insertInDb(op);
+            }
+        }};
+        
+        final Collection<ReplaceOrder> replaces = new 
ArrayList<ReplaceOrder>(){{
+            for (CustOrder o : orders) {
+                if (o.orderId % 7 == 0) {
+                    ReplaceOrder replace = new 
ReplaceOrder(idGen.incrementAndGet(), o.orderId, o.rootOrderId, o.alias,
+                        new Date(o.date.getTime() + 12 * 60 * 60 * 1000), 
o.orderId); // Plus a half of day.
+
+                    add(replace);
+
+                    pCache.put(replace.key(), replace);
+
+                    insertInDb(replace);
+                }
+            }
+        }};
+
+        final Collection<Cancel> cancels = new ArrayList<Cancel>(){{
+            for (CustOrder o : orders) {
+                if (o.orderId % 9 == 0) {
+                    Cancel c = new Cancel(idGen.incrementAndGet(), o.orderId, 
+                        new Date(o.date.getTime() + 12 * 60 * 60 * 1000));// 
Plus a half of day.
+
+                    add(c);
+
+                    pCache.put(c.key(), c); 
+
+                    insertInDb(c);
+                }
+            }
+        }};
+
+        final Collection<Exec> execs = new ArrayList<Exec>(){{
+            for (int rootOrderId : rootOrderIds) {
+                int execShares = 10000 + rootOrderId;
+                int price = 1000 + rootOrderId;
+                int latsMkt = 3000 + rootOrderId;
+                
+                Exec exec = new Exec(rootOrderId, dates.get(rootOrderId % 
dates.size()), execShares, price, latsMkt);
+
+                add(exec);
+
+                rCache.put(exec.rootOrderId, exec);
+
+                insertInDb(exec);
+            }
+        }};
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Override protected void checkAllDataEquals() throws Exception {
+        compareQueryRes0("select _key, _val, date, orderId, rootOrderId, 
alias, archSeq, origOrderId " +
+            "from \"part\".CustOrder");
+        compareQueryRes0("select _key, _val, id, date, orderId, rootOrderId, 
alias, archSeq, refOrderId " +
+            "from \"part\".ReplaceOrder");
+        compareQueryRes0("select _key, _val, id, date, orderId, parentAlgo 
from \"part\".OrderParams\n");
+        compareQueryRes0("select _key, _val, id, date, refOrderId from 
\"part\".Cancel\n");
+        compareQueryRes0(rCache, "select _key, _val, date, rootOrderId, 
execShares, price, lastMkt from \"repl\".Exec\n");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testUnionAllOrders() throws Exception {
+        compareQueryRes0(
+            "   select  date, orderId, rootOrderId " +
+                "   from \"part\".CustOrder where alias='CUSTOM'");
+                
+        compareQueryRes0(
+                "   select  date, orderId, rootOrderId " +
+                "   from \"part\".ReplaceOrder where alias='CUSTOM'");
+        
+        compareQueryRes0(
+            "   select 10" +
+
+                "   union all" +
+
+                "   select  20");
+        
+        compareQueryRes0(
+            "   select  date, orderId, rootOrderId " +
+                "   from \"part\".CustOrder where alias='CUSTOM'" +
+
+                "   union all" +
+
+                "   select  date, orderId, rootOrderId " +
+                "   from \"part\".ReplaceOrder where alias='CUSTOM'");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testBigQuery() throws Exception {
+        List<List<?>> res = compareQueryRes0(bigQry);
+        
+        assertTrue(!res.isEmpty()); // Ensure we set good testing data at 
database.
+    }
+    
+    /** {@inheritDoc} */
+    @Override protected void initializeH2Schema() throws SQLException {
+        Statement st = conn.createStatement();
+
+        st.execute("CREATE SCHEMA \"part\"");
+        st.execute("CREATE SCHEMA \"repl\"");
+
+        st.execute("create table \"part\".CustOrder" +
+            "  (" +
+            "  _key int not null," +
+            "  _val other not null," +
+            "  orderId int unique," +
+            "  rootOrderId int," +
+            "  origOrderId int," +
+            "  archSeq int," +
+            "  date Date, " +
+            "  alias varchar(255)" +
+            "  )");
+
+        st.execute("create table \"part\".ReplaceOrder" +
+            "  (" +
+            "  _key other not null," +
+            "  _val other not null," +
+            "  id int unique," +
+            "  orderId int ," +
+            "  rootOrderId int," +
+            "  refOrderId int," +
+            "  archSeq int," +
+            "  date Date, " +
+            "  alias varchar(255)" +
+            "  )");
+
+        st.execute("create table \"part\".OrderParams" +
+            "  (" +
+            "  _key other not null," +
+            "  _val other not null," +
+            "  id int unique," +
+            "  orderId int ," +
+            "  date Date, " +
+            "  parentAlgo varchar(255)" +
+            "  )");
+
+        st.execute("create table \"part\".Cancel" +
+            "  (" +
+            "  _key other not null," +
+            "  _val other not null," +
+            "  id int unique," +
+            "  date Date, " +
+            "  refOrderId int" +
+            "  )");
+
+        st.execute("create table \"repl\".Exec" +
+            "  (" +
+            "  _key int not null," +
+            "  _val other not null," +
+            "  rootOrderId int unique," +
+            "  date Date, " +
+            "  execShares int," +
+            "  price int," +
+            "  lastMkt int" +
+            "  )");
+        
+        conn.commit();
+    }
+
+    /**
+     * Insert {@link CustOrder} at h2 database.
+     *  
+     * @param o CustOrder.
+     */
+    private void insertInDb(CustOrder o) throws SQLException {
+        try(PreparedStatement st = conn.prepareStatement(
+            "insert into \"part\".CustOrder (_key, _val, orderId, rootOrderId, 
date, alias, archSeq, origOrderId) " +
+                "values(?, ?, ?, ?, ?, ?, ?, ?)")) {
+            int i = 0;
+            
+            st.setObject(++i, o.orderId);
+            st.setObject(++i, o);
+            st.setObject(++i, o.orderId);
+            st.setObject(++i, o.rootOrderId);
+            st.setObject(++i, o.date);
+            st.setObject(++i, o.alias);
+            st.setObject(++i, o.archSeq);
+            st.setObject(++i, o.origOrderId);
+
+            st.executeUpdate();
+        }
+    }
+
+    /**
+     * Insert {@link ReplaceOrder} at h2 database.
+     *
+     * @param o ReplaceOrder.
+     */
+    private void insertInDb(ReplaceOrder o) throws SQLException {
+        try(PreparedStatement st = conn.prepareStatement(
+            "insert into \"part\".ReplaceOrder (_key, _val, id, orderId, 
rootOrderId, date, alias, archSeq, refOrderId) " +
+                "values(?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
+            int i = 0;
+            
+            st.setObject(++i, o.key());
+            st.setObject(++i, o);
+            st.setObject(++i, o.id);
+            st.setObject(++i, o.orderId);
+            st.setObject(++i, o.rootOrderId);
+            st.setObject(++i, o.date);
+            st.setObject(++i, o.alias);
+            st.setObject(++i, o.archSeq);
+            st.setObject(++i, o.refOrderId);
+
+            st.executeUpdate();
+        }
+    }
+
+    /**
+     * Insert {@link OrderParams} at h2 database.
+     *
+     * @param o OrderParams.
+     */
+    private void insertInDb(OrderParams o) throws SQLException {
+        try(PreparedStatement st = conn.prepareStatement(
+            "insert into \"part\".OrderParams (_key, _val, id, date, orderId, 
parentAlgo) values(?, ?, ?, ?, ?, ?)")) {
+            int i = 0;
+            
+            st.setObject(++i, o.key());
+            st.setObject(++i, o);
+            st.setObject(++i, o.id);
+            st.setObject(++i, o.date);
+            st.setObject(++i, o.orderId);
+            st.setObject(++i, o.parentAlgo);
+
+            st.executeUpdate();
+        }
+    }
+
+    /**
+     * Insert {@link Cancel} at h2 database.
+     *
+     * @param o Cancel.
+     */
+    private void insertInDb(Cancel o) throws SQLException {
+        try(PreparedStatement st = conn.prepareStatement(
+            "insert into \"part\".Cancel (_key, _val, id, date, refOrderId) 
values(?, ?, ?, ?, ?)")) {
+            int i = 0;
+            
+            st.setObject(++i, o.key());
+            st.setObject(++i, o);
+            st.setObject(++i, o.id);
+            st.setObject(++i, o.date);
+            st.setObject(++i, o.refOrderId);
+
+            st.executeUpdate();
+        }
+    }
+
+    /**
+     * Insert {@link Exec} at h2 database.
+     *
+     * @param o Execution.
+     */
+    private void insertInDb(Exec o) throws SQLException {
+        try(PreparedStatement st = conn.prepareStatement(
+            "insert into \"repl\".Exec (_key, _val, date, rootOrderId, 
execShares, price, lastMkt) " +
+                "values(?, ?, ?, ?, ?, ?, ?)")) {
+            int i = 0;
+            
+            st.setObject(++i, o.rootOrderId);
+            st.setObject(++i, o);
+            st.setObject(++i, o.date);
+            st.setObject(++i, o.rootOrderId);
+            st.setObject(++i, o.execShares);
+            st.setObject(++i, o.price);
+            st.setObject(++i, o.lastMkt);
+
+            st.executeUpdate();
+        }
+    }
+
+    /**
+     * Custom Order.
+     */
+    static class CustOrder implements Serializable {
+        /** Primary key. */
+        @QuerySqlField(index = true)
+        private int orderId;
+
+        /** Root order ID*/
+        @QuerySqlField
+        private int rootOrderId;
+
+        /** Orig order ID*/
+        @QuerySqlField
+        private int origOrderId;
+
+        /** Date */
+        @QuerySqlField
+        private Date date ;
+
+        /**  */
+        @QuerySqlField
+        private String alias = "CUSTOM";
+
+        /**  */
+        @QuerySqlField
+        private int archSeq = 11; // TODO: use it.
+
+        /**
+         * @param orderId Order id.
+         * @param rootOrderId Root order id.
+         * @param date Date.
+         * @param alias Alias.
+         * @param origOrderId Orig order id.
+         */
+        CustOrder(int orderId, int rootOrderId, Date date, String alias, int 
origOrderId) {
+            this.orderId = orderId;
+            this.rootOrderId = rootOrderId;
+            this.origOrderId = origOrderId;
+            this.date = date;
+            this.alias = alias;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            return this == o || o instanceof CustOrder && orderId == 
((CustOrder)o).orderId;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return orderId;
+        }
+    }
+
+    /**
+     * Replace Order.
+     */
+    static class ReplaceOrder implements Serializable {
+        /** Primary key. */
+        @QuerySqlField(index = true)
+        private int id;
+        
+        /** Order id. */
+        @QuerySqlField(index = true)
+        private int orderId;
+
+        /** Root order ID*/
+        @QuerySqlField
+        private int rootOrderId;
+
+        /** Ref order ID*/
+        @QuerySqlField
+        private int refOrderId;
+
+        /** Date */
+        @QuerySqlField
+        private Date date ;
+
+        /**  */
+        @QuerySqlField
+        private String alias = "CUSTOM";
+
+        /**  */
+        @QuerySqlField
+        private int archSeq = 111; // TODO: use it.
+
+        /**
+         * @param id Id.
+         * @param orderId Order id.
+         * @param rootOrderId Root order id.
+         * @param alias Alias.
+         * @param date Date.
+         * @param refOrderId Reference order id.
+         */
+        ReplaceOrder(int id, int orderId, int rootOrderId, String alias, Date 
date, int refOrderId) {
+            this.id = id;
+            this.orderId = orderId;
+            this.rootOrderId = rootOrderId;
+            this.refOrderId = refOrderId;
+            this.date = date;
+            this.alias = alias;
+        }
+
+        /**
+         * @return Afinity key.
+         */
+        public AffinityKey<Integer> key() {
+            return new AffinityKey<>(id, orderId);
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            return this == o || o instanceof ReplaceOrder && id == 
((ReplaceOrder)o).id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return id;
+        }
+    }
+
+    /**
+     * Order params.
+     */
+    static class OrderParams implements Serializable {
+        /** Primary key. */
+        @QuerySqlField(index = true)
+        private int id;
+
+        /** Order id. */
+        @QuerySqlField(index = true)
+        private int orderId;
+
+        /** Date */
+        @QuerySqlField
+        private Date date ;
+
+        /**  */
+        @QuerySqlField
+        private String parentAlgo = "CUSTOM_ALGO";
+
+        /**
+         * @param id Id.
+         * @param orderId Order id.
+         * @param date Date.
+         * @param parentAlgo Parent algo.
+         */
+        OrderParams(int id, int orderId, Date date, String parentAlgo) {
+            this.id = id;
+            this.orderId = orderId;
+            this.date = date;
+            this.parentAlgo = parentAlgo;
+        }
+
+        /**
+         * @return Afinity key.
+         */
+        public AffinityKey<Integer> key() {
+            return new AffinityKey<>(id, orderId);
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            return this == o || o instanceof OrderParams && id == 
((OrderParams)o).id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return id;
+        }
+    }
+
+    /**
+     * Cancel Order.
+     */
+    static class Cancel implements Serializable {
+        /** Primary key. */
+        @QuerySqlField(index = true)
+        private int id;
+
+        /** Order id. */
+        @QuerySqlField(index = true)
+        private int refOrderId;
+
+        /** Date */
+        @QuerySqlField
+        private Date date;
+
+        /**
+         * @param id
+         * @param refOrderId Reference order id.
+         * @param date Date.
+         */
+        Cancel(int id, int refOrderId, Date date) {
+            this.id = id;
+            this.refOrderId = refOrderId;
+            this.date = date;
+        }
+
+        /**
+         * @return Afinity key.
+         */
+        public AffinityKey<Integer> key() {
+            return new AffinityKey<>(id, refOrderId);
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            return this == o || o instanceof Cancel && id == ((Cancel)o).id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return id;
+        }
+    }
+
+    /**
+     * Execute information about root query.
+     */
+    static class Exec implements Serializable {
+        /** Primary key. */
+        @QuerySqlField
+        private int rootOrderId;
+
+        /** Date */
+        @QuerySqlField
+        private Date date ;
+
+        /** */
+        @QuerySqlField
+        private int execShares;
+
+        /** */
+        @QuerySqlField
+        private int price;
+
+        /** */
+        @QuerySqlField
+        private int lastMkt;
+
+        /**
+         * @param rootOrderId Root order id.
+         * @param date Date.
+         * @param execShares Execute shares.
+         * @param price Price.
+         * @param lastMkt Last mkt.
+         */
+        Exec(int rootOrderId, Date date, int execShares, int price, int 
lastMkt) {
+            this.rootOrderId = rootOrderId;
+            this.date = date;
+            this.execShares = execShares;
+            this.price = price;
+            this.lastMkt = lastMkt;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            return this == o || o instanceof Exec && rootOrderId == 
((Exec)o).rootOrderId;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return rootOrderId;
+        }
+    }
+}

Reply via email to