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>