You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lens.apache.org by ra...@apache.org on 2015/08/21 03:30:54 UTC

incubator-lens git commit: LENS-731 : Enhance cube.xsd to accept Hierarchical dimattribute and inline dimattribute

Repository: incubator-lens
Updated Branches:
  refs/heads/master 4afce1fd1 -> 3ff3f142e


LENS-731 : Enhance cube.xsd to accept Hierarchical dimattribute and inline dimattribute


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

Branch: refs/heads/master
Commit: 3ff3f142e57d5d5b4a5d65ddf8b11b1a1d3dec8e
Parents: 4afce1f
Author: Amareshwari Sriramadasu <am...@apache.org>
Authored: Fri Aug 21 06:59:38 2015 +0530
Committer: Raju Bairishetti <ra...@apache.org>
Committed: Fri Aug 21 06:59:38 2015 +0530

----------------------------------------------------------------------
 lens-api/src/main/resources/cube-0.1.xsd        |  24 +++-
 .../lens/cli/TestLensDimensionCommands.java     |   4 +-
 lens-cli/src/test/resources/test-dimension.xml  |  12 ++
 .../lens/cube/metadata/BaseDimAttribute.java    |  43 ++++++-
 .../lens/cube/metadata/InlineDimAttribute.java  |  97 ---------------
 .../lens/cube/metadata/MetastoreUtil.java       |   4 -
 .../cube/metadata/ReferencedDimAtrribute.java   |  14 ++-
 .../cube/metadata/TestCubeMetastoreClient.java  |  14 ++-
 .../apache/lens/cube/parse/CubeTestSetup.java   |   3 +-
 lens-examples/src/main/resources/customer.xml   |   5 +-
 lens-examples/src/main/resources/sales-cube.xml |  18 ++-
 .../apache/lens/server/metastore/JAXBUtils.java |  31 ++++-
 .../server/metastore/TestMetastoreService.java  | 122 +++++++++++++++++--
 13 files changed, 258 insertions(+), 133 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/lens-api/src/main/resources/cube-0.1.xsd
----------------------------------------------------------------------
diff --git a/lens-api/src/main/resources/cube-0.1.xsd b/lens-api/src/main/resources/cube-0.1.xsd
index 02ea2d1..0a981dd 100644
--- a/lens-api/src/main/resources/cube-0.1.xsd
+++ b/lens-api/src/main/resources/cube-0.1.xsd
@@ -413,8 +413,30 @@
               </xs:choice>
             </xs:complexType>
           </xs:element>
+          <xs:element name="hierarchy" type="x_dim_attributes" maxOccurs="1" minOccurs="0">
+            <xs:annotation>
+              <xs:documentation>
+                If the dim attribute is a hierarchical attribute consisting of more dim attribute. This specification
+                is supplied in the definition. When cube or dimension has a hierarchy defined, the underlying fact or
+                dimtables, can have one or more elements in the hierarchy.
+                For example, location can be hierarchical dim attribute with its hierarchy defined as zipcode, city,
+                state and country; A fact can have zipcode and city as columns in the table and another fact can have
+                city alone.
+              </xs:documentation>
+            </xs:annotation>
+          </xs:element>
+          <xs:element name="values" type="xs:string" maxOccurs="unbounded" minOccurs="0">
+            <xs:annotation>
+              <xs:documentation>
+                These values specified here represent what actual values the dim attribute can take. This value is
+                usually specified if the values the attribute can take are minimal and can be listed. This is more
+                indicative information specified, for user to understand what values the attribute can hold.
+                For example, a gender attribute can enumerate the values attribute can take and specify them here.
+              </xs:documentation>
+            </xs:annotation>
+          </xs:element>
         </xs:sequence>
