You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lens.apache.org by pr...@apache.org on 2016/10/10 09:41:50 UTC

[1/4] lens git commit: LENS-1273 : Resolve issues with case when aggregate expressions with dim-attributes conditions

Repository: lens
Updated Branches:
  refs/heads/master 9ef7ce736 -> d9884ec6d


http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/test/java/org/apache/lens/cube/parse/TestAggregateResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestAggregateResolver.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestAggregateResolver.java
index 35234a1..dd0b6dc 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestAggregateResolver.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestAggregateResolver.java
@@ -81,14 +81,14 @@ public class TestAggregateResolver extends TestQueryRewrite {
     // pass
     String q7 =
       "SELECT cityid, sum(testCube.msr2) from testCube where " + TWO_DAYS_RANGE
-        + " having (testCube.msr2 > 100) OR (testcube.msr2 < 100" + " AND max(testcube.msr3) > 1000)";
+        + " having (testCube.msr2 > 100) OR (testcube.msr2 < 100 AND max(testcube.msr3) > 1000)";
 
     // pass
-    String q8 = "SELECT cityid, sum(testCube.msr2) * max(testCube.msr3) from" + " testCube where " + TWO_DAYS_RANGE;
+    String q8 = "SELECT cityid, sum(testCube.msr2) * max(testCube.msr3) from testCube where " + TWO_DAYS_RANGE;
 
     // pass
     String q9 =
-      "SELECT cityid c1, max(msr3) m3 from testCube where " + "c1 > 100 and " + TWO_DAYS_RANGE + " having (msr2 < 100"
+      "SELECT cityid c1, max(msr3) m3 from testCube where c1 > 100 and " + TWO_DAYS_RANGE + " having (msr2 < 100"
         + " AND m3 > 1000)";
 
     String q10 = "SELECT cityid, round(testCube.msr2) from testCube where " + TWO_DAYS_RANGE;
@@ -97,39 +97,39 @@ public class TestAggregateResolver extends TestQueryRewrite {
     String q11 = "SELECT cityid from testCube where " + TWO_DAYS_RANGE + " having (testCube.msr2 > 100)";
 
     String expectedq1 =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         "group by testcube.cityid", getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     String expectedq2 =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) * max(testCube.msr3) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) * max(testCube.msr3) from ", null,
         "group by testcube.cityid", getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     String expectedq3 =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         "group by testcube.cityid", getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     String expectedq4 =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         "group by testcube.cityid having" + " sum(testCube.msr2) > 100",
         getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     String expectedq5 =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         "group by testcube.cityid having" + " sum(testCube.msr2) + max(testCube.msr3) > 100",
         getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     String expectedq6 =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         "group by testcube.cityid having" + " sum(testCube.msr2) > 100 and sum(testCube.msr2) < 1000",
         getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     String expectedq7 =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         "group by testcube.cityid having" + " sum(testCube.msr2) > 100 OR (sum(testCube.msr2) < 100 AND"
           + " max(testcube.msr3) > 1000)", getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     String expectedq8 =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) * max(testCube.msr3) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) * max(testCube.msr3) from ", null,
         "group by testcube.cityid", getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     String expectedq9 =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid as `c1`," + " max(testCube.msr3) as `m3` from ", "c1 > 100",
+      getExpectedQuery(cubeName, "SELECT testcube.cityid as `c1`, max(testCube.msr3) as `m3` from ", "c1 > 100",
         "group by testcube.cityid" + " having sum(testCube.msr2) < 100 AND (m3 > 1000)",
         getWhereForDailyAndHourly2days(cubeName, "c2_testfact"));
     String expectedq10 =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " round(sum(testCube.msr2)) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, round(sum(testCube.msr2)) from ", null,
         "group by testcube.cityid", getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     String expectedq11 =
       getExpectedQuery(cubeName, "SELECT testcube.cityid from ", null,
@@ -216,7 +216,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     CandidateFact candidateFact = cubeql.getCandidateFacts().iterator().next();
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     String expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " testCube.msr2 from ", null, null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, testCube.msr2 from ", null, null,
         getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
     conf2.set(CubeQueryConfUtil.DRIVER_SUPPORTED_STORAGES, "C2");
@@ -247,7 +247,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     cubeql = rewriteCtx(query, conf);
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         "group by testcube.cityid", getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     compareQueries(hQL, expectedQL);
 
@@ -255,7 +255,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     cubeql = rewriteCtx(query, conf);
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) as `m2` from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) as `m2` from ", null,
         "group by testcube.cityid order by m2 asc", getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     compareQueries(hQL, expectedQL);
 
@@ -263,7 +263,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     cubeql = rewriteCtx(query, conf);
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         "group by testcube.cityid having max(testcube.msr3) > 100",
         getWhereForDailyAndHourly2days(cubeName, "C2_testfact"));
     compareQueries(hQL, expectedQL);
@@ -278,7 +278,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     CandidateFact candidateFact = cubeql.getCandidateFacts().iterator().next();
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     String expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " avg(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, avg(testCube.msr2) from ", null,
         "group by testcube.cityid", getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
 
@@ -290,7 +290,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", "testcube.msr1 < 100",
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", "testcube.msr1 < 100",
         "group by testcube.cityid", getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
 
@@ -301,7 +301,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " testCube.msr2 from ", "testcube.msr2 < 100", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, testCube.msr2 from ", "testcube.msr2 < 100", null,
         getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
 
@@ -312,8 +312,8 @@ public class TestAggregateResolver extends TestQueryRewrite {
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
-        " group by testCube.msr1, testcube.cityid", getWhereForHourly2days("c1_testfact2_raw"));
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
+        " group by testCube.msr1", getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
 
     query = "SELECT cityid, sum(testCube.msr2) FROM testCube WHERE " + TWO_DAYS_RANGE + " group by testCube.msr3";
@@ -323,8 +323,8 @@ public class TestAggregateResolver extends TestQueryRewrite {
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
-        " group by testCube.msr3, testcube.cityid", getWhereForHourly2days("c1_testfact2_raw"));
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
+        " group by testCube.msr3", getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
 
     query = "SELECT cityid, sum(testCube.msr2) FROM testCube WHERE " + TWO_DAYS_RANGE + " order by testCube.msr1";
@@ -334,7 +334,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         " group by testcube.cityid order by testcube.msr1 asc", getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
 
@@ -345,7 +345,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         " group by testcube.cityid order by testcube.msr3 asc", getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
 
@@ -356,7 +356,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT distinct testcube.cityid," + " round(testCube.msr2) from ", null, null,
+      getExpectedQuery(cubeName, "SELECT distinct testcube.cityid, round(testCube.msr2) from ", null, null,
         getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
 
@@ -379,7 +379,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " round(testCube.msr1) from ", null, null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, round(testCube.msr1) from ", null, null,
         getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
 
@@ -390,7 +390,7 @@ public class TestAggregateResolver extends TestQueryRewrite {
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT distinct testcube.cityid," + " round(testCube.msr1) from ", null, null,
+      getExpectedQuery(cubeName, "SELECT distinct testcube.cityid, round(testCube.msr1) from ", null, null,
         getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
 
@@ -412,14 +412,14 @@ public class TestAggregateResolver extends TestQueryRewrite {
     Assert.assertEquals("testFact2_raw".toLowerCase(), candidateFact.fact.getName().toLowerCase());
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr1) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr1) from ", null,
         "group by testcube.cityid", getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
     query = "SELECT cityid, sum(testCube.msr2) FROM testCube WHERE " + TWO_DAYS_RANGE + " having max(msr1) > 100";
     cubeql = rewriteCtx(query, conf);
     hQL = cubeql.toHQL();
     expectedQL =
-      getExpectedQuery(cubeName, "SELECT testcube.cityid," + " sum(testCube.msr2) from ", null,
+      getExpectedQuery(cubeName, "SELECT testcube.cityid, sum(testCube.msr2) from ", null,
         "group by testcube.cityid having max(testcube.msr1) > 100", getWhereForHourly2days("c1_testfact2_raw"));
     compareQueries(hQL, expectedQL);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/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 053cad3..f6cec1b 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
@@ -34,6 +34,7 @@ import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.lens.api.error.ErrorCollectionFactory;
 import org.apache.lens.cube.error.LensCubeErrorCode;
 import org.apache.lens.cube.error.NoCandidateFactAvailableException;
 import org.apache.lens.cube.metadata.TimeRange;
@@ -86,8 +87,11 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
     LensException e;
 
     e = getLensExceptionInRewrite("select msr11 + msr2 from basecube" + " where " + TWO_DAYS_RANGE, conf);
+    e.buildLensErrorResponse(new ErrorCollectionFactory().createErrorCollection(), null, "testid");
     assertEquals(e.getErrorCode(),
-        LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getLensErrorInfo().getErrorCode());
+      LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo().getErrorCode());
+    assertTrue(e.getMessage().contains("msr11"), e.getMessage());
+    assertTrue(e.getMessage().contains("msr2"), e.getMessage());
     // no fact has the all the dimensions queried
     e = getLensExceptionInRewrite("select dim1, test_time_dim, msr3, msr13 from basecube where "
       + TWO_DAYS_RANGE, conf);
@@ -728,6 +732,115 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
         && hqlQuery.endsWith("mq2 on mq1.booleancut <=> mq2.booleancut"),
       hqlQuery);
   }
