Repository: ignite Updated Branches: refs/heads/ignite-1232 e48c1d490 -> 22f923cb3
ignite-1232 Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/22f923cb Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/22f923cb Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/22f923cb Branch: refs/heads/ignite-1232 Commit: 22f923cb3231ab330a2d6a37111a4993674c98c0 Parents: e48c1d4 Author: sboikov <[email protected]> Authored: Fri Jul 15 17:07:10 2016 +0300 Committer: sboikov <[email protected]> Committed: Fri Jul 15 17:48:42 2016 +0300 ---------------------------------------------------------------------- .../query/h2/opt/GridH2CollocationModel.java | 23 ++++-- .../query/h2/sql/GridSqlQueryParser.java | 2 +- .../IgniteCacheDistributedJoinNoIndexTest.java | 73 +++++++++++++++----- 3 files changed, 75 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/22f923cb/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2CollocationModel.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2CollocationModel.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2CollocationModel.java index 2f35792..b3cb7f1 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2CollocationModel.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2CollocationModel.java @@ -21,6 +21,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.cache.CacheException; +import org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser; +import org.apache.ignite.internal.util.typedef.F; import org.h2.command.dml.Query; import org.h2.command.dml.Select; import org.h2.command.dml.SelectUnion; @@ -34,6 +36,7 @@ import org.h2.table.IndexColumn; import org.h2.table.SubQueryInfo; import org.h2.table.Table; import org.h2.table.TableFilter; +import org.h2.table.TableView; /** * Collocation model for a query. @@ -327,6 +330,12 @@ public final class GridH2CollocationModel { if (validate) { if (tbl.rowDescriptor().context().customAffinityMapper()) throw customAffinityError(tbl.spaceName()); + + if (childFilters.length > 1 && F.isEmpty(tf.getIndexConditions())) { + throw new CacheException("Failed to prepare distributed join query: " + + "join condition does not use index [joinedCache=" + tbl.spaceName() + + ", plan=" + tf.getSelect().getPlanSQL() + ']'); + } } IndexColumn affCol = tbl.getAffinityKeyColumn(); @@ -401,17 +410,22 @@ public final class GridH2CollocationModel { Table t = col.getTable(); if (t.isView()) { - Query qry = getSubQuery(f); + Query qry; + + if (f.getIndex() != null) + qry = getSubQuery(f); + else + qry = GridSqlQueryParser.VIEW_QUERY.get((TableView)t); return isAffinityColumn(qry, expCol, validate); } if (t instanceof GridH2Table) { - IndexColumn affCol = ((GridH2Table)t).getAffinityKeyColumn(); - if (validate && ((GridH2Table)t).rowDescriptor().context().customAffinityMapper()) throw customAffinityError(((GridH2Table)t).spaceName()); + IndexColumn affCol = ((GridH2Table)t).getAffinityKeyColumn(); + return affCol != null && col.getColumnId() == affCol.column.getColumnId(); } @@ -689,7 +703,8 @@ public final class GridH2CollocationModel { * @return Error. */ private static CacheException customAffinityError(String cacheName) { - return new CacheException("Can not use distributed joins for cache with custom AffinityKeyMapper configured. " + + return new CacheException("Failed to prepare distributed join query: can not use distributed joins for cache " + + "with custom AffinityKeyMapper configured. " + "Please use AffinityKeyMapped annotation instead [cache=" + cacheName + ']'); } http://git-wip-us.apache.org/repos/asf/ignite/blob/22f923cb/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java index 30226c8..e35d4e9 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java @@ -140,7 +140,7 @@ public class GridSqlQueryParser { private static final Getter<ConditionAndOr, Expression> ANDOR_RIGHT = getter(ConditionAndOr.class, "right"); /** */ - private static final Getter<TableView, Query> VIEW_QUERY = getter(TableView.class, "viewQuery"); + public static final Getter<TableView, Query> VIEW_QUERY = getter(TableView.class, "viewQuery"); /** */ private static final Getter<TableFilter, String> ALIAS = getter(TableFilter.class, "alias"); http://git-wip-us.apache.org/repos/asf/ignite/blob/22f923cb/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheDistributedJoinNoIndexTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheDistributedJoinNoIndexTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheDistributedJoinNoIndexTest.java index 51f47aa..95c56fa 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheDistributedJoinNoIndexTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheDistributedJoinNoIndexTest.java @@ -25,7 +25,6 @@ import java.util.concurrent.atomic.AtomicInteger; import javax.cache.CacheException; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; -import org.apache.ignite.IgniteException; import org.apache.ignite.cache.QueryEntity; import org.apache.ignite.cache.affinity.Affinity; import org.apache.ignite.cache.query.QueryCursor; @@ -165,46 +164,82 @@ public class IgniteCacheDistributedJoinNoIndexTest extends GridCommonAbstractTes personCache.put(keyForNode(aff, pKey, node1), new Person(orgId, "org-" + i)); } - GridTestUtils.assertThrows(log, new Callable<Void>() { + checkNoIndexError(personCache, "select o.name, p._key, p.orgName " + + "from \"org\".Organization o, \"person\".Person p " + + "where p.orgName = o.name"); + + checkNoIndexError(personCache, "select o.name, p._key, p.orgName " + + "from \"org\".Organization o inner join \"person\".Person p " + + "on p.orgName = o.name"); + + checkNoIndexError(personCache, "select o.name, p._key, p.orgName " + + "from \"org\".Organization o, \"person\".Person p " + + "where p.orgName > o.name"); + + checkNoIndexError(personCache, "select o.name, p._key, p.orgName " + + "from (select * from \"org\".Organization) o, \"person\".Person p " + + "where p.orgName = o.name"); + + checkNoIndexError(personCache, "select o.name, p._key, p.orgName " + + "from \"org\".Organization o, (select * from \"person\".Person) p " + + "where p.orgName = o.name"); + + checkNoIndexError(personCache, "select o.name, p._key, p.orgName " + + "from (select * from \"org\".Organization) o, (select * from \"person\".Person) p " + + "where p.orgName = o.name"); + + checkNoIndexError(personCache, "select o.name, p._key, p.orgName " + + "from \"org\".Organization o, \"person\".Person p"); + + checkNoIndexError(personCache, "select o.name, p._key, p.orgName " + + "from \"org\".Organization o, \"person\".Person p where o._key != p._key"); + + checkQuery("select o.name, p._key, p.orgName " + + "from \"org\".Organization o, \"person\".Person p " + + "where p._key = o._key and o.name=?", personCache, 0, "aaa"); + } + + /** + * @param cache Cache. + * @param sql SQL. + */ + private void checkNoIndexError(final IgniteCache<Object, Object> cache, final String sql) { + Throwable err = GridTestUtils.assertThrows(log, new Callable<Void>() { @Override public Void call() throws Exception { - SqlFieldsQuery qry = new SqlFieldsQuery("select o.name, p._key, p.orgName " + - "from \"org\".Organization o, \"person\".Person p " + - "where p.orgName = o.name"); + SqlFieldsQuery qry = new SqlFieldsQuery(sql); qry.setDistributedJoins(true); - personCache.query(qry).getAll(); + cache.query(qry).getAll(); return null; } }, CacheException.class, null); + + log.info("Error: " + err.getMessage()); + + assertTrue("Unexpected error message: " + err.getMessage(), + err.getMessage().contains("join condition does not use index")); } - + /** * @param sql SQL. * @param cache Cache. - * @param enforceJoinOrder Enforce join order flag. * @param expSize Expected results size. * @param args Arguments. + * @return Results. */ - private void checkQuery(String sql, + private List<List<?>> checkQuery(String sql, IgniteCache<Object, Object> cache, - boolean enforceJoinOrder, int expSize, Object... args) { - String plan = (String)cache.query(new SqlFieldsQuery("explain " + sql) - .setDistributedJoins(true) - .setEnforceJoinOrder(enforceJoinOrder)) - .getAll().get(0).get(0); - - log.info("Plan: " + plan); - SqlFieldsQuery qry = new SqlFieldsQuery(sql); qry.setDistributedJoins(true); - qry.setEnforceJoinOrder(enforceJoinOrder); qry.setArgs(args); + log.info("Plan: " + queryPlan(cache, qry)); + QueryCursor<List<?>> cur = cache.query(qry); List<List<?>> res = cur.getAll(); @@ -213,6 +248,8 @@ public class IgniteCacheDistributedJoinNoIndexTest extends GridCommonAbstractTes log.info("Results: " + res); assertEquals(expSize, res.size()); + + return res; } /**
