Repository: lens
Updated Branches:
  refs/heads/master 42c4dfcb6 -> a736f4697


LENS-1208 : Fix join condition for outer join of multi fact queries for 
expression attributes


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

Branch: refs/heads/master
Commit: a736f4697ee91fa7949e4e895407dbcbf3d5e62b
Parents: 42c4dfc
Author: Amareshwari Sriramadasu <amareshw...@gmail.com>
Authored: Tue Jul 5 15:04:05 2016 +0530
Committer: Rajat Khandelwal <rajatgupt...@gmail.com>
Committed: Tue Jul 5 15:04:05 2016 +0530

----------------------------------------------------------------------
 .../apache/lens/cube/parse/CandidateFact.java   | 19 +++++++++--
 .../lens/cube/parse/ExpressionResolver.java     |  2 ++
 .../apache/lens/cube/parse/CubeTestSetup.java   | 34 +++++++++++++++++++-
 .../lens/cube/parse/TestBaseCubeQueries.java    | 30 +++++++++++++++--
 4 files changed, 79 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/a736f469/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 187d98d..01265a5 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
@@ -180,8 +180,6 @@ public class CandidateFact implements CandidateTable, 
QueryAST {
    * @throws LensException
    */
   public void updateASTs(CubeQueryContext cubeql) throws LensException {
-    Set<String> cubeCols = cubeql.getCube().getAllFieldNames();
-
     // update select AST with selected fields
     int currentChild = 0;
     for (int i = 0; i < cubeql.getSelectAST().getChildCount(); i++) {
@@ -189,7 +187,9 @@ public class CandidateFact implements CandidateTable, 
QueryAST {
       Set<String> exprCols = 
HQLParser.getColsInExpr(cubeql.getAliasForTableName(cubeql.getCube()), 
selectExpr);
       if (getColumns().containsAll(exprCols)) {
         selectIndices.add(i);
-        if (cubeql.getCube().getDimAttributeNames().containsAll(exprCols)) {
+        if (exprCols.isEmpty() // no direct fact columns
+          // does not have measure names
+          || (!containsAny(cubeql.getCube().getMeasureNames(), exprCols))) {
           dimFieldIndices.add(i);
         }
         ASTNode aliasNode = HQLParser.findNodeByPath(selectExpr, Identifier);
@@ -220,6 +220,19 @@ public class CandidateFact implements CandidateTable, 
QueryAST {
     // push down of having clauses happens just after this call in 
cubequerycontext
   }
 
+  // The source set contains atleast one column in the colSet
+  static boolean containsAny(Collection<String> srcSet, Collection<String> 
colSet) {
+    if (colSet == null || colSet.isEmpty()) {
+      return true;
+    }
+    for (String column : colSet) {
+      if (srcSet.contains(column)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   @Override
   public String getStorageString(String alias) {
     return StringUtils.join(storageTables, ",") + " " + alias;

http://git-wip-us.apache.org/repos/asf/lens/blob/a736f469/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 898c438..5adea6c 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
@@ -356,7 +356,9 @@ class ExpressionResolver implements ContextRewriter {
       ExpressionContext ec = getExpressionContext(expr, alias);
       if (cTable.getColumns().contains(expr)) {
         // expression is directly materialized in candidate table
+        log.debug("{} is directly evaluable in {}", expr, cTable);
         ec.addDirectlyAvailable(cTable);
+        return;
       }
       for (ExprSpecContext esc : ec.allExprs) {
         if (esc.getTblAliasToColumns().get(alias) == null) {

http://git-wip-us.apache.org/repos/asf/lens/blob/a736f469/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 ea6b4a1..48652f2 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
@@ -1302,10 +1302,26 @@ public class CubeTestSetup {
     factColumns.add(new FieldSchema("dim11", "string", "base dim"));
     factColumns.add(new FieldSchema("test_time_dim_hour_id", "int", "time 
id"));
 
-    // create cube fact
+    // create cube fact with materialized expressions
     client.createCubeFactTable(BASE_CUBE_NAME, factName, factColumns, 
storageAggregatePeriods, 5L,
       factValidityProperties, storageTables);
 
+    factName = "testFact5_BASE";
+    factColumns = new ArrayList<>(cubeMeasures.size());
+    for (CubeMeasure measure : cubeMeasures) {
+      factColumns.add(measure.getColumn());
+    }
+
+    // add dimensions of the cube
+    factColumns.add(new FieldSchema("d_time", "timestamp", "event time"));
+    factColumns.add(new FieldSchema("processing_time", "timestamp", 
"processing time"));
+    factColumns.add(new FieldSchema("dim1", "string", "base dim"));
+    factColumns.add(new FieldSchema("booleancut", "boolean", "expr dim"));
+
+    // create cube fact
+    client.createCubeFactTable(BASE_CUBE_NAME, factName, factColumns, 
storageAggregatePeriods, 150L,
+      factValidityProperties, storageTables);
+
     // create fact only with extra measures
     factName = "testFact2_BASE";
     factColumns = new ArrayList<FieldSchema>();
@@ -1345,6 +1361,22 @@ public class CubeTestSetup {
     client.createCubeFactTable(BASE_CUBE_NAME, factName, factColumns, 
storageAggregatePeriods, 5L,
       factValidityProperties, storageTables);
 
+    // create fact with materialized expression
+    factName = "testFact6_BASE";
+    factColumns = new ArrayList<>();
+    factColumns.add(new FieldSchema("msr13", "double", "third measure"));
+    factColumns.add(new FieldSchema("msr14", "bigint", "fourth measure"));
+
+    // add dimensions of the cube
+    factColumns.add(new FieldSchema("d_time", "timestamp", "event time"));
+    factColumns.add(new FieldSchema("processing_time", "timestamp", 
"processing time"));
+    factColumns.add(new FieldSchema("dim1", "string", "base dim"));
+    factColumns.add(new FieldSchema("booleancut", "boolean", "expr dim"));
+
+    // create cube fact
+    client.createCubeFactTable(BASE_CUBE_NAME, factName, factColumns, 
storageAggregatePeriods, 150L,
+      factValidityProperties, storageTables);
+
     // create raw fact only with extra measures
     factName = "testFact2_RAW_BASE";
     factColumns = new ArrayList<FieldSchema>();

http://git-wip-us.apache.org/repos/asf/lens/blob/a736f469/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 d17c18f..d42d494 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
@@ -112,7 +112,8 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
      *
      */
     boolean columnNotFound = false;
-    List<String> testTimeDimFactTables = Arrays.asList("testfact3_base", 
"testfact1_raw_base", "testfact3_raw_base");
+    List<String> testTimeDimFactTables = Arrays.asList("testfact3_base", 
"testfact1_raw_base", "testfact3_raw_base",
+      "testfact5_base", "testfact6_base");
     List<String> factTablesForMeasures = Arrays.asList("testfact_deprecated", 
"testfact2_raw_base", "testfact2_base");
     for (Map.Entry<String, List<CandidateTablePruneCause>> entry : 
pruneCauses.getDetails().entrySet()) {
       if 
(entry.getValue().contains(CandidateTablePruneCause.columnNotFound("test_time_dim")))
 {
@@ -213,7 +214,7 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
     String lower = hqlQuery.toLowerCase();
     assertTrue(
       lower.startsWith("select coalesce(mq1.dim1, mq2.dim1) dim1, 
mq2.roundedmsr2 roundedmsr2, mq1.msr12 msr12 from ")
-      || lower.startsWith("select coalesce(mq1.dim1, mq2.dim1) dim1, 
mq1.roundedmsr2 roundedmsr2, mq2.msr12 msr12"
+        || lower.startsWith("select coalesce(mq1.dim1, mq2.dim1) dim1, 
mq1.roundedmsr2 roundedmsr2, mq2.msr12 msr12"
         + " from "), hqlQuery);
 
     assertTrue(hqlQuery.contains("mq1 full outer join ") && 
hqlQuery.endsWith("mq2 on mq1.dim1 <=> mq2.dim1"),
@@ -663,6 +664,31 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
         && hqlQuery.endsWith("mq2 on mq1.booleancut <=> mq2.booleancut"),
       hqlQuery);
   }
+
+  @Test
+  public void testMultiFactQueryWithMaterializedExpressions() throws Exception 
{
+    Configuration tconf = new Configuration(conf);
+    tconf.set(CubeQueryConfUtil.getValidFactTablesKey("basecube"), 
"testfact5_base,testfact6_base");
+    String hqlQuery =
+      rewrite(
+        "select booleancut, round(sum(msr2)/1000), msr13 from basecube where " 
+ TWO_DAYS_RANGE, tconf);
+    String expected1 =
+      getExpectedQuery(cubeName, "select basecube.booleancut as 
`booleancut`,max(basecube.msr13) as `msr13` FROM ",
+        null, " group by basecube.booleancut", 
getWhereForDailyAndHourly2days(cubeName, "C1_testfact6_base"));
+    String expected2 =
+      getExpectedQuery(cubeName, "select basecube.booleancut as `booleancut`,"
+          + " round(sum(basecube.msr2)/1000) as `expr2` FROM ", null, " group 
by basecube.booleancut",
+        getWhereForDailyAndHourly2days(cubeName, "C1_testfact5_base"));
+    compareContains(expected1, hqlQuery);
+    compareContains(expected2, hqlQuery);
+    assertTrue(hqlQuery.toLowerCase().startsWith("select 
coalesce(mq1.booleancut, mq2.booleancut) booleancut, "
+      + "mq2.expr2 `round((sum(msr2) / 1000))`, mq1.msr13 msr13 from ")
+      || hqlQuery.toLowerCase().startsWith("select coalesce(mq1.booleancut, 
mq2.booleancut) booleancut, "
+        + "mq1.expr2 `round((sum(msr2) / 1000))`, mq2.msr13 msr13 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");

Reply via email to