+
+  @Test
+  public void testMultiFactQueryCaseWhenExpressionWithChainField() throws Exception {
+    Configuration tconf = new Configuration(conf);
+    String hqlQuery =
+      rewrite("select sum(case when dim22 = 'x' then msr12 else 0 end) as case_expr, sum(msr1) from basecube where "
+          + TWO_DAYS_RANGE, tconf);
+    String expected1 =
+      getExpectedQuery(cubeName, "select sum(case when basecube.dim22 = 'x' then basecube.msr12 else 0 end) as "
+          + "`expr1` FROM ", null, null, getWhereForHourly2days(cubeName, "C1_testfact2_raw_base"));
+    String expected2 =
+      getExpectedQuery(cubeName, "select sum(basecube.msr1) as `expr2` FROM ", null, null,
+        getWhereForHourly2days(cubeName, "c1_testfact1_raw_base"));
+    compareContains(expected1, hqlQuery);
+    compareContains(expected2, hqlQuery);
+    assertTrue(hqlQuery.toLowerCase().startsWith("select mq2.expr1 `case_expr`, mq1.expr2 `sum(msr1)` from ")
+      || hqlQuery.toLowerCase().startsWith("select mq1.expr1 `case_expr`, mq2.expr2 `sum(msr1)` from "), hqlQuery);
+    assertTrue(hqlQuery.contains("mq1 full outer join ") && hqlQuery.endsWith("mq2"), hqlQuery);
+  }
+
+  @Test
+  public void testMultiFactQueryCaseWhenExpression() throws Exception {
+    Configuration tconf = new Configuration(conf);
+    String hqlQuery =
+      rewrite("select sum(case when dim13 = 'x' then msr12 else 0 end) as case_expr, sum(msr1) from basecube where "
+        + TWO_DAYS_RANGE, tconf);
+    String expected1 =
+      getExpectedQuery(cubeName, "select sum(case when basecube.dim13 = 'x' then basecube.msr12 else 0 end) as "
+        + "`expr1` FROM ", null, null, getWhereForHourly2days(cubeName, "C1_testfact2_raw_base"));
+    String expected2 =
+      getExpectedQuery(cubeName, "select sum(basecube.msr1) as `expr2` FROM ", null, null,
+        getWhereForHourly2days(cubeName, "c1_testfact1_raw_base"));
+    compareContains(expected1, hqlQuery);
+    compareContains(expected2, hqlQuery);
+    assertTrue(hqlQuery.toLowerCase().startsWith("select mq2.expr1 `case_expr`, mq1.expr2 `sum(msr1)` from ")
+      || hqlQuery.toLowerCase().startsWith("select mq1.expr1 `case_expr`, mq2.expr2 `sum(msr1)` from "), hqlQuery);
+    assertTrue(hqlQuery.contains("mq1 full outer join ") && hqlQuery.endsWith("mq2"), hqlQuery);
+  }
+
+  @Test
+  public void testMultiFactQueryCaseWhenExpressionWithGroupby() throws Exception {
+    Configuration tconf = new Configuration(conf);
+    String hqlQuery =
+      rewrite("select dim1, sum(case when dim13 = 'x' then msr12 else 0 end) as case_expr, sum(msr1) from basecube "
+        + "where " + TWO_DAYS_RANGE, tconf);
+    String expected1 =
+      getExpectedQuery(cubeName, "select basecube.dim1 as `dim1`, sum(case when basecube.dim13 = 'x' then basecube"
+          + ".msr12 else 0 end) as `expr2` FROM ", null, " group by basecube.dim1 ",
+        getWhereForHourly2days(cubeName, "C1_testfact2_raw_base"));
+    String expected2 =
+      getExpectedQuery(cubeName, "select basecube.dim1 as `dim1`, sum(basecube.msr1) as `expr3` FROM ", null,
+        " group by basecube.dim1 ", getWhereForHourly2days(cubeName, "c1_testfact1_raw_base"));
+    compareContains(expected1, hqlQuery);
+    compareContains(expected2, hqlQuery);
+    assertTrue(hqlQuery.toLowerCase().startsWith(
+      "select coalesce(mq1.dim1, mq2.dim1) dim1, mq2.expr2 `case_expr`, mq1.expr3 `sum(msr1)` from ")
+      || hqlQuery.toLowerCase().startsWith(
+        "select coalesce(mq1.dim1, mq2.dim1) dim1, mq1.expr2 `case_expr`, mq2.expr3 `sum(msr1)` from "), hqlQuery);
+    assertTrue(hqlQuery.contains("mq1 full outer join ") && hqlQuery.endsWith("mq2 on mq1.dim1 <=> mq2.dim1"),
+      hqlQuery);
+  }
+
+  @Test
+  public void testMultiFactQueryCaseWhenExpressionWithHavingClause() throws Exception {
+    Configuration tconf = new Configuration(conf);
+    String hqlQuery =
+      rewrite("select sum(case when dim13 = 'x' then msr12 else 0 end) as case_expr, sum(msr1) from basecube "
+        + "where "
+        + TWO_DAYS_RANGE + " having sum(case when dim13 = 'x' then msr12 else 0 end) > 100 and sum(msr1) > 500", tconf);
+    String expected1 =
+      getExpectedQuery(cubeName, "select sum(case when basecube.dim13 = 'x' then basecube.msr12 else 0 end) as "
+        + "`expr1` FROM ", null, " having sum(case when basecube.dim13 = 'x' then basecube.msr12 else 0 end) > 100",
+        getWhereForHourly2days(cubeName, "C1_testfact2_raw_base"));
+    String expected2 =
+      getExpectedQuery(cubeName, "select sum(basecube.msr1) as `expr2` FROM ", null, " having sum(basecube.msr1) > 500",
+        getWhereForHourly2days(cubeName, "c1_testfact1_raw_base"));
+    compareContains(expected1, hqlQuery);
+    compareContains(expected2, hqlQuery);
+    assertTrue(hqlQuery.toLowerCase().startsWith("select mq2.expr1 `case_expr`, mq1.expr2 `sum(msr1)` from ")
+      || hqlQuery.toLowerCase().startsWith("select mq1.expr1 `case_expr`, mq2.expr2 `sum(msr1)` from "), hqlQuery);
+    assertTrue(hqlQuery.contains("mq1 full outer join ") && hqlQuery.endsWith("mq2"), hqlQuery);
+  }
+
+  @Test
+  public void testMultiFactQueryCaseWhenExpressionWithGroubyAndHavingClause() throws Exception {
+    Configuration tconf = new Configuration(conf);
+    String hqlQuery =
+      rewrite("select dim1, sum(case when dim13 = 'x' then msr12 else 0 end) as case_expr, sum(msr1) from basecube "
+        + "where "
+        + TWO_DAYS_RANGE + " having sum(case when dim13 = 'x' then msr12 else 0 end) > 100 and sum(msr1) > 500", tconf);
+    String expected1 =
+      getExpectedQuery(cubeName, "select basecube.dim1 as `dim1`, sum(case when basecube.dim13 = 'x' then basecube"
+          + ".msr12 else  0 end) as `expr2` FROM ", null,
+        " group by basecube.dim1 having sum(case when basecube.dim13 = 'x' then basecube.msr12 else 0 end) > 100",
+        getWhereForHourly2days(cubeName, "C1_testfact2_raw_base"));
+    String expected2 =
+      getExpectedQuery(cubeName, "select basecube.dim1 as `dim1`, sum(basecube.msr1) as `expr3` FROM ", null,
+        " group by basecube.dim1 having sum(basecube.msr1) > 500",
+        getWhereForHourly2days(cubeName, "c1_testfact1_raw_base"));
+    compareContains(expected1, hqlQuery);
+    compareContains(expected2, hqlQuery);
+    assertTrue(hqlQuery.toLowerCase().startsWith(
+      "select coalesce(mq1.dim1, mq2.dim1) dim1, mq2.expr2 `case_expr`, mq1.expr3 `sum(msr1)` from ")
+      || hqlQuery.toLowerCase().startsWith(
+        "select coalesce(mq1.dim1, mq2.dim1) dim1, mq1.expr2 `case_expr`, mq2.expr3 `sum(msr1)` from "), hqlQuery);
+    assertTrue(hqlQuery.contains("mq1 full outer join ") && hqlQuery.endsWith("mq2 on mq1.dim1 <=> mq2.dim1"),
+      hqlQuery);
+  }
+
   @Test
   public void testFallbackPartCol() throws Exception {
     Configuration conf = getConfWithStorages("C1");


[3/4] lens git commit: LENS-1287: Create command in cli to create schema taking parent directory where schema is stored

Posted by pr...@apache.org.
http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/test-dimension.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/test-dimension.xml b/lens-cli/src/test/resources/test-dimension.xml
deleted file mode 100644
index 01de8e6..0000000
--- a/lens-cli/src/test/resources/test-dimension.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<x_dimension name="test_dim" xmlns="uri:lens:cube:0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
-  <attributes>
-    <dim_attribute name="id" _type="INT" />
-    <dim_attribute name="name" _type="STRING" />
-    <dim_attribute name="detail" _type="STRING" start_time='2013-12-01T00:00:00' />
-    <dim_attribute name="d2id" _type="INT" start_time='2013-12-01T00:00:00'/>
-    <dim_attribute name="inline" _type="STRING" >
-      <values>A</values>
-      <values>B</values>
-      <values>C</values>
-    </dim_attribute>
-    <dim_attribute name="location">
-      <hierarchy>
-        <dim_attribute name="zipcode" _type="INT" />
-        <dim_attribute name="city" _type="STRING" />
-        <dim_attribute name="state" _type="STRING" />
-      </hierarchy>
-    </dim_attribute>
-  </attributes>
-
-  <join_chains>
-    <join_chain name="dim2chain">
-      <paths>
-        <path>
-         <edges>
-            <edge>
-              <from table="test_dim" column="d2id" />
-              <to table="test_detail" column="id" />
-            </edge>
-          </edges>
-        </path>
-      </paths>
-    </join_chain>
-  </join_chains>
-  <properties>
-    <property name="test_dim.prop" value="test" />
-    <property name="dimension.test_dim.timed.dimension" value="dt" />
-  </properties>
-</x_dimension>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/src/site/apt/user/cli.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/user/cli.apt b/src/site/apt/user/cli.apt
index 2522e03..cf9657a 100644
--- a/src/site/apt/user/cli.apt
+++ b/src/site/apt/user/cli.apt
@@ -97,29 +97,29 @@ User CLI Commands
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|add file [--path] \<path-to-file-on-server-side\>|Adds a file resource to session|
+|add file [--path] \<path-to-file-on-server-side\>|Adds a file resource to session\ |
 *--+--+
-|add jar [--path] \<path-to-jar-on-server-side\>|Adds jar resource to the session|
+|add jar [--path] \<path-to-jar-on-server-side\>|Adds jar resource to the session\ |
 *--+--+
-|close/bye|Releases all resources of the server session and exits the shell|
+|close/bye|Releases all resources of the server session and exits the shell\ |
 *--+--+
-|debug [[--enable] ]|prints all class level logs and verbose logs on cli for debugging purpose. 'debug false' to turn off all class level logging and verbose level logging |
+|debug [[--enable] ]|prints all class level logs and verbose logs on cli for debugging purpose. 'debug false' to turn off all class level logging and verbose level logging \ |
 *--+--+
-|get [--key] \<key\>|Fetches and prints session parameter specified with name <<<key>>> from lens server|
+|get [--key] \<key\>|Fetches and prints session parameter specified with name <<<key>>> from lens server\ |
 *--+--+
-|list resources [[--type] \<resource-type\>]|list all resources from session. If type is provided,  lists resources of type <<<resource-type>>>. Valid values for type are jar and file.|
+|list resources [[--type] \<resource-type\>]|list all resources from session. If type is provided,  lists resources of type <<<resource-type>>>. Valid values for type are jar and file.\ |
 *--+--+
-|remove file [--path] \<path-to-file-on-server-side\>|removes a file resource from session|
+|remove file [--path] \<path-to-file-on-server-side\>|removes a file resource from session\ |
 *--+--+
-|remove jar [--path] \<path-to-jar-on-server-side\>|Removes a jar resource from session|
+|remove jar [--path] \<path-to-jar-on-server-side\>|Removes a jar resource from session\ |
 *--+--+
-|session|Print the current session handle|
+|session|Print the current session handle\ |
 *--+--+
-|set \<key\>=\<value\>|Assign <<<value>>> to session parameter specified with <<<key>>> on lens server|
+|set \<key\>=\<value\>|Assign <<<value>>> to session parameter specified with <<<key>>> on lens server\ |
 *--+--+
-|show params|Fetches and prints all session parameter from lens server|
+|show params|Fetches and prints all session parameter from lens server\ |
 *--+--+
-|verbose [[--enable] ]|Show cliLogger logs on cli. 'verbose false'  turns off the cliLogger logs on console|
+|verbose [[--enable] ]|Show cliLogger logs on cli. 'verbose false'  turns off the cliLogger logs on console\ |
 *--+--+
   <<Lens Connection Commands>>
 
@@ -132,13 +132,13 @@ User CLI Commands
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|create database [--db] \<database-name\> [--ignoreIfExists \<ignore-if-exists\>]|create a database with specified name. if <<<ignore-if-exists>>> is true, create will not be tried if already exists. Default is false|
+|create database [--db] \<database-name\> [--ignoreIfExists \<ignore-if-exists\>]|create a database with specified name. if <<<ignore-if-exists>>> is true, create will not be tried if already exists. Default is false\ |
 *--+--+
-|drop database [--db] \<database-name\> [--cascade ]|drop a database with specified name|
+|drop database [--db] \<database-name\> [--cascade ]|drop a database with specified name\ |
 *--+--+
-|show databases|displays list of all databases|
+|show databases|displays list of all databases\ |
 *--+--+
-|use [--db] \<database-name\>|change to new database|
+|use [--db] \<database-name\>|change to new database\ |
 *--+--+
   <<Lens Database Commands>>
 
@@ -151,15 +151,15 @@ User CLI Commands
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|create storage [--path] \<path-to-storage-spec\>|Create a new Storage from file <<<path-to-storage-spec>>>|
+|create storage [--path] \<path-to-storage-spec\>|Create a new Storage from file <<<path-to-storage-spec>>>\ |
 *--+--+
-|describe storage [--name] \<storage-name\>|describe storage <<<storage-name>>>|
+|describe storage [--name] \<storage-name\>|describe storage <<<storage-name>>>\ |
 *--+--+
-|drop storage [--name] \<storage-name\>|drop storage <<<storage-name>>>|
+|drop storage [--name] \<storage-name\>|drop storage <<<storage-name>>>\ |
 *--+--+
-|show storages|list all storages|
+|show storages|list all storages\ |
 *--+--+
-|update storage [--name] \<storage-name\> [--path] \<path-to-storage-spec\>|update storage <<<storage-name>>> with storage spec from <<<path-to-storage-spec>>>|
+|update storage [--name] \<storage-name\> [--path] \<path-to-storage-spec\>|update storage <<<storage-name>>> with storage spec from <<<path-to-storage-spec>>>\ |
 *--+--+
   <<Lens Storage Commands>>
 
@@ -172,21 +172,21 @@ User CLI Commands
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|create cube [--path] \<path-to-cube-spec-file\>|Create a new Cube, taking spec from <<<path-to-cube-spec-file>>>|
+|create cube [--path] \<path-to-cube-spec-file\>|Create a new Cube, taking spec from <<<path-to-cube-spec-file>>>\ |
 *--+--+
-|cube latestdate [--name] \<cube_name\> [--time_dimension] \<time_dimension\>|get latest date of data available in cube <<<cube_name>>> for time dimension <<<time_dimension_name>>>.  Instead of time dimension, partition column can be directly passed as <<<time_dimension>>>|
+|cube latestdate [--name] \<cube_name\> [--time_dimension] \<time_dimension\>|get latest date of data available in cube <<<cube_name>>> for time dimension <<<time_dimension_name>>>.  Instead of time dimension, partition column can be directly passed as <<<time_dimension>>>\ |
 *--+--+
-|cube show fields [--name] \<cube_name\> [--flattened \<flattened\>]|Show queryable fields of the given cube <<<cube_name>>>. Optionally specify <<<flattened>>> to include chained fields|
+|cube show fields [--name] \<cube_name\> [--flattened \<flattened\>]|Show queryable fields of the given cube <<<cube_name>>>. Optionally specify <<<flattened>>> to include chained fields\ |
 *--+--+
-|cube show joinchains [--name] \<cube_name\>|Show joinchains of the given cube <<<cube_name>>>. |
+|cube show joinchains [--name] \<cube_name\>|Show joinchains of the given cube <<<cube_name>>>. \ |
 *--+--+
-|describe cube [--name] \<cube_name\>|describe cube with name <<<cube_name>>>|
+|describe cube [--name] \<cube_name\>|describe cube with name <<<cube_name>>>\ |
 *--+--+
-|drop cube [--name] \<cube_name\>|drop cube <<<cube_name>>>|
+|drop cube [--name] \<cube_name\>|drop cube <<<cube_name>>>\ |
 *--+--+
-|show cubes|show list of cubes in current database|
+|show cubes|show list of cubes in current database\ |
 *--+--+
-|update cube [--name] \<cube_name\> [--path] \<path-to-cube-spec-file\>|update cube <<<cube_name>>> with spec from <<<path-to-cube-spec-file>>>|
+|update cube [--name] \<cube_name\> [--path] \<path-to-cube-spec-file\>|update cube <<<cube_name>>> with spec from <<<path-to-cube-spec-file>>>\ |
 *--+--+
   <<Lens Cube Commands>>
 
@@ -199,19 +199,19 @@ User CLI Commands
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|create dimension [--path] \<path-to-dimension-spec file\>|Create a new Dimension, taking spec from <<<path-to-dimension-spec file>>>|
+|create dimension [--path] \<path-to-dimension-spec file\>|Create a new Dimension, taking spec from <<<path-to-dimension-spec file>>>\ |
 *--+--+
-|describe dimension [--name] \<dimension_name\>|describe dimension <<<dimension_name>>>|
+|describe dimension [--name] \<dimension_name\>|describe dimension <<<dimension_name>>>\ |
 *--+--+
-|dimension show fields [--name] \<dimension_name\> [--flattened \<flattened\>]|Show queryable fields of the given dimension <<<dimension_name>>>. Optionally specify <<<flattened>>> to include chained fields|
+|dimension show fields [--name] \<dimension_name\> [--flattened \<flattened\>]|Show queryable fields of the given dimension <<<dimension_name>>>. Optionally specify <<<flattened>>> to include chained fields\ |
 *--+--+
-|dimension show joinchains [--name] \<dimension_name\>|Show joinchains of the given dimension <<<dimension_name>>>. |
+|dimension show joinchains [--name] \<dimension_name\>|Show joinchains of the given dimension <<<dimension_name>>>. \ |
 *--+--+
-|drop dimension [--name] \<dimension_name\>|drop dimension <<<dimension_name>>>|
+|drop dimension [--name] \<dimension_name\>|drop dimension <<<dimension_name>>>\ |
 *--+--+
-|show dimensions|show list of all dimensions in current database|
+|show dimensions|show list of all dimensions in current database\ |
 *--+--+
-|update dimension [--name] \<dimension_name\> [--path] \<path-to-dimension-spec-file\>|update dimension <<<dimension_name>>>, taking spec from <<<path-to-dimension-spec file>>>|
+|update dimension [--name] \<dimension_name\> [--path] \<path-to-dimension-spec-file\>|update dimension <<<dimension_name>>>, taking spec from <<<path-to-dimension-spec file>>>\ |
 *--+--+
   <<Lens Dimension Commands>>
 
@@ -224,39 +224,39 @@ User CLI Commands
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|create fact [--path] \<path-to-fact-spec-file\>|create a fact table with spec from <<<path-to-fact-spec-file>>>|
+|create fact [--path] \<path-to-fact-spec-file\>|create a fact table with spec from <<<path-to-fact-spec-file>>>\ |
 *--+--+
-|describe fact [--fact_name] \<fact_name\>|describe fact <<<fact_name>>>|
+|describe fact [--fact_name] \<fact_name\>|describe fact <<<fact_name>>>\ |
 *--+--+
-|drop fact [--fact_name] \<fact_name\> [--cascade \<cascade\>]|drops fact <<<fact_name>>>. If <<<cascade>>> is true, all the storage tables associated with the fact <<<fact_name>>> are also dropped. By default <<<cascade>>> is false|
+|drop fact [--fact_name] \<fact_name\> [--cascade \<cascade\>]|drops fact <<<fact_name>>>. If <<<cascade>>> is true, all the storage tables associated with the fact <<<fact_name>>> are also dropped. By default <<<cascade>>> is false\ |
 *--+--+
-|fact add partitions [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [--path] \<partition-list-spec-path\>|add multiple partition to fact <<<fact_name>>>'s storage <<<storage_name>>>, reading partition list spec from <<<partition-list-spec-path>>>|
+|fact add partitions [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [--path] \<partition-list-spec-path\>|add multiple partition to fact <<<fact_name>>>'s storage <<<storage_name>>>, reading partition list spec from <<<partition-list-spec-path>>>\ |
 *--+--+
-|fact add single-partition [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [--path] \<partition-spec-path\>|add single partition to fact <<<fact_name>>>'s storage <<<storage_name>>>, reading spec from <<<partition-spec-path>>>|
+|fact add single-partition [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [--path] \<partition-spec-path\>|add single partition to fact <<<fact_name>>>'s storage <<<storage_name>>>, reading spec from <<<partition-spec-path>>>\ |
 *--+--+
-|fact add storage [--fact_name] \<fact_name\> [--path] \<path-to-storage-spec\>|adds a new storage to fact <<<fact_name>>>, taking storage spec from <<<path-to-storage-spec>>>|
+|fact add storage [--fact_name] \<fact_name\> [--path] \<path-to-storage-spec\>|adds a new storage to fact <<<fact_name>>>, taking storage spec from <<<path-to-storage-spec>>>\ |
 *--+--+
-|fact drop all storages [--fact_name] \<fact_name\>|drop all storages associated to fact <<<fact_name>>>|
+|fact drop all storages [--fact_name] \<fact_name\>|drop all storages associated to fact <<<fact_name>>>\ |
 *--+--+
-|fact drop partitions [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [[--filter] \<partition-filter\>]|drop all partitions associated with fact <<<fact_name>>>, storage <<<storage_name>>> filtered by <<<partition-filter>>>|
+|fact drop partitions [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [[--filter] \<partition-filter\>]|drop all partitions associated with fact <<<fact_name>>>, storage <<<storage_name>>> filtered by <<<partition-filter>>>\ |
 *--+--+
-|fact drop storage [--fact_name] \<fact_name\> [--storage_name] \<storage_name\>|drop storage <<<storage_name>>> from fact <<<fact_name>>>|
+|fact drop storage [--fact_name] \<fact_name\> [--storage_name] \<storage_name\>|drop storage <<<storage_name>>> from fact <<<fact_name>>>\ |
 *--+--+
-|fact get storage [--fact_name] \<fact_name\> [--storage_name] \<path-to-storage-spec\>|describe storage <<<storage_name>>> of fact <<<fact_name>>>|
+|fact get storage [--fact_name] \<fact_name\> [--storage_name] \<path-to-storage-spec\>|describe storage <<<storage_name>>> of fact <<<fact_name>>>\ |
 *--+--+
-|fact list partitions [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [[--filter] \<partition-filter\>]|get all partitions associated with fact <<<fact_name>>>, storage <<<storage_name>>> filtered by <<<partition-filter>>>|
+|fact list partitions [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [[--filter] \<partition-filter\>]|get all partitions associated with fact <<<fact_name>>>, storage <<<storage_name>>> filtered by <<<partition-filter>>>\ |
 *--+--+
-|fact list storage [--fact_name] \<fact_name\>|display list of storages associated to fact <<<fact_name>>>|
+|fact list storage [--fact_name] \<fact_name\>|display list of storages associated to fact <<<fact_name>>>\ |
 *--+--+
-|fact timelines [--fact_name] \<fact_name\> [--storage_name \<storage_name\>] [--update_period \<update_period\>] [--time_dimension \<time_dimension\>]|get timelines for fact. Can optionally specify storage, update period and time dimension to filter by. Instead of time dimension, partition column can be directly passed as <<<time_dimension>>>|
+|fact timelines [--fact_name] \<fact_name\> [--storage_name \<storage_name\>] [--update_period \<update_period\>] [--time_dimension \<time_dimension\>]|get timelines for fact. Can optionally specify storage, update period and time dimension to filter by. Instead of time dimension, partition column can be directly passed as <<<time_dimension>>>\ |
 *--+--+
-|fact update partitions [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [--path] \<partition-list-spec-path\>|update multiple partition of fact <<<fact_name>>>'s storage <<<storage_name>>>, reading partition list spec from <<<partition-list-spec-path>>> The partitions have to exist to be eligible for updation.|
+|fact update partitions [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [--path] \<partition-list-spec-path\>|update multiple partition of fact <<<fact_name>>>'s storage <<<storage_name>>>, reading partition list spec from <<<partition-list-spec-path>>> The partitions have to exist to be eligible for updation.\ |
 *--+--+
-|fact update single-partition [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [--path] \<partition-spec-path\>|update single partition to fact <<<fact_name>>>'s storage <<<storage_name>>>, reading spec from <<<partition-spec-path>>> The partition has to exist to be eligible for updation.|
+|fact update single-partition [--fact_name] \<fact_name\> [--storage_name] \<storage_name\> [--path] \<partition-spec-path\>|update single partition to fact <<<fact_name>>>'s storage <<<storage_name>>>, reading spec from <<<partition-spec-path>>> The partition has to exist to be eligible for updation.\ |
 *--+--+
-|show facts [[--cube_name] \<cube_name\>]|display list of fact tables in current database. If optional <<<cube_name>>> is supplied, only facts belonging to cube <<<cube_name>>> will be displayed|
+|show facts [[--cube_name] \<cube_name\>]|display list of fact tables in current database. If optional <<<cube_name>>> is supplied, only facts belonging to cube <<<cube_name>>> will be displayed\ |
 *--+--+
-|update fact [--fact_name] \<fact_name\> [--path] \<path-to-fact-spec\>|update fact <<<fact_name>>> taking spec from <<<path-to-fact-spec>>>|
+|update fact [--fact_name] \<fact_name\> [--path] \<path-to-fact-spec\>|update fact <<<fact_name>>> taking spec from <<<path-to-fact-spec>>>\ |
 *--+--+
   <<Lens Fact Commands>>
 
@@ -269,37 +269,37 @@ User CLI Commands
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|create dimtable [--path] \<path-to-dimtable-spec-file\>|Create a new dimension table taking spec from <<<path-to-dimtable-spec-file>>>|
+|create dimtable [--path] \<path-to-dimtable-spec-file\>|Create a new dimension table taking spec from <<<path-to-dimtable-spec-file>>>\ |
 *--+--+
-|describe dimtable [--dimtable_name] \<dimtable_name\>|describe dimtable <<<dimtable_name>>>|
+|describe dimtable [--dimtable_name] \<dimtable_name\>|describe dimtable <<<dimtable_name>>>\ |
 *--+--+
-|dimtable add partitions [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [--path] \<partition-list-spec-path\>|add multiple partition to dimtable <<<dimtable_name>>>'s storage <<<storage_name>>>, reading partition list spec from <<<partition-list-spec-path>>>|
+|dimtable add partitions [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [--path] \<partition-list-spec-path\>|add multiple partition to dimtable <<<dimtable_name>>>'s storage <<<storage_name>>>, reading partition list spec from <<<partition-list-spec-path>>>\ |
 *--+--+
-|dimtable add single-partition [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [--path] \<partition-spec-path\>|add single partition to dimtable <<<dimtable_name>>>'s storage <<<storage_name>>>, reading spec from <<<partition-spec-path>>>|
+|dimtable add single-partition [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [--path] \<partition-spec-path\>|add single partition to dimtable <<<dimtable_name>>>'s storage <<<storage_name>>>, reading spec from <<<partition-spec-path>>>\ |
 *--+--+
-|dimtable add storage [--dimtable_name] \<dimtable_name\> [--path] \<path-to-storage-spec\>|adds a new storage to dimtable <<<dimtable_name>>>, taking storage spec from <<<path-to-storage-spec>>>|
+|dimtable add storage [--dimtable_name] \<dimtable_name\> [--path] \<path-to-storage-spec\>|adds a new storage to dimtable <<<dimtable_name>>>, taking storage spec from <<<path-to-storage-spec>>>\ |
 *--+--+
-|dimtable drop all storages [--dimtable_name] \<dimtable_name\>|drop all storages associated to dimension table|
+|dimtable drop all storages [--dimtable_name] \<dimtable_name\>|drop all storages associated to dimension table\ |
 *--+--+
-|dimtable drop partitions [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [[--filter] \<partition-filter\>]|drop all partitions associated with dimtable <<<dimtable_name>>>, storage <<<storage_name>>> filtered by <<<partition-filter>>>|
+|dimtable drop partitions [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [[--filter] \<partition-filter\>]|drop all partitions associated with dimtable <<<dimtable_name>>>, storage <<<storage_name>>> filtered by <<<partition-filter>>>\ |
 *--+--+
-|dimtable drop storage [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\>|drop storage <<<storage_name>>> from dimtable <<<dimtable_name>>>|
+|dimtable drop storage [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\>|drop storage <<<storage_name>>> from dimtable <<<dimtable_name>>>\ |
 *--+--+
-|dimtable get storage [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\>|describe storage <<<storage_name>>> of dimtable <<<dimtable_name>>>|
+|dimtable get storage [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\>|describe storage <<<storage_name>>> of dimtable <<<dimtable_name>>>\ |
 *--+--+
-|dimtable list partitions [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [[--filter] \<partition-filter\>]|get all partitions associated with dimtable <<<dimtable_name>>>, storage <<<storage_name>>> filtered by <<<partition-filter>>>|
+|dimtable list partitions [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [[--filter] \<partition-filter\>]|get all partitions associated with dimtable <<<dimtable_name>>>, storage <<<storage_name>>> filtered by <<<partition-filter>>>\ |
 *--+--+
-|dimtable list storages [--dimtable_name] \<dimtable_name\>|display list of storage associated to dimtable <<<dimtable_name>>>|
+|dimtable list storages [--dimtable_name] \<dimtable_name\>|display list of storage associated to dimtable <<<dimtable_name>>>\ |
 *--+--+
-|dimtable update partitions [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [--path] \<partition-list-spec-path\>|update multiple partition to dimtable <<<dimtable_name>>>'s storage <<<storage_name>>>, reading partition list spec from <<<partition-list-spec-path>>> The partitions have to exist to be eligible for updation.|
+|dimtable update partitions [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [--path] \<partition-list-spec-path\>|update multiple partition to dimtable <<<dimtable_name>>>'s storage <<<storage_name>>>, reading partition list spec from <<<partition-list-spec-path>>> The partitions have to exist to be eligible for updation.\ |
 *--+--+
-|dimtable update single-partition [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [--path] \<partition-spec-path\>|update single partition to dimtable <<<dimtable_name>>>'s storage <<<storage_name>>>, reading spec from <<<partition-spec-path>>> The partition has to exist to be eligible for updation.|
+|dimtable update single-partition [--dimtable_name] \<dimtable_name\> [--storage_name] \<storage_name\> [--path] \<partition-spec-path\>|update single partition to dimtable <<<dimtable_name>>>'s storage <<<storage_name>>>, reading spec from <<<partition-spec-path>>> The partition has to exist to be eligible for updation.\ |
 *--+--+
-|drop dimtable [--dimtable_name] \<dimtable_name\> [--cascade \<cascade\>]|drop dimtable <<<dimtable_name>>>.  If <<<cascade>>> is true, all the storage tables associated with the dimtable <<<dimtable_name>>> are also dropped. By default <<<cascade>>> is false|
+|drop dimtable [--dimtable_name] \<dimtable_name\> [--cascade \<cascade\>]|drop dimtable <<<dimtable_name>>>.  If <<<cascade>>> is true, all the storage tables associated with the dimtable <<<dimtable_name>>> are also dropped. By default <<<cascade>>> is false\ |
 *--+--+
-|show dimtables [[--dimension_name] \<dimension_name\>]|display list of dimtables in current database. If optional <<<dimension_name>>> is supplied, only facts belonging to dimension <<<dimension_name>>> will be displayed|
+|show dimtables [[--dimension_name] \<dimension_name\>]|display list of dimtables in current database. If optional <<<dimension_name>>> is supplied, only facts belonging to dimension <<<dimension_name>>> will be displayed\ |
 *--+--+
-|update dimtable [--dimtable_name] \<dimtable_name\> [--path] \<path-to-dimtable-spec\>|update dimtable <<<dimtable_name>>> taking spec from <<<path-to-dimtable-spec>>>|
+|update dimtable [--dimtable_name] \<dimtable_name\> [--path] \<path-to-dimtable-spec\>|update dimtable <<<dimtable_name>>> taking spec from <<<path-to-dimtable-spec>>>\ |
 *--+--+
   <<Lens Dimension Table Commands>>
 
@@ -312,9 +312,9 @@ User CLI Commands
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|describe nativetable [--name] \<native-table-name\>|describe nativetable named <<<native-table-name>>>|
+|describe nativetable [--name] \<native-table-name\>|describe nativetable named <<<native-table-name>>>\ |
 *--+--+
-|show nativetables|show list of native tables belonging to current database|
+|show nativetables|show list of native tables belonging to current database\ |
 *--+--+
   <<Lens Native Table Commands>>
 
@@ -335,35 +335,35 @@ User CLI Commands
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|cube select \<query-string-without-cube-select\> [--async \<async\>] [--name \<query-name\>]|Execute cube query <<<cube select query-string-without-cube-select>>>. If <<<async>>> is true, The query is launched in async manner and query handle is returned. It's by default false. <<<query name>>> can also be provided, though not required.|
+|cube select \<query-string-without-cube-select\> [--async \<async\>] [--name \<query-name\>]|Execute cube query <<<cube select query-string-without-cube-select>>>. If <<<async>>> is true, The query is launched in async manner and query handle is returned. It's by default false. <<<query name>>> can also be provided, though not required.\ |
 *--+--+
-|prepQuery destroy [--prepare_handle] \<prepare_handle\>|Destroy prepared query with handle <<<prepare_handle>>>|
+|prepQuery destroy [--prepare_handle] \<prepare_handle\>|Destroy prepared query with handle <<<prepare_handle>>>\ |
 *--+--+
-|prepQuery details [--prepare_handle] \<prepare_handle\>|Get prepared query with handle <<<prepare_handle>>>|
+|prepQuery details [--prepare_handle] \<prepare_handle\>|Get prepared query with handle <<<prepare_handle>>>\ |
 *--+--+
-|prepQuery execute [--prepare_handle] Prepare handle to execute [--async \<async\>] [--name \<query-name\>]|Execute prepared query with handle <<<prepare_handle>>>. If <<<async>>> is supplied and is true, query is run in async manner and query handle is returned immediately. Optionally, <<<query-name>>> can be provided, though not required.|
+|prepQuery execute [--prepare_handle] Prepare handle to execute [--async \<async\>] [--name \<query-name\>]|Execute prepared query with handle <<<prepare_handle>>>. If <<<async>>> is supplied and is true, query is run in async manner and query handle is returned immediately. Optionally, <<<query-name>>> can be provided, though not required.\ |
 *--+--+
-|prepQuery explain [--query] \<query-string\> [--name \<query-name\>]|Explain and prepare query <<<query-string>>>. Can optionally provide <<<query-name>>>|
+|prepQuery explain [--query] \<query-string\> [--name \<query-name\>]|Explain and prepare query <<<query-string>>>. Can optionally provide <<<query-name>>>\ |
 *--+--+
-|prepQuery list [--name \<query-name\>] [--user \<user-who-submitted-query\>] [--fromDate \<submission-time-is-after\>] [--toDate \<submission-time-is-before\>]|Get all prepared queries. Various filters can be provided(optionally) as can be seen from command syntax|
+|prepQuery list [--name \<query-name\>] [--user \<user-who-submitted-query\>] [--fromDate \<submission-time-is-after\>] [--toDate \<submission-time-is-before\>]|Get all prepared queries. Various filters can be provided(optionally) as can be seen from command syntax\ |
 *--+--+
-|prepQuery prepare [--query] \<query-string\> [--name \<query-name\>]|Prepapre query <<<query-string>>> and return prepare handle. Can optionaly provide <<<query-name>>>|
+|prepQuery prepare [--query] \<query-string\> [--name \<query-name\>]|Prepapre query <<<query-string>>> and return prepare handle. Can optionaly provide <<<query-name>>>\ |
 *--+--+
-|query details [[--query_handle] \<query_handle\>]|Get query details of query with handle <<<query_handle>>>.If not provided, takes last query handle interacted with.|
+|query details [[--query_handle] \<query_handle\>]|Get query details of query with handle <<<query_handle>>>.If not provided, takes last query handle interacted with.\ |
 *--+--+
-|query execute [--query] \<query-string\> [--async \<async\>] [--name \<query-name\>]|Execute query <<<query-string>>>. If <<<async>>> is true, The query is launched in async manner and query handle is returned. It's by default false. <<<query name>>> can also be provided, though not required.|
+|query execute [--query] \<query-string\> [--async \<async\>] [--name \<query-name\>]|Execute query <<<query-string>>>. If <<<async>>> is true, The query is launched in async manner and query handle is returned. It's by default false. <<<query name>>> can also be provided, though not required.\ |
 *--+--+
-|query explain [--query] \<query-string\> [--save_location \<save_location\>]|Explain execution plan of query <<<query-string>>>. Can optionally save the plan to a file by providing <<<save_location>>>|
+|query explain [--query] \<query-string\> [--save_location \<save_location\>]|Explain execution plan of query <<<query-string>>>. Can optionally save the plan to a file by providing <<<save_location>>>\ |
 *--+--+
-|query kill [[--query_handle] \<query_handle\>]|Kill query with handle <<<query_handle>>>.If not provided, takes last query handle interacted with.|
+|query kill [[--query_handle] \<query_handle\>]|Kill query with handle <<<query_handle>>>.If not provided, takes last query handle interacted with.\ |
 *--+--+
-|query list [--state \<query-status\>] [--name \<query-name\>] [--user \<user-who-submitted-query\>] [--driver \<driver-where-query-ran\>] [--fromDate \<submission-time-is-after\>] [--toDate \<submission-time-is-before\>]|Get all queries. Various filter options can be provided(optionally),  as can be seen from the command syntax|
+|query list [--state \<query-status\>] [--name \<query-name\>] [--user \<user-who-submitted-query\>] [--driver \<driver-where-query-ran\>] [--fromDate \<submission-time-is-after\>] [--toDate \<submission-time-is-before\>]|Get all queries. Various filter options can be provided(optionally),  as can be seen from the command syntax\ |
 *--+--+
-|query results [[--query_handle] \<query_handle\>] [--save_location \<save_location\>] [--async \<async\>]|get results of query with query handle <<<query_handle>>>. If not provided, takes last query handle interacted with.If async is false then wait till the query execution is completed, it's by default true. Can optionally save the results to a file by providing <<<save_location>>>.|
+|query results [[--query_handle] \<query_handle\>] [--save_location \<save_location\>] [--async \<async\>]|get results of query with query handle <<<query_handle>>>. If not provided, takes last query handle interacted with.If async is false then wait till the query execution is completed, it's by default true. Can optionally save the results to a file by providing <<<save_location>>>.\ |
 *--+--+
-|query status [[--query_handle] \<query_handle\>]|Fetch status of executed query having query handle <<<query_handle>>>. If not provided, takes last query handle interacted with.|
+|query status [[--query_handle] \<query_handle\>]|Fetch status of executed query having query handle <<<query_handle>>>. If not provided, takes last query handle interacted with.\ |
 *--+--+
-|select \<query-string-without-select\> [--async \<async\>] [--name \<query-name\>]|Execute query <<<select query-string-without-select>>>. If <<<async>>> is true, The query is launched in async manner and query handle is returned. It's by default false. <<<query name>>> can also be provided, though not required.|
+|select \<query-string-without-select\> [--async \<async\>] [--name \<query-name\>]|Execute query <<<select query-string-without-select>>>. If <<<async>>> is true, The query is launched in async manner and query handle is returned. It's by default false. <<<query name>>> can also be provided, though not required.\ |
 *--+--+
   <<Lens Query Commands>>
 
@@ -376,9 +376,63 @@ User CLI Commands
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|show logs [[--log_handle] \<log_handle\>] [--save_location \<save_location\>]|show logs for the given handle <<<log_handle>>>. Handle can either be a query handle or request id. If not provided, takes last query handle interacted with. You can optionally provide a location to save the logs as <<<save_location>>>|
+|show logs [[--log_handle] \<log_handle\>] [--save_location \<save_location\>]|show logs for the given handle <<<log_handle>>>. Handle can either be a query handle or request id. If not provided, takes last query handle interacted with. You can optionally provide a location to save the logs as <<<save_location>>>\ |
 *--+--+
   <<Lens Log Resource Commands>>
 
 ===
 
+** Creating schema with one command
+
+  
+
+*--+--+
+|<<Command>>|<<Description>>|
+*--+--+
+|schema [--db] \<database-to-create-schema-in\> [--file] \<schema-directory\>|Parses the specified resource file and executes commands for creation/updation of schema                                       \ |
+|                                                                            |Expected\ structure\ is\                                                                                                       \ |
+|                                                                            |.                                                                                                                              \ |
+|                                                                            |\|--\ storages                                                                                                                 \ |
+|                                                                            |\|\ \ \|--\ storage1.xml                                                                                                       \ |
+|                                                                            |\|\ \ \|--\ storage2.xml                                                                                                       \ |
+|                                                                            |\|                                                                                                                             \ |
+|                                                                            |\|--\ dimensions                                                                                                               \ |
+|                                                                            |\|\ \ \|--\ dim1.xml                                                                                                           \ |
+|                                                                            |\|\ \ \|--\ dim2.xml                                                                                                           \ |
+|                                                                            |\|                                                                                                                             \ |
+|                                                                            |\|--\ cubes                                                                                                                    \ |
+|                                                                            |\|\ \ \|--\ base                                                                                                               \ |
+|                                                                            |\|\ \ \|\ \ \|--\ base_cube1.xml                                                                                               \ |
+|                                                                            |\|\ \ \|\ \ \|--\ base_cube2.xml                                                                                               \ |
+|                                                                            |\|\ \ \|                                                                                                                       \ |
+|                                                                            |\|\ \ \|--\ derived                                                                                                            \ |
+|                                                                            |\|\ \ \|\ \ \|--\ derived_cube1.xml                                                                                            \ |
+|                                                                            |\|\ \ \|\ \ \|--\ derived_cube2.xml                                                                                            \ |
+|                                                                            |\|\ \ \|                                                                                                                       \ |
+|                                                                            |\|\ \ \|--\ independent_cube1.xml                                                                                              \ |
+|                                                                            |\|\ \ \|--\ independent_cube2.xml                                                                                              \ |
+|                                                                            |\|                                                                                                                             \ |
+|                                                                            |\|--\ dimensiontables                                                                                                          \ |
+|                                                                            |\|\ \ \|--\ dimtable1.xml                                                                                                      \ |
+|                                                                            |\|\ \ \|--\ dimtable2.xml                                                                                                      \ |
+|                                                                            |\|                                                                                                                             \ |
+|                                                                            |\|--\ dimtables                                                                                                                \ |
+|                                                                            |\|\ \ \|--\ dimtable3.xml                                                                                                      \ |
+|                                                                            |\|\ \ \|--\ dimtable4.xml                                                                                                      \ |
+|                                                                            |\|                                                                                                                             \ |
+|                                                                            |\|--\ facts                                                                                                                    \ |
+|                                                                            |\ \ \ \|--\ fact1.xml                                                                                                          \ |
+|                                                                            |\ \ \ \|--\ fact2.xml                                                                                                          \ |
+|                                                                            |                                                                                                                               \ |
+|                                                                            |                                                                                                                               \ |
+|                                                                            |If\ your\ cubes\ are\ divided\ between\ base\ and\ derived\ cubes,                                                             \ |
+|                                                                            |it\ makes\ sense\ to\ seperate\ into\ two\ directories,\ since\ derived\ cubes\ can't\ be\ created\ unless\ base\ cube\ exists.\ |
+|                                                                            |In\ the\ other\ case\ you\ can\ keep\ them\ in\ the\ cubes\ directory\ itself.                                                 \ |
+|                                                                            |For\ dimtables,\ you\ can\ keep\ your\ schema\ files\ in\ a\ directory\ named\ either\ dimtables\ or\ dimensiontables.         \ |
+|                                                                            |Each\ of\ these\ directories\ is\ optional\ and\ the\ order\ of\ processing\ is\ top\ to\ bottom.                              \ |
+|                                                                            |CLI\ will\ let\ you\ know\ in\ case\ of\ any\ errors\ and\ proceed\ further\ without\ failing\ in\ between.                    \ |
+*--+--+
+  <<Lens Schema Commands>>
+
+===
+


[2/4] lens git commit: LENS-1273 : Resolve issues with case when aggregate expressions with dim-attributes conditions

Posted by pr...@apache.org.
LENS-1273 : Resolve issues with case when aggregate expressions with dim-attributes conditions


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

Branch: refs/heads/master
Commit: 2cfb7b097c5367f21779f3c27bc347a9ff536de1
Parents: 9ef7ce7
Author: Amareshwari Sriramadasu <am...@gmail.com>
Authored: Mon Oct 10 15:09:13 2016 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Mon Oct 10 15:09:13 2016 +0530

----------------------------------------------------------------------
 .../lens/cube/parse/AggregateResolver.java      |  24 ---
 .../apache/lens/cube/parse/AliasReplacer.java   |  75 ++++----
 .../apache/lens/cube/parse/CandidateFact.java   |   2 +-
 .../lens/cube/parse/CandidateTableResolver.java | 161 +++++++++-------
 .../apache/lens/cube/parse/ColumnResolver.java  | 110 +++++++----
 .../lens/cube/parse/CubeQueryContext.java       | 123 ++++--------
 .../cube/parse/DenormalizationResolver.java     |   4 +-
 .../lens/cube/parse/ExpressionResolver.java     |  16 +-
 .../apache/lens/cube/parse/GroupbyResolver.java | 111 +++--------
 .../lens/cube/parse/MultiFactHQLContext.java    |   9 +-
 .../lens/cube/parse/QueriedPhraseContext.java   | 186 +++++++++++++++++++
 .../lens/cube/parse/SelectPhraseContext.java    |  51 +++++
 .../lens/cube/parse/TimeRangeChecker.java       |   4 +-
 .../lens/cube/parse/TrackQueriedColumns.java    |  29 ++-
 .../lens/cube/parse/TrackQueriedCubeFields.java |  66 +++++++
 .../lens/cube/parse/TracksQueriedColumns.java   |  59 ++++++
 .../apache/lens/cube/parse/CubeTestSetup.java   |   3 +
 .../lens/cube/parse/TestAggregateResolver.java  |  62 +++----
 .../lens/cube/parse/TestBaseCubeQueries.java    | 115 +++++++++++-
 19 files changed, 821 insertions(+), 389 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
index 292868a..c522061 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
@@ -159,15 +159,6 @@ class AggregateResolver implements ContextRewriter {
         if (wrapped != node) {
           if (parent != null) {
             parent.setChild(nodePos, wrapped);
-            // Check if this node has an alias
-            ASTNode sibling = HQLParser.findNodeByPath(parent, Identifier);
-            String expr;
-            if (sibling != null) {
-              expr = HQLParser.getString(parent);
-            } else {
-              expr = HQLParser.getString(wrapped);
-            }
-            cubeql.addAggregateExpr(expr.trim());
           } else {
             return wrapped;
           }
@@ -342,19 +333,4 @@ class AggregateResolver implements ContextRewriter {
 
     return false;
   }
-
-  static void updateAggregates(ASTNode root, CubeQueryContext cubeql) {
-    if (root == null) {
-      return;
-    }
-
-    if (HQLParser.isAggregateAST(root)) {
-      cubeql.addAggregateExpr(HQLParser.getString(root).trim());
-    } else {
-      for (int i = 0; i < root.getChildCount(); i++) {
-        ASTNode child = (ASTNode) root.getChild(i);
-        updateAggregates(child, cubeql);
-      }
-    }
-  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
index 5b48ca4..da34242 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
@@ -18,10 +18,6 @@
  */
 package org.apache.lens.cube.parse;
 
-import static org.apache.hadoop.hive.ql.parse.HiveParser.Identifier;
-import static org.apache.hadoop.hive.ql.parse.HiveParser.TOK_SELEXPR;
-
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -54,7 +50,11 @@ class AliasReplacer implements ContextRewriter {
     Map<String, String> colToTableAlias = cubeql.getColToTableAlias();
 
     extractTabAliasForCol(cubeql);
-    findDimAttributesAndMeasures(cubeql);
+    // Resolve aliases in all queried phrases
+    for (QueriedPhraseContext qur : cubeql.getQueriedPhrases()) {
+      extractTabAliasForCol(colToTableAlias, qur);
+    }
+    findExpressionsAndMeasures(cubeql);
 
     if (colToTableAlias.isEmpty()) {
       return;
@@ -83,11 +83,6 @@ class AliasReplacer implements ContextRewriter {
 
     replaceAliases(cubeql.getJoinAST(), 0, colToTableAlias);
 
-    // Update the aggregate expression set
-    AggregateResolver.updateAggregates(cubeql.getSelectAST(), cubeql);
-    AggregateResolver.updateAggregates(cubeql.getHavingAST(), cubeql);
-    // Update alias map as well
-    updateAliasMap(cubeql.getSelectAST(), cubeql);
   }
 
   /**
@@ -95,27 +90,26 @@ class AliasReplacer implements ContextRewriter {
    * @param cubeql
    * @throws LensException
    */
-  private void findDimAttributesAndMeasures(CubeQueryContext cubeql) throws LensException {
+  private void findExpressionsAndMeasures(CubeQueryContext cubeql) throws LensException {
     CubeInterface cube = cubeql.getCube();
     if (cube != null) {
-      Set<String> cubeColsQueried = cubeql.getColumnsQueried(cube.getName());
-      Set<String> queriedDimAttrs = new HashSet<String>();
-      Set<String> queriedMsrs = new HashSet<String>();
-      Set<String> queriedExprs = new HashSet<String>();
-      if (cubeColsQueried != null && !cubeColsQueried.isEmpty()) {
-        for (String col : cubeColsQueried) {
-          if (cube.getMeasureNames().contains(col)) {
-            queriedMsrs.add(col);
-          } else if (cube.getDimAttributeNames().contains(col)) {
-            queriedDimAttrs.add(col);
-          } else if (cube.getExpressionNames().contains(col)) {
-            queriedExprs.add(col);
+      String cubeAlias = cubeql.getAliasForTableName(cube.getName());
+      for (QueriedPhraseContext qur : cubeql.getQueriedPhrases()) {
+        Set<String> cubeColsQueried = qur.getColumnsQueried(cubeAlias);
+        if (cubeColsQueried != null && !cubeColsQueried.isEmpty()) {
+          for (String col : cubeColsQueried) {
+            if (cube.getMeasureNames().contains(col)) {
+              qur.addQueriedMsr(col);
+            } else if (cube.getDimAttributeNames().contains(col)) {
+              qur.addQueriedDimAttr(col);
+            } else if (cube.getExpressionNames().contains(col)) {
+              qur.addQueriedExprColumn(col);
+            }
           }
         }
+        cubeql.addQueriedMsrs(qur.getQueriedMsrs());
+        cubeql.addQueriedExprs(qur.getQueriedExprColumns());
       }
-      cubeql.addQueriedDimAttrs(queriedDimAttrs);
-      cubeql.addQueriedMsrs(queriedMsrs);
-      cubeql.addQueriedExprs(queriedExprs);
     }
   }
 
@@ -164,6 +158,18 @@ class AliasReplacer implements ContextRewriter {
     }
   }
 
+  static void extractTabAliasForCol(Map<String, String> colToTableAlias, TrackQueriedColumns tqc) throws LensException {
+    Set<String> columns = tqc.getTblAliasToColumns().get(CubeQueryContext.DEFAULT_TABLE);
+    if (columns == null) {
+      return;
+    }
+    for (String col : columns) {
+      tqc.addColumnsQueried(colToTableAlias.get(col.toLowerCase()), col.toLowerCase());
+      if (colToTableAlias.get(col.toLowerCase()) == null) {
+        throw new LensException(LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo(), col);
+      }
+    }
+  }
   static ASTNode replaceAliases(ASTNode node, int nodePos, Map<String, String> colToTableAlias) {
     if (node == null) {
       return node;
@@ -213,21 +219,4 @@ class AliasReplacer implements ContextRewriter {
     return node;
   }
 
-  static void updateAliasMap(ASTNode root, CubeQueryContext cubeql) {
-    if (root == null) {
-      return;
-    }
-
-    if (root.getToken().getType() == TOK_SELEXPR) {
-      ASTNode alias = HQLParser.findNodeByPath(root, Identifier);
-      if (alias != null) {
-        cubeql.addExprToAlias(root, alias);
-      }
-    } else {
-      for (int i = 0; i < root.getChildCount(); i++) {
-        updateAliasMap((ASTNode) root.getChild(i), cubeql);
-      }
-    }
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/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 01265a5..5dc9dc9 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
@@ -193,7 +193,7 @@ public class CandidateFact implements CandidateTable, QueryAST {
           dimFieldIndices.add(i);
         }
         ASTNode aliasNode = HQLParser.findNodeByPath(selectExpr, Identifier);
-        String alias = cubeql.getSelectAlias(i);
+        String alias = cubeql.getSelectPhrases().get(i).getSelectAlias();
         if (aliasNode != null) {
           String queryAlias = aliasNode.getText();
           if (!queryAlias.equals(alias)) {

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
index 83e5088..510bd8c 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
@@ -52,7 +52,7 @@ class CandidateTableResolver implements ContextRewriter {
 
   private boolean checkForQueriedColumns = true;
 
-  public CandidateTableResolver(Configuration conf) {
+  public CandidateTableResolver(Configuration ignored) {
   }
 
   @Override
@@ -233,10 +233,17 @@ class CandidateTableResolver implements ContextRewriter {
       String str = cubeql.getConf().get(CubeQueryConfUtil.getValidFactTablesKey(cubeql.getCube().getName()));
       List<String> validFactTables =
         StringUtils.isBlank(str) ? null : Arrays.asList(StringUtils.split(str.toLowerCase(), ","));
-      Set<String> queriedDimAttrs = cubeql.getQueriedDimAttrs();
-      Set<String> queriedMsrs = cubeql.getQueriedMsrs();
 
-      // Remove fact tables based on columns in the query
+      Set<QueriedPhraseContext> queriedMsrs = new HashSet<>();
+      Set<QueriedPhraseContext> dimExprs = new HashSet<>();
+      for (QueriedPhraseContext qur : cubeql.getQueriedPhrases()) {
+        if (qur.hasMeasures(cubeql)) {
+          queriedMsrs.add(qur);
+        } else {
+          dimExprs.add(qur);
+        }
+      }
+      // Remove fact tables based on whether they are valid or not.
       for (Iterator<CandidateFact> i = cubeql.getCandidateFacts().iterator(); i.hasNext();) {
         CandidateFact cfact = i.next();
 
@@ -249,26 +256,37 @@ class CandidateTableResolver implements ContextRewriter {
             continue;
           }
         }
+
+        // update expression evaluability for this fact
+        for (String expr : cubeql.getQueriedExprs()) {
+          cubeql.getExprCtx().updateEvaluables(expr, cfact);
+        }
+
         // go over the columns accessed in the query and find out which tables
         // can answer the query
         // the candidate facts should have all the dimensions queried and
         // atleast
         // one measure
         boolean toRemove = false;
-        for (String col : queriedDimAttrs) {
-          if (!cfact.getColumns().contains(col.toLowerCase())) {
-            // check if it available as reference, if not remove the candidate
-            if (!cubeql.getDeNormCtx().addRefUsage(cfact, col, cubeql.getCube().getName())) {
-              log.info("Not considering fact table:{} as column {} is not available", cfact, col);
-              cubeql.addFactPruningMsgs(cfact.fact, CandidateTablePruneCause.columnNotFound(col));
-              toRemove = true;
-              break;
-            }
-          } else if (!isFactColumnValidForRange(cubeql, cfact, col)) {
+        for (QueriedPhraseContext qur : dimExprs) {
+          if (!qur.isEvaluable(cubeql, cfact)) {
+            log.info("Not considering fact table:{} as columns {} are not available", cfact, qur.getColumns());
+            cubeql.addFactPruningMsgs(cfact.fact, CandidateTablePruneCause.columnNotFound(qur.getColumns()));
             toRemove = true;
             break;
           }
         }
+
+        // check if the candidate fact has atleast one measure queried
+        // if expression has measures, they should be considered along with other measures and see if the fact can be
+        // part of measure covering set
+        if (!checkForFactColumnExistsAndValidForRange(cfact, queriedMsrs, cubeql)) {
+          Set<String> columns = getColumns(queriedMsrs);
+
+          log.info("Not considering fact table:{} as columns {} is not available", cfact, columns);
+          cubeql.addFactPruningMsgs(cfact.fact, CandidateTablePruneCause.columnNotFound(columns));
+          toRemove = true;
+        }
         // go over join chains and prune facts that dont have any of the columns in each chain
         for (JoinChain chain : cubeql.getJoinchains().values()) {
           OptionalDimCtx optdim = cubeql.getOptionalDimensionMap().get(Aliased.create((Dimension)cubeql.getCubeTbls()
@@ -284,45 +302,17 @@ class CandidateTableResolver implements ContextRewriter {
             }
           }
         }
-        // go over expressions queried
-        // if expression has no measures, prune facts which cannot evaluate expression
-        // if expression has measures, they should be considered along with other measures and see if the fact can be
-        // part of measure covering set
-        for (String expr : cubeql.getQueriedExprs()) {
-          cubeql.getExprCtx().updateEvaluables(expr, cfact);
-          if (!cubeql.getQueriedExprsWithMeasures().contains(expr) && !cubeql.getExprCtx().isEvaluable(expr, cfact)) {
-            // if expression has no measures, prune facts which cannot evaluate expression
-            log.info("Not considering fact table:{} as expression {} is not evaluatable", cfact, expr);
-            cubeql.addFactPruningMsgs(cfact.fact, CandidateTablePruneCause.expressionNotEvaluable(expr));
-            toRemove = true;
-            break;
-          }
-        }
-        // check if the candidate fact has atleast one measure queried
-        // if expression has measures, they should be considered along with other measures and see if the fact can be
-        // part of measure covering set
-        if (!checkForFactColumnExistsAndValidForRange(cfact, queriedMsrs, cubeql)
-          && (cubeql.getQueriedExprsWithMeasures().isEmpty()
-            || cubeql.getExprCtx().allNotEvaluable(cubeql.getQueriedExprsWithMeasures(), cfact))) {
-          log.info("Not considering fact table:{} as columns {},{} is not available", cfact, queriedMsrs,
-                  cubeql.getQueriedExprsWithMeasures());
-          cubeql.addFactPruningMsgs(cfact.fact, CandidateTablePruneCause.columnNotFound(queriedMsrs,
-            cubeql.getQueriedExprsWithMeasures()));
-          toRemove = true;
-        }
+
         if (toRemove) {
           i.remove();
         }
       }
-      Set<String> dimExprs = new HashSet<>(cubeql.getQueriedExprs());
-      dimExprs.removeAll(cubeql.getQueriedExprsWithMeasures());
       if (cubeql.getCandidateFacts().size() == 0) {
         throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
-          (!queriedDimAttrs.isEmpty() ? queriedDimAttrs.toString() : "")
-          +  (!dimExprs.isEmpty() ? dimExprs.toString() : ""));
+          getColumns(cubeql.getQueriedPhrases()).toString());
       }
       Set<Set<CandidateFact>> cfactset;
-      if (queriedMsrs.isEmpty() && cubeql.getQueriedExprsWithMeasures().isEmpty()) {
+      if (queriedMsrs.isEmpty()) {
         // if no measures are queried, add all facts individually as single covering sets
         cfactset = new HashSet<>();
         for (CandidateFact cfact : cubeql.getCandidateFacts()) {
@@ -334,18 +324,16 @@ class CandidateTableResolver implements ContextRewriter {
       } else {
         // Find out candidate fact table sets which contain all the measures
         // queried
+
         List<CandidateFact> cfacts = new ArrayList<>(cubeql.getCandidateFacts());
-        cfactset = findCoveringSets(cubeql, cfacts, queriedMsrs,
-          cubeql.getQueriedExprsWithMeasures());
+        cfactset = findCoveringSets(cubeql, cfacts, queriedMsrs);
         log.info("Measure covering fact sets :{}", cfactset);
-        String msrString = (!queriedMsrs.isEmpty() ? queriedMsrs.toString() : "")
-          + (!cubeql.getQueriedExprsWithMeasures().isEmpty() ? cubeql.getQueriedExprsWithMeasures().toString() : "");
+        String msrString = getColumns(queriedMsrs).toString();
         if (cfactset.isEmpty()) {
           throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(), msrString);
         }
         cubeql.getCandidateFactSets().addAll(cfactset);
-        cubeql.pruneCandidateFactWithCandidateSet(CandidateTablePruneCause.columnNotFound(queriedMsrs,
-          cubeql.getQueriedExprsWithMeasures()));
+        cubeql.pruneCandidateFactWithCandidateSet(CandidateTablePruneCause.columnNotFound(getColumns(queriedMsrs)));
 
         if (cubeql.getCandidateFacts().size() == 0) {
           throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(), msrString);
@@ -354,19 +342,25 @@ class CandidateTableResolver implements ContextRewriter {
     }
   }
 
+  private static Set<String> getColumns(Collection<QueriedPhraseContext> queriedPhraseContexts) {
+    Set<String> cols = new HashSet<>();
+    for (QueriedPhraseContext qur : queriedPhraseContexts) {
+      cols.addAll(qur.getColumns());
+    }
+    return cols;
+  }
   static Set<Set<CandidateFact>> findCoveringSets(CubeQueryContext cubeql, List<CandidateFact> cfactsPassed,
-    Set<String> msrs, Set<String> exprsWithMeasures) {
+    Set<QueriedPhraseContext> msrs) throws LensException {
     Set<Set<CandidateFact>> cfactset = new HashSet<>();
     List<CandidateFact> cfacts = new ArrayList<>(cfactsPassed);
     for (Iterator<CandidateFact> i = cfacts.iterator(); i.hasNext();) {
       CandidateFact cfact = i.next();
       i.remove();
-      // cfact does not contain any of msrs and none of exprsWithMeasures are evaluable.
-      if ((msrs.isEmpty() || !checkForFactColumnExistsAndValidForRange(cfact, msrs, cubeql))
-        && (exprsWithMeasures.isEmpty() || cubeql.getExprCtx().allNotEvaluable(exprsWithMeasures, cfact))) {
+      if (!checkForFactColumnExistsAndValidForRange(cfact, msrs, cubeql)) {
+        // cfact does not contain any of msrs and none of exprsWithMeasures are evaluable.
         // ignore the fact
         continue;
-      } else if (cfact.getColumns().containsAll(msrs) && cubeql.getExprCtx().allEvaluable(cfact, exprsWithMeasures)) {
+      } else if (allEvaluable(cfact, msrs, cubeql)) {
         // return single set
         Set<CandidateFact> one = new LinkedHashSet<>();
         one.add(cfact);
@@ -374,18 +368,18 @@ class CandidateTableResolver implements ContextRewriter {
       } else {
         // find the remaining measures in other facts
         if (i.hasNext()) {
-          Set<String> remainingMsrs = new HashSet<>(msrs);
-          Set<String> remainingExprs = new HashSet<>(exprsWithMeasures);
-          remainingMsrs.removeAll(cfact.getColumns());
-          remainingExprs.removeAll(cubeql.getExprCtx().coveringExpressions(exprsWithMeasures, cfact));
-          Set<Set<CandidateFact>> coveringSets = findCoveringSets(cubeql, cfacts, remainingMsrs, remainingExprs);
+          Set<QueriedPhraseContext> remainingMsrs = new HashSet<>(msrs);
+          Set<QueriedPhraseContext> coveredMsrs  = coveredMeasures(cfact, msrs, cubeql);
+          remainingMsrs.removeAll(coveredMsrs);
+
+          Set<Set<CandidateFact>> coveringSets = findCoveringSets(cubeql, cfacts, remainingMsrs);
           if (!coveringSets.isEmpty()) {
             for (Set<CandidateFact> set : coveringSets) {
               set.add(cfact);
               cfactset.add(set);
             }
           } else {
-            log.info("Couldnt find any set containing remaining measures:{} {} in {}", remainingMsrs, remainingExprs,
+            log.info("Couldnt find any set containing remaining measures:{} {} in {}", remainingMsrs,
               cfactsPassed);
           }
         }
@@ -682,8 +676,8 @@ class CandidateTableResolver implements ContextRewriter {
         // can answer the query
         for (Iterator<CandidateDim> i = cubeql.getCandidateDimTables().get(dim).iterator(); i.hasNext();) {
           CandidateDim cdim = i.next();
-          if (cubeql.getColumnsQueried(dim.getName()) != null) {
-            for (String col : cubeql.getColumnsQueried(dim.getName())) {
+          if (cubeql.getColumnsQueriedForTable(dim.getName()) != null) {
+            for (String col : cubeql.getColumnsQueriedForTable(dim.getName())) {
               if (!cdim.getColumns().contains(col.toLowerCase())) {
                 // check if the column is an expression
                 if (cdim.getBaseTable().getExpressionNames().contains(col)) {
@@ -711,7 +705,7 @@ class CandidateTableResolver implements ContextRewriter {
 
         if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
           throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.getName(), cubeql
-            .getColumnsQueried(dim.getName()).toString());
+            .getColumnsQueriedForTable(dim.getName()).toString());
         }
       }
     }
@@ -731,4 +725,41 @@ class CandidateTableResolver implements ContextRewriter {
     }
     return false;
   }
+
+  static boolean checkForFactColumnExistsAndValidForRange(CandidateFact table, Collection<QueriedPhraseContext> colSet,
+                                                          CubeQueryContext cubeql) throws LensException {
+    if (colSet == null || colSet.isEmpty()) {
+      return true;
+    }
+    for (QueriedPhraseContext qur : colSet) {
+      if (qur.isEvaluable(cubeql, table)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  static boolean allEvaluable(CandidateFact table, Collection<QueriedPhraseContext> colSet,
+                                                          CubeQueryContext cubeql) throws LensException {
+    if (colSet == null || colSet.isEmpty()) {
+      return true;
+    }
+    for (QueriedPhraseContext qur : colSet) {
+      if (!qur.isEvaluable(cubeql, table)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  static Set<QueriedPhraseContext> coveredMeasures(CandidateFact table, Collection<QueriedPhraseContext> msrs,
+                              CubeQueryContext cubeql) throws LensException {
+    Set<QueriedPhraseContext> coveringSet = new HashSet<>();
+    for (QueriedPhraseContext msr : msrs) {
+      if (msr.isEvaluable(cubeql, table)) {
+        coveringSet.add(msr);
+      }
+    }
+    return coveringSet;
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
index 2db5dd1..87e094a 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
@@ -28,8 +28,11 @@ import org.apache.lens.cube.parse.HQLParser.ASTNodeVisitor;
 import org.apache.lens.cube.parse.HQLParser.TreeNode;
 import org.apache.lens.server.api.error.LensException;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.ql.lib.Node;
 import org.apache.hadoop.hive.ql.parse.ASTNode;
+import org.apache.hadoop.hive.ql.parse.HiveParser;
 
 import com.google.common.base.Optional;
 
@@ -40,10 +43,11 @@ class ColumnResolver implements ContextRewriter {
 
   @Override
   public void rewriteContext(CubeQueryContext cubeql) throws LensException {
+    checkForAllColumnsSelected(cubeql);
     extractColumns(cubeql);
   }
 
-  private void extractColumns(CubeQueryContext cubeql) throws LensException {
+  private void checkForAllColumnsSelected(CubeQueryContext cubeql) throws LensException {
     // Check if its 'select * from...'
     ASTNode selTree = cubeql.getSelectAST();
     if (selTree.getChildCount() == 1) {
@@ -59,12 +63,15 @@ class ColumnResolver implements ContextRewriter {
         }
       }
     }
+  }
+
+  private void extractColumns(CubeQueryContext cubeql) throws LensException {
     getColsForSelectTree(cubeql);
     getColsForWhereTree(cubeql);
-    getColsForTree(cubeql, cubeql.getJoinAST(), cubeql, true);
-    getColsForTree(cubeql, cubeql.getGroupByAST(), cubeql, true);
-    getColsForTree(cubeql, cubeql.getHavingAST(), cubeql, true);
-    getColsForTree(cubeql, cubeql.getOrderByAST(), cubeql, true);
+    getColsForAST(cubeql, cubeql.getJoinAST());
+    getColsForAST(cubeql, cubeql.getGroupByAST());
+    getColsForHavingAST(cubeql, cubeql.getHavingAST());
+    getColsForAST(cubeql, cubeql.getOrderByAST());
 
     // Update join dimension tables
     for (String table : cubeql.getTblAliasToColumns().keySet()) {
@@ -76,6 +83,38 @@ class ColumnResolver implements ContextRewriter {
     }
   }
 
+  private void getColsForAST(CubeQueryContext cubeql, ASTNode clause) throws LensException {
+    if (clause == null) {
+      return;
+    }
+    for (int i = 0; i < clause.getChildCount(); i++) {
+      ASTNode queriedExpr = (ASTNode) clause.getChild(i);
+      QueriedPhraseContext qur = new QueriedPhraseContext(queriedExpr);
+      getColsForTree(cubeql, queriedExpr, qur, true);
+      cubeql.addColumnsQueried(qur.getTblAliasToColumns());
+      cubeql.addQueriedPhrase(qur);
+    }
+  }
+
+  private void getColsForHavingAST(CubeQueryContext cubeql, ASTNode clause) throws LensException {
+    if (clause == null) {
+      return;
+    }
+
+    // split having clause phrases to be column level sothat having clause can be pushed to multiple facts if required.
+    if (HQLParser.isAggregateAST(clause) || clause.getType() == HiveParser.TOK_TABLE_OR_COL
+      || clause.getType() == HiveParser.DOT || clause.getChildCount() == 0) {
+      QueriedPhraseContext qur = new QueriedPhraseContext(clause);
+      qur.setAggregate(true);
+      getColsForTree(cubeql, clause, qur, true);
+      cubeql.addColumnsQueried(qur.getTblAliasToColumns());
+      cubeql.addQueriedPhrase(qur);
+    } else {
+      for (Node child : clause.getChildren()) {
+        getColsForHavingAST(cubeql, (ASTNode)child);
+      }
+    }
+  }
   // finds columns in AST passed.
   static void getColsForTree(final CubeQueryContext cubeql, ASTNode tree, final TrackQueriedColumns tqc,
     final boolean skipAliases)
@@ -99,7 +138,7 @@ class ColumnResolver implements ContextRewriter {
           // Take child ident.totext
           ASTNode ident = (ASTNode) node.getChild(0);
           String column = ident.getText().toLowerCase();
-          if (skipAliases && cubeql.getExprToAliasMap().values().contains(column)) {
+          if (skipAliases && cubeql.isColumnAnAlias(column)) {
             // column is an existing alias
             return;
           }
@@ -129,7 +168,13 @@ class ColumnResolver implements ContextRewriter {
     if (cubeql.getWhereAST() == null) {
       return;
     }
-    addColumnsForWhere(cubeql, cubeql.getWhereAST(), null);
+    for (int i = 0; i < cubeql.getWhereAST().getChildCount(); i++) {
+      ASTNode queriedExpr = (ASTNode) cubeql.getWhereAST().getChild(i);
+      QueriedPhraseContext qur = new QueriedPhraseContext(queriedExpr);
+      addColumnsForWhere(cubeql, qur, queriedExpr, cubeql.getWhereAST());
+      cubeql.addColumnsQueried(qur.getTblAliasToColumns());
+      cubeql.addQueriedPhrase(qur);
+    }
   }
 
   // Find all columns of select tree.
@@ -153,13 +198,13 @@ class ColumnResolver implements ContextRewriter {
       ASTNode selectExpr = (ASTNode) cubeql.getSelectAST().getChild(i);
       ASTNode selectExprChild = (ASTNode)selectExpr.getChild(0);
       Set<String> cols = new HashSet<>();
-      addColumnsForSelectExpr(cubeql, selectExpr, cubeql.getSelectAST(), cols);
-      ASTNode alias = HQLParser.findNodeByPath(selectExpr, Identifier);
+      SelectPhraseContext sel = new SelectPhraseContext(selectExpr);
+      addColumnsForSelectExpr(sel, selectExpr, cubeql.getSelectAST(), cols);
+      String alias = selectExpr.getChildCount() > 1 ? selectExpr.getChild(1).getText() : null;
       String selectAlias;
       String selectFinalAlias = null;
       if (alias != null) {
-        cubeql.addExprToAlias(selectExpr, alias);
-        selectFinalAlias = alias.getText();
+        selectFinalAlias = alias;
         selectAlias = SELECT_ALIAS_PREFIX + exprInd;
       } else if (cols.size() == 1 && (selectExprChild.getToken().getType() == TOK_TABLE_OR_COL
         || selectExprChild.getToken().getType() == DOT)) {
@@ -170,21 +215,26 @@ class ColumnResolver implements ContextRewriter {
         selectFinalAlias = HQLParser.getString(selectExprChild);
       }
       exprInd++;
-      cubeql.addSelectAlias(selectAlias, selectFinalAlias);
+      cubeql.addColumnsQueried(sel.getTblAliasToColumns());
+      sel.setSelectAlias(selectAlias);
+      sel.setFinalAlias(!StringUtils.isBlank(selectFinalAlias) ? "`" + selectFinalAlias + "`" : selectAlias);
+      sel.setActualAlias(alias != null ? alias.toLowerCase() : null);
+      cubeql.addSelectPhrase(sel);
     }
   }
 
-  private static void addColumnsForWhere(final CubeQueryContext cubeql, ASTNode node, ASTNode parent) {
+  private static void addColumnsForWhere(final CubeQueryContext cubeql, QueriedPhraseContext qur, ASTNode node,
+    ASTNode parent) {
     if (node.getToken().getType() == TOK_TABLE_OR_COL && (parent != null && parent.getToken().getType() != DOT)) {
       // Take child ident.totext
       ASTNode ident = (ASTNode) node.getChild(0);
       String column = ident.getText().toLowerCase();
-      if (cubeql.getExprToAliasMap().values().contains(column)) {
+      if (cubeql.isColumnAnAlias(column)) {
         // column is an existing alias
         return;
       }
 
-      addColumnQueriedWithTimeRangeFuncCheck(cubeql, parent, CubeQueryContext.DEFAULT_TABLE, column);
+      addColumnQueriedWithTimeRangeFuncCheck(cubeql, qur, parent, CubeQueryContext.DEFAULT_TABLE, column);
 
     } else if (node.getToken().getType() == DOT) {
       // This is for the case where column name is prefixed by table name
@@ -197,32 +247,31 @@ class ColumnResolver implements ContextRewriter {
       String column = colIdent.getText().toLowerCase();
       String table = tabident.getText().toLowerCase();
 
-      addColumnQueriedWithTimeRangeFuncCheck(cubeql, parent, table, column);
+      addColumnQueriedWithTimeRangeFuncCheck(cubeql, qur, parent, table, column);
 
     } else if (node.getToken().getType() == TOK_FUNCTION) {
       ASTNode fname = HQLParser.findNodeByPath(node, Identifier);
       if (fname != null && CubeQueryContext.TIME_RANGE_FUNC.equalsIgnoreCase(fname.getText())) {
-        addColumnsForWhere(cubeql, (ASTNode) node.getChild(1), node);
+        addColumnsForWhere(cubeql, qur, (ASTNode) node.getChild(1), node);
       } else {
         for (int i = 0; i < node.getChildCount(); i++) {
-          addColumnsForWhere(cubeql, (ASTNode) node.getChild(i), node);
+          addColumnsForWhere(cubeql, qur, (ASTNode) node.getChild(i), node);
         }
       }
     } else {
       for (int i = 0; i < node.getChildCount(); i++) {
-        addColumnsForWhere(cubeql, (ASTNode) node.getChild(i), node);
+        addColumnsForWhere(cubeql, qur, (ASTNode) node.getChild(i), node);
       }
     }
   }
 
-  private static void addColumnQueriedWithTimeRangeFuncCheck(final CubeQueryContext cubeql, final ASTNode parent,
-      final String table, final String column) {
-
+  private static void addColumnQueriedWithTimeRangeFuncCheck(final CubeQueryContext cubeql, QueriedPhraseContext qur,
+    final ASTNode parent, final String table, final String column) {
     if (isTimeRangeFunc(parent)) {
       cubeql.addQueriedTimeDimensionCols(column);
-      cubeql.addColumnsQueriedWithTimeDimCheck(CubeQueryContext.DEFAULT_TABLE, column);
+      cubeql.addColumnsQueriedWithTimeDimCheck(qur, CubeQueryContext.DEFAULT_TABLE, column);
     } else {
-      cubeql.addColumnsQueried(table, column);
+      qur.addColumnsQueried(table, column);
     }
   }
 
@@ -244,17 +293,14 @@ class ColumnResolver implements ContextRewriter {
     }
     return Optional.fromNullable(funcName);
   }
-  private static void addColumnsForSelectExpr(final CubeQueryContext cubeql, ASTNode node, ASTNode parent,
+
+  private static void addColumnsForSelectExpr(final TrackQueriedColumns sel, ASTNode node, ASTNode parent,
     Set<String> cols) {
     if (node.getToken().getType() == TOK_TABLE_OR_COL && (parent != null && parent.getToken().getType() != DOT)) {
       // Take child ident.totext
       ASTNode ident = (ASTNode) node.getChild(0);
       String column = ident.getText().toLowerCase();
-      if (cubeql.getExprToAliasMap().values().contains(column)) {
-        // column is an existing alias
-        return;
-      }
-      cubeql.addColumnsQueried(CubeQueryContext.DEFAULT_TABLE, column);
+      sel.addColumnsQueried(CubeQueryContext.DEFAULT_TABLE, column);
       cols.add(column);
     } else if (node.getToken().getType() == DOT) {
       // This is for the case where column name is prefixed by table name
@@ -266,11 +312,11 @@ class ColumnResolver implements ContextRewriter {
 
       String column = colIdent.getText().toLowerCase();
       String table = tabident.getText().toLowerCase();
-      cubeql.addColumnsQueried(table, column);
+      sel.addColumnsQueried(table, column);
       cols.add(column);
     } else {
       for (int i = 0; i < node.getChildCount(); i++) {
-        addColumnsForSelectExpr(cubeql, (ASTNode) node.getChild(i), node, cols);
+        addColumnsForSelectExpr(sel, (ASTNode) node.getChild(i), node, cols);
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/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 63ec8b2..6d53d00 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
@@ -59,7 +59,7 @@ import lombok.*;
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
-public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
+public class CubeQueryContext extends TracksQueriedColumns implements QueryAST {
   public static final String TIME_RANGE_FUNC = "time_range_in";
   public static final String NOW = "now";
   public static final String DEFAULT_TABLE = "_default_";
@@ -86,7 +86,6 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
   // Joinchains accessed in the query
   @Getter
   protected Map<String, JoinChain> joinchains = new HashMap<String, JoinChain>();
-  private final Set<String> queriedDimAttrs = new HashSet<String>();
 
   @Getter
   private final Set<String> queriedMsrs = new HashSet<String>();
@@ -112,20 +111,31 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
 
   // Alias to table object mapping of tables accessed in this query
   @Getter
-  private final Map<String, AbstractCubeTable> cubeTbls = new HashMap<String, AbstractCubeTable>();
-  // Alias name to fields queried
-  @Getter
-  private final Map<String, Set<String>> tblAliasToColumns = new HashMap<String, Set<String>>();
-  // Mapping of an expression to its column alias in the query
-  @Getter
-  private final Map<String, String> exprToAlias = new HashMap<String, String>();
-  @Getter
-  private final List<String> selectAliases = new ArrayList<String>();
+  private final Map<String, AbstractCubeTable> cubeTbls = new HashMap<>();
+
+  void addSelectPhrase(SelectPhraseContext sel) {
+    selectPhrases.add(sel);
+    addQueriedPhrase(sel);
+  }
+
+  boolean isColumnAnAlias(String col) {
+    for (SelectPhraseContext sel : selectPhrases) {
+      if (col.equals(sel.getActualAlias())) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void addQueriedPhrase(QueriedPhraseContext qur) {
+    queriedPhrases.add(qur);
+  }
   @Getter
-  private final List<String> selectFinalAliases = new ArrayList<String>();
-  // All aggregate expressions in the query
+  private final List<SelectPhraseContext> selectPhrases = new ArrayList<>();
+
   @Getter
-  private final Set<String> aggregateExprs = new HashSet<String>();
+  private final List<QueriedPhraseContext> queriedPhrases = new ArrayList<>();
+
   // Join conditions used in all join expressions
   @Getter
   private final Map<QBJoinTree, String> joinConds = new HashMap<QBJoinTree, String>();
@@ -203,11 +213,6 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
       this.selectAST = qb.getParseInfo().getSelForClause(clauseName);
     }
 
-    for (ASTNode aggrTree : qb.getParseInfo().getAggregationExprsForClause(clauseName).values()) {
-      String aggr = HQLParser.getString(aggrTree);
-      aggregateExprs.add(aggr);
-    }
-
     extractMetaTables();
   }
 
@@ -670,10 +675,6 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
     return qb.getParseInfo().getJoinExpr();
   }
 
-  public QBJoinTree getQBJoinTree() {
-    return qb.getQbJoinTree();
-  }
-
   public String getOrderByString() {
     if (orderByAST != null) {
       return HQLParser.getString(orderByAST);
@@ -1037,25 +1038,15 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
     return ParseUtils.findRootNonNullToken(tree);
   }
 
-  public Set<String> getColumnsQueried(String tblName) {
-    return tblAliasToColumns.get(getAliasForTableName(tblName));
+  public Set<String> getColumnsQueriedForTable(String tblName) {
+    return getColumnsQueried(getAliasForTableName(tblName));
   }
 
-  public void addColumnsQueriedWithTimeDimCheck(String alias, String timeDimColumn) {
+  public void addColumnsQueriedWithTimeDimCheck(QueriedPhraseContext qur, String alias, String timeDimColumn) {
 
     if (!shouldReplaceTimeDimWithPart()) {
-      addColumnsQueried(alias, timeDimColumn);
-    }
-  }
-
-  public void addColumnsQueried(String alias, String column) {
-
-    Set<String> cols = tblAliasToColumns.get(alias.toLowerCase());
-    if (cols == null) {
-      cols = new LinkedHashSet<String>();
-      tblAliasToColumns.put(alias.toLowerCase(), cols);
+      qur.addColumnsQueried(alias, timeDimColumn);
     }
-    cols.add(column);
   }
 
   public boolean isCubeMeasure(String col) {
@@ -1116,32 +1107,16 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
     return isCubeMeasure(msrname);
   }
 
-  public boolean isAggregateExpr(String expr) {
-    return aggregateExprs.contains(expr == null ? null : expr.toLowerCase());
-  }
-
   public boolean hasAggregates() {
-    return !aggregateExprs.isEmpty() || getExprCtx().hasAggregates();
-  }
-
-  public String getAlias(String expr) {
-    return exprToAlias.get(expr);
-  }
-
-  public String getSelectAlias(int index) {
-    return selectAliases.get(index);
-  }
-
-  public String getSelectFinalAlias(int index) {
-    return selectFinalAliases.get(index);
-  }
-
-  public Map<String, String> getExprToAliasMap() {
-    return exprToAlias;
-  }
-
-  public void addAggregateExpr(String expr) {
-    aggregateExprs.add(expr);
+    if (getExprCtx().hasAggregates()) {
+      return true;
+    }
+    for (QueriedPhraseContext qur : queriedPhrases) {
+      if (qur.isAggregate()) {
+        return true;
+      }
+    }
+    return false;
   }
 
   public void setJoinCond(QBJoinTree qb, String cond) {
@@ -1168,19 +1143,6 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
     return "";
   }
 
-  public void addExprToAlias(ASTNode expr, ASTNode alias) {
-    exprToAlias.put(HQLParser.getString(expr).trim(), alias.getText().toLowerCase());
-  }
-
-  public void addSelectAlias(String alias, String spacedAlias) {
-    selectAliases.add(alias);
-    if (!StringUtils.isBlank(spacedAlias)) {
-      selectFinalAliases.add("`" + spacedAlias + "`");
-    } else {
-      selectFinalAliases.add(alias);
-    }
-  }
-
   public Set<Aliased<Dimension>> getOptionalDimensions() {
     return optionalDimensionMap.keySet();
   }
@@ -1230,17 +1192,6 @@ public class CubeQueryContext implements TrackQueriedColumns, QueryAST {
     }
   }
 
-  /**
-   * @return the queriedDimAttrs
-   */
-  public Set<String> getQueriedDimAttrs() {
-    return queriedDimAttrs;
-  }
-
-  public void addQueriedDimAttrs(Set<String> dimAttrs) {
-    queriedDimAttrs.addAll(dimAttrs);
-  }
-
   public void addQueriedMsrs(Set<String> msrs) {
     queriedMsrs.addAll(msrs);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/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 ab1710d..40ed387 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
@@ -360,7 +360,7 @@ public class DenormalizationResolver implements ContextRewriter {
         }
         if (cubeql.getCandidateFacts().size() == 0) {
           throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
-              cubeql.getColumnsQueried(cubeql.getCube().getName()).toString());
+              cubeql.getColumnsQueriedForTable(cubeql.getCube().getName()).toString());
         }
         cubeql.pruneCandidateFactSet(CandidateTablePruneCode.COLUMN_NOT_FOUND);
       }
@@ -382,7 +382,7 @@ public class DenormalizationResolver implements ContextRewriter {
 
           if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
             throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(),
-              dim.toString(), cubeql.getColumnsQueried(dim.getName()).toString());
+              dim.toString(), cubeql.getColumnsQueriedForTable(dim.getName()).toString());
           }
         }
       }

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/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 5adea6c..60dacdb 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
@@ -59,8 +59,7 @@ class ExpressionResolver implements ContextRewriter {
     private Set<ExprSpecContext> allExprs = new LinkedHashSet<ExprSpecContext>();
     private Set<CandidateTable> directlyAvailableIn = new HashSet<CandidateTable>();
     @Getter
-    private Map<CandidateTable, Set<ExprSpecContext>> evaluableExpressions =
-      new HashMap<CandidateTable, Set<ExprSpecContext>>();
+    private Map<CandidateTable, Set<ExprSpecContext>> evaluableExpressions = new HashMap<>();
     private boolean hasMeasures = false;
 
     public boolean hasMeasures() {
@@ -197,16 +196,13 @@ class ExpressionResolver implements ContextRewriter {
     }
   }
 
-  static class ExprSpecContext implements TrackQueriedColumns {
+  static class ExprSpecContext extends TracksQueriedColumns {
     private Set<ExprSpec> exprSpecs = new LinkedHashSet<>();
     @Getter
     @Setter
     private ASTNode finalAST;
     @Getter
     private Set<Dimension> exprDims = new HashSet<>();
-    // for each expression store alias to columns queried
-    @Getter
-    private Map<String, Set<String>> tblAliasToColumns = new HashMap<>();
 
     ExprSpecContext(ExprSpec exprSpec, CubeQueryContext cubeql) throws LensException {
       // replaces table names in expression with aliases in the query
@@ -224,14 +220,6 @@ class ExpressionResolver implements ContextRewriter {
       AliasReplacer.extractTabAliasForCol(cubeql, this);
       finalAST = AliasReplacer.replaceAliases(finalAST, 0, cubeql.getColToTableAlias());
     }
-    public void addColumnsQueried(String alias, String column) {
-      Set<String> cols = tblAliasToColumns.get(alias.toLowerCase());
-      if (cols == null) {
-        cols = new HashSet<String>();
-        tblAliasToColumns.put(alias.toLowerCase(), cols);
-      }
-      cols.add(column);
-    }
 
     void resolveColumns(CubeQueryContext cubeql) throws LensException {
       // finds all columns and table aliases in the expression

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/GroupbyResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/GroupbyResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/GroupbyResolver.java
index 8beeb9d..26ae1e7 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/GroupbyResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/GroupbyResolver.java
@@ -21,7 +21,6 @@ package org.apache.lens.cube.parse;
 import static org.apache.hadoop.hive.ql.parse.HiveParser.*;
 
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
 
 import org.apache.lens.cube.metadata.AbstractBaseTable;
@@ -54,7 +53,7 @@ class GroupbyResolver implements ContextRewriter {
         CubeQueryConfUtil.DEFAULT_ENABLE_GROUP_BY_TO_SELECT);
   }
 
-  private void promoteSelect(CubeQueryContext cubeql, List<String> nonMsrNonAggSelExprsWithoutAlias,
+  private void promoteSelect(CubeQueryContext cubeql, List<SelectPhraseContext> selectExprs,
     List<String> groupByExprs) throws LensException {
     if (!selectPromotionEnabled) {
       return;
@@ -68,10 +67,10 @@ class GroupbyResolver implements ContextRewriter {
     // each selected column, if it is not a cube measure, and does not have
     // aggregation on the column, then it is added to group by columns.
     if (cubeql.hasAggregates()) {
-      for (String expr : nonMsrNonAggSelExprsWithoutAlias) {
-
+      for (SelectPhraseContext sel : selectExprs) {
+        String expr = sel.getExprWithoutAlias();
         if (!groupByExprs.contains(expr)) {
-          if (!cubeql.isAggregateExpr(expr)) {
+          if (!sel.isAggregate()) {
             ASTNode exprAST = HQLParser.parseExpr(expr);
             ASTNode groupbyAST = cubeql.getGroupByAST();
             if (!isConstantsUsed(exprAST)) {
@@ -116,23 +115,21 @@ class GroupbyResolver implements ContextRewriter {
     return false;
   }
 
-  private void promoteGroupby(CubeQueryContext cubeql, List<String> selectExprs, List<String> groupByExprs)
+  private void promoteGroupby(CubeQueryContext cubeql, List<SelectPhraseContext> selectExprs,
+                              List<String> groupByExprs)
     throws LensException {
     if (!groupbyPromotionEnabled) {
       return;
     }
 
-    for (String expr : selectExprs) {
-      expr = getExpressionWithoutAlias(cubeql, expr);
-      if (!cubeql.isAggregateExpr(expr)) {
-        log.info("Not promoting groupby expression to select, since there are expression projected");
-        return;
-      }
+    if (selectExprs.size() > 0) {
+      log.info("Not promoting groupby expression to select, since there are expression projected");
+      return;
     }
 
     int index = 0;
     for (String expr : groupByExprs) {
-      if (!contains(cubeql, selectExprs, expr)) {
+      if (!contains(selectExprs, expr)) {
         ASTNode exprAST = HQLParser.parseExpr(expr);
         addChildAtIndex(index, cubeql.getSelectAST(), exprAST);
         index++;
@@ -158,33 +155,21 @@ class GroupbyResolver implements ContextRewriter {
   public void rewriteContext(CubeQueryContext cubeql) throws LensException {
     // Process Aggregations by making sure that all group by keys are projected;
     // and all projection fields are added to group by keylist;
-    List<String> selectExprs = new ArrayList<String>();
-    String[] sel = getExpressions(cubeql.getSelectAST(), cubeql).toArray(new String[]{});
-    for (String s : sel) {
-      selectExprs.add(s.trim());
-    }
-    List<String> groupByExprs = new ArrayList<String>();
+    List<SelectPhraseContext> selectExprs = getSelectNonAggregateNonMeasureExpressions(cubeql);
+    List<String> groupByExprs = new ArrayList<>();
     if (cubeql.getGroupByString() != null) {
-      String[] gby = getExpressions(cubeql.getGroupByAST(), cubeql).toArray(new String[]{});
+      String[] gby = getGroupbyExpressions(cubeql.getGroupByAST()).toArray(new String[]{});
       for (String g : gby) {
         groupByExprs.add(g.trim());
       }
     }
-    promoteSelect(cubeql, getNonMsrNonAggSelExprsWithoutAlias(cubeql.getSelectAST(), cubeql), groupByExprs);
+    promoteSelect(cubeql, selectExprs, groupByExprs);
     promoteGroupby(cubeql, selectExprs, groupByExprs);
   }
 
-  private String getExpressionWithoutAlias(CubeQueryContext cubeql, String sel) {
-    String alias = cubeql.getAlias(sel);
-    if (alias != null) {
-      sel = sel.substring(0, (sel.length() - alias.length())).trim();
-    }
-    return sel;
-  }
-
-  private boolean contains(CubeQueryContext cubeql, List<String> selExprs, String expr) {
-    for (String sel : selExprs) {
-      sel = getExpressionWithoutAlias(cubeql, sel);
+  private boolean contains(List<SelectPhraseContext> selExprs, String expr) {
+    for (SelectPhraseContext selExpr : selExprs) {
+      String sel = selExpr.getExprWithoutAlias();
       if (sel.equals(expr)) {
         return true;
       }
@@ -192,72 +177,32 @@ class GroupbyResolver implements ContextRewriter {
     return false;
   }
 
-  /**
-   * @param selectASTNode a select AST Node
-   * @param cubeQueryCtx
-   * @return List of non measure and non aggregate select expressions in string format without aliases
-   */
-  private List<String> getNonMsrNonAggSelExprsWithoutAlias(final ASTNode selectASTNode, CubeQueryContext cubeQueryCtx) {
-
-    List<String> nonMsrNonAggSelExprsWithoutAlias = new LinkedList<String>();
-    List<ASTNode> nonMsrNonAggSelASTChildren = filterNonMsrNonAggSelectASTChildren(selectASTNode, cubeQueryCtx);
-
-    for (ASTNode nonMsrNonAggSelASTChild : nonMsrNonAggSelASTChildren) {
+  private List<SelectPhraseContext> getSelectNonAggregateNonMeasureExpressions(CubeQueryContext cubeql) {
 
-      /* Assuming all children of SelectASTNode are SELECT Expression AST Nodes only.
-      Refer:https://reviews.apache.org/r/29422/#comment109498 for more details.
-      Order of Children of select expression AST Node => Index 0: Select Expression Without Alias, Index 1: Alias */
+    List<SelectPhraseContext> list = new ArrayList<>();
 
-      ASTNode selExprWithoutAlias = (ASTNode) nonMsrNonAggSelASTChild.getChildren().get(0);
-      String result = HQLParser.getString(selExprWithoutAlias);
-      nonMsrNonAggSelExprsWithoutAlias.add(result);
-
-    }
-    return nonMsrNonAggSelExprsWithoutAlias;
-  }
-
-  /**
-   * @param selectASTNode a select ASTNode
-   * @param cubeQueryCtx
-   * @return list of selectASTNode Children which does not contain a measure or an aggregate. Empty list is returned
-   * when selectASTNode is not a Select AST Node. Empty list is returned when there are no non measure and non aggregate
-   * children nodes present in select AST.
-   */
-  private List<ASTNode> filterNonMsrNonAggSelectASTChildren(final ASTNode selectASTNode,
-    CubeQueryContext cubeQueryCtx) {
-    List<ASTNode> nonMsrNonAggSelASTChildren = new LinkedList<ASTNode>();
-
-    if (!HQLParser.isSelectASTNode(selectASTNode)) {
-      return nonMsrNonAggSelASTChildren;
-    }
-
-    for (int i = 0; i < selectASTNode.getChildCount(); i++) {
-      ASTNode childNode = (ASTNode) selectASTNode.getChild(i);
-      if (hasMeasure(childNode, cubeQueryCtx) || hasAggregate(childNode, cubeQueryCtx)) {
+    for (SelectPhraseContext sel : cubeql.getSelectPhrases()) {
+      if (hasMeasure(sel.getExprAST(), cubeql)) {
+        continue;
+      }
+      if (hasAggregate(sel.getExprAST(), cubeql)) {
         continue;
       }
-      nonMsrNonAggSelASTChildren.add(childNode);
+      list.add(sel);
     }
 
-    return nonMsrNonAggSelASTChildren;
+    return list;
   }
 
-  private List<String> getExpressions(ASTNode node, CubeQueryContext cubeql) {
+  private List<String> getGroupbyExpressions(ASTNode node) {
 
-    List<String> list = new ArrayList<String>();
+    List<String> list = new ArrayList<>();
 
     if (node == null) {
       return list;
     }
 
     for (int i = 0; i < node.getChildCount(); i++) {
-      ASTNode child = (ASTNode) node.getChild(i);
-      if (hasMeasure(child, cubeql)) {
-        continue;
-      }
-      if (hasAggregate(child, cubeql)) {
-        continue;
-      }
       list.add(HQLParser.getString((ASTNode) node.getChild(i)));
     }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
index b3547db..979c24b 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
@@ -111,17 +111,18 @@ class MultiFactHQLContext extends SimpleHQLContext {
       }
       if (selectToFactIndex.get(i).size() == 1) {
         select.append("mq").append(selectToFactIndex.get(i).get(0)).append(".")
-          .append(query.getSelectAlias(i)).append(" ");
+          .append(query.getSelectPhrases().get(i).getSelectAlias()).append(" ");
       } else {
         select.append("COALESCE(");
         String sep = "";
         for (Integer factIndex : selectToFactIndex.get(i)) {
-          select.append(sep).append("mq").append(factIndex).append(".").append(query.getSelectAlias(i));
+          select.append(sep).append("mq").append(factIndex).append(".").append(
+            query.getSelectPhrases().get(i).getSelectAlias());
           sep = ", ";
         }
         select.append(") ");
       }
-      select.append(query.getSelectFinalAlias(i));
+      select.append(query.getSelectPhrases().get(i).getFinalAlias());
       if (i != query.getSelectAST().getChildCount() - 1) {
         select.append(", ");
       }
@@ -152,7 +153,7 @@ class MultiFactHQLContext extends SimpleHQLContext {
         fromBuilder.append(" on ");
         Iterator<Integer> dimIter = fact.getDimFieldIndices().iterator();
         while (dimIter.hasNext()) {
-          String dim = query.getSelectAlias(dimIter.next());
+          String dim = query.getSelectPhrases().get(dimIter.next()).getSelectAlias();
           fromBuilder.append(getMultiFactJoinCondition(aliasCount, dim));
           if (dimIter.hasNext()) {
             fromBuilder.append(" AND ");

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/QueriedPhraseContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/QueriedPhraseContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/QueriedPhraseContext.java
new file mode 100644
index 0000000..11eb8f7
--- /dev/null
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/QueriedPhraseContext.java
@@ -0,0 +1,186 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.cube.parse;
+
+import java.util.*;
+
+import org.apache.lens.cube.metadata.MetastoreConstants;
+import org.apache.lens.cube.metadata.TimeRange;
+import org.apache.lens.server.api.error.LensException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.hive.ql.parse.ASTNode;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Slf4j
+class QueriedPhraseContext extends TracksQueriedColumns implements TrackQueriedCubeFields {
+  private final ASTNode exprAST;
+  private Boolean aggregate;
+  private String expr;
+  private final Set<String> queriedDimAttrs = new HashSet<>();
+  private final Set<String> queriedMsrs = new HashSet<>();
+  private final Set<String> queriedExprColumns = new HashSet<>();
+  private final Set<String> columns = new HashSet<>();
+
+  void setNotAggregate() {
+    this.aggregate = false;
+  }
+
+  boolean isAggregate() {
+    if (aggregate == null) {
+      aggregate = HQLParser.hasAggregate(exprAST);
+    }
+    return aggregate;
+  }
+
+  String getExpr() {
+    if (expr == null) {
+      expr = HQLParser.getString(getExprAST()).trim();
+    }
+    return expr;
+  }
+
+  void updateExprs() {
+    expr = HQLParser.getString(getExprAST()).trim();
+  }
+
+  @Override
+  public void addQueriedDimAttr(String attrName) {
+    queriedDimAttrs.add(attrName);
+    columns.add(attrName);
+  }
+
+  @Override
+  public void addQueriedMsr(String msrName) {
+    queriedMsrs.add(msrName);
+    columns.add(msrName);
+  }
+
+  @Override
+  public void addQueriedExprColumn(String exprCol) {
+    queriedExprColumns.add(exprCol);
+    columns.add(exprCol);
+  }
+
+  public boolean hasMeasures(CubeQueryContext cubeQl) {
+    if (!queriedMsrs.isEmpty()) {
+      return true;
+    }
+    if (!queriedExprColumns.isEmpty()) {
+      for (String exprCol : queriedExprColumns) {
+        if (cubeQl.getQueriedExprsWithMeasures().contains(exprCol)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  boolean isEvaluable(CubeQueryContext cubeQl, CandidateFact cfact) throws LensException {
+    // all measures of the queried phrase should be present
+    for (String msr : queriedMsrs) {
+      if (!checkForColumnExistsAndValidForRange(cfact, msr, cubeQl)) {
+        return false;
+      }
+    }
+    // all expression columns should be evaluable
+    for (String exprCol : queriedExprColumns) {
+      if (!cubeQl.getExprCtx().isEvaluable(exprCol, cfact)) {
+        log.info("expression {} is not evaluable in fact table:{}", expr, cfact);
+        return false;
+      }
+    }
+    // all dim-attributes should be present.
+    for (String col : queriedDimAttrs) {
+      if (!cfact.getColumns().contains(col.toLowerCase())) {
+        // check if it available as reference
+        if (!cubeQl.getDeNormCtx().addRefUsage(cfact, col, cubeQl.getCube().getName())) {
+          log.info("column {} is not available in fact table:{} ", col, cfact);
+          return false;
+        }
+      } else if (!isFactColumnValidForRange(cubeQl, cfact, col)) {
+        log.info("column {} is not available in range queried in fact {}", col, cfact);
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public static boolean isColumnAvailableInRange(final TimeRange range, Date startTime, Date endTime) {
+    return (isColumnAvailableFrom(range.getFromDate(), startTime)
+      && isColumnAvailableTill(range.getToDate(), endTime));
+  }
+
+  public static boolean isColumnAvailableFrom(@NonNull final Date date, Date startTime) {
+    return (startTime == null) || date.equals(startTime) || date.after(startTime);
+  }
+
+  public static boolean isColumnAvailableTill(@NonNull final Date date, Date endTime) {
+    return (endTime == null) || date.equals(endTime) || date.before(endTime);
+  }
+
+  public static boolean isFactColumnValidForRange(CubeQueryContext cubeql, CandidateTable cfact, String col) {
+    for(TimeRange range : cubeql.getTimeRanges()) {
+      if (!isColumnAvailableInRange(range, getFactColumnStartTime(cfact, col), getFactColumnEndTime(cfact, col))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public static Date getFactColumnStartTime(CandidateTable table, String factCol) {
+    Date startTime = null;
+    if (table instanceof CandidateFact) {
+      for (String key : ((CandidateFact) table).fact.getProperties().keySet()) {
+        if (key.contains(MetastoreConstants.FACT_COL_START_TIME_PFX)) {
+          String propCol = StringUtils.substringAfter(key, MetastoreConstants.FACT_COL_START_TIME_PFX);
+          if (factCol.equals(propCol)) {
+            startTime = ((CandidateFact) table).fact.getDateFromProperty(key, false, true);
+          }
+        }
+      }
+    }
+    return startTime;
+  }
+
+  public static Date getFactColumnEndTime(CandidateTable table, String factCol) {
+    Date endTime = null;
+    if (table instanceof CandidateFact) {
+      for (String key : ((CandidateFact) table).fact.getProperties().keySet()) {
+        if (key.contains(MetastoreConstants.FACT_COL_END_TIME_PFX)) {
+          String propCol = StringUtils.substringAfter(key, MetastoreConstants.FACT_COL_END_TIME_PFX);
+          if (factCol.equals(propCol)) {
+            endTime = ((CandidateFact) table).fact.getDateFromProperty(key, false, true);
+          }
+        }
+      }
+    }
+    return endTime;
+  }
+
+  static boolean checkForColumnExistsAndValidForRange(CandidateTable table, String column, CubeQueryContext cubeql) {
+    return (table.getColumns().contains(column) &&  isFactColumnValidForRange(cubeql, table, column));
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/SelectPhraseContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/SelectPhraseContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/SelectPhraseContext.java
new file mode 100644
index 0000000..b6702e5
--- /dev/null
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/SelectPhraseContext.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.cube.parse;
+
+import org.apache.hadoop.hive.ql.parse.ASTNode;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+class SelectPhraseContext extends QueriedPhraseContext {
+  private String actualAlias;
+  private String selectAlias;
+  private String finalAlias;
+  private String exprWithoutAlias;
+
+  public SelectPhraseContext(ASTNode selectExpr) {
+    super(selectExpr);
+  }
+
+  String getExprWithoutAlias() {
+    if (exprWithoutAlias == null) {
+      //Order of Children of select expression AST Node => Index 0: Select Expression Without Alias, Index 1: Alias */
+      exprWithoutAlias = HQLParser.getString((ASTNode) getExprAST().getChild(0)).trim();
+    }
+    return exprWithoutAlias;
+  }
+
+  void updateExprs() {
+    super.updateExprs();
+    exprWithoutAlias = HQLParser.getString((ASTNode) getExprAST().getChild(0)).trim();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRangeChecker.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRangeChecker.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRangeChecker.java
index ca176ee..89b50f5 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRangeChecker.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRangeChecker.java
@@ -139,13 +139,13 @@ public class TimeRangeChecker implements ContextRewriter {
 
   private void doColLifeValidation(CubeQueryContext cubeql) throws LensException,
       ColUnAvailableInTimeRangeException {
-    Set<String> cubeColumns = cubeql.getColumnsQueried(cubeql.getCube().getName());
+    Set<String> cubeColumns = cubeql.getColumnsQueriedForTable(cubeql.getCube().getName());
     if (cubeColumns == null || cubeColumns.isEmpty()) {
       // Query doesn't have any columns from cube
       return;
     }
 
-    for (String col : cubeql.getColumnsQueried(cubeql.getCube().getName())) {
+    for (String col : cubeql.getColumnsQueriedForTable(cubeql.getCube().getName())) {
       CubeColumn column = cubeql.getCube().getColumnByName(col);
       for (TimeRange range : cubeql.getTimeRanges()) {
         if (column == null) {

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/TrackQueriedColumns.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TrackQueriedColumns.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TrackQueriedColumns.java
index b65ac26..45d59df 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TrackQueriedColumns.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TrackQueriedColumns.java
@@ -22,6 +22,33 @@ import java.util.Map;
 import java.util.Set;
 
 interface TrackQueriedColumns {
+
+  /**
+   * Get tblAlias to column
+   * @return map of tblAliasToColumns
+   */
   Map<String, Set<String>> getTblAliasToColumns();
-  void addColumnsQueried(String alias, String column);
+
+  /**
+   * Get columns queried by tblAlias
+   *
+   * @param tblAlias tbl alias name
+   *
+   * @return set of column names
+   */
+  Set<String> getColumnsQueried(String tblAlias);
+
+  /**
+   * Add given table alias and column
+   * @param tblAlias Table alias
+   * @param column column
+   */
+  void addColumnsQueried(String tblAlias, String column);
+
+  /**
+   * Add given map of tblAliasToColumns.
+   *
+   * @param tblAliasToColumns map of tblAliasToColumns
+   */
+  void addColumnsQueried(Map<String, Set<String>> tblAliasToColumns);
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/TrackQueriedCubeFields.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TrackQueriedCubeFields.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TrackQueriedCubeFields.java
new file mode 100644
index 0000000..eafbb0e
--- /dev/null
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TrackQueriedCubeFields.java
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.cube.parse;
+
+import java.util.Set;
+
+interface TrackQueriedCubeFields {
+
+  /**
+   * Get queried dim attributes
+   *
+   * @return set of dim attribute names
+   */
+  Set<String> getQueriedDimAttrs();
+
+  /**
+   * Get queried measures
+   *
+   * @return set of measure names
+   */
+  Set<String> getQueriedMsrs();
+
+  /**
+   * Get queried expr columns
+   *
+   * @return set of expr column names
+   */
+  Set<String> getQueriedExprColumns();
+
+  /**
+   * Add queried dim attribute
+   *
+   * @param attrName attribute name
+   */
+  void addQueriedDimAttr(String attrName);
+
+  /**
+   * Add queried measure
+   *
+   * @param msrName measure name
+   */
+  void addQueriedMsr(String msrName);
+
+  /**
+   * Add queried expression column
+   *
+   * @param exprCol expression column name
+   */
+  void addQueriedExprColumn(String exprCol);
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/lens-cube/src/main/java/org/apache/lens/cube/parse/TracksQueriedColumns.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TracksQueriedColumns.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TracksQueriedColumns.java
new file mode 100644
index 0000000..fb16478
--- /dev/null
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TracksQueriedColumns.java
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.cube.parse;
+
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import lombok.Getter;
+
+abstract class TracksQueriedColumns implements TrackQueriedColumns {
+
+  @Getter
+  private Map<String, Set<String>> tblAliasToColumns = new HashMap<>();
+
+  public void addColumnsQueried(String tblAlias, String column) {
+
+    Set<String> cols = tblAliasToColumns.get(tblAlias.toLowerCase());
+    if (cols == null) {
+      cols = new LinkedHashSet<>();
+      tblAliasToColumns.put(tblAlias.toLowerCase(), cols);
+    }
+    cols.add(column);
+  }
+
+  public void addColumnsQueried(Map<String, Set<String>> tblAliasToColumns) {
+
+    for (Map.Entry<String, Set<String>> entry : tblAliasToColumns.entrySet()) {
+      Set<String> cols = this.tblAliasToColumns.get(entry.getKey());
+      if (cols == null) {
+        cols = new LinkedHashSet<>();
+        this.tblAliasToColumns.put(entry.getKey(), cols);
+      }
+      cols.addAll(entry.getValue());
+    }
+  }
+
+  public Set<String> getColumnsQueried(String tblAlias) {
+    return tblAliasToColumns.get(tblAlias);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/2cfb7b09/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 f7f8af2..0c43cb5 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
@@ -984,6 +984,7 @@ public class CubeTestSetup {
       "dim2chain", "id", null, null, null)); // used as key in the chains
     cubeDimensions2.add(new ReferencedDimAttribute(new FieldSchema("dim22", "int", "ref dim"), "Dim2 refer",
       "dim2chain", "id", null, null, null)); // not used as key in the chains
+    cubeDimensions2.add(new BaseDimAttribute(new FieldSchema("dim13", "string", "basedim")));
     cubeDimensions2.add(new BaseDimAttribute(new FieldSchema("userid", "int", "userid")));
     cubeDimensions2.add(new BaseDimAttribute(new FieldSchema("xuserid", "int", "userid")));
     cubeDimensions2.add(new BaseDimAttribute(new FieldSchema("yuserid", "int", "userid")));
@@ -1232,6 +1233,7 @@ public class CubeTestSetup {
     dimensions.add("dim2big2");
     dimensions.add("dim2bignew");
     dimensions.add("dim11");
+    dimensions.add("dim13");
     dimensions.add("dim12");
     dimensions.add("dim22");
     dimensions.add("d_time");
@@ -1408,6 +1410,7 @@ public class CubeTestSetup {
     factColumns.add(new FieldSchema("processing_time", "timestamp", "processing time"));
     factColumns.add(new FieldSchema("dim1", "string", "base dim"));
     factColumns.add(new FieldSchema("dim11", "string", "base dim"));
+    factColumns.add(new FieldSchema("dim13", "string", "base dim"));
     factColumns.add(new FieldSchema("dim12", "string", "base dim"));
     factColumns.add(new FieldSchema("dim22", "string", "base dim"));
     factColumns.add(new FieldSchema("cityid", "int", "city id"));


[4/4] lens git commit: LENS-1287: Create command in cli to create schema taking parent directory where schema is stored

Posted by pr...@apache.org.
LENS-1287: Create command in cli to create schema taking parent directory where schema is stored


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

Branch: refs/heads/master
Commit: d9884ec6dcc59825f7f771b4d0c3cf7f187686f8
Parents: 2cfb7b0
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Mon Oct 10 15:11:14 2016 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Mon Oct 10 15:11:14 2016 +0530

----------------------------------------------------------------------
 .../lens/cli/commands/LensDatabaseCommands.java |   3 +-
 .../commands/LensDimensionTableCommands.java    |   3 +-
 .../lens/cli/commands/LensFactCommands.java     |   3 +-
 .../lens/cli/commands/LensSchemaCommands.java   | 162 +++++++++++++
 .../java/org/apache/lens/cli/LensCLITest.java   |  67 ++++++
 .../apache/lens/cli/TestLensCubeCommands.java   |   6 +-
 .../lens/cli/TestLensDatabaseCommands.java      |   4 +-
 .../lens/cli/TestLensDimensionCommands.java     |   8 +-
 .../cli/TestLensDimensionTableCommands.java     |   7 +-
 .../apache/lens/cli/TestLensFactCommands.java   |   6 +-
 .../TestLensFactCommandsWithMissingWeight.java  |   4 +-
 .../apache/lens/cli/TestLensQueryCommands.java  |   4 +-
 .../apache/lens/cli/TestLensSchemaCommands.java |  49 ++++
 .../lens/cli/TestLensSegmentationCommands.java  |   6 +-
 .../lens/cli/TestLensStorageCommands.java       |   6 +-
 .../lens/cli/doc/TestGenerateCLIUserDoc.java    |  68 ++++--
 .../resources/cube_with_no_weight_facts.xml     |  41 ----
 lens-cli/src/test/resources/dim_table.xml       |  48 ----
 lens-cli/src/test/resources/dim_table2.xml      |  48 ----
 lens-cli/src/test/resources/fact1.xml           |  51 -----
 .../src/test/resources/fact_without_weight.xml  |  51 -----
 lens-cli/src/test/resources/local-storage.xml   |  27 ---
 lens-cli/src/test/resources/sample-cube.xml     | 102 ---------
 .../cubes/base/cube_with_no_weight_facts.xml    |  41 ++++
 .../resources/schema/cubes/base/sample-cube.xml | 102 +++++++++
 .../resources/schema/dimensions/test-detail.xml |  32 +++
 .../schema/dimensions/test-dimension.xml        |  61 +++++
 .../resources/schema/dimtables/dim_table.xml    |  48 ++++
 .../resources/schema/dimtables/dim_table2.xml   |  48 ++++
 .../src/test/resources/schema/facts/fact1.xml   |  51 +++++
 .../schema/facts/fact_without_weight.xml        |  51 +++++
 .../resources/schema/segmentations/seg1.xml     |  45 ++++
 .../resources/schema/storages/local-storage.xml |  26 +++
 lens-cli/src/test/resources/seg1.xml            |  45 ----
 lens-cli/src/test/resources/test-detail.xml     |  32 ---
 lens-cli/src/test/resources/test-dimension.xml  |  61 -----
 src/site/apt/user/cli.apt                       | 228 ++++++++++++-------
 37 files changed, 1010 insertions(+), 635 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java
index 05108f0..c6ae02b 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java
@@ -87,7 +87,8 @@ public class LensDatabaseCommands extends LensCRUDCommand {
    * @return the string
    */
   @CliCommand(value = "drop database", help = "drop a database with specified name")
-  public String dropDatabase(@CliOption(key = {"", "db"}, mandatory = true, help = "<database-name>") String database,
+  public String dropDatabase(
+    @CliOption(key = {"", "db", "database"}, mandatory = true, help = "<database-name>") String database,
     @CliOption(key = "cascade", specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") boolean cascade) {
     return drop(database, cascade);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
index 7df5c7c..26650c1 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
@@ -110,7 +110,8 @@ public class LensDimensionTableCommands extends LogicalTableCrudCommand<XDimensi
       + " By default <cascade> is false")
   public String dropDimensionTable(
     @CliOption(key = {"", "dimtable_name"}, mandatory = true, help = "<dimtable_name>") String name,
-    @CliOption(key = {"cascade"}, mandatory = false, unspecifiedDefaultValue = "false", help = "<cascade>")
+    @CliOption(key = {"cascade"}, mandatory = false, specifiedDefaultValue = "true", unspecifiedDefaultValue = "false",
+      help = "<cascade>")
     boolean cascade) {
     return drop(name, cascade);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
index 6457bce..9ea887a 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
@@ -105,7 +105,8 @@ public class LensFactCommands extends LogicalTableCrudCommand<XFactTable> {
       + " By default <cascade> is false")
   public String dropFact(
     @CliOption(key = {"", "fact_name"}, mandatory = true, help = "<fact_name>") String fact,
-    @CliOption(key = {"cascade"}, mandatory = false, unspecifiedDefaultValue = "false", help = "<cascade>")
+    @CliOption(key = {"cascade"}, mandatory = false, specifiedDefaultValue = "true", unspecifiedDefaultValue = "false",
+      help = "<cascade>")
     boolean cascade) {
     return drop(fact, cascade);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/main/java/org/apache/lens/cli/commands/LensSchemaCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensSchemaCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensSchemaCommands.java
new file mode 100644
index 0000000..feabf9c
--- /dev/null
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensSchemaCommands.java
@@ -0,0 +1,162 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.cli.commands;
+
+import java.io.*;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.lens.cli.commands.annotations.UserDocumentation;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.shell.core.CommandMarker;
+import org.springframework.shell.core.JLineShellComponent;
+import org.springframework.shell.core.annotation.CliCommand;
+import org.springframework.shell.core.annotation.CliOption;
+import org.springframework.shell.support.logging.HandlerUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
+
+import com.google.common.collect.Lists;
+
+@Component
+@UserDocumentation(title = "Creating schema with one command",
+  description = "")
+public class LensSchemaCommands implements CommandMarker {
+  public static final String STRUCTURE = "\n"
+    + ".\n"
+    + "|-- storages\n"
+    + "|  |-- storage1.xml\n"
+    + "|  |-- storage2.xml\n"
+    + "|\n"
+    + "|-- dimensions\n"
+    + "|  |-- dim1.xml\n"
+    + "|  |-- dim2.xml\n"
+    + "|\n"
+    + "|-- cubes\n"
+    + "|  |-- base\n"
+    + "|  |  |-- base_cube1.xml\n"
+    + "|  |  |-- base_cube2.xml\n"
+    + "|  |\n"
+    + "|  |-- derived\n"
+    + "|  |  |-- derived_cube1.xml\n"
+    + "|  |  |-- derived_cube2.xml\n"
+    + "|  |\n"
+    + "|  |-- independent_cube1.xml\n"
+    + "|  |-- independent_cube2.xml\n"
+    + "|\n"
+    + "|-- dimensiontables\n"
+    + "|  |-- dimtable1.xml\n"
+    + "|  |-- dimtable2.xml\n"
+    + "|\n"
+    + "|-- dimtables\n"
+    + "|  |-- dimtable3.xml\n"
+    + "|  |-- dimtable4.xml\n"
+    + "|\n"
+    + "|-- facts\n"
+    + "   |-- fact1.xml\n"
+    + "   |-- fact2.xml\n\n\n"
+    + "If your cubes are divided between base and derived cubes,\nit makes sense to seperate into two directories, "
+    + "since derived cubes can't be created unless base cube exists.\nIn the other case you can keep them in the cubes "
+    + "directory itself.\nFor dimtables, you can keep your schema files in a directory named either dimtables or "
+    + "dimensiontables.\nEach of these directories is optional and the order of processing is top to bottom.\nCLI will "
+    + "let you know in case of any errors and proceed further without failing in between.";
+  protected final Logger logger = HandlerUtils.getLogger(getClass());
+
+  {
+    logger.setLevel(Level.FINE);
+  }
+
+  private static final FilenameFilter XML_FILTER = new FilenameFilter() {
+    @Override
+    public boolean accept(File dir, String name) {
+      return name.endsWith(".xml");
+    }
+  };
+  @Autowired
+  private JLineShellComponent shell;
+
+  @CliCommand(value = {"schema", "create schema"},
+    help = "Parses the specified resource file and executes commands for "
+      + "creation/updation of schema\nExpected structure is " + STRUCTURE)
+  public void script(
+    @CliOption(key = {"", "db"},
+      help = "<database-to-create-schema-in>", mandatory = true) final String database,
+    @CliOption(key = {"", "file", "path"},
+      help = "<schema-directory>", mandatory = true) final File schemaDirectory) {
+    if (!schemaDirectory.isDirectory()) {
+      throw new IllegalStateException("Schema directory should be a directory");
+    }
+
+    // ignore result. it can fail if database already exists
+    shell.executeCommand("create database " + database);
+    if (shell.executeScriptLine("use " + database)) {
+      createOrUpdate(new File(schemaDirectory, "storages"), "storage",
+        "create storage --path %s", "update storage --name %s --path %s");
+      createOrUpdate(new File(schemaDirectory, "dimensions"), "dimension",
+        "create dimension --path %s", "update dimension --name %s --path %s");
+      createOrUpdate(new File(new File(schemaDirectory, "cubes"), "base"), "base cube",
+        "create cube --path %s", "update cube --name %s --path %s");
+      createOrUpdate(new File(new File(schemaDirectory, "cubes"), "derived"), "derived cube",
+        "create cube --path %s", "update cube --name %s --path %s");
+      createOrUpdate(new File(schemaDirectory, "dimensiontables"), "dimension table",
+        "create dimtable --path %s", "update dimtable --dimtable_name %s --path %s");
+      createOrUpdate(new File(schemaDirectory, "dimtables"), "dimension table",
+        "create dimtable --path %s", "update dimtable --dimtable_name %s --path %s");
+      createOrUpdate(new File(schemaDirectory, "facts"), "fact",
+        "create fact --path %s", "update fact --fact_name %s --path %s");
+      createOrUpdate(new File(schemaDirectory, "segmentations"), "fact",
+        "create segmentation --path %s", "update segmentation --name %s --path %s");
+    } else {
+      throw new IllegalStateException("Switching to database " + database + " failed");
+    }
+  }
+
+  public List<File> createOrUpdate(File parent, String entityType, String createSyntax, String updateSyntax) {
+    List<File> failedFiles = Lists.newArrayList();
+    // Create/update entities
+    if (parent.exists()) {
+      Assert.isTrue(parent.isDirectory(), parent.toString() + " must be a directory");
+      for (File entityFile : parent.listFiles(XML_FILTER)) {
+        String entityName = entityFile.getName().substring(0, entityFile.getName().length() - 4);
+        String entityPath = entityFile.getAbsolutePath();
+        String createCommand = String.format(createSyntax, entityPath);
+        logger.fine(createCommand);
+        if (shell.executeScriptLine(createCommand)) {
+          logger.info("Created " + entityType + " " + entityName);
+        } else {
+          logger.warning("Create failed, trying update");
+          String updateCommand = String.format(updateSyntax, entityName, entityPath);
+          logger.fine(updateCommand);
+          if (shell.executeScriptLine(updateCommand)) {
+            logger.info("Updated " + entityType + " " + entityName);
+          } else {
+            logger.severe("Couldn't create or update " + entityType + " " + entityName);
+            failedFiles.add(entityFile);
+          }
+        }
+      }
+    }
+    if (!failedFiles.isEmpty()) {
+      logger.severe("Failed for " + entityType + ": " + failedFiles);
+    }
+    return failedFiles;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/LensCLITest.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/LensCLITest.java b/lens-cli/src/test/java/org/apache/lens/cli/LensCLITest.java
new file mode 100644
index 0000000..8d80c7b
--- /dev/null
+++ b/lens-cli/src/test/java/org/apache/lens/cli/LensCLITest.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.cli;
+
+import org.springframework.shell.Bootstrap;
+import org.springframework.shell.core.CommandResult;
+import org.springframework.shell.core.JLineShellComponent;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+
+/**
+ * The Class TestLensStorageCommands.
+ */
+public class LensCLITest extends LensCliApplicationTest {
+
+  protected static JLineShellComponent shell;
+
+  @BeforeClass
+  public static void startUp() throws InterruptedException {
+    Bootstrap bootstrap = new Bootstrap();
+    shell = bootstrap.getJLineShellComponent();
+  }
+
+
+  public <T> T execute(String command) throws Throwable {
+    CommandResult commandResult = shell.executeCommand(command);
+    if (commandResult.isSuccess()) {
+      return (T) commandResult.getResult();
+    }
+    if (commandResult.getException() != null) {
+      throw commandResult.getException();
+    }
+    throw new AssertionError("Result is not success and exception is null");
+  }
+
+  public <T> void execute(String command, T result) throws Throwable {
+    Assert.assertEquals(execute(command), result);
+  }
+
+  public <T> void execute(String command, T result, Throwable throwable) throws Throwable {
+    CommandResult commandResult = shell.executeCommand(command);
+    if (commandResult.isSuccess()) {
+      Assert.assertNull(throwable);
+      Assert.assertEquals(commandResult.getResult(), result);
+    } else {
+      Assert.assertNull(result);
+      Assert.assertEquals(commandResult.getException().getClass(), throwable.getClass());
+      Assert.assertEquals(commandResult.getException().getMessage(), throwable.getMessage());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
index c20766c..ae12deb 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
@@ -55,13 +55,13 @@ public class TestLensCubeCommands extends LensCliApplicationTest {
       LensDimensionCommands dimensionCommand = new LensDimensionCommands();
       dimensionCommand.setClient(client);
       dimensionCommand.createDimension(new File(
-          TestLensCubeCommands.class.getClassLoader().getResource("test-detail.xml").toURI()));
+          TestLensCubeCommands.class.getClassLoader().getResource("schema/dimensions/test-detail.xml").toURI()));
       dimensionCommand.createDimension(new File(
-          TestLensCubeCommands.class.getClassLoader().getResource("test-dimension.xml").toURI()));
+          TestLensCubeCommands.class.getClassLoader().getResource("schema/dimensions/test-dimension.xml").toURI()));
       LensCubeCommands command = new LensCubeCommands();
       command.setClient(client);
       LOG.debug("Starting to test cube commands");
-      URL cubeSpec = TestLensCubeCommands.class.getClassLoader().getResource("sample-cube.xml");
+      URL cubeSpec = TestLensCubeCommands.class.getClassLoader().getResource("schema/cubes/base/sample-cube.xml");
       String cubeList = command.showCubes();
       assertFalse(cubeList.contains("sample_cube"));
       command.createCube(new File(cubeSpec.toURI()));

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/TestLensDatabaseCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDatabaseCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDatabaseCommands.java
index 9687c60..7fc8438 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDatabaseCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDatabaseCommands.java
@@ -68,8 +68,8 @@ public class TestLensDatabaseCommands extends LensCliApplicationTest {
     result = command.switchDatabase(myDatabase);
     assertEquals(result, "Successfully switched to my_db");
     if (cascade) {
-      String createOutput = cubeCommand.createCube(
-        new File(TestLensDatabaseCommands.class.getClassLoader().getResource("sample-cube.xml").toURI()));
+      String createOutput = cubeCommand.createCube(new File(TestLensDatabaseCommands.class.getClassLoader()
+        .getResource("schema/cubes/base/sample-cube.xml").toURI()));
       assertEquals(createOutput, "succeeded");
       assertTrue(cubeCommand.showCubes().contains("sample_cube"));
     }

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionCommands.java
index a3f01c3..c29e842 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionCommands.java
@@ -71,8 +71,9 @@ public class TestLensDimensionCommands extends LensCliApplicationTest {
    */
   public static void createDimension() throws URISyntaxException {
     getCommand().createDimension(new File(
-      TestLensCubeCommands.class.getClassLoader().getResource("test-detail.xml").toURI()));
-    URL dimensionSpec = TestLensDimensionCommands.class.getClassLoader().getResource("test-dimension.xml");
+      TestLensCubeCommands.class.getClassLoader().getResource("schema/dimensions/test-detail.xml").toURI()));
+    URL dimensionSpec = TestLensDimensionCommands.class.getClassLoader()
+      .getResource("schema/dimensions/test-dimension.xml");
     getCommand().createDimension(new File(dimensionSpec.toURI()));
   }
 
@@ -85,7 +86,8 @@ public class TestLensDimensionCommands extends LensCliApplicationTest {
   @Test
   public void testDimensionCommands() throws Exception {
     log.debug("Starting to test dimension commands");
-    URL dimensionSpec = TestLensDimensionCommands.class.getClassLoader().getResource("test-dimension.xml");
+    URL dimensionSpec = TestLensDimensionCommands.class.getClassLoader()
+      .getResource("schema/dimensions/test-dimension.xml");
     String dimensionList = getCommand().showDimensions();
     Assert.assertFalse(dimensionList.contains("test_dim"));
     createDimension();

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionTableCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionTableCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionTableCommands.java
index 5d6d768..20289cd 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionTableCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensDimensionTableCommands.java
@@ -85,7 +85,7 @@ public class TestLensDimensionTableCommands extends LensCliApplicationTest {
   @Test
   public void testDimTableCommands() throws IOException, URISyntaxException {
     createDimension();
-    addDim1Table("dim_table2", "dim_table2.xml", DIM_LOCAL);
+    addDim1Table("dim_table2", "schema/dimtables/dim_table2.xml", DIM_LOCAL);
     updateDim1Table();
     testDimStorageActions();
     testDimPartitionActions();
@@ -98,7 +98,8 @@ public class TestLensDimensionTableCommands extends LensCliApplicationTest {
   }
 
   private void createDimension() throws URISyntaxException {
-    URL dimensionSpec = TestLensDimensionTableCommands.class.getClassLoader().getResource("test-dimension.xml");
+    URL dimensionSpec = TestLensDimensionTableCommands.class.getClassLoader()
+      .getResource("schema/dimensions/test-dimension.xml");
     getDimensionCommand().createDimension(new File(dimensionSpec.toURI()));
 
   }
@@ -153,7 +154,7 @@ public class TestLensDimensionTableCommands extends LensCliApplicationTest {
    */
   private static void updateDim1Table() throws IOException {
     LensDimensionTableCommands command = getCommand();
-    URL dimSpec = TestLensFactCommands.class.getClassLoader().getResource("dim_table2.xml");
+    URL dimSpec = TestLensFactCommands.class.getClassLoader().getResource("schema/dimtables/dim_table2.xml");
     StringBuilder sb = new StringBuilder();
     BufferedReader bufferedReader = new BufferedReader(new FileReader(dimSpec.getFile()));
     String s;

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java
index b4cbf34..f176078 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java
@@ -66,7 +66,7 @@ public class TestLensFactCommands extends LensCliApplicationTest {
   }
 
   private void createSampleCube() throws URISyntaxException {
-    URL cubeSpec = TestLensCubeCommands.class.getClassLoader().getResource("sample-cube.xml");
+    URL cubeSpec = TestLensCubeCommands.class.getClassLoader().getResource("schema/cubes/base/sample-cube.xml");
     String cubeList = getCubeCommand().showCubes();
     assertFalse(cubeList.contains("sample_cube"), cubeList);
     getCubeCommand().createCube(new File(cubeSpec.toURI()));
@@ -118,7 +118,7 @@ public class TestLensFactCommands extends LensCliApplicationTest {
     assertEquals(factList, "No fact found", "Fact tables should not be found");
     // add local storage before adding fact table
     TestLensStorageCommands.addLocalStorage(FACT_LOCAL);
-    URL factSpec = TestLensFactCommands.class.getClassLoader().getResource("fact1.xml");
+    URL factSpec = TestLensFactCommands.class.getClassLoader().getResource("schema/facts/fact1.xml");
     try {
       command.createFact(new File(factSpec.toURI()));
     } catch (Exception e) {
@@ -147,7 +147,7 @@ public class TestLensFactCommands extends LensCliApplicationTest {
   public static void updateFact1Table() {
     try {
       LensFactCommands command = getCommand();
-      URL factSpec = TestLensFactCommands.class.getClassLoader().getResource("fact1.xml");
+      URL factSpec = TestLensFactCommands.class.getClassLoader().getResource("schema/facts/fact1.xml");
       StringBuilder sb = new StringBuilder();
       BufferedReader bufferedReader = new BufferedReader(new FileReader(factSpec.getFile()));
       String s;

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommandsWithMissingWeight.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommandsWithMissingWeight.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommandsWithMissingWeight.java
index 24f9279..dcbb355 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommandsWithMissingWeight.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommandsWithMissingWeight.java
@@ -53,10 +53,10 @@ public class TestLensFactCommandsWithMissingWeight extends LensCliApplicationTes
   public static final String FACT_NAME = "fact_without_wt";
 
   /* The File name with cube details */
-  public static final String CUBE_XML_FILE = "cube_with_no_weight_facts.xml";
+  public static final String CUBE_XML_FILE = "schema/cubes/base/cube_with_no_weight_facts.xml";
 
   /* The File name with fact details */
-  public static final String FACT_XML_FILE = "fact_without_weight.xml";
+  public static final String FACT_XML_FILE = "schema/facts/fact_without_weight.xml";
 
   /** The command. */
   private static LensFactCommands command = null;

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
index e75fc0e..e1eaae5 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
@@ -416,10 +416,10 @@ public class TestLensQueryCommands extends LensCliApplicationTest {
     command.setClient(client);
 
     log.debug("Starting to test cube commands");
-    URL cubeSpec = TestLensQueryCommands.class.getClassLoader().getResource("sample-cube.xml");
+    URL cubeSpec = TestLensQueryCommands.class.getClassLoader().getResource("schema/cubes/base/sample-cube.xml");
     command.createCube(new File(cubeSpec.toURI()));
     TestLensDimensionCommands.createDimension();
-    TestLensDimensionTableCommands.addDim1Table("dim_table", "dim_table.xml", "local");
+    TestLensDimensionTableCommands.addDim1Table("dim_table", "schema/dimtables/dim_table.xml", "local");
 
     // Add partition
     URL dataDir = TestLensQueryCommands.class.getClassLoader().getResource("dim2-part");

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/TestLensSchemaCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensSchemaCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensSchemaCommands.java
new file mode 100644
index 0000000..ca6db2c
--- /dev/null
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensSchemaCommands.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.cli;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+
+/**
+ * The Class TestLensStorageCommands.
+ */
+public class TestLensSchemaCommands extends LensCLITest {
+
+  @Test
+  public void testCreateSchema() throws Throwable {
+    String schemaDirectory = TestLensSchemaCommands.class.getClassLoader().getResource("schema").getFile();
+    String dbName = "schema_command_db";
+    try {
+      execute("schema --db " + dbName + " --path " + schemaDirectory, null);
+      assertTrue(((String) execute("show databases")).contains(dbName));
+      execute("show storages", "local");
+      execute("show dimensions", "test_detail\ntest_dim");
+      execute("show cubes", "sample_cube\ncube_with_no_weight_facts");
+      assertTrue(((String) execute("show dimtables")).contains("dim_table"));
+      assertTrue(((String) execute("show facts")).contains("fact1"));
+      execute("show segmentations", "seg1");
+    } finally {
+      execute("drop database --db " + dbName + " --cascade", "succeeded");
+      assertFalse(((String) execute("show databases")).contains(dbName));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/TestLensSegmentationCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensSegmentationCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensSegmentationCommands.java
index e6d4bc5..beafd43 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensSegmentationCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensSegmentationCommands.java
@@ -41,7 +41,7 @@ public class TestLensSegmentationCommands extends LensCliApplicationTest {
   private static LensCubeCommands cubeCommands = null;
 
   private void createSampleCube() throws URISyntaxException {
-    URL cubeSpec = TestLensCubeCommands.class.getClassLoader().getResource("sample-cube.xml");
+    URL cubeSpec = TestLensCubeCommands.class.getClassLoader().getResource("schema/cubes/base/sample-cube.xml");
     String cubeList = getCubeCommand().showCubes();
     assertFalse(cubeList.contains("sample_cube"), cubeList);
     getCubeCommand().createCube(new File(cubeSpec.toURI()));
@@ -72,7 +72,7 @@ public class TestLensSegmentationCommands extends LensCliApplicationTest {
     String segList = command.showSegmentations(null);
     assertEquals(command.showSegmentations("sample_cube"), "No segmentation found for sample_cube");
     assertEquals(segList, "No segmentation found");
-    URL segSpec = TestLensSegmentationCommands.class.getClassLoader().getResource("seg1.xml");
+    URL segSpec = TestLensSegmentationCommands.class.getClassLoader().getResource("schema/segmentations/seg1.xml");
     try {
       command.createSegmentation(new File(segSpec.toURI()));
     } catch (Exception e) {
@@ -91,7 +91,7 @@ public class TestLensSegmentationCommands extends LensCliApplicationTest {
   public static void testUpdateSegmentation() {
     try {
       LensSegmentationCommands command = getCommand();
-      URL segSpec = TestLensSegmentationCommands.class.getClassLoader().getResource("seg1.xml");
+      URL segSpec = TestLensSegmentationCommands.class.getClassLoader().getResource("schema/segmentations/seg1.xml");
       StringBuilder sb = new StringBuilder();
       BufferedReader bufferedReader = new BufferedReader(new FileReader(segSpec.getFile()));
       String s;

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/TestLensStorageCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensStorageCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensStorageCommands.java
index c4ab614..d320d79 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensStorageCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensStorageCommands.java
@@ -92,8 +92,8 @@ public class TestLensStorageCommands extends LensCliApplicationTest {
    */
   public static synchronized void addLocalStorage(String storageName) throws IOException {
     LensStorageCommands command = getCommand();
-    URL storageSpec = TestLensStorageCommands.class.getClassLoader().getResource("local-storage.xml");
-    File newFile = new File("target/local-" + storageName + ".xml");
+    URL storageSpec = TestLensStorageCommands.class.getClassLoader().getResource("schema/storages/local-storage.xml");
+    File newFile = new File(storageSpec.getFile().replace("local-storage", "local-"+storageName));
     try {
       StringBuilder sb = new StringBuilder();
       BufferedReader bufferedReader = new BufferedReader(new FileReader(storageSpec.getFile()));
@@ -131,7 +131,7 @@ public class TestLensStorageCommands extends LensCliApplicationTest {
   private void testUpdateStorage(String storageName) throws IOException {
 
     LensStorageCommands command = getCommand();
-    URL storageSpec = TestLensStorageCommands.class.getClassLoader().getResource("local-storage.xml");
+    URL storageSpec = TestLensStorageCommands.class.getClassLoader().getResource("schema/storages/local-storage.xml");
     StringBuilder sb = new StringBuilder();
     BufferedReader bufferedReader = new BufferedReader(new FileReader(storageSpec.getFile()));
     String s;

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/java/org/apache/lens/cli/doc/TestGenerateCLIUserDoc.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/doc/TestGenerateCLIUserDoc.java b/lens-cli/src/test/java/org/apache/lens/cli/doc/TestGenerateCLIUserDoc.java
index 95e6b4e..34bb5ce 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/doc/TestGenerateCLIUserDoc.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/doc/TestGenerateCLIUserDoc.java
@@ -28,24 +28,53 @@ import org.apache.lens.cli.commands.annotations.UserDocumentation;
 
 import org.apache.commons.lang.StringUtils;
 
+import org.springframework.shell.core.CommandMarker;
 import org.springframework.shell.core.annotation.CliCommand;
 import org.springframework.shell.core.annotation.CliOption;
 import org.testng.annotations.Test;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
+import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
 public class TestGenerateCLIUserDoc {
   public static final String APT_FILE = "../src/site/apt/user/cli.apt";
-
+  @Data
+  static class DocEntry {
+    private String command;
+    private String[] help;
+    private int maxLength = 0;
+    public DocEntry(String command, String help) {
+      this.command = command;
+      this.help = help.split("\r|\n");
+      for (int i = 0; i < this.help.length; i++) {
+        this.help[i] = this.help[i].replaceAll("\\|", "\\\\|");
+        if (i > 0) {
+          this.help[i] = this.help[i].replaceAll("\\ ", "\\\\ ");
+        }
+      }
+      for (String line: this.help) {
+        if (line.length() > maxLength) {
+          maxLength = line.length();
+        }
+      }
+      for (int i = 0; i < this.help.length; i++) {
+        StringBuilder sb = new StringBuilder(this.help[i]);
+        while (sb.length() < maxLength) {
+          sb.append(" ");
+        }
+        this.help[i] = sb.append("\\ ").toString();
+      }
+    }
+  }
   @Test
   public void generateDoc() throws IOException {
     BufferedWriter bw = new BufferedWriter(new FileWriter(new File(APT_FILE)));
     StringBuilder sb = new StringBuilder();
     sb.append(getCLIIntroduction()).append("\n\n\n");
-    List<Class<? extends BaseLensCommand>> classes = Lists.newArrayList(
+    List<Class<? extends CommandMarker>> classes = Lists.newArrayList(
       LensConnectionCommands.class,
       LensDatabaseCommands.class,
       LensStorageCommands.class,
@@ -55,8 +84,10 @@ public class TestGenerateCLIUserDoc {
       LensDimensionTableCommands.class,
       LensNativeTableCommands.class,
       LensQueryCommands.class,
-      LensLogResourceCommands.class
+      LensLogResourceCommands.class,
+      LensSchemaCommands.class
     );
+
     for (Class claz : classes) {
       UserDocumentation doc = (UserDocumentation) claz.getAnnotation(UserDocumentation.class);
       if (doc != null && StringUtils.isNotBlank(doc.title())) {
@@ -79,13 +110,13 @@ public class TestGenerateCLIUserDoc {
           log.info("Not adding " + method.getDeclaringClass().getSimpleName() + "#" + method.getName());
         }
       }
-
+      List<DocEntry> docEntries = Lists.newArrayList();
       for (Method method : methods) {
         CliCommand annot = method.getAnnotation(CliCommand.class);
-        sb.append("|");
+        StringBuilder commandBuilder = new StringBuilder();
         String sep = "";
         for (String value : annot.value()) {
-          sb.append(sep).append(value);
+          commandBuilder.append(sep).append(value);
           sep = "/";
         }
         for (Annotation[] annotations : method.getParameterAnnotations()) {
@@ -99,32 +130,39 @@ public class TestGenerateCLIUserDoc {
                 keys.remove("");
               }
               if (!keys.isEmpty()) {
-                sb.append(" ");
+                commandBuilder.append(" ");
                 if (!cliOption.mandatory()) {
-                  sb.append("[");
+                  commandBuilder.append("[");
                 }
                 if (optional) {
-                  sb.append("[");
+                  commandBuilder.append("[");
                 }
                 sep = "";
                 for (String key : keys) {
-                  sb.append(sep).append("--").append(key);
+                  commandBuilder.append(sep).append("--").append(key);
                   sep = "/";
                 }
                 if (optional) {
-                  sb.append("]");
+                  commandBuilder.append("]");
                 }
                 sep = "";
               }
-              sb.append(" ").append(cliOption.help().replaceAll("<", "\\\\<").replaceAll(">", "\\\\>"));
+              commandBuilder.append(" ").append(cliOption.help().replaceAll("<", "\\\\<").replaceAll(">", "\\\\>"));
               if (!cliOption.mandatory()) {
-                sb.append("]");
+                commandBuilder.append("]");
               }
             }
           }
         }
-        sb.append("|").append(annot.help().replaceAll("<", "<<<").replaceAll(">", ">>>")).append("|").append("\n")
-          .append("*--+--+\n");
+        docEntries.add(new DocEntry(commandBuilder.toString(),
+          annot.help().replaceAll("<", "<<<").replaceAll(">", ">>>")));
+      }
+      for (DocEntry entry: docEntries) {
+        for (int i = 0; i < entry.getHelp().length; i++) {
+          sb.append("|").append(i == 0 ? entry.getCommand() : entry.getCommand().replaceAll(".", " "))
+            .append("|").append(entry.getHelp()[i]).append("|").append("\n");
+        }
+        sb.append("*--+--+\n");
       }
       sb.append("  <<").append(getReadableName(claz.getSimpleName())).append(">>\n\n===\n\n");
     }

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/cube_with_no_weight_facts.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/cube_with_no_weight_facts.xml b/lens-cli/src/test/resources/cube_with_no_weight_facts.xml
deleted file mode 100644
index 4673ca4..0000000
--- a/lens-cli/src/test/resources/cube_with_no_weight_facts.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<x_base_cube name="cube_with_no_weight_facts" xmlns="uri:lens:cube:0.1"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
-    <measures>
-        <measure name="measure1" _type="BIGINT" />
-        <measure name="measure2" _type="INT" default_aggr="SUM" />
-        <measure name="measure3" _type="FLOAT" default_aggr="MAX" start_time='2013-12-12T00:00:00' />
-        <measure name="measure4" _type="DOUBLE" default_aggr="MIN" />
-    </measures>
-    <dim_attributes>
-        <dim_attribute name="dim1" _type="INT" />
-        <dim_attribute name="dim2" _type="INT" start_time='2013-12-01T00:00:00' />
-        <dim_attribute name="dim3" _type="INT"/>
-    </dim_attributes>
-    <expressions>
-        <expression name="expr_msr5" _type="DOUBLE">
-            <expr_spec expr = "measure3 + measure4" end_time='2013-12-12T00:00:00'/>
-            <expr_spec expr = "measure3 + measure4 + 0.01" start_time='2013-12-12T00:00:00'/>
-        </expression>
-    </expressions>
-</x_base_cube>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/dim_table.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/dim_table.xml b/lens-cli/src/test/resources/dim_table.xml
deleted file mode 100644
index eb4ddfc..0000000
--- a/lens-cli/src/test/resources/dim_table.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<x_dimension_table dimension_name="test_dim" table_name="dim_table" weight="100.0" xmlns="uri:lens:cube:0.1"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
-  <columns>
-    <column comment="ID" name="id" _type="INT"/>
-    <column comment="name" name="name" _type="STRING"/>
-    <column comment="more details" name="detail" _type="STRING"/>
-    <column comment="d2 ID" name="d2id" _type="INT"/>
-  </columns>
-  <properties>
-    <property name="dim1.prop" value="d1"/>
-  </properties>
-  <storage_tables>
-    <storage_table>
-      <update_periods>
-        <update_period>HOURLY</update_period>
-      </update_periods>
-      <storage_name>local</storage_name>
-      <table_desc external="true" field_delimiter=","
-        table_location="${project.build.directory}/metastore/examples/local">
-        <part_cols>
-          <column comment="Time column" name="dt" _type="STRING"/>
-        </part_cols>
-        <time_part_cols>dt</time_part_cols>
-      </table_desc>
-    </storage_table>
-  </storage_tables>
-</x_dimension_table>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/dim_table2.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/dim_table2.xml b/lens-cli/src/test/resources/dim_table2.xml
deleted file mode 100644
index 8440e28..0000000
--- a/lens-cli/src/test/resources/dim_table2.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<x_dimension_table dimension_name="test_dim" table_name="dim_table2" weight="100.0" xmlns="uri:lens:cube:0.1"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
-  <columns>
-    <column comment="ID" name="id" _type="INT"/>
-    <column comment="name" name="name" _type="STRING"/>
-    <column comment="more details for dim2" name="detail2" _type="STRING"/>
-  </columns>
-
-  <properties>
-    <property name="dim2.prop" value="d2"/>
-  </properties>
-  <storage_tables>
-    <storage_table>
-      <update_periods>
-        <update_period>HOURLY</update_period>
-      </update_periods>
-      <storage_name>dim_local</storage_name>
-      <table_desc external="true" field_delimiter=","
-        table_location="${project.build.directory}/metastore/examples/dim1">
-        <part_cols>
-          <column comment="Time column" name="dt" _type="STRING"/>
-        </part_cols>
-        <time_part_cols>dt</time_part_cols>
-      </table_desc>
-    </storage_table>
-  </storage_tables>
-</x_dimension_table>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/fact1.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/fact1.xml b/lens-cli/src/test/resources/fact1.xml
deleted file mode 100644
index b18a393..0000000
--- a/lens-cli/src/test/resources/fact1.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<x_fact_table cube_name="sample_cube" name="fact1" weight="100.0" xmlns="uri:lens:cube:0.1"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
-  <columns>
-    <column comment="" name="dim1" _type="INT"/>
-    <column comment="" name="measure1" _type="BIGINT"/>
-    <column comment="" name="measure2" _type="INT"/>
-    <column comment="" name="measure3" _type="FLOAT"/>
-  </columns>
-  <properties>
-    <property name="fact1.prop" value="f1"/>
-    <property name="cube.fact.is.aggregated" value="true"/>
-  </properties>
-  <storage_tables>
-    <storage_table>
-      <update_periods>
-        <update_period>HOURLY</update_period>
-        <update_period>DAILY</update_period>
-        <update_period>MONTHLY</update_period>
-      </update_periods>
-      <storage_name>fact_local</storage_name>
-      <table_desc external="true" field_delimiter=","
-        table_location="${project.build.directory}/metastore/examples/fact1_local">
-        <part_cols>
-          <column comment="Time column" name="dt" _type="STRING"/>
-        </part_cols>
-        <time_part_cols>dt</time_part_cols>
-      </table_desc>
-    </storage_table>
-  </storage_tables>
-</x_fact_table>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/fact_without_weight.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/fact_without_weight.xml b/lens-cli/src/test/resources/fact_without_weight.xml
deleted file mode 100644
index 0c124b2..0000000
--- a/lens-cli/src/test/resources/fact_without_weight.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<x_fact_table cube_name="cube_with_no_weight_facts" name="fact_without_wt" xmlns="uri:lens:cube:0.1"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
-  <columns>
-    <column comment="" name="dim1" _type="INT"/>
-    <column comment="" name="measure1" _type="BIGINT"/>
-    <column comment="" name="measure2" _type="INT"/>
-    <column comment="" name="measure3" _type="FLOAT"/>
-  </columns>
-  <properties>
-    <property name="fact_without_wt.prop" value="f1"/>
-    <property name="cube.fact.is.aggregated" value="true"/>
-  </properties>
-  <storage_tables>
-    <storage_table>
-      <update_periods>
-        <update_period>HOURLY</update_period>
-        <update_period>DAILY</update_period>
-        <update_period>MONTHLY</update_period>
-      </update_periods>
-      <storage_name>fact_local_without_wt</storage_name>
-      <table_desc external="true" field_delimiter=","
-        table_location="${project.build.directory}/metastore/examples/fact_local_without_wt">
-        <part_cols>
-          <column comment="Time column" name="dt" _type="STRING"/>
-        </part_cols>
-        <time_part_cols>dt</time_part_cols>
-      </table_desc>
-    </storage_table>
-  </storage_tables>
-</x_fact_table>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/local-storage.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/local-storage.xml b/lens-cli/src/test/resources/local-storage.xml
deleted file mode 100644
index 6551375..0000000
--- a/lens-cli/src/test/resources/local-storage.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<x_storage classname="org.apache.lens.cube.metadata.HDFSStorage" name="local" xmlns="uri:lens:cube:0.1"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
-  <properties>
-    <property name="storage.url" value="file:///" />
-  </properties>
-</x_storage>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/sample-cube.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/sample-cube.xml b/lens-cli/src/test/resources/sample-cube.xml
deleted file mode 100644
index 2d6bc34..0000000
--- a/lens-cli/src/test/resources/sample-cube.xml
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<x_base_cube name="sample_cube" xmlns="uri:lens:cube:0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
-  <properties>
-    <property name="sample_cube.prop" value="sample" />
-    <property name="cube.sample_cube.timed.dimensions.list" value="dt" />
-  </properties>
-  <measures>
-    <measure name="measure1" _type="BIGINT" />
-    <measure name="measure2" _type="INT" default_aggr="SUM" />
-    <measure name="measure3" _type="FLOAT" default_aggr="MAX" start_time='2013-12-12T00:00:00' />
-    <measure name="measure4" _type="DOUBLE" default_aggr="MIN" />
-    <measure name="measure5" _type="BIGINT">
-      <tags>
-        <property name="category" value="primary"/>
-        <property name="is_ui_visible" value="true"/>
-      </tags>
-    </measure>
-    <measure name="measure6" _type="BIGINT">
-      <tags>
-        <property name="category" value="secondary"/>
-        <property name="is_ui_visible" value="false"/>
-      </tags>
-    </measure>
-  </measures>
-  <dim_attributes>
-    <dim_attribute name="dim1" _type="INT" />
-    <dim_attribute name="dim2" _type="INT" start_time='2013-12-01T00:00:00' />
-    <dim_attribute name="dim3" _type="INT"/>
-    <dim_attribute name="dimDetail" _type="string" description="City name to which the customer belongs"
-                   display_string="Customer City">
-      <chain_ref_column chain_name="testdimchain" ref_col="detail" />
-      <chain_ref_column chain_name="testdetailchain" ref_col="name" />
-    </dim_attribute>
-    <dim_attribute name="dim4" _type="BIGINT">
-      <tags>
-         <property name="category" value="primary"/>
-          <property name="is_ui_visible" value="true"/>
-        </tags>
-    </dim_attribute>
-  </dim_attributes>
-  <expressions>
-    <expression name="expr_msr5" _type="DOUBLE">
-      <expr_spec expr = "measure3 + measure4" end_time='2013-12-12T00:00:00'/>
-      <expr_spec expr = "measure3 + measure4 + 0.01" start_time='2013-12-12T00:00:00'/>
-    </expression>
-    <expression name="expr_msr6" _type="DOUBLE">
-      <tags>
-        <property name="category" value="primary"/>
-        <property name="is_ui_visible" value="true"/>
-      </tags>
-      <expr_spec expr = "measure3 + measure4" start_time='2013-12-12T00:00:00' />
-      <expr_spec expr = "measure3 + measure4 + 0.01" end_time='2013-12-12T00:00:00'/>
-    </expression>
-  </expressions>
-  <join_chains>
-    <join_chain name="testdimchain">
-      <paths>
-        <path>
-          <edges>
-            <edge>
-              <from table="sample_cube" column="dim1" />
-              <to table="test_dim" column="id" />
-            </edge>
-          </edges>
-        </path>
-      </paths>
-    </join_chain>
-    <join_chain name="testdetailchain">
-      <paths>
-        <path>
-          <edges>
-            <edge>
-              <from table="sample_cube" column="dim2" />
-              <to table="test_detail" column="id" />
-            </edge>
-          </edges>
-        </path>
-      </paths>
-    </join_chain>
-  </join_chains>
-</x_base_cube>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/schema/cubes/base/cube_with_no_weight_facts.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/schema/cubes/base/cube_with_no_weight_facts.xml b/lens-cli/src/test/resources/schema/cubes/base/cube_with_no_weight_facts.xml
new file mode 100644
index 0000000..4673ca4
--- /dev/null
+++ b/lens-cli/src/test/resources/schema/cubes/base/cube_with_no_weight_facts.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<x_base_cube name="cube_with_no_weight_facts" xmlns="uri:lens:cube:0.1"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
+    <measures>
+        <measure name="measure1" _type="BIGINT" />
+        <measure name="measure2" _type="INT" default_aggr="SUM" />
+        <measure name="measure3" _type="FLOAT" default_aggr="MAX" start_time='2013-12-12T00:00:00' />
+        <measure name="measure4" _type="DOUBLE" default_aggr="MIN" />
+    </measures>
+    <dim_attributes>
+        <dim_attribute name="dim1" _type="INT" />
+        <dim_attribute name="dim2" _type="INT" start_time='2013-12-01T00:00:00' />
+        <dim_attribute name="dim3" _type="INT"/>
+    </dim_attributes>
+    <expressions>
+        <expression name="expr_msr5" _type="DOUBLE">
+            <expr_spec expr = "measure3 + measure4" end_time='2013-12-12T00:00:00'/>
+            <expr_spec expr = "measure3 + measure4 + 0.01" start_time='2013-12-12T00:00:00'/>
+        </expression>
+    </expressions>
+</x_base_cube>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/schema/cubes/base/sample-cube.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/schema/cubes/base/sample-cube.xml b/lens-cli/src/test/resources/schema/cubes/base/sample-cube.xml
new file mode 100644
index 0000000..2d6bc34
--- /dev/null
+++ b/lens-cli/src/test/resources/schema/cubes/base/sample-cube.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<x_base_cube name="sample_cube" xmlns="uri:lens:cube:0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
+  <properties>
+    <property name="sample_cube.prop" value="sample" />
+    <property name="cube.sample_cube.timed.dimensions.list" value="dt" />
+  </properties>
+  <measures>
+    <measure name="measure1" _type="BIGINT" />
+    <measure name="measure2" _type="INT" default_aggr="SUM" />
+    <measure name="measure3" _type="FLOAT" default_aggr="MAX" start_time='2013-12-12T00:00:00' />
+    <measure name="measure4" _type="DOUBLE" default_aggr="MIN" />
+    <measure name="measure5" _type="BIGINT">
+      <tags>
+        <property name="category" value="primary"/>
+        <property name="is_ui_visible" value="true"/>
+      </tags>
+    </measure>
+    <measure name="measure6" _type="BIGINT">
+      <tags>
+        <property name="category" value="secondary"/>
+        <property name="is_ui_visible" value="false"/>
+      </tags>
+    </measure>
+  </measures>
+  <dim_attributes>
+    <dim_attribute name="dim1" _type="INT" />
+    <dim_attribute name="dim2" _type="INT" start_time='2013-12-01T00:00:00' />
+    <dim_attribute name="dim3" _type="INT"/>
+    <dim_attribute name="dimDetail" _type="string" description="City name to which the customer belongs"
+                   display_string="Customer City">
+      <chain_ref_column chain_name="testdimchain" ref_col="detail" />
+      <chain_ref_column chain_name="testdetailchain" ref_col="name" />
+    </dim_attribute>
+    <dim_attribute name="dim4" _type="BIGINT">
+      <tags>
+         <property name="category" value="primary"/>
+          <property name="is_ui_visible" value="true"/>
+        </tags>
+    </dim_attribute>
+  </dim_attributes>
+  <expressions>
+    <expression name="expr_msr5" _type="DOUBLE">
+      <expr_spec expr = "measure3 + measure4" end_time='2013-12-12T00:00:00'/>
+      <expr_spec expr = "measure3 + measure4 + 0.01" start_time='2013-12-12T00:00:00'/>
+    </expression>
+    <expression name="expr_msr6" _type="DOUBLE">
+      <tags>
+        <property name="category" value="primary"/>
+        <property name="is_ui_visible" value="true"/>
+      </tags>
+      <expr_spec expr = "measure3 + measure4" start_time='2013-12-12T00:00:00' />
+      <expr_spec expr = "measure3 + measure4 + 0.01" end_time='2013-12-12T00:00:00'/>
+    </expression>
+  </expressions>
+  <join_chains>
+    <join_chain name="testdimchain">
+      <paths>
+        <path>
+          <edges>
+            <edge>
+              <from table="sample_cube" column="dim1" />
+              <to table="test_dim" column="id" />
+            </edge>
+          </edges>
+        </path>
+      </paths>
+    </join_chain>
+    <join_chain name="testdetailchain">
+      <paths>
+        <path>
+          <edges>
+            <edge>
+              <from table="sample_cube" column="dim2" />
+              <to table="test_detail" column="id" />
+            </edge>
+          </edges>
+        </path>
+      </paths>
+    </join_chain>
+  </join_chains>
+</x_base_cube>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/schema/dimensions/test-detail.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/schema/dimensions/test-detail.xml b/lens-cli/src/test/resources/schema/dimensions/test-detail.xml
new file mode 100644
index 0000000..b51c188
--- /dev/null
+++ b/lens-cli/src/test/resources/schema/dimensions/test-detail.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<x_dimension name="test_detail" xmlns="uri:lens:cube:0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
+  <attributes>
+    <dim_attribute name="id" _type="INT" />
+    <dim_attribute name="name" _type="STRING" />
+  </attributes>
+
+  <properties>
+    <property name="dimension.test_dim.timed.dimension" value="dt" />
+  </properties>
+</x_dimension>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/schema/dimensions/test-dimension.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/schema/dimensions/test-dimension.xml b/lens-cli/src/test/resources/schema/dimensions/test-dimension.xml
new file mode 100644
index 0000000..01de8e6
--- /dev/null
+++ b/lens-cli/src/test/resources/schema/dimensions/test-dimension.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<x_dimension name="test_dim" xmlns="uri:lens:cube:0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
+  <attributes>
+    <dim_attribute name="id" _type="INT" />
+    <dim_attribute name="name" _type="STRING" />
+    <dim_attribute name="detail" _type="STRING" start_time='2013-12-01T00:00:00' />
+    <dim_attribute name="d2id" _type="INT" start_time='2013-12-01T00:00:00'/>
+    <dim_attribute name="inline" _type="STRING" >
+      <values>A</values>
+      <values>B</values>
+      <values>C</values>
+    </dim_attribute>
+    <dim_attribute name="location">
+      <hierarchy>
+        <dim_attribute name="zipcode" _type="INT" />
+        <dim_attribute name="city" _type="STRING" />
+        <dim_attribute name="state" _type="STRING" />
+      </hierarchy>
+    </dim_attribute>
+  </attributes>
+
+  <join_chains>
+    <join_chain name="dim2chain">
+      <paths>
+        <path>
+         <edges>
+            <edge>
+              <from table="test_dim" column="d2id" />
+              <to table="test_detail" column="id" />
+            </edge>
+          </edges>
+        </path>
+      </paths>
+    </join_chain>
+  </join_chains>
+  <properties>
+    <property name="test_dim.prop" value="test" />
+    <property name="dimension.test_dim.timed.dimension" value="dt" />
+  </properties>
+</x_dimension>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/schema/dimtables/dim_table.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/schema/dimtables/dim_table.xml b/lens-cli/src/test/resources/schema/dimtables/dim_table.xml
new file mode 100644
index 0000000..eb4ddfc
--- /dev/null
+++ b/lens-cli/src/test/resources/schema/dimtables/dim_table.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<x_dimension_table dimension_name="test_dim" table_name="dim_table" weight="100.0" xmlns="uri:lens:cube:0.1"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
+  <columns>
+    <column comment="ID" name="id" _type="INT"/>
+    <column comment="name" name="name" _type="STRING"/>
+    <column comment="more details" name="detail" _type="STRING"/>
+    <column comment="d2 ID" name="d2id" _type="INT"/>
+  </columns>
+  <properties>
+    <property name="dim1.prop" value="d1"/>
+  </properties>
+  <storage_tables>
+    <storage_table>
+      <update_periods>
+        <update_period>HOURLY</update_period>
+      </update_periods>
+      <storage_name>local</storage_name>
+      <table_desc external="true" field_delimiter=","
+        table_location="${project.build.directory}/metastore/examples/local">
+        <part_cols>
+          <column comment="Time column" name="dt" _type="STRING"/>
+        </part_cols>
+        <time_part_cols>dt</time_part_cols>
+      </table_desc>
+    </storage_table>
+  </storage_tables>
+</x_dimension_table>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/schema/dimtables/dim_table2.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/schema/dimtables/dim_table2.xml b/lens-cli/src/test/resources/schema/dimtables/dim_table2.xml
new file mode 100644
index 0000000..8440e28
--- /dev/null
+++ b/lens-cli/src/test/resources/schema/dimtables/dim_table2.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<x_dimension_table dimension_name="test_dim" table_name="dim_table2" weight="100.0" xmlns="uri:lens:cube:0.1"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
+  <columns>
+    <column comment="ID" name="id" _type="INT"/>
+    <column comment="name" name="name" _type="STRING"/>
+    <column comment="more details for dim2" name="detail2" _type="STRING"/>
+  </columns>
+
+  <properties>
+    <property name="dim2.prop" value="d2"/>
+  </properties>
+  <storage_tables>
+    <storage_table>
+      <update_periods>
+        <update_period>HOURLY</update_period>
+      </update_periods>
+      <storage_name>dim_local</storage_name>
+      <table_desc external="true" field_delimiter=","
+        table_location="${project.build.directory}/metastore/examples/dim1">
+        <part_cols>
+          <column comment="Time column" name="dt" _type="STRING"/>
+        </part_cols>
+        <time_part_cols>dt</time_part_cols>
+      </table_desc>
+    </storage_table>
+  </storage_tables>
+</x_dimension_table>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/schema/facts/fact1.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/schema/facts/fact1.xml b/lens-cli/src/test/resources/schema/facts/fact1.xml
new file mode 100644
index 0000000..b18a393
--- /dev/null
+++ b/lens-cli/src/test/resources/schema/facts/fact1.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<x_fact_table cube_name="sample_cube" name="fact1" weight="100.0" xmlns="uri:lens:cube:0.1"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
+  <columns>
+    <column comment="" name="dim1" _type="INT"/>
+    <column comment="" name="measure1" _type="BIGINT"/>
+    <column comment="" name="measure2" _type="INT"/>
+    <column comment="" name="measure3" _type="FLOAT"/>
+  </columns>
+  <properties>
+    <property name="fact1.prop" value="f1"/>
+    <property name="cube.fact.is.aggregated" value="true"/>
+  </properties>
+  <storage_tables>
+    <storage_table>
+      <update_periods>
+        <update_period>HOURLY</update_period>
+        <update_period>DAILY</update_period>
+        <update_period>MONTHLY</update_period>
+      </update_periods>
+      <storage_name>fact_local</storage_name>
+      <table_desc external="true" field_delimiter=","
+        table_location="${project.build.directory}/metastore/examples/fact1_local">
+        <part_cols>
+          <column comment="Time column" name="dt" _type="STRING"/>
+        </part_cols>
+        <time_part_cols>dt</time_part_cols>
+      </table_desc>
+    </storage_table>
+  </storage_tables>
+</x_fact_table>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/schema/facts/fact_without_weight.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/schema/facts/fact_without_weight.xml b/lens-cli/src/test/resources/schema/facts/fact_without_weight.xml
new file mode 100644
index 0000000..0c124b2
--- /dev/null
+++ b/lens-cli/src/test/resources/schema/facts/fact_without_weight.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<x_fact_table cube_name="cube_with_no_weight_facts" name="fact_without_wt" xmlns="uri:lens:cube:0.1"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
+  <columns>
+    <column comment="" name="dim1" _type="INT"/>
+    <column comment="" name="measure1" _type="BIGINT"/>
+    <column comment="" name="measure2" _type="INT"/>
+    <column comment="" name="measure3" _type="FLOAT"/>
+  </columns>
+  <properties>
+    <property name="fact_without_wt.prop" value="f1"/>
+    <property name="cube.fact.is.aggregated" value="true"/>
+  </properties>
+  <storage_tables>
+    <storage_table>
+      <update_periods>
+        <update_period>HOURLY</update_period>
+        <update_period>DAILY</update_period>
+        <update_period>MONTHLY</update_period>
+      </update_periods>
+      <storage_name>fact_local_without_wt</storage_name>
+      <table_desc external="true" field_delimiter=","
+        table_location="${project.build.directory}/metastore/examples/fact_local_without_wt">
+        <part_cols>
+          <column comment="Time column" name="dt" _type="STRING"/>
+        </part_cols>
+        <time_part_cols>dt</time_part_cols>
+      </table_desc>
+    </storage_table>
+  </storage_tables>
+</x_fact_table>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/schema/segmentations/seg1.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/schema/segmentations/seg1.xml b/lens-cli/src/test/resources/schema/segmentations/seg1.xml
new file mode 100644
index 0000000..8a39915
--- /dev/null
+++ b/lens-cli/src/test/resources/schema/segmentations/seg1.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<x_segmentation cube_name="sample_cube" name="seg1" weight="100.0" xmlns="uri:lens:cube:0.1"
+                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
+    <properties>
+        <property name="seg1.prop" value="s1"/>
+        <property name="cube.segmentation.relative.start.time" value="now -10days"/>
+    </properties>
+    <segements>
+        <segment cube_name="cube11">
+            <segment_parameters>
+                <property name="lens.metastore.cube.column.mapping" value="foo=bar"/>
+            </segment_parameters>
+        </segment>
+        <segment cube_name="cube22">
+            <segment_parameters>
+                <property name="lens.metastore.cube.column.mapping" value="foo1=bar1"/>
+            </segment_parameters>
+        </segment>
+        <segment cube_name="cube33">
+            <segment_parameters>
+                <property name="lens.metastore.cube.column.mapping" value="foo2=bar2"/>
+            </segment_parameters>
+        </segment>
+    </segements>
+</x_segmentation>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/schema/storages/local-storage.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/schema/storages/local-storage.xml b/lens-cli/src/test/resources/schema/storages/local-storage.xml
new file mode 100644
index 0000000..4dd0f0c
--- /dev/null
+++ b/lens-cli/src/test/resources/schema/storages/local-storage.xml
@@ -0,0 +1,26 @@
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<x_storage classname="org.apache.lens.cube.metadata.HDFSStorage" name="local" xmlns="uri:lens:cube:0.1"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
+  <properties>
+    <property name="storage.url" value="file:///" />
+  </properties>
+</x_storage>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/seg1.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/seg1.xml b/lens-cli/src/test/resources/seg1.xml
deleted file mode 100644
index 8a39915..0000000
--- a/lens-cli/src/test/resources/seg1.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<x_segmentation cube_name="sample_cube" name="seg1" weight="100.0" xmlns="uri:lens:cube:0.1"
-                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
-    <properties>
-        <property name="seg1.prop" value="s1"/>
-        <property name="cube.segmentation.relative.start.time" value="now -10days"/>
-    </properties>
-    <segements>
-        <segment cube_name="cube11">
-            <segment_parameters>
-                <property name="lens.metastore.cube.column.mapping" value="foo=bar"/>
-            </segment_parameters>
-        </segment>
-        <segment cube_name="cube22">
-            <segment_parameters>
-                <property name="lens.metastore.cube.column.mapping" value="foo1=bar1"/>
-            </segment_parameters>
-        </segment>
-        <segment cube_name="cube33">
-            <segment_parameters>
-                <property name="lens.metastore.cube.column.mapping" value="foo2=bar2"/>
-            </segment_parameters>
-        </segment>
-    </segements>
-</x_segmentation>

http://git-wip-us.apache.org/repos/asf/lens/blob/d9884ec6/lens-cli/src/test/resources/test-detail.xml
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/test-detail.xml b/lens-cli/src/test/resources/test-detail.xml
deleted file mode 100644
index b51c188..0000000
--- a/lens-cli/src/test/resources/test-detail.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements. See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership. The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied. See the License for the
-  specific language governing permissions and limitations
-  under the License.
-
--->
-<x_dimension name="test_detail" xmlns="uri:lens:cube:0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="uri:lens:cube:0.1 cube-0.1.xsd ">
-  <attributes>
-    <dim_attribute name="id" _type="INT" />
-    <dim_attribute name="name" _type="STRING" />
-  </attributes>
-
-  <properties>
-    <property name="dimension.test_dim.timed.dimension" value="dt" />
-  </properties>
-</x_dimension>