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 2017/02/13 11:29:50 UTC

[10/40] ignite git commit: IGNITE-3964: SQL: add support for custom table name. This closes #1301.

IGNITE-3964: SQL: add support for custom table name. This closes #1301.


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

Branch: refs/heads/ignite-2.0
Commit: 74d0dcc6c56118f9e4fdaa4aa70d25d1abe7b80e
Parents: 67225b2
Author: Andrey V. Mashenkov <an...@gmail.com>
Authored: Tue Jan 17 15:00:08 2017 +0300
Committer: Andrey V. Mashenkov <an...@gmail.com>
Committed: Tue Jan 17 15:04:21 2017 +0300

----------------------------------------------------------------------
 .../org/apache/ignite/cache/QueryEntity.java    |  21 ++
 .../processors/query/GridQueryProcessor.java    |  26 +-
 .../query/GridQueryTypeDescriptor.java          |   7 +
 .../processors/query/h2/IgniteH2Indexing.java   |  16 +-
 .../cache/IgniteCacheAbstractQuerySelfTest.java | 260 ++++++++++++++++++-
 .../h2/GridIndexingSpiAbstractSelfTest.java     |   5 +
 6 files changed, 325 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/74d0dcc6/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
index 9758cfc..3d02478 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
@@ -48,6 +48,9 @@ public class QueryEntity implements Serializable {
     /** Collection of query indexes. */
     private Map<String, QueryIndex> idxs = new HashMap<>();
 
+    /** Table name. */
+    private String tableName;
+
     /**
      * Creates an empty query entity.
      */
@@ -169,6 +172,24 @@ public class QueryEntity implements Serializable {
         }
     }
 
+
+    /**
+     * Gets table name for this query entity.
+     *
+     * @return table name
+     */
+    public String getTableName() {
+        return tableName;
+    }
+
+    /**
+     * Sets table name for this query entity.
+     * @param tableName table name
+     */
+    public void setTableName(String tableName) {
+        this.tableName = tableName;
+    }
+
     /**
      * Utility method for building query entities programmatically.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/74d0dcc6/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index 6c093ee..0f2bc9a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -253,10 +253,12 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                     if (keyCls == null)
                         keyCls = Object.class;
 
-                    String simpleValType = valCls == null ? typeName(qryEntity.getValueType()) : typeName(valCls);
+                    String simpleValType = ((valCls == null) ? typeName(qryEntity.getValueType()) : typeName(valCls));
 
                     desc.name(simpleValType);
 
+                    desc.tableName(qryEntity.getTableName());
+
                     if (binaryEnabled && !keyOrValMustDeserialize) {
                         // Safe to check null.
                         if (SQL_TYPES.contains(valCls))
@@ -466,7 +468,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
      * @param desc Type descriptor.
      * @throws IgniteCheckedException If failed.
      */