-        <xs:attribute type="xs:string" name="type" use="required">
+        <xs:attribute type="xs:string" name="type">
           <xs:annotation>
             <xs:documentation>
               The type indicating what the evaluation of expression will produce. Allowed types are BOOLEAN,TINYINT,

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/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 3a7c29a..42c6bae 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
@@ -95,8 +95,8 @@ public class TestLensDimensionCommands extends LensCliApplicationTest {
 
   private void testFields(LensDimensionCommands qCom) {
     String testDimFields = qCom.showQueryableFields("test_dim", true);
-    for (String field : Arrays.asList("detail", "id", "d2id", "name")) {
-      assertTrue(testDimFields.contains(field));
+    for (String field : Arrays.asList("detail", "id", "d2id", "name", "inline", "location")) {
+      assertTrue(testDimFields.contains(field), "Got " + testDimFields);
     }
     assertFalse(testDimFields.contains("measure"));
   }

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/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
index a9b7c08..6eb3d31 100644
--- a/lens-cli/src/test/resources/test-dimension.xml
+++ b/lens-cli/src/test/resources/test-dimension.xml
@@ -32,6 +32,18 @@
         </table_references>
       </ref_spec>
     </dim_attribute>
+    <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>
 
   <properties>

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/lens-cube/src/main/java/org/apache/lens/cube/metadata/BaseDimAttribute.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/BaseDimAttribute.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/BaseDimAttribute.java
index f5a84d8..bd4ae57 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/BaseDimAttribute.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/BaseDimAttribute.java
@@ -21,7 +21,9 @@ package org.apache.lens.cube.metadata;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import java.util.Arrays;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.hadoop.hive.metastore.api.FieldSchema;
@@ -37,6 +39,7 @@ import lombok.extern.slf4j.Slf4j;
 public class BaseDimAttribute extends CubeDimAttribute {
   @Getter private final String type;
   @Getter private Optional<Long> numOfDistinctValues = Optional.absent();
+  @Getter private Optional<List<String>> values = Optional.absent();
 
   public BaseDimAttribute(FieldSchema column) {
     this(column, null, null, null, null);
@@ -48,6 +51,11 @@ public class BaseDimAttribute extends CubeDimAttribute {
 
   public BaseDimAttribute(FieldSchema column, String displayString, Date startTime, Date endTime, Double cost,
       Long numOfDistinctValues) {
+    this(column, displayString, startTime, endTime, cost, numOfDistinctValues, null);
+  }
+
+  public BaseDimAttribute(FieldSchema column, String displayString, Date startTime, Date endTime, Double cost,
+    Long numOfDistinctValues, List<String> values) {
     super(column.getName(), column.getComment(), displayString, startTime, endTime, cost);
     this.type = column.getType();
     checkNotNull(type);
@@ -56,6 +64,14 @@ public class BaseDimAttribute extends CubeDimAttribute {
       this.numOfDistinctValues = optionalNumOfDistnctValues;
       checkArgument(this.numOfDistinctValues.get() > 0);
     }
+    Optional<List<String>> optionalValues = Optional.fromNullable(values);
+    if (optionalValues.isPresent()) {
+      this.values = optionalValues;
+      if (!this.values.get().isEmpty()) {
+        // always put num distinct values same of values size, if values are specified.
+        this.numOfDistinctValues = Optional.of(Long.valueOf(optionalValues.get().size()));
+      }
+    }
   }
 
   @Override
@@ -66,6 +82,9 @@ public class BaseDimAttribute extends CubeDimAttribute {
       props.put(MetastoreUtil.getDimNumOfDistinctValuesPropertyKey(getName()),
           String.valueOf(numOfDistinctValues.get()));
     }
+    if (values.isPresent() && !this.values.get().isEmpty()) {
+      props.put(MetastoreUtil.getInlineDimensionValuesKey(getName()), MetastoreUtil.getStr(values.get()));
+    }
   }
 
   /**
@@ -78,13 +97,15 @@ public class BaseDimAttribute extends CubeDimAttribute {
     super(name, props);
     this.type = getDimType(name, props);
     this.numOfDistinctValues = getDimNumOfDistinctValues(name, props);
+    this.values = getValues(name, props);
+
   }
 
-  public static String getDimType(String name, Map<String, String> props) {
+  static String getDimType(String name, Map<String, String> props) {
     return props.get(MetastoreUtil.getDimTypePropertyKey(name));
   }
 
-  public static Optional<Long> getDimNumOfDistinctValues(String name, Map<String, String> props) {
+  static Optional<Long> getDimNumOfDistinctValues(String name, Map<String, String> props) {
     if (props.containsKey(MetastoreUtil.getDimNumOfDistinctValuesPropertyKey(name))) {
       try {
         return Optional.of(Long.parseLong((props.get(MetastoreUtil.getDimNumOfDistinctValuesPropertyKey(name)))));
@@ -96,11 +117,25 @@ public class BaseDimAttribute extends CubeDimAttribute {
     return Optional.absent();
   }
 
+  static Optional<List<String>> getValues(String name, Map<String, String> props) {
+    if (props.containsKey(MetastoreUtil.getInlineDimensionValuesKey(name))) {
+      String valueStr = props.get(MetastoreUtil.getInlineDimensionValuesKey(name));
+      return Optional.of(Arrays.asList(valueStr.split(",")));
+    }
+    return Optional.absent();
+  }
+
   @Override
   public int hashCode() {
     final int prime = 31;
     int result = super.hashCode();
     result = prime * result + ((getType() == null) ? 0 : getType().toLowerCase().hashCode());
+    if (numOfDistinctValues.isPresent()) {
+      result = prime * result + numOfDistinctValues.get().hashCode();
+    }
+    if (values.isPresent()) {
+      result = prime * result + values.get().hashCode();
+    }
     return result;
   }
 
@@ -116,6 +151,10 @@ public class BaseDimAttribute extends CubeDimAttribute {
       }
     } else if (!this.getType().equalsIgnoreCase(other.getType())) {
       return false;
+    } else if (!this.numOfDistinctValues.equals(other.numOfDistinctValues)) {
+      return false;
+    } else if (!this.getValues().equals(other.getValues())) {
+      return false;
     }
     return true;
   }

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/lens-cube/src/main/java/org/apache/lens/cube/metadata/InlineDimAttribute.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/InlineDimAttribute.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/InlineDimAttribute.java
deleted file mode 100644
index e8d2fae..0000000
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/InlineDimAttribute.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * 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.metadata;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.hadoop.hive.metastore.api.FieldSchema;
-
-public class InlineDimAttribute extends BaseDimAttribute {
-
-  private final List<String> values;
-
-  public InlineDimAttribute(FieldSchema column, List<String> values) {
-    this(column, null, null, null, null, values);
-  }
-
-  public InlineDimAttribute(FieldSchema column, String displayString, Date startTime, Date endTime, Double cost,
-    List<String> values) {
-    super(column, displayString, startTime, endTime, cost, Long.valueOf(values.size()));
-    this.values = values;
-  }
-
-  public List<String> getValues() {
-    return values;
-  }
-
-  @Override
-  public void addProperties(Map<String, String> props) {
-    super.addProperties(props);
-    props.put(MetastoreUtil.getInlineDimensionSizeKey(getName()), String.valueOf(values.size()));
-    props.put(MetastoreUtil.getInlineDimensionValuesKey(getName()), MetastoreUtil.getStr(values));
-  }
-
-  /**
-   * This is used only for serializing
-   *
-   * @param name
-   * @param props
-   */
-  public InlineDimAttribute(String name, Map<String, String> props) {
-    super(name, props);
-    String valueStr = props.get(MetastoreUtil.getInlineDimensionValuesKey(name));
-    this.values = Arrays.asList(valueStr.split(","));
-  }
-
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = super.hashCode();
-    result = prime * result + ((getValues() == null) ? 0 : getValues().hashCode());
-    return result;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (!super.equals(obj)) {
-      return false;
-    }
-    InlineDimAttribute other = (InlineDimAttribute) obj;
-    if (this.getValues() == null) {
-      if (other.getValues() != null) {
-        return false;
-      }
-    } else if (!this.getValues().equals(other.getValues())) {
-      return false;
-    }
-    return true;
-  }
-
-  @Override
-  public String toString() {
-    String str = super.toString();
-    str += "values:" + MetastoreUtil.getStr(values);
-    return str;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java
index 59a30a9..bf27b99 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java
@@ -80,10 +80,6 @@ public class MetastoreUtil {
     return getDimensionKeyPrefix(dimName) + CLASS_SFX;
   }
 
-  public static String getInlineDimensionSizeKey(String name) {
-    return getDimensionKeyPrefix(name) + INLINE_SIZE_SFX;
-  }
-
   public static String getInlineDimensionValuesKey(String name) {
     return getDimensionKeyPrefix(name) + INLINE_VALUES_SFX;
   }

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/lens-cube/src/main/java/org/apache/lens/cube/metadata/ReferencedDimAtrribute.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/ReferencedDimAtrribute.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/ReferencedDimAtrribute.java
index a60281b..c51b489 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/ReferencedDimAtrribute.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/ReferencedDimAtrribute.java
@@ -83,7 +83,12 @@ public class ReferencedDimAtrribute extends BaseDimAttribute {
 
   public ReferencedDimAtrribute(FieldSchema column, String displayString, Collection<TableReference> references,
       Date startTime, Date endTime, Double cost, boolean isJoinKey, Long numOfDistinctValues) {
-    super(column, displayString, startTime, endTime, cost, numOfDistinctValues);
+    this(column, displayString, references, startTime, endTime, cost, isJoinKey, numOfDistinctValues, null);
+  }
+
+  public ReferencedDimAtrribute(FieldSchema column, String displayString, Collection<TableReference> references,
+      Date startTime, Date endTime, Double cost, boolean isJoinKey, Long numOfDistinctValues, List<String> values) {
+    super(column, displayString, startTime, endTime, cost, numOfDistinctValues, values);
     this.references.addAll(references);
     this.isJoinKey = isJoinKey;
   }
@@ -102,7 +107,12 @@ public class ReferencedDimAtrribute extends BaseDimAttribute {
 
   public ReferencedDimAtrribute(FieldSchema column, String displayString, List<ChainRefCol> chainRefCols,
     Date startTime, Date endTime, Double cost, Long numOfDistinctValues) {
-    super(column, displayString, startTime, endTime, cost, numOfDistinctValues);
+    this(column, displayString, chainRefCols, startTime, endTime, cost, numOfDistinctValues, null);
+  }
+
+  public ReferencedDimAtrribute(FieldSchema column, String displayString, List<ChainRefCol> chainRefCols,
+    Date startTime, Date endTime, Double cost, Long numOfDistinctValues, List<String> values) {
+    super(column, displayString, startTime, endTime, cost, numOfDistinctValues, values);
     chainRefColumns.addAll(chainRefCols);
     this.isJoinKey = false;
   }

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestCubeMetastoreClient.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestCubeMetastoreClient.java b/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestCubeMetastoreClient.java
index 5d66039..c2980af 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestCubeMetastoreClient.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestCubeMetastoreClient.java
@@ -191,7 +191,8 @@ public class TestCubeMetastoreClient {
     locationHierarchy.add(new ReferencedDimAtrribute(new FieldSchema("countryid", "int", "country"), "Country refer",
       new TableReference("countrydim", "id")));
     List<String> regions = Arrays.asList("APAC", "EMEA", "USA");
-    locationHierarchy.add(new InlineDimAttribute(new FieldSchema("regionname", "string", "region"), regions));
+    locationHierarchy.add(new BaseDimAttribute(new FieldSchema("regionname", "string", "region"), "regionname", null,
+      null, null, null, regions));
     cubeDimensions.add(new HierarchicalDimAttribute("location", "location hierarchy", locationHierarchy));
     cubeDimensions.add(new BaseDimAttribute(new FieldSchema("dim1", "string", "basedim")));
     cubeDimensions.add(new ReferencedDimAtrribute(new FieldSchema("dim2", "id", "ref dim"), "Dim2 refer",
@@ -231,8 +232,8 @@ public class TestCubeMetastoreClient {
       "state refer2", new TableReference("statedim", "id"), now, null, 100.0));
     locationHierarchyWithStartTime.add(new ReferencedDimAtrribute(new FieldSchema("countryid2", "int", "country"),
       "Country refer2", new TableReference("countrydim", "id"), null, null, null));
-    locationHierarchyWithStartTime.add(new InlineDimAttribute(new FieldSchema("regionname2", "string", "region"),
-      regions));
+    locationHierarchyWithStartTime.add(new BaseDimAttribute(new FieldSchema("regionname2", "string", "region"),
+      "regionname2", null, null, null, null, regions));
 
     cubeDimensions
       .add(new HierarchicalDimAttribute("location2", "localtion hierarchy2", locationHierarchyWithStartTime));
@@ -251,9 +252,10 @@ public class TestCubeMetastoreClient {
     cubeDimensions.add(new ReferencedDimAtrribute(new FieldSchema("dim3start", "string", "multi ref dim"),
       "Dim3 with starttime", multiRefs, now, null, 100.0));
 
-    cubeDimensions.add(new InlineDimAttribute(new FieldSchema("region", "string", "region dim"), regions));
-    cubeDimensions.add(new InlineDimAttribute(new FieldSchema("regionstart", "string", "region dim"),
-      "Region with starttime", now, null, 100.0, regions));
+    cubeDimensions.add(new BaseDimAttribute(new FieldSchema("region", "string", "region dim"), "region", null, null,
+      null, null, regions));
+    cubeDimensions.add(new BaseDimAttribute(new FieldSchema("regionstart", "string", "region dim"),
+      "Region with starttime", now, null, 100.0, null, regions));
     JoinChain zipCity = new JoinChain("cityFromZip", "Zip City", "zip city desc");
     List<TableReference> chain = new ArrayList<TableReference>();
     chain.add(new TableReference(cubeName, "zipcode"));

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/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 13eca27..7f56292 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
@@ -610,7 +610,8 @@ public class CubeTestSetup {
     locationHierarchy.add(new ReferencedDimAtrribute(new FieldSchema("countryid", "int", "country"), "Country refer",
       new TableReference("countrydim", "id")));
     List<String> regions = Arrays.asList("APAC", "EMEA", "USA");
-    locationHierarchy.add(new InlineDimAttribute(new FieldSchema("regionname", "string", "region"), regions));
+    locationHierarchy.add(new BaseDimAttribute(new FieldSchema("regionname", "string", "region"), "regionname", null,
+      null, null, null, regions));
 
     cubeDimensions.add(new HierarchicalDimAttribute("location", "Location hierarchy", locationHierarchy));
     cubeDimensions.add(new BaseDimAttribute(new FieldSchema("dim1", "string", "basedim")));

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/lens-examples/src/main/resources/customer.xml
----------------------------------------------------------------------
diff --git a/lens-examples/src/main/resources/customer.xml b/lens-examples/src/main/resources/customer.xml
index 1b4f854..920fd49 100644
--- a/lens-examples/src/main/resources/customer.xml
+++ b/lens-examples/src/main/resources/customer.xml
@@ -24,7 +24,10 @@
   <attributes>
     <dim_attribute name="id" type="INT"/>
     <dim_attribute name="name" type="STRING"/>
-    <dim_attribute name="gender" type="STRING" />
+    <dim_attribute name="gender" type="STRING">
+      <values>M</values>
+      <values>F</values>
+    </dim_attribute>
     <dim_attribute name="age" type="INT" />
     <dim_attribute name="city_id" type="INT" />
     <dim_attribute name="customer_city_name" type="string" description="City name to which the customer belongs"

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/lens-examples/src/main/resources/sales-cube.xml
----------------------------------------------------------------------
diff --git a/lens-examples/src/main/resources/sales-cube.xml b/lens-examples/src/main/resources/sales-cube.xml
index 2d67f5c..9cc2fe6 100644
--- a/lens-examples/src/main/resources/sales-cube.xml
+++ b/lens-examples/src/main/resources/sales-cube.xml
@@ -61,11 +61,19 @@
         <chain_ref_column chain_name="customer_details" ref_col="customer_city_name" />
       </ref_spec>
     </dim_attribute>
-    <dim_attribute name="production_city_name" type="STRING" description="City name in which the product was produced"
-                   display_string="Production City">
-      <ref_spec>
-        <chain_ref_column chain_name="production_city" ref_col="name" />
-      </ref_spec>
+    <dim_attribute name="production_location">
+      <hierarchy>
+      <dim_attribute name="production_city_name" type="STRING" description="City name in which the product was produced"
+                     display_string="Production City">
+        <ref_spec>
+          <chain_ref_column chain_name="production_city" ref_col="name" />
+        </ref_spec>
+      </dim_attribute>
+      <dim_attribute name="production_state" type="STRING" description="State name in which the product was produced"
+                     display_string="Production State"/>
+      <dim_attribute name="production_country" type="STRING" description="Country name in which the product was produced"
+                     display_string="Production Country"/>
+      </hierarchy>
     </dim_attribute>
     <dim_attribute name="delivery_city_name" type="STRING" description="City name to which the product was delivered"
                    display_string="Delivery City">

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/lens-server/src/main/java/org/apache/lens/server/metastore/JAXBUtils.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/metastore/JAXBUtils.java b/lens-server/src/main/java/org/apache/lens/server/metastore/JAXBUtils.java
index d6c4f17..ed472f6 100644
--- a/lens-server/src/main/java/org/apache/lens/server/metastore/JAXBUtils.java
+++ b/lens-server/src/main/java/org/apache/lens/server/metastore/JAXBUtils.java
@@ -164,7 +164,13 @@ public final class JAXBUtils {
 
     CubeDimAttribute hiveDim;
 
-    if (xd.getRefSpec() != null && xd.getRefSpec().getTableReferences() != null
+    if (xd.getHierarchy() != null) {
+      List<CubeDimAttribute> hierarchy = new ArrayList<>();
+      for (XDimAttribute hd : xd.getHierarchy().getDimAttribute()) {
+        hierarchy.add(hiveDimAttrFromXDimAttr(hd));
+      }
+      hiveDim = new HierarchicalDimAttribute(xd.getName(), xd.getDescription(), hierarchy);
+    } else if (xd.getRefSpec() != null && xd.getRefSpec().getTableReferences() != null
       && !xd.getRefSpec().getTableReferences().getTableReference().isEmpty()) {
 
       List<TableReference> dimRefs = new ArrayList<TableReference>(
@@ -182,7 +188,8 @@ public final class JAXBUtils {
         endDate,
         null,
         xd.isJoinKey(),
-        xd.getNumDistinctValues()
+        xd.getNumDistinctValues(),
+        xd.getValues()
       );
     } else if (xd.getRefSpec() != null && xd.getRefSpec().getChainRefColumn() != null
       && !xd.getRefSpec().getChainRefColumn().isEmpty()) {
@@ -193,7 +200,8 @@ public final class JAXBUtils {
         startDate,
         endDate,
         null,
-        xd.getNumDistinctValues()
+        xd.getNumDistinctValues(),
+        xd.getValues()
       );
     } else {
       hiveDim = new BaseDimAttribute(new FieldSchema(xd.getName(), xd.getType().toLowerCase(),
@@ -202,10 +210,10 @@ public final class JAXBUtils {
         startDate,
         endDate,
         null,
-        xd.getNumDistinctValues()
+        xd.getNumDistinctValues(),
+        xd.getValues()
       );
     }
-
     return hiveDim;
   }
 
@@ -353,6 +361,9 @@ public final class JAXBUtils {
       if (numOfDistinctValues.isPresent()) {
         xd.setNumDistinctValues(numOfDistinctValues.get());
       }
+      if (rd.getValues().isPresent()) {
+        xd.getValues().addAll(rd.getValues().get());
+      }
     } else if (cd instanceof BaseDimAttribute) {
       BaseDimAttribute bd = (BaseDimAttribute) cd;
       xd.setType(bd.getType());
@@ -360,6 +371,16 @@ public final class JAXBUtils {
       if (numOfDistinctValues.isPresent()) {
         xd.setNumDistinctValues(numOfDistinctValues.get());
       }
+      if (bd.getValues().isPresent()) {
+        xd.getValues().addAll(bd.getValues().get());
+      }
+    } else if (cd instanceof HierarchicalDimAttribute) {
+      HierarchicalDimAttribute hd = (HierarchicalDimAttribute) cd;
+      XDimAttributes hierarchy = new XDimAttributes();
+      for (CubeDimAttribute hdDim : hd.getHierarchy()) {
+        hierarchy.getDimAttribute().add(xDimAttrFromHiveDimAttr(hdDim, baseTable));
+      }
+      xd.setHierarchy(hierarchy);
     }
     return xd;
   }

http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/3ff3f142/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java b/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
index 308ce33..f9be6e6 100644
--- a/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
+++ b/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
@@ -1065,7 +1065,6 @@ public class TestMetastoreService extends LensJerseyTest {
     dimension.getAttributes().getDimAttribute().add(xd1);
     dimension.getAttributes().getDimAttribute().add(xd2);
 
-
     XExprColumn xe1 = new XExprColumn();
     xe1.setName("dimexpr");
     xe1.setType("STRING");
@@ -1087,6 +1086,60 @@ public class TestMetastoreService extends LensJerseyTest {
     XDimension dimension = createDimension("testdim");
     XDimension dimension2 = createDimension("testdim2");
 
+    XDimAttribute xd3 = cubeObjectFactory.createXDimAttribute();
+    xd3.setName("col3");
+    xd3.setType("STRING");
+    xd3.setDescription("inline column");
+    xd3.setDisplayString("Column3");
+    xd3.getValues().add("Val1");
+    xd3.getValues().add("Val2");
+    xd3.getValues().add("Val3");
+
+    XDimAttribute xd4 = cubeObjectFactory.createXDimAttribute();
+    xd4.setName("col4");
+    xd4.setDescription("hierarchical column");
+    xd4.setDisplayString("Column4");
+    XDimAttributes hierarchy = new XDimAttributes();
+    XDimAttribute hd1 = cubeObjectFactory.createXDimAttribute();
+    hd1.setName("col4-h1");
+    hd1.setType("STRING");
+    hd1.setDescription("inline column");
+    hd1.setDisplayString("Column4-h1");
+    hd1.getValues().add("Val1-h1");
+    hd1.getValues().add("Val2-h1");
+    hd1.getValues().add("Val3-h1");
+    hierarchy.getDimAttribute().add(hd1);
+    XDimAttribute hd2 = cubeObjectFactory.createXDimAttribute();
+    hd2.setName("col4-h2");
+    hd2.setType("STRING");
+    hd2.setDescription("base column");
+    hd2.setDisplayString("Column4-h2");
+    hierarchy.getDimAttribute().add(hd2);
+    XDimAttribute hd3 = cubeObjectFactory.createXDimAttribute();
+    hd3.setName("col4-h3");
+    hd3.setType("STRING");
+    hd3.setDescription("ref column");
+    hd3.setDisplayString("Column4-h3");
+    XChainColumn xcc = new XChainColumn();
+    xcc.setChainName("chain1");
+    xcc.setRefCol("col2");
+    hd3.setRefSpec(cubeObjectFactory.createXDimAttributeRefSpec());
+    hd3.getRefSpec().getChainRefColumn().add(xcc);
+    hd3.setNumDistinctValues(1000L);
+    hierarchy.getDimAttribute().add(hd3);
+    xd4.setHierarchy(hierarchy);
+
+    XDimAttribute xd5 = cubeObjectFactory.createXDimAttribute();
+    xd5.setName("col5");
+    xd5.setType("INT");
+    xd5.setDescription("ref column");
+    xd5.setDisplayString("Column5");
+    xd5.setRefSpec(cubeObjectFactory.createXDimAttributeRefSpec());
+    xd5.getRefSpec().getChainRefColumn().add(xcc);
+    xd5.getValues().add("1");
+    xd5.getValues().add("2");
+    xd5.getValues().add("3");
+
     XJoinChain xj1 = new XJoinChain();
     xj1.setName("chain1");
     xj1.setDescription("first chain");
@@ -1106,6 +1159,9 @@ public class TestMetastoreService extends LensJerseyTest {
     path1.getEdges().getEdge().add(edge1);
     xj1.getPaths().getPath().add(path1);
     dimension.getJoinChains().getJoinChain().add(xj1);
+    dimension.getAttributes().getDimAttribute().add(xd3);
+    dimension.getAttributes().getDimAttribute().add(xd4);
+    dimension.getAttributes().getDimAttribute().add(xd5);
 
     final WebTarget target = target().path("metastore").path("dimensions");
 
@@ -1120,7 +1176,6 @@ public class TestMetastoreService extends LensJerseyTest {
       mediaType).post(Entity.xml(cubeObjectFactory.createXDimension(dimension2)), APIResult.class);
     assertNotNull(result);
     assertEquals(result.getStatus(), APIResult.Status.SUCCEEDED);
-
   }
 
   @Test
@@ -1153,7 +1208,7 @@ public class TestMetastoreService extends LensJerseyTest {
       assertTrue(testDim.getProperties().getProperty().size() >= 1);
       assertTrue(JAXBUtils.mapFromXProperties(testDim.getProperties()).containsKey("dimension.foo"));
       assertEquals(JAXBUtils.mapFromXProperties(testDim.getProperties()).get("dimension.foo"), "dim.bar");
-      assertEquals(testDim.getAttributes().getDimAttribute().size(), 2);
+      assertEquals(testDim.getAttributes().getDimAttribute().size(), 5);
       assertEquals(testDim.getExpressions().getExpression().size(), 1);
       assertEquals(testDim.getJoinChains().getJoinChain().size(), 1);
       assertEquals(testDim.getJoinChains().getJoinChain().get(0).getPaths().getPath().size(), 1);
@@ -1172,6 +1227,51 @@ public class TestMetastoreService extends LensJerseyTest {
       assertNotNull(dim.getExpressionByName("dimexpr"));
       assertEquals(dim.getExpressionByName("dimexpr").getDescription(), "dimension expression");
       assertEquals(dim.getExpressionByName("dimexpr").getDisplayString(), "Dim Expression");
+      assertNotNull(dim.getAttributeByName("col3"));
+      BaseDimAttribute col3 = (BaseDimAttribute) dim.getAttributeByName("col3");
+      assertEquals(col3.getDescription(), "inline column");
+      assertEquals(col3.getDisplayString(), "Column3");
+      assertEquals(col3.getType(), "string");
+      assertEquals(col3.getValues().get().get(0), "Val1");
+      assertEquals(col3.getValues().get().get(1), "Val2");
+      assertEquals(col3.getValues().get().get(2), "Val3");
+      assertEquals(col3.getNumOfDistinctValues().get(), (Long) 3L);
+      assertNotNull(dim.getAttributeByName("col4"));
+      HierarchicalDimAttribute col4 = (HierarchicalDimAttribute) dim.getAttributeByName("col4");
+      assertEquals(col4.getDescription(), "hierarchical column");
+      BaseDimAttribute col4h1 = (BaseDimAttribute) col4.getHierarchy().get(0);
+      assertEquals(col4h1.getName(), "col4-h1");
+      assertEquals(col4h1.getType(), "string");
+      assertEquals(col4h1.getDescription(), "inline column");
+      assertEquals(col4h1.getDisplayString(), "Column4-h1");
+      assertEquals(col4h1.getValues().get().get(0), "Val1-h1");
+      assertEquals(col4h1.getValues().get().get(1), "Val2-h1");
+      assertEquals(col4h1.getValues().get().get(2), "Val3-h1");
+      assertEquals(col4h1.getNumOfDistinctValues().get(), (Long) 3L);
+      BaseDimAttribute col4h2 = (BaseDimAttribute) col4.getHierarchy().get(1);
+      assertEquals(col4h2.getName(), "col4-h2");
+      assertEquals(col4h2.getType(), "string");
+      assertEquals(col4h2.getDescription(), "base column");
+      assertEquals(col4h2.getDisplayString(), "Column4-h2");
+      ReferencedDimAtrribute col4h3 = (ReferencedDimAtrribute) col4.getHierarchy().get(2);
+      assertEquals(col4h3.getName(), "col4-h3");
+      assertEquals(col4h3.getDescription(), "ref column");
+      assertEquals(col4h3.getDisplayString(), "Column4-h3");
+      assertEquals(col4h3.getType(), "string");
+      assertEquals(col4h3.getChainRefColumns().get(0).getChainName(), "chain1");
+      assertEquals(col4h3.getChainRefColumns().get(0).getRefColumn(), "col2");
+      assertEquals(col4h3.getNumOfDistinctValues().get(), (Long)1000L);
+      assertNotNull(dim.getAttributeByName("col5"));
+      ReferencedDimAtrribute col5 = (ReferencedDimAtrribute) dim.getAttributeByName("col5");
+      assertEquals(col5.getDescription(), "ref column");
+      assertEquals(col5.getDisplayString(), "Column5");
+      assertEquals(col5.getType(), "int");
+      assertEquals(col5.getChainRefColumns().get(0).getChainName(), "chain1");
+      assertEquals(col5.getChainRefColumns().get(0).getRefColumn(), "col2");
+      assertEquals(col5.getValues().get().get(0), "1");
+      assertEquals(col5.getValues().get().get(1), "2");
+      assertEquals(col5.getValues().get().get(2), "3");
+      assertEquals(col5.getNumOfDistinctValues().get(), (Long) 3L);
 
       // alter dimension
       XProperty prop = cubeObjectFactory.createXProperty();
@@ -1181,7 +1281,7 @@ public class TestMetastoreService extends LensJerseyTest {
 
       testDim.getAttributes().getDimAttribute().remove(1);
       XDimAttribute xd1 = cubeObjectFactory.createXDimAttribute();
-      xd1.setName("col3");
+      xd1.setName("col3Added");
       xd1.setType("STRING");
       testDim.getAttributes().getDimAttribute().add(xd1);
 
@@ -1198,11 +1298,13 @@ public class TestMetastoreService extends LensJerseyTest {
       assertEquals(JAXBUtils.mapFromXProperties(altered.getProperties()).get("dim.prop2.name"), "dim.prop2.value");
       assertTrue(JAXBUtils.mapFromXProperties(altered.getProperties()).containsKey("dimension.foo"));
       assertEquals(JAXBUtils.mapFromXProperties(altered.getProperties()).get("dimension.foo"), "dim.bar");
-      assertEquals(testDim.getAttributes().getDimAttribute().size(), 2);
+      assertEquals(testDim.getAttributes().getDimAttribute().size(), 5);
 
       dim = JAXBUtils.dimensionFromXDimension(altered);
-      assertNotNull(dim.getAttributeByName("col3"));
-      assertTrue(dim.getAttributeByName("col2") == null || dim.getAttributeByName("col1") == null);
+      assertNotNull(dim.getAttributeByName("col3Added"));
+      assertTrue(dim.getAttributeByName("col2") == null || dim.getAttributeByName("col1") == null
+        || dim.getAttributeByName("col3") == null || dim.getAttributeByName("col4") == null
+        || dim.getAttributeByName("col5") == null);
 
       // drop the dimension
       result = target.path("testdim")
@@ -2462,6 +2564,9 @@ public class TestMetastoreService extends LensJerseyTest {
         "flattestcube.expr2",
         "chain1-testdim.col2",
         "chain1-testdim.col1",
+        "chain1-testdim.col3",
+        "chain1-testdim.col4",
+        "chain1-testdim.col5",
         "chain1-testdim.dimexpr",
         "dim2chain-testdim2.col2",
         "dim2chain-testdim2.col1",
@@ -2487,6 +2592,9 @@ public class TestMetastoreService extends LensJerseyTest {
       assertEquals(colSet, new HashSet<String>(Arrays.asList(
         "testdim.col2",
         "testdim.col1",
+        "testdim.col3",
+        "testdim.col4",
+        "testdim.col5",
         "testdim.dimexpr",
         "chain1-testdim2.col2",
         "chain1-testdim2.col1",