You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lens.apache.org by am...@apache.org on 2016/02/08 07:31:17 UTC
lens git commit: LENS-946 : Fix filter clauses in multi fact or multi
storage queries
Repository: lens
Updated Branches:
refs/heads/master bee5cfd8d -> 0b3203d04
LENS-946 : Fix filter clauses in multi fact or multi storage queries
Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/0b3203d0
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/0b3203d0
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/0b3203d0
Branch: refs/heads/master
Commit: 0b3203d047d9738141d153e9f7894fcc6ac64f79
Parents: bee5cfd
Author: Amareshwari Sriramadasu <am...@apache.org>
Authored: Mon Feb 8 12:00:53 2016 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Mon Feb 8 12:00:53 2016 +0530
----------------------------------------------------------------------
.../apache/lens/cube/parse/CandidateFact.java | 22 ++-----
.../lens/cube/parse/CubeQueryContext.java | 9 ++-
.../apache/lens/cube/parse/DefaultQueryAST.java | 2 +-
.../cube/parse/DenormalizationResolver.java | 13 +++-
.../lens/cube/parse/ExpressionResolver.java | 12 +++-
.../parse/SingleFactMultiStorageHQLContext.java | 10 ---
.../apache/lens/cube/parse/CubeTestSetup.java | 24 +++++--
.../lens/cube/parse/TestBaseCubeQueries.java | 68 ++++++++++++++++++--
.../lens/cube/parse/TestCubeRewriter.java | 25 ++++++-
9 files changed, 132 insertions(+), 53 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lens/blob/0b3203d0/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateFact.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateFact.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateFact.java
index 4faebe1..1b0de34 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateFact.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateFact.java
@@ -76,12 +76,11 @@ public class CandidateFact implements CandidateTable, QueryAST {
@Getter
@Setter
private Integer limitValue;
- private List<TimeRangeNode> timenodes = Lists.newArrayList();
private final List<Integer> selectIndices = Lists.newArrayList();
private final List<Integer> dimFieldIndices = Lists.newArrayList();
private Collection<String> columns;
@Getter
- private final Map<String, String> storgeWhereClauseMap = new HashMap<>();
+ private final Map<String, ASTNode> storgeWhereClauseMap = new HashMap<>();
@Getter
private final Map<TimeRange, Map<String, LinkedHashSet<FactPartition>>> rangeToStoragePartMap = new HashMap<>();
@Getter
@@ -145,18 +144,6 @@ public class CandidateFact implements CandidateTable, QueryAST {
return alias;
}
- static class TimeRangeNode {
- ASTNode timenode;
- ASTNode parent;
- int childIndex;
-
- TimeRangeNode(ASTNode timenode, ASTNode parent, int childIndex) {
- this.timenode = timenode;
- this.parent = parent;
- this.childIndex = childIndex;
- }
- }
-
void incrementPartsQueried(int incr) {
numQueriedParts += incr;
}
@@ -174,8 +161,8 @@ public class CandidateFact implements CandidateTable, QueryAST {
}
- public String getWhereClause(String storageTable) {
- return getStorgeWhereClauseMap().get(storageTable);
+ public ASTNode getStorageWhereClause(String storageTable) {
+ return storgeWhereClauseMap.get(storageTable);
}
public boolean isExpressionAnswerable(ASTNode node, CubeQueryContext context) throws LensException {
@@ -231,7 +218,7 @@ public class CandidateFact implements CandidateTable, QueryAST {
private Set<String> getColsInExpr(final CubeQueryContext cubeql, final Set<String> cubeCols,
ASTNode expr) throws LensException {
- final Set<String> cubeColsInExpr = new HashSet<String>();
+ final Set<String> cubeColsInExpr = new HashSet<>();
HQLParser.bft(expr, new ASTNodeVisitor() {
@Override
public void visit(TreeNode visited) {
@@ -346,7 +333,6 @@ public class CandidateFact implements CandidateTable, QueryAST {
return null;
}
-
/**
* @return the selectIndices
*/
http://git-wip-us.apache.org/repos/asf/lens/blob/0b3203d0/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
index ebf8875..b8b6db9 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
@@ -875,7 +875,7 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
ASTNode rangeAST = HQLParser.parseExpr(rangeWhere);
range.getParent().setChild(range.getChildIndex(), rangeAST);
}
- fact.getStorgeWhereClauseMap().put(table, getWhereTree());
+ fact.getStorgeWhereClauseMap().put(table, HQLParser.parseExpr(getWhereTree()));
}
}
}
@@ -905,7 +905,7 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
}
// pick dimension tables required during expression expansion for the picked fact and dimensions
- Set<Dimension> exprDimensions = new HashSet<Dimension>();
+ Set<Dimension> exprDimensions = new HashSet<>();
if (cfacts != null) {
for (CandidateFact cfact : cfacts) {
Set<Dimension> factExprDimTables = exprCtx.rewriteExprCtx(cfact, dimsToQuery, cfacts.size() > 1 ? cfact : this);
@@ -970,6 +970,7 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
whereAST = MultiFactHQLContext.convertHavingToWhere(havingAST, this, cfacts, new DefaultAliasDecider());
}
}
+
hqlContext = createHQLContext(cfacts, dimsToQuery, factDimMap);
return hqlContext.toHQL();
}
@@ -982,8 +983,10 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
//create single fact with multiple storage context
return new SingleFactMultiStorageHQLContext(facts.iterator().next(), dimsToQuery, this, this);
} else if (facts.size() == 1 && facts.iterator().next().getStorageTables().size() == 1) {
+ CandidateFact fact = facts.iterator().next();
// create single fact context
- return new SingleFactSingleStorageHQLContext(facts.iterator().next(), dimsToQuery, this, this);
+ return new SingleFactSingleStorageHQLContext(fact, null,
+ dimsToQuery, this, DefaultQueryAST.fromCandidateFact(fact, fact.getStorageTables().iterator().next(), this));
} else {
return new MultiFactHQLContext(facts, dimsToQuery, factDimMap, this);
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0b3203d0/lens-cube/src/main/java/org/apache/lens/cube/parse/DefaultQueryAST.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/DefaultQueryAST.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/DefaultQueryAST.java
index 0997f37..a403e36 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/DefaultQueryAST.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/DefaultQueryAST.java
@@ -68,7 +68,7 @@ public class DefaultQueryAST implements QueryAST {
public static DefaultQueryAST fromCandidateFact(CandidateFact fact, String storageTable, QueryAST ast) throws
LensException {
return new DefaultQueryAST(ast.getSelectAST(),
- HQLParser.parseExpr(fact.getWhereClause(storageTable.substring(storageTable.indexOf(".") + 1))),
+ fact.getStorageWhereClause(storageTable.substring(storageTable.indexOf(".") + 1)),
ast.getGroupByAST(), ast.getHavingAST(), ast.getJoinAST(), ast.getOrderByAST(), ast.getLimitValue());
}
}
http://git-wip-us.apache.org/repos/asf/lens/blob/0b3203d0/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
index f2dc2e5..ab1710d 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
@@ -239,12 +239,19 @@ public class DenormalizationResolver implements ContextRewriter {
private void replaceReferencedColumns(CandidateFact cfact, boolean replaceFact) throws LensException {
QueryAST ast = cubeql;
- if (replaceFact
- && (tableToRefCols.get(cfact.getName()) != null && !tableToRefCols.get(cfact.getName()).isEmpty())) {
+ boolean factRefExists = cfact != null && tableToRefCols.get(cfact.getName()) != null && !tableToRefCols.get(cfact
+ .getName()).isEmpty();
+ if (replaceFact && factRefExists) {
ast = cfact;
}
resolveClause(cubeql, ast.getSelectAST());
- resolveClause(cubeql, ast.getWhereAST());
+ if (factRefExists) {
+ for (ASTNode storageWhereClauseAST : cfact.getStorgeWhereClauseMap().values()) {
+ resolveClause(cubeql, storageWhereClauseAST);
+ }
+ } else {
+ resolveClause(cubeql, ast.getWhereAST());
+ }
resolveClause(cubeql, ast.getGroupByAST());
resolveClause(cubeql, ast.getHavingAST());
resolveClause(cubeql, cubeql.getOrderByAST());
http://git-wip-us.apache.org/repos/asf/lens/blob/0b3203d0/lens-cube/src/main/java/org/apache/lens/cube/parse/ExpressionResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/ExpressionResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/ExpressionResolver.java
index fa81831..04c3c45 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/ExpressionResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/ExpressionResolver.java
@@ -447,7 +447,7 @@ class ExpressionResolver implements ContextRewriter {
}
}
// Replace picked expressions in all the base trees
- replacePickedExpressions(queryAST);
+ replacePickedExpressions(cfact, queryAST);
log.debug("Picked expressions: {}", pickedExpressions);
for (Set<PickedExpression> peSet : pickedExpressions.values()) {
for (PickedExpression pe : peSet) {
@@ -459,10 +459,16 @@ class ExpressionResolver implements ContextRewriter {
return exprDims;
}
- private void replacePickedExpressions(QueryAST queryAST)
+ private void replacePickedExpressions(CandidateFact cfact, QueryAST queryAST)
throws LensException {
replaceAST(cubeql, queryAST.getSelectAST());
- replaceAST(cubeql, queryAST.getWhereAST());
+ if (cfact != null) {
+ for (ASTNode storageWhereClauseAST : cfact.getStorgeWhereClauseMap().values()) {
+ replaceAST(cubeql, storageWhereClauseAST);
+ }
+ } else {
+ replaceAST(cubeql, queryAST.getWhereAST());
+ }
replaceAST(cubeql, queryAST.getJoinAST());
replaceAST(cubeql, queryAST.getGroupByAST());
// Having AST is resolved by each fact, so that all facts can expand their expressions.
http://git-wip-us.apache.org/repos/asf/lens/blob/0b3203d0/lens-cube/src/main/java/org/apache/lens/cube/parse/SingleFactMultiStorageHQLContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/SingleFactMultiStorageHQLContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/SingleFactMultiStorageHQLContext.java
index 9f16c5a..63cb388 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/SingleFactMultiStorageHQLContext.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/SingleFactMultiStorageHQLContext.java
@@ -56,7 +56,6 @@ public class SingleFactMultiStorageHQLContext extends UnionHQLContext {
this.ast = ast;
processSelectAST();
processGroupByAST();
- processWhereAST();
processHavingAST();
processOrderByAST();
processLimit();
@@ -76,15 +75,6 @@ public class SingleFactMultiStorageHQLContext extends UnionHQLContext {
}
}
- private void processWhereAST() throws LensException {
- for (String storageTable : fact.getStorgeWhereClauseMap().keySet()) {
- ASTNode tree = parseExpr(fact.getStorgeWhereClauseMap().get(storageTable));
- ASTNode replaced = replaceAST(tree);
- //TODO: optimize parse/unparse cycle
- fact.getStorgeWhereClauseMap().put(storageTable, getString(replaced));
- }
- }
-
private void processHavingAST() throws LensException {
if (ast.getHavingAST() != null) {
setHaving(getString(processExpression(ast.getHavingAST())));
http://git-wip-us.apache.org/repos/asf/lens/blob/0b3203d0/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
index 100d7c9..42decc6 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
@@ -119,7 +119,7 @@ public class CubeTestSetup {
}
public static String getExpectedUnionQuery(String cubeName, List<String> storages, StoragePartitionProvider provider,
- String outerSelectPart, String outerWhere, String outerPostWhere, String innerQuerySelectPart,
+ String outerSelectPart, String outerWhere, String outerPostWhere, String innerQuerySelectPart, String innerJoin,
String innerWhere, String innerPostWhere) {
if (!innerQuerySelectPart.trim().toLowerCase().endsWith("from")) {
innerQuerySelectPart += " from ";
@@ -132,13 +132,19 @@ public class CubeTestSetup {
sb.append(" (");
String sep = "";
for (String storage : storages) {
- sb.append(sep).append(getExpectedQuery(cubeName, innerQuerySelectPart + " ",
- innerWhere, innerPostWhere, provider.providePartitionsForStorage(storage)));
+ sb.append(sep).append(getExpectedQuery(cubeName, innerQuerySelectPart + " ", innerJoin,
+ innerWhere, innerPostWhere, null, provider.providePartitionsForStorage(storage)));
sep = " UNION ALL ";
}
return sb.append(") ").append(cubeName).append(" ").append(outerWhere == null ? "" : outerWhere)
.append(" ").append(outerPostWhere == null ? "" : outerPostWhere).toString();
}
+ public static String getExpectedUnionQuery(String cubeName, List<String> storages, StoragePartitionProvider provider,
+ String outerSelectPart, String outerWhere, String outerPostWhere, String innerQuerySelectPart,
+ String innerWhere, String innerPostWhere) {
+ return getExpectedUnionQuery(cubeName, storages, provider, outerSelectPart, outerWhere, outerPostWhere,
+ innerQuerySelectPart, null, innerWhere, innerPostWhere);
+ }
public static String getExpectedQuery(String cubeName, String selExpr, String whereExpr, String postWhereExpr,
Map<String, String> storageTableToWhereClause) {
@@ -206,8 +212,11 @@ public class CubeTestSetup {
assertEquals(1, numTabs);
for (Map.Entry<String, String> entry : storageTableToWhereClause.entrySet()) {
String storageTable = entry.getKey();
- expected.append(selExpr).append(storageTable).append(" ").append(cubeName).append(joinExpr)
- .append(" WHERE ").append("(");
+ expected.append(selExpr).append(storageTable).append(" ").append(cubeName);
+ if (joinExpr != null) {
+ expected.append(joinExpr);
+ }
+ expected.append(" WHERE ").append("(");
if (notLatestConditions != null) {
for (String cond : notLatestConditions) {
expected.append(cond).append(" AND ");
@@ -553,6 +562,8 @@ public class CubeTestSetup {
cubeDimensions.add(new BaseDimAttribute(new FieldSchema("test_time_dim_day_id2", "int", "ref dim")));
cubeDimensions.add(new ReferencedDimAttribute(new FieldSchema("testDim3id", "string", "direct id to testdim3"),
"dim3 refer", "dim3chain", "id", null, null, 0.0));
+ cubeDimensions.add(new ReferencedDimAttribute(new FieldSchema("cityname", "string", "city name"),
+ "city name", "cubecity", "name", null, null, 0.0));
List<ChainRefCol> references = new ArrayList<>();
references.add(new ChainRefCol("timedatechain1", "full_date"));
references.add(new ChainRefCol("timehourchain1", "full_hour"));
@@ -623,7 +634,8 @@ public class CubeTestSetup {
"substr(cubestate.name, 5)"));
exprs.add(new ExprColumn(new FieldSchema("substrdim2big1", "String", "substr of dim2big1"), "dim2big1 substr",
"substr(dim2big1, 5)"));
-
+ exprs.add(new ExprColumn(new FieldSchema("asciicity", "String", "ascii cityname"), "ascii cityname substr",
+ "ascii(cityname)"));
Map<String, String> cubeProperties = new HashMap<String, String>();
cubeProperties.put(MetastoreUtil.getCubeTimedDimensionListKey(TEST_CUBE_NAME),
"d_time,pt,it,et,test_time_dim,test_time_dim2");
http://git-wip-us.apache.org/repos/asf/lens/blob/0b3203d0/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
index 8aab777..1d27558 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
@@ -195,6 +195,7 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
assertTrue(lower.startsWith("select mq2.roundedmsr2 roundedmsr2, mq1.msr12 msr12 from ")
|| lower.startsWith("select mq1.roundedmsr2 roundedmsr2, mq2.msr12 msr12 from "), hqlQuery);
assertTrue(lower.contains("mq1 full outer join") && lower.endsWith("mq2"), hqlQuery);
+ assertFalse(lower.contains("mq2 on"), hqlQuery);
assertFalse(lower.contains("<=>"), hqlQuery);
}
@@ -205,8 +206,8 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
getExpectedQuery(cubeName, "select basecube.dim1 as `dim1`, sum(basecube.msr12) as `msr12` FROM ", null,
" group by basecube.dim1", getWhereForDailyAndHourly2days(cubeName, "C1_testFact2_BASE"));
String expected2 = getExpectedQuery(cubeName,
- "select basecube.dim1 as `dim1`, round(sum(basecube.msr2)/1000) as `roundedmsr2` FROM ", null,
- " group by basecube.dim1", getWhereForDailyAndHourly2days(cubeName, "C1_testFact1_BASE"));
+ "select basecube.dim1 as `dim1`, round(sum(basecube.msr2)/1000) as `roundedmsr2` FROM ", null,
+ " group by basecube.dim1", getWhereForDailyAndHourly2days(cubeName, "C1_testFact1_BASE"));
compareContains(expected1, hqlQuery);
compareContains(expected2, hqlQuery);
String lower = hqlQuery.toLowerCase();
@@ -359,7 +360,7 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
@Test
public void testMultiFactQueryWithNoAggregates() throws Exception {
// no aggregates in the query
- String hqlQuery = rewrite("select dim1, msr11, roundedmsr2 from basecube" + " where " + TWO_DAYS_RANGE, conf);
+ String hqlQuery = rewrite("select dim1, msr11, roundedmsr2 from basecube where " + TWO_DAYS_RANGE, conf);
String expected1 =
getExpectedQuery(cubeName, "select basecube.dim1 as `dim1`, basecube.msr11 as `msr11` FROM ", null, null,
getWhereForHourly2days(cubeName, "C1_testfact2_raw_base"));
@@ -381,7 +382,7 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
public void testMultiFactQueryWithColumnAliases() throws Exception {
// query with aliases passed
String hqlQuery =
- rewrite("select dim1 d1, msr12 `my msr12`, roundedmsr2 m2 from basecube" + " where " + TWO_DAYS_RANGE, conf);
+ rewrite("select dim1 d1, msr12 `my msr12`, roundedmsr2 m2 from basecube where " + TWO_DAYS_RANGE, conf);
String expected1 =
getExpectedQuery(cubeName, "select basecube.dim1 as `d1`, sum(basecube.msr12) as `expr2` FROM ", null,
" group by basecube.dim1", getWhereForDailyAndHourly2days(cubeName, "C1_testFact2_BASE"));
@@ -401,7 +402,7 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
@Test
public void testMultiFactQueryWithNoDefaultAggregates() throws Exception {
// query with non default aggregate
- String hqlQuery = rewrite("select dim1, avg(msr12), avg(msr2) from basecube" + " where " + TWO_DAYS_RANGE, conf);
+ String hqlQuery = rewrite("select dim1, avg(msr12), avg(msr2) from basecube where " + TWO_DAYS_RANGE, conf);
String expected1 =
getExpectedQuery(cubeName, "select basecube.dim1 as `dim1`, avg(basecube.msr12) as `msr12` FROM ", null,
" group by basecube.dim1", getWhereForHourly2days(cubeName, "C1_testfact2_raw_base"));
@@ -444,7 +445,7 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
@Test
public void testMultiFactQueryWithDenormColumn() throws Exception {
// query with denorm variable
- String hqlQuery = rewrite("select dim2, msr13, roundedmsr2 from basecube" + " where " + TWO_DAYS_RANGE, conf);
+ String hqlQuery = rewrite("select dim2, msr13, roundedmsr2 from basecube where " + TWO_DAYS_RANGE, conf);
String expected1 = getExpectedQuery(cubeName, "select dim2chain.id as `dim2`, max(basecube.msr13) as `msr13` FROM ",
" JOIN " + getDbName() + "c1_testdim2tbl dim2chain ON basecube.dim12 = "
+ " dim2chain.id and (dim2chain.dt = 'latest') ", null, " group by dim2chain.id", null,
@@ -463,12 +464,33 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
}
@Test
+ public void testMultiFactQueryWithDenormColumnInWhere() throws Exception {
+ // query with denorm variable
+ String hqlQuery = rewrite("select dim2, msr13, roundedmsr2 from basecube where dim2 == 10 and " + TWO_DAYS_RANGE,
+ conf);
+ String expected1 = getExpectedQuery(cubeName, "select dim2chain.id as `dim2`, max(basecube.msr13) as `msr13` FROM ",
+ " JOIN " + getDbName() + "c1_testdim2tbl dim2chain ON basecube.dim12 = "
+ + " dim2chain.id and (dim2chain.dt = 'latest') ", "dim2chain.id == 10", " group by dim2chain.id", null,
+ getWhereForHourly2days(cubeName, "C1_testFact3_RAW_BASE"));
+ String expected2 = getExpectedQuery(cubeName,
+ "select basecube.dim2 as `dim2`, round(sum(basecube.msr2)/1000) as `roundedmsr2` FROM ", "basecube.dim2 == 10",
+ " group by basecube.dim2", getWhereForHourly2days(cubeName, "C1_testfact1_raw_base"));
+ compareContains(expected1, hqlQuery);
+ compareContains(expected2, hqlQuery);
+ assertTrue(hqlQuery.toLowerCase().startsWith(
+ "select coalesce(mq1.dim2, mq2.dim2) dim2, mq2.msr13 msr13, mq1.roundedmsr2 roundedmsr2 from ")
+ || hqlQuery.toLowerCase().startsWith(
+ "select coalesce(mq1.dim2, mq2.dim2) dim2, mq1.msr13 msr13, mq2.roundedmsr2 roundedmsr2 from "), hqlQuery);
+ assertTrue(hqlQuery.contains("mq1 full outer join ") && hqlQuery.endsWith("mq2 on mq1.dim2 <=> mq2.dim2"),
+ hqlQuery);
+ }
+ @Test
public void testMultiFactQueryWithExpressionInvolvingDenormVariable() throws Exception {
// query with expression
// The expression to be answered from denorm columns
String hqlQuery =
rewrite(
- "select booleancut, round(sum(msr2)/1000), avg(msr13 + msr14) from basecube" + " where " + TWO_DAYS_RANGE,
+ "select booleancut, round(sum(msr2)/1000), avg(msr13 + msr14) from basecube where " + TWO_DAYS_RANGE,
conf);
String expected1 =
getExpectedQuery(cubeName, "select basecube.dim1 != 'x' AND dim2chain.id != 10 as `booleancut`,"
@@ -495,6 +517,38 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
}
@Test
+ public void testMultiFactQueryWithExpressionInvolvingDenormVariableInWhereClause() throws Exception {
+ // query with expression
+ // The expression to be answered from denorm columns
+ String hqlQuery =
+ rewrite(
+ "select booleancut, round(sum(msr2)/1000), avg(msr13 + msr14) from basecube where booleancut == 'true' and "
+ + TWO_DAYS_RANGE, conf);
+ String expected1 =
+ getExpectedQuery(cubeName, "select basecube.dim1 != 'x' AND dim2chain.id != 10 as `booleancut`,"
+ + " avg(basecube.msr13 + basecube.msr14) as `expr3` FROM ", " JOIN " + getDbName()
+ + "c1_testdim2tbl dim2chain ON basecube.dim12 = " + " dim2chain.id and (dim2chain.dt = 'latest') ",
+ "(basecube.dim1 != 'x' AND dim2chain.id != 10) == true",
+ " group by basecube.dim1 != 'x' AND dim2chain.id != 10", null,
+ getWhereForHourly2days(cubeName, "C1_testfact3_raw_base"));
+ String expected2 =
+ getExpectedQuery(cubeName, "select basecube.dim1 != 'x' AND basecube.dim2 != 10 as `booleancut`,"
+ + " round(sum(basecube.msr2)/1000) as `msr2` FROM ", "(basecube.dim1 != 'x' AND basecube.dim2 != 10) == true",
+ " group by basecube.dim1 != 'x' AND basecube.dim2 != 10",
+ getWhereForHourly2days(cubeName, "C1_testfact1_raw_base"));
+ compareContains(expected1, hqlQuery);
+ compareContains(expected2, hqlQuery);
+ assertTrue(hqlQuery.toLowerCase()
+ .startsWith("select coalesce(mq1.booleancut, mq2.booleancut) booleancut, mq2.msr2 msr2,"
+ + " mq1.expr3 expr3 from ")
+ || hqlQuery.toLowerCase()
+ .startsWith("select coalesce(mq1.booleancut, mq2.booleancut) booleancut, mq1.msr2 msr2,"
+ + " mq2.expr3 expr3 from "), hqlQuery);
+ assertTrue(hqlQuery.contains("mq1 full outer join ")
+ && hqlQuery.endsWith("mq2 on mq1.booleancut <=> mq2.booleancut"),
+ hqlQuery);
+ }
+ @Test
public void testFallbackPartCol() throws Exception {
Configuration conf = getConfWithStorages("C1");
conf.setBoolean(CubeQueryConfUtil.FAIL_QUERY_ON_PARTIAL_DATA, false);
http://git-wip-us.apache.org/repos/asf/lens/blob/0b3203d0/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
index e569fb1..45b4334 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
@@ -396,6 +396,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
conf.set(getValidUpdatePeriodsKey("testfact", "C1"), "DAILY,HOURLY");
conf.set(getValidUpdatePeriodsKey("testfact2", "C1"), "YEARLY");
conf.set(getValidUpdatePeriodsKey("testfact", "C2"), "MONTHLY,DAILY");
+ conf.set(CubeQueryConfUtil.DISABLE_AUTO_JOINS, "false");
ArrayList<String> storages = Lists.newArrayList("c1_testfact", "c2_testfact");
try {
getStorageToUpdatePeriodMap().put("c1_testfact", Lists.newArrayList(HOURLY, DAILY));
@@ -419,6 +420,26 @@ public class TestCubeRewriter extends TestQueryRewrite {
}
conf.setBoolean(CubeQueryConfUtil.ENABLE_STORAGES_UNION, true);
+ hqlQuery = rewrite("select ascii(cityname) as `City Name`, msr8, msr7 as `Third measure` "
+ + "from testCube where ascii(cityname) = 'c' and cityname = 'a' and zipcode = 'b' and "
+ + TWO_MONTHS_RANGE_UPTO_HOURS, conf);
+ expected = getExpectedUnionQuery(TEST_CUBE_NAME, storages, provider,
+ "SELECT testcube.alias0 as `City Name`, sum(testcube.alias1) + max(testcube.alias2), "
+ + "case when sum(testcube.alias1) = 0 then 0 else sum(testcube.alias3)/sum(testcube.alias1) end "
+ + "as `Third Measure`",
+ null, "group by testcube.alias0",
+ "select ascii(cubecity.name) as `alias0`, sum(testcube.msr2) as `alias1`, "
+ + "max(testcube.msr3) as `alias2`, "
+ + "sum(case when testcube.cityid = 'x' then testcube.msr21 else testcube.msr22 end) as `alias3`", " join "
+ + getDbName() + "c1_citytable cubecity on testcube.cityid = cubecity.id and (cubecity.dt = 'latest')",
+ "ascii(cubecity.name) = 'c' and cubecity.name = 'a' and testcube.zipcode = 'b'",
+ "group by ascii(cubecity.name))");
+ compareQueries(hqlQuery, expected);
+ hqlQuery = rewrite("select asciicity as `City Name`, msr8, msr7 as `Third measure` "
+ + "from testCube where asciicity = 'c' and cityname = 'a' and zipcode = 'b' and "
+ + TWO_MONTHS_RANGE_UPTO_HOURS, conf);
+ compareQueries(hqlQuery, expected);
+
hqlQuery = rewrite("select ascii(cityid) as `City ID`, msr8, msr7 as `Third measure` "
+ "from testCube where ascii(cityid) = 'c' and cityid = 'a' and zipcode = 'b' and "
+ TWO_MONTHS_RANGE_UPTO_HOURS, conf);
@@ -431,7 +452,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
"select ascii(testcube.cityid) as `alias0`, sum(testcube.msr2) as `alias1`, "
+ "max(testcube.msr3) as `alias2`, "
+ "sum(case when testcube.cityid = 'x' then testcube.msr21 else testcube.msr22 end) as `alias3`",
- "testcube.alias0 = 'c' and testcube.cityid = 'a' and testcube.zipcode = 'b'",
+ "ascii(testcube.cityid) = 'c' and testcube.cityid = 'a' and testcube.zipcode = 'b'",
"group by ascii(testcube.cityid)");
compareQueries(hqlQuery, expected);
@@ -447,7 +468,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
"select testcube.cityid as `alias0`, sum(testcube.msr2) as `alias1`, "
+ "max(testcube.msr3) as `alias2`, "
+ "sum(case when testcube.cityid = 'x' then testcube.msr21 else testcube.msr22 end) as `alias3`",
- "testcube.alias0 = 'a' and testcube.zipcode = 'b'", "group by testcube.cityid");
+ "testcube.cityid = 'a' and testcube.zipcode = 'b'", "group by testcube.cityid");
compareQueries(hqlQuery, expected);