You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2020/05/19 16:33:43 UTC

[ignite] 01/01: Test added.

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

amashenkov pushed a commit to branch ignite-12984
in repository https://gitbox.apache.org/repos/asf/ignite.git

commit 30b49de59611a2e4cd27fd183e38b110fd6782ba
Author: Andrey V. Mashenkov <an...@gmail.com>
AuthorDate: Tue May 19 18:38:18 2020 +0300

    Test added.
---
 .../query/IgniteSqlDistributedJoin2SelfTest.java   | 366 +++++++++++++++++++++
 1 file changed, 366 insertions(+)

diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlDistributedJoin2SelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlDistributedJoin2SelfTest.java
new file mode 100644
index 0000000..d50685f
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/IgniteSqlDistributedJoin2SelfTest.java
@@ -0,0 +1,366 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.processors.cache.index.AbstractIndexingCommonTest;
+import org.junit.Test;
+
+/**
+ * Tests for correct distributed sql joins.
+ */
+public class IgniteSqlDistributedJoin2SelfTest extends AbstractIndexingCommonTest {
+    /** */
+    private static final int NODES_COUNT = 3;
+
+    /** */
+    private static String PERSON_CACHE = "person";
+
+    /** */
+    private static String MED_INFO_CACHE = "medical_info";
+
+    /** */
+    private static String BLOOD_INFO_PJ_CACHE = "blood_group_info_PJ";
+
+    /** */
+    private static String BLOOD_INFO_P_CACHE = "blood_group_info_P";
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        super.afterTest();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testNonCollocatedDistributedJoinSingleCache() throws Exception {
+        startGridsMultiThreaded(NODES_COUNT, false);
+
+        IgniteCache<Object, Object> cache = ignite(0).createCache(
+            new CacheConfiguration<>(DEFAULT_CACHE_NAME)
+                .setQueryEntities(Arrays.asList(
+                    new QueryEntity(String.class, Person.class).setTableName(PERSON_CACHE),
+                    new QueryEntity(Long.class, MedicalInfo.class).setTableName(MED_INFO_CACHE),
+                    new QueryEntity(Long.class, BloodGroupInfoPJ.class).setTableName(BLOOD_INFO_PJ_CACHE),
+                    new QueryEntity(String.class, BloodGroupInfoP.class).setTableName(BLOOD_INFO_P_CACHE)
+                ))
+        );
+
+        awaitPartitionMapExchange();
+
+        populatePersonData(cache);
+        populateMedInfoData(cache);
+        populateBloodGrpPJData(cache);
+        populateBloodGrpPData(cache);
+
+        checkQueries(cache);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testNonCollocatedDistributedJoin() throws Exception {
+        startGridsMultiThreaded(NODES_COUNT, false);
+
+        IgniteCache<Object, Object> personCache = ignite(0).createCache(
+            new CacheConfiguration<>(PERSON_CACHE).setQueryEntities(Collections.singleton(
+                new QueryEntity(String.class, Person.class)))
+                .setSqlSchema("PUBLIC")
+        );
+
+        IgniteCache<Object, Object> medInfoCache = ignite(0).createCache(
+            new CacheConfiguration<>(MED_INFO_CACHE).setQueryEntities(Collections.singleton(
+                new QueryEntity(Long.class, MedicalInfo.class).setTableName(MED_INFO_CACHE)))
+                .setSqlSchema("PUBLIC")
+        );
+
+        IgniteCache<Object, Object> bloodGrpCache1 = ignite(0).createCache(
+            new CacheConfiguration<>(BLOOD_INFO_PJ_CACHE).setQueryEntities(Collections.singleton(
+                new QueryEntity(Long.class, BloodGroupInfoPJ.class).setTableName(BLOOD_INFO_PJ_CACHE)))
+                .setSqlSchema("PUBLIC")
+        );
+
+        IgniteCache<Object, Object> bloodGrpCache2 = ignite(0).createCache(
+            new CacheConfiguration<>(BLOOD_INFO_P_CACHE).setQueryEntities(Collections.singleton(
+                new QueryEntity(String.class, BloodGroupInfoP.class).setTableName(BLOOD_INFO_P_CACHE)))
+                .setSqlSchema("PUBLIC")
+        );
+
+        awaitPartitionMapExchange();
+
+        populatePersonData(personCache);
+        populateMedInfoData(medInfoCache);
+        populateBloodGrpPJData(bloodGrpCache1);
+        populateBloodGrpPData(bloodGrpCache2);
+
+        checkQueries(personCache);
+    }
+
+    /**
+     * Start queries and check query results.
+     *
+     * @param cache Cache.
+     */
+    private void checkQueries(IgniteCache<Object, Object> cache) {
+        SqlFieldsQuery qry1 = new SqlFieldsQuery("SELECT person.id, person.name, medical_info.blood_group, blood_group_info_PJ.universal_donor FROM person\n" +
+            "  LEFT JOIN medical_info ON medical_info.name = person.name \n" +
+            "  LEFT JOIN blood_group_info_PJ ON blood_group_info_PJ.blood_group = medical_info.blood_group;");
+
+        SqlFieldsQuery qry2 = new SqlFieldsQuery("SELECT person.id, person.name, medical_info.blood_group, blood_group_info_P.universal_donor FROM person\n" +
+            "  LEFT JOIN medical_info ON medical_info.name = person.name \n" +
+            "  LEFT JOIN blood_group_info_P ON blood_group_info_P.blood_group = medical_info.blood_group;");
+
+        qry1.setDistributedJoins(true);
+        qry2.setDistributedJoins(true);
+
+        final String res1 = queryResultAsString(cache.query(qry1).getAll());
+        final String res2 = queryResultAsString(cache.query(qry2).getAll());
+
+        log.info("Query1 result: \n" + res1);
+        log.info("Query2 result: \n" + res2);
+
+        String expOut = "2001,Shravya,null,null\n" +
+            "2002,Kiran,O+,O+A+B+AB+\n" +
+            "2003,Harika,AB+,AB+\n" +
+            "2004,Srinivas,null,null\n" +
+            "2005,Madhavi,A+,A+AB+\n" +
+            "2006,Deeps,null,null\n" +
+            "2007,Hope,null,null\n";
+
+        assertEquals("Not equal results", res1, res2);
+        assertEquals("Wrong result", expOut, res2);
+    }
+
+    /**
+     * Convert query result to string.
+     *
+     * @param res Query result set.
+     * @return String representation.
+     */
+    private String queryResultAsString(List<List<?>> res) {
+        List<String> results = new ArrayList<>();
+
+        for (List<?> row : res) {
+            StringBuilder sb = new StringBuilder('\t');
+            for (Iterator<?> iterator = row.iterator(); iterator.hasNext(); ) {
+                sb.append(iterator.next());
+
+                if (iterator.hasNext())
+                    sb.append(',');
+            }
+            results.add(sb.toString());
+        }
+
+        results.sort(String::compareTo);
+
+        StringBuilder sb = new StringBuilder();
+
+        for (String result : results)
+            sb.append(result).append('\n');
+
+        return sb.toString();
+    }
+
+    /**
+     * @param cache Ignite cache.
+     */
+    private void populatePersonData(IgniteCache<Object, Object> cache) {
+        cache.put("Shravya", new Person(2001, "Shravya"));
+        cache.put("Kiran", new Person(2002, "Kiran"));
+        cache.put("Harika", new Person(2003, "Harika"));
+        cache.put("Srinivas", new Person(2004, "Srinivas"));
+        cache.put("Madhavi", new Person(2005, "Madhavi"));
+        cache.put("Deeps", new Person(2006, "Deeps"));
+        cache.put("Hope", new Person(2007, "Hope"));
+    }
+
+    /**
+     * @param cache Ignite cache.
+     */
+    private void populateMedInfoData(IgniteCache<Object, Object> cache) {
+        cache.put(2001L, new MedicalInfo(2001, "Madhavi", "A+"));
+        cache.put(2002L, new MedicalInfo(2002, "Diggi", "B+"));
+        cache.put(2003L, new MedicalInfo(2003, "Kiran", "O+"));
+        cache.put(2004L, new MedicalInfo(2004, "Harika", "AB+"));
+    }
+
+    /**
+     * @param cache Ignite cache.
+     */
+    private void populateBloodGrpPJData(IgniteCache<Object, Object> cache) {
+        cache.put(2001L, new BloodGroupInfoPJ(2001, "A+", "A+AB+"));
+        cache.put(2002L, new BloodGroupInfoPJ(2002, "O+", "O+A+B+AB+"));
+        cache.put(2003L, new BloodGroupInfoPJ(2003, "B+", "B+AB+"));
+        cache.put(2004L, new BloodGroupInfoPJ(2004, "AB+", "AB+"));
+        cache.put(2005L, new BloodGroupInfoPJ(2005, "O-", "EveryOne"));
+    }
+
+    /**
+     * @param cache Ignite cache.
+     */
+    private void populateBloodGrpPData(IgniteCache<Object, Object> cache) {
+        cache.put("A+", new BloodGroupInfoP(2001, "A+", "A+AB+"));
+        cache.put("O+", new BloodGroupInfoP(2002, "O+", "O+A+B+AB+"));
+        cache.put("B+", new BloodGroupInfoP(2003, "B+", "B+AB+"));
+        cache.put("AB+", new BloodGroupInfoP(2004, "AB+", "AB+"));
+        cache.put("O-", new BloodGroupInfoP(2005, "O-", "EveryOne"));
+    }
+
+    /**
+     *
+     */
+    private static class Person {
+        /** */
+        @QuerySqlField
+        private long id;
+
+        /** */
+        @QuerySqlField
+        private String name;
+
+        public Person(long id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        public long getId() { return id; }
+
+        public void setId(long id) { this.id = id; }
+
+        public String getName() { return name; }
+
+        public void setName(String name) { this.name = name; }
+    }
+
+    /**
+     *
+     */
+    private static class MedicalInfo {
+        /** */
+        @QuerySqlField
+        private long id;
+
+        /** */
+        @QuerySqlField(index = true)
+        private String name;
+
+        /** */
+        @QuerySqlField(name = "blood_group")
+        private String bloodGroup;
+
+        public MedicalInfo(long id, String name, String bloodGroup) {
+            this.id = id;
+            this.name = name;
+            this.bloodGroup = bloodGroup;
+        }
+
+        public void setId(long id) { this.id = id; }
+
+        public long getId() { return id; }
+
+        public String getName() { return name; }
+
+        public void setName(String name) { this.name = name; }
+
+        public String getBloodGroup() { return bloodGroup; }
+
+        public void setBloodGroup(String bloodGroup) { this.bloodGroup = bloodGroup; }
+    }
+
+    /**
+     *
+     */
+    private static class BloodGroupInfoPJ {
+        /** */
+        @QuerySqlField
+        private long id;
+
+        /** */
+        @QuerySqlField(index = true, name = "blood_group")
+        private String bloodGroup;
+
+        /** */
+        @QuerySqlField(name = "universal_donor")
+        private String universalDonor;
+
+        public BloodGroupInfoPJ(long id, String bloodGroup, String universalDonor) {
+            this.id = id;
+            this.bloodGroup = bloodGroup;
+            this.universalDonor = universalDonor;
+        }
+
+        public void setId(long id) { this.id = id; }
+
+        public long getId() { return id; }
+
+        public String getBloodGroup() { return bloodGroup; }
+
+        public void setBloodGroup(String bloodGroup) { this.bloodGroup = bloodGroup; }
+
+        public String getUniversalDonor() { return universalDonor; }
+
+        public void setUniversalDonor(String universalDonor) { this.universalDonor = universalDonor; }
+    }
+
+    /**
+     *
+     */
+    private static class BloodGroupInfoP {
+        /** */
+        private long id;
+
+        /** */
+        @QuerySqlField(index = true, name = "blood_group")
+        private String bloodGroup;  // PK
+
+        /** */
+        @QuerySqlField(name = "universal_donor")
+        private String universalDonor;
+
+        public BloodGroupInfoP(long id, String bloodGroup, String universalDonor) {
+            this.id = id;
+            this.bloodGroup = bloodGroup;
+            this.universalDonor = universalDonor;
+        }
+
+        public void setId(long id) { this.id = id; }
+
+        public long getId() { return id; }
+
+        public String getBloodGroup() { return bloodGroup; }
+
+        public void setBloodGroup(String bloodGroup) { this.bloodGroup = bloodGroup; }
+
+        public String getUniversalDonor() { return universalDonor; }
+
+        public void setUniversalDonor(String universalDonor) { this.universalDonor = universalDonor; }
+    }
+}