-    private void addTypeByName(CacheConfiguration<?,?> ccfg, TypeDescriptor desc) throws IgniteCheckedException {
+    private void addTypeByName(CacheConfiguration<?, ?> ccfg, TypeDescriptor desc) throws IgniteCheckedException {
         if (typesByName.putIfAbsent(new TypeName(ccfg.getName(), desc.name()), desc) != null)
             throw new IgniteCheckedException("Type with name '" + desc.name() + "' already indexed " +
                 "in cache '" + ccfg.getName() + "'.");
@@ -2108,6 +2110,9 @@ public class GridQueryProcessor extends GridProcessorAdapter {
         /** */
         private String name;
 
+        /** */
+        private String tblName;
+
         /** Value field names and types with preserved order. */
         @GridToStringInclude
         private final Map<String, Class<?>> fields = new LinkedHashMap<>();
@@ -2166,6 +2171,23 @@ public class GridQueryProcessor extends GridProcessorAdapter {
             this.name = name;
         }
 
+        /**
+         * Gets table name for type.
+         * @return Table name.
+         */
+        public String tableName() {
+            return tblName;
+        }
+
+        /**
+         * Sets table name for type.
+         *
+         * @param tblName Table name.
+         */
+        public void tableName(String tblName) {
+            this.tblName = tblName;
+        }
+
         /** {@inheritDoc} */
         @Override public Map<String, Class<?>> fields() {
             return fields;

http://git-wip-us.apache.org/repos/asf/ignite/blob/74d0dcc6/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
index b636841..e939525 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java
@@ -32,6 +32,13 @@ public interface GridQueryTypeDescriptor {
     public String name();
 
     /**
+     * Gets table name for type.
+     *
+     * @return Table name.
+     */
+    public String tableName();
+
+    /**
      * Gets mapping from field name to its type.
      *
      * @return Fields that can be indexed, participate in queries and can be queried using method.

http://git-wip-us.apache.org/repos/asf/ignite/blob/74d0dcc6/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 362ddd8..bc51552 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -741,7 +741,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
 
         tbl.onDrop();
 
-        tbl.schema.tbls.remove(tbl.name());
+        tbl.schema.tbls.remove(tbl.typeName());
     }
 
     /** {@inheritDoc} */
@@ -2397,7 +2397,9 @@ public class IgniteH2Indexing implements GridQueryIndexing {
             this.type = type;
             this.schema = schema;
 
-            fullTblName = schema.schemaName + "." + escapeName(type.name(), schema.escapeAll());
+            String tblName = escapeName(type.tableName() != null ? type.tableName() : type.name(), schema.escapeAll());
+
+            fullTblName = schema.schemaName + "." + tblName;
         }
 
         /**
@@ -2408,16 +2410,16 @@ public class IgniteH2Indexing implements GridQueryIndexing {
         }
 
         /**
-         * @return Database table name.
+         * @return Database full table name.
          */
         String fullTableName() {
             return fullTblName;
         }
 
         /**
-         * @return Database table name.
+         * @return type name.
          */
-        String name() {
+        String typeName() {
             return type.name();
         }
 
@@ -2739,8 +2741,8 @@ public class IgniteH2Indexing implements GridQueryIndexing {
          * @param tbl Table descriptor.
          */
         public void add(TableDescriptor tbl) {
-            if (tbls.putIfAbsent(tbl.name(), tbl) != null)
-                throw new IllegalStateException("Table already registered: " + tbl.name());
+            if (tbls.putIfAbsent(tbl.typeName(), tbl) != null)
+                throw new IllegalStateException("Table already registered: " + tbl.fullTableName());
         }
 
         /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/74d0dcc6/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
index 7c5b472..ad6922c 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
@@ -23,6 +23,7 @@ import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -45,10 +46,13 @@ import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteBinary;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.CachePeekMode;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
 import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.cache.query.QueryCursor;
 import org.apache.ignite.cache.query.ScanQuery;
@@ -66,11 +70,11 @@ import org.apache.ignite.configuration.NearCacheConfiguration;
 import org.apache.ignite.events.CacheQueryExecutedEvent;
 import org.apache.ignite.events.CacheQueryReadEvent;
 import org.apache.ignite.events.Event;
-import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.query.QueryCursorEx;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
+import org.apache.ignite.internal.util.lang.GridPlainCallable;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.G;
@@ -180,6 +184,32 @@ public abstract class IgniteCacheAbstractQuerySelfTest extends GridCommonAbstrac
                     Long.class, EnumObject.class
                 );
 
+                List<QueryEntity> entityList = new ArrayList<>();
+
+                QueryEntity qryEntity = new QueryEntity();
+
+                qryEntity.setKeyType(Integer.class.getName());
+                qryEntity.setValueType(Type1.class.getName());
+                qryEntity.addQueryField("id", Integer.class.getName(), null);
+                qryEntity.addQueryField("name", String.class.getName(), null);
+                qryEntity.setTableName("Type2");
+                qryEntity.setIndexes(Arrays.asList(new QueryIndex("id")));
+
+                entityList.add(qryEntity);
+
+                qryEntity = new QueryEntity();
+
+                qryEntity.setKeyType(Integer.class.getName());
+                qryEntity.setValueType(Type2.class.getName());
+                qryEntity.addQueryField("id", Integer.class.getName(), null);
+                qryEntity.addQueryField("name", String.class.getName(), null);
+                qryEntity.setTableName("Type1");
+                qryEntity.setIndexes(Arrays.asList(new QueryIndex("id")));
+
+                entityList.add(qryEntity);
+
+                cc.setQueryEntities(entityList);
+
                 if (cacheMode() != CacheMode.LOCAL)
                     cc.setAffinity(new RendezvousAffinityFunction());
 
@@ -234,6 +264,7 @@ public abstract class IgniteCacheAbstractQuerySelfTest extends GridCommonAbstrac
 
         stopAllGrids();
 
+
         store.reset();
     }
 
@@ -548,6 +579,113 @@ public abstract class IgniteCacheAbstractQuerySelfTest extends GridCommonAbstrac
      *
      * @throws Exception In case of error.
      */
+    public void testSimpleCustomTableName() throws Exception {
+        final IgniteCache<Integer, Object> cache = ignite().cache(null);
+
+        cache.put(10, new Type1(1, "Type1 record #1"));
+        cache.put(20, new Type1(2, "Type1 record #2"));
+
+        QueryCursor<Cache.Entry<Integer, Type1>> qry1 =
+            cache.query(new SqlQuery<Integer, Type1>(Type1.class, "FROM Type2"));
+
+        List<Cache.Entry<Integer, Type1>> all = qry1.getAll();
+
+        assertEquals(2, all.size());
+
+        QueryCursor<List<?>> qry = cache.query(new SqlFieldsQuery("SELECT name FROM Type2"));
+
+        assertEquals(2, qry.getAll().size());
+
+        GridTestUtils.assertThrows(log, new GridPlainCallable<Void>() {
+            @Override public Void call() throws Exception {
+                QueryCursor<Cache.Entry<Integer, Type1>> qry =
+                    cache.query(new SqlQuery<Integer, Type1>(Type1.class, "FROM Type1"));
+
+                qry.getAll();
+
+                return null;
+            }
+        }, IgniteException.class, null);
+    }
+
+    /**
+     * JUnit.
+     *
+     * @throws Exception In case of error.
+     */
+    public void testMixedCustomTableName() throws Exception {
+        final IgniteCache<Integer, Object> cache = ignite().cache(null);
+
+        cache.put(10, new Type1(1, "Type1 record #1"));
+        cache.put(20, new Type1(2, "Type1 record #2"));
+        cache.put(30, new Type2(1, "Type2 record #1"));
+        cache.put(40, new Type2(2, "Type2 record #2"));
+        cache.put(50, new Type2(3, "Type2 record #3"));
+
+        QueryCursor<Cache.Entry<Integer, Type1>> qry1 =
+            cache.query(new SqlQuery<Integer, Type1>(Type1.class, "FROM Type2"));
+
+        List<Cache.Entry<Integer, Type1>> all = qry1.getAll();
+
+        assertEquals(2, all.size());
+
+        QueryCursor<Cache.Entry<Integer, Type2>> qry2 =
+            cache.query(new SqlQuery<Integer, Type2>(Type2.class, "FROM Type1"));
+
+        assertEquals(3, qry2.getAll().size());
+
+        QueryCursor<List<?>> qry = cache.query(new SqlFieldsQuery("SELECT name FROM Type1"));
+
+        assertEquals(3, qry.getAll().size());
+
+        qry = cache.query(new SqlFieldsQuery("SELECT name FROM Type2"));
+
+        assertEquals(2, qry.getAll().size());
+
+        GridTestUtils.assertThrows(log, new GridPlainCallable<Void>() {
+            @Override public Void call() throws Exception {
+                QueryCursor<Cache.Entry<Integer, Type1>> qry1 =
+                    cache.query(new SqlQuery<Integer, Type1>(Type1.class, "FROM Type1"));
+
+                qry1.getAll().size();
+
+                return null;
+            }
+        }, IgniteException.class, null);
+    }
+
+    /**
+     * JUnit.
+     *
+     * @throws Exception In case of error.
+     */
+    public void testDistributedJoinCustomTableName() throws Exception {
+        IgniteCache<Integer, Object> cache = ignite().cache(null);
+
+        cache.put(10, new Type1(1, "Type1 record #1"));
+        cache.put(20, new Type1(2, "Type1 record #2"));
+        cache.put(30, new Type2(1, "Type2 record #1"));
+        cache.put(40, new Type2(2, "Type2 record #2"));
+        cache.put(50, new Type2(3, "Type2 record #3"));
+
+        QueryCursor<List<?>> query = cache.query(
+            new SqlFieldsQuery("SELECT t2.name, t1.name FROM Type2 as t2 LEFT JOIN Type1 as t1 ON t1.id = t2.id")
+                .setDistributedJoins(cacheMode() == PARTITIONED));
+
+        assertEquals(2, query.getAll().size());
+
+        query = cache.query(
+            new SqlFieldsQuery("SELECT t2.name, t1.name FROM Type2 as t2 RIGHT JOIN Type1 as t1 ON t1.id = t2.id")
+                .setDistributedJoins(cacheMode() == PARTITIONED));
+
+        assertEquals(3, query.getAll().size());
+    }
+
+    /**
+     * JUnit.
+     *
+     * @throws Exception In case of error.
+     */
     public void testObjectQuery() throws Exception {
         IgniteCache<Integer, ObjectValue> cache = ignite().cache(null);
 
@@ -1654,6 +1792,126 @@ public abstract class IgniteCacheAbstractQuerySelfTest extends GridCommonAbstrac
     }
 
     /**
+     *
+     */
+    public static class Type1 implements Serializable {
+        /** */
+        private int id;
+
+        /** */
+        private String name;
+
+        /**
+         * @param id ID.
+         * @param name Name.
+         */
+        Type1(int id, String name) {
+            assert name != null;
+            assert id > 0;
+
+            this.name = name;
+            this.id = id;
+        }
+
+        /**
+         * @return Name.
+         */
+        public String name() {
+            return name;
+        }
+
+        /**
+         * @return ID.
+         */
+        public int id() {
+            return id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return name.hashCode() + 31 * id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object obj) {
+            if (obj == this)
+                return true;
+
+            if (!(obj instanceof Type1))
+                return false;
+
+            Type1 that = (Type1)obj;
+
+            return that.name.equals(name) && that.id == id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(Type1.class, this);
+        }
+    }
+
+    /**
+     *
+     */
+    public static class Type2 implements Serializable {
+        /** */
+        private int id;
+
+        /** */
+        private String name;
+
+        /**
+         * @param id ID.
+         * @param name Name.
+         */
+        Type2(int id, String name) {
+            assert name != null;
+            assert id > 0;
+
+            this.name = name;
+            this.id = id;
+        }
+
+        /**
+         * @return Name.
+         */
+        public String name() {
+            return name;
+        }
+
+        /**
+         * @return ID.
+         */
+        public int id() {
+            return id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return name.hashCode() + 31 * id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object obj) {
+            if (obj == this)
+                return true;
+
+            if (!(obj instanceof Type2))
+                return false;
+
+            Type2 that = (Type2)obj;
+
+            return that.name.equals(name) && that.id == id;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(Type2.class, this);
+        }
+    }
+
+    /**
      * Test value object.
      */
     @SuppressWarnings("PublicInnerClass")

http://git-wip-us.apache.org/repos/asf/ignite/blob/74d0dcc6/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
index bcf8f9d..81e34d6 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java
@@ -539,6 +539,11 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract
             return name;
         }
 
+        /** {@inheritDoc} */
+        @Override public String tableName() {
+            return null;
+        }
+
         /**
          * @return Space name.
          */