Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id A9F8E200C0C for ; Mon, 30 Jan 2017 15:20:41 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id A8A0E160B61; Mon, 30 Jan 2017 14:20:41 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 7C350160B67 for ; Mon, 30 Jan 2017 15:20:40 +0100 (CET) Received: (qmail 23788 invoked by uid 500); 30 Jan 2017 14:20:39 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 23656 invoked by uid 99); 30 Jan 2017 14:20:39 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 Jan 2017 14:20:39 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 8129EF1820; Mon, 30 Jan 2017 14:20:39 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: av@apache.org To: commits@ignite.apache.org Date: Mon, 30 Jan 2017 14:20:48 -0000 Message-Id: <3e5b1fd414b34938aee8685081be1c7f@git.apache.org> In-Reply-To: <9fab79575ab445be816584c23ab09618@git.apache.org> References: <9fab79575ab445be816584c23ab09618@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [10/32] ignite git commit: IGNITE-3964: SQL: add support for custom table name. This closes #1301. archived-at: Mon, 30 Jan 2017 14:20:41 -0000 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-4621 Commit: 74d0dcc6c56118f9e4fdaa4aa70d25d1abe7b80e Parents: 67225b2 Author: Andrey V. Mashenkov Authored: Tue Jan 17 15:00:08 2017 +0300 Committer: Andrey V. Mashenkov 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 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> 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> 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 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 cache = ignite().cache(null); + + cache.put(10, new Type1(1, "Type1 record #1")); + cache.put(20, new Type1(2, "Type1 record #2")); + + QueryCursor> qry1 = + cache.query(new SqlQuery(Type1.class, "FROM Type2")); + + List> all = qry1.getAll(); + + assertEquals(2, all.size()); + + QueryCursor> qry = cache.query(new SqlFieldsQuery("SELECT name FROM Type2")); + + assertEquals(2, qry.getAll().size()); + + GridTestUtils.assertThrows(log, new GridPlainCallable() { + @Override public Void call() throws Exception { + QueryCursor> qry = + cache.query(new SqlQuery(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 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> qry1 = + cache.query(new SqlQuery(Type1.class, "FROM Type2")); + + List> all = qry1.getAll(); + + assertEquals(2, all.size()); + + QueryCursor> qry2 = + cache.query(new SqlQuery(Type2.class, "FROM Type1")); + + assertEquals(3, qry2.getAll().size()); + + QueryCursor> 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() { + @Override public Void call() throws Exception { + QueryCursor> qry1 = + cache.query(new SqlQuery(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 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> 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 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. */