You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/02/09 17:43:10 UTC
[10/24] 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/master
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.
*/