You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by sa...@apache.org on 2016/04/25 20:52:45 UTC

[01/52] [abbrv] phoenix git commit: PHOENIX-2722 support mysql offset clause [Forced Update!]

Repository: phoenix
Updated Branches:
  refs/heads/encodecolumns 9915c047f -> ba8d6abbc (forced update)


http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
index b4f612c..a4815aa 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
@@ -677,11 +677,11 @@ public class ParseNodeFactory {
     }
 
     public SelectStatement select(TableNode from, HintNode hint, boolean isDistinct, List<AliasedNode> select, ParseNode where,
-            List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit, int bindCount, boolean isAggregate, 
+            List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit, OffsetNode offset, int bindCount, boolean isAggregate, 
             boolean hasSequence, List<SelectStatement> selects, Map<String, UDFParseNode> udfParseNodes) {
 
         return new SelectStatement(from, hint, isDistinct, select, where, groupBy == null ? Collections.<ParseNode>emptyList() : groupBy, having,
-                orderBy == null ? Collections.<OrderByNode>emptyList() : orderBy, limit, bindCount, isAggregate, hasSequence, selects == null ? Collections.<SelectStatement>emptyList() : selects, udfParseNodes);
+                orderBy == null ? Collections.<OrderByNode>emptyList() : orderBy, limit, offset, bindCount, isAggregate, hasSequence, selects == null ? Collections.<SelectStatement>emptyList() : selects, udfParseNodes);
     } 
     
     public UpsertStatement upsert(NamedTableNode table, HintNode hint, List<ColumnName> columns, List<ParseNode> values, SelectStatement select, int bindCount, Map<String, UDFParseNode> udfParseNodes) {
@@ -694,89 +694,90 @@ public class ParseNodeFactory {
 
     public SelectStatement select(SelectStatement statement, ParseNode where) {
         return select(statement.getFrom(), statement.getHint(), statement.isDistinct(), statement.getSelect(), where, statement.getGroupBy(), statement.getHaving(),
-                statement.getOrderBy(), statement.getLimit(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
+                statement.getOrderBy(), statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
 
     public SelectStatement select(SelectStatement statement, ParseNode where, ParseNode having) {
         return select(statement.getFrom(), statement.getHint(), statement.isDistinct(), statement.getSelect(), where, statement.getGroupBy(), having,
-                statement.getOrderBy(), statement.getLimit(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
+                statement.getOrderBy(), statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
     
     public SelectStatement select(SelectStatement statement, List<AliasedNode> select, ParseNode where, List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy) {
         return select(statement.getFrom(), statement.getHint(), statement.isDistinct(), 
-                select, where, groupBy, having, orderBy, statement.getLimit(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
+                select, where, groupBy, having, orderBy, statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
     
     public SelectStatement select(SelectStatement statement, TableNode table) {
         return select(table, statement.getHint(), statement.isDistinct(), statement.getSelect(), statement.getWhere(), statement.getGroupBy(),
-                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getBindCount(), statement.isAggregate(),
+                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(),
                 statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
 
     public SelectStatement select(SelectStatement statement, TableNode table, ParseNode where) {
         return select(table, statement.getHint(), statement.isDistinct(), statement.getSelect(), where, statement.getGroupBy(),
-                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getBindCount(), statement.isAggregate(),
+                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(),
                 statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
 
     public SelectStatement select(SelectStatement statement, boolean isDistinct, List<AliasedNode> select) {
         return select(statement.getFrom(), statement.getHint(), isDistinct, select, statement.getWhere(), statement.getGroupBy(),
-                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getBindCount(), statement.isAggregate(),
+                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(),
                 statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
 
     public SelectStatement select(SelectStatement statement, boolean isDistinct, List<AliasedNode> select, ParseNode where) {
         return select(statement.getFrom(), statement.getHint(), isDistinct, select, where, statement.getGroupBy(),
-                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getBindCount(), statement.isAggregate(),
+                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(),
                 statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
 
     public SelectStatement select(SelectStatement statement, boolean isDistinct, List<AliasedNode> select, ParseNode where, List<ParseNode> groupBy, boolean isAggregate) {
         return select(statement.getFrom(), statement.getHint(), isDistinct, select, where, groupBy,
-                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getBindCount(), isAggregate,
+                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getOffset(), statement.getBindCount(), isAggregate,
                 statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
 
     public SelectStatement select(SelectStatement statement, List<OrderByNode> orderBy) {
         return select(statement.getFrom(), statement.getHint(), statement.isDistinct(), statement.getSelect(),
                 statement.getWhere(), statement.getGroupBy(), statement.getHaving(), orderBy, statement.getLimit(),
-                statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
+                statement.getOffset(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
 
     public SelectStatement select(SelectStatement statement, HintNode hint) {
         return hint == null || hint.isEmpty() ? statement : select(statement.getFrom(), hint, statement.isDistinct(), statement.getSelect(),
-                statement.getWhere(), statement.getGroupBy(), statement.getHaving(), statement.getOrderBy(), statement.getLimit(),
+                statement.getWhere(), statement.getGroupBy(), statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getOffset(), 
                 statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
 
     public SelectStatement select(SelectStatement statement, HintNode hint, ParseNode where) {
         return select(statement.getFrom(), hint, statement.isDistinct(), statement.getSelect(), where, statement.getGroupBy(),
-                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getBindCount(), statement.isAggregate(),
+                statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(),
                 statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
 
-    public SelectStatement select(SelectStatement statement, List<OrderByNode> orderBy, LimitNode limit, int bindCount, boolean isAggregate) {
+    public SelectStatement select(SelectStatement statement, List<OrderByNode> orderBy, LimitNode limit, OffsetNode offset, int bindCount, boolean isAggregate) {
         return select(statement.getFrom(), statement.getHint(), statement.isDistinct(), statement.getSelect(),
-            statement.getWhere(), statement.getGroupBy(), statement.getHaving(), orderBy, limit,
+            statement.getWhere(), statement.getGroupBy(), statement.getHaving(), orderBy, limit, offset,
             bindCount, isAggregate || statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
 
     }
 
     public SelectStatement select(SelectStatement statement, LimitNode limit) {
         return select(statement.getFrom(), statement.getHint(), statement.isDistinct(), statement.getSelect(),
-            statement.getWhere(), statement.getGroupBy(), statement.getHaving(), statement.getOrderBy(), limit,
-            statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
+                statement.getWhere(), statement.getGroupBy(), statement.getHaving(), statement.getOrderBy(), limit,
+                statement.getOffset(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(),
+                statement.getSelects(), statement.getUdfParseNodes());
     }
 
-    public SelectStatement select(SelectStatement statement, List<OrderByNode> orderBy, LimitNode limit) {
+    public SelectStatement select(SelectStatement statement, List<OrderByNode> orderBy, LimitNode limit, OffsetNode offset) {
         return select(statement.getFrom(), statement.getHint(), statement.isDistinct(), statement.getSelect(),
-            statement.getWhere(), statement.getGroupBy(), statement.getHaving(), orderBy, limit,
+            statement.getWhere(), statement.getGroupBy(), statement.getHaving(), orderBy, limit,offset,
             statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
     }
 
-    public SelectStatement select(List<SelectStatement> statements, List<OrderByNode> orderBy, LimitNode limit, int bindCount, boolean isAggregate) {
-        if (statements.size() == 1)
-            return select(statements.get(0), orderBy, limit, bindCount, isAggregate);        
+    public SelectStatement select(List<SelectStatement> statements, List<OrderByNode> orderBy, LimitNode limit,
+            OffsetNode offset, int bindCount, boolean isAggregate) {
+        if (statements.size() == 1) return select(statements.get(0), orderBy, limit, offset, bindCount, isAggregate);        
 
         // Get a list of adjusted aliases from a non-wildcard sub-select if any. 
         // We do not check the number of select nodes among all sub-selects, as 
@@ -809,7 +810,7 @@ public class ParseNodeFactory {
         }
         
         return select(null, HintNode.EMPTY_HINT_NODE, false, aliasedNodes, 
-                null, null, null, orderBy, limit, bindCount, false, false, statements, udfParseNodes);
+                null, null, null, orderBy, limit,offset, bindCount, false, false, statements, udfParseNodes);
     }
 
     public SubqueryParseNode subquery(SelectStatement select, boolean expectSingleRow) {
@@ -823,4 +824,12 @@ public class ParseNodeFactory {
     public LimitNode limit(LiteralParseNode l) {
         return new LimitNode(l);
     }
+
+    public OffsetNode offset(BindParseNode b) {
+        return new OffsetNode(b);
+    }
+
+    public OffsetNode offset(LiteralParseNode l) {
+        return new OffsetNode(l);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java
index e48967b..12ef2e1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java
@@ -150,7 +150,7 @@ public class ParseNodeRewriter extends TraverseAllParseNodeVisitor<ParseNode> {
         }
         return NODE_FACTORY.select(normFrom, statement.getHint(), statement.isDistinct(),
                 normSelectNodes, normWhere, normGroupByNodes, normHaving, normOrderByNodes,
-                statement.getLimit(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(),
+                statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(),
                 statement.getSelects(), statement.getUdfParseNodes());
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatement.java
index 93c7364..a7c1a0b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatement.java
@@ -44,7 +44,7 @@ public class SelectStatement implements FilterableStatement {
                     Collections.<AliasedNode>singletonList(new AliasedNode(null, LiteralParseNode.ONE)),
                     null, Collections.<ParseNode>emptyList(),
                     null, Collections.<OrderByNode>emptyList(),
-                    null, 0, false, false, Collections.<SelectStatement>emptyList(), new HashMap<String, UDFParseNode>(1));
+                    null, null, 0, false, false, Collections.<SelectStatement>emptyList(), new HashMap<String, UDFParseNode>(1));
     public static final SelectStatement COUNT_ONE =
             new SelectStatement(
                     null, null, false,
@@ -56,14 +56,14 @@ public class SelectStatement implements FilterableStatement {
                                 new BuiltInFunctionInfo(CountAggregateFunction.class, CountAggregateFunction.class.getAnnotation(BuiltInFunction.class))))),
                     null, Collections.<ParseNode>emptyList(), 
                     null, Collections.<OrderByNode>emptyList(), 
-                    null, 0, true, false, Collections.<SelectStatement>emptyList(), new HashMap<String, UDFParseNode>(1));
+                    null,null, 0, true, false, Collections.<SelectStatement>emptyList(), new HashMap<String, UDFParseNode>(1));
     public static SelectStatement create(SelectStatement select, HintNode hint) {
         if (select.getHint() == hint || hint.isEmpty()) {
             return select;
         }
         return new SelectStatement(select.getFrom(), hint, select.isDistinct(), 
                 select.getSelect(), select.getWhere(), select.getGroupBy(), select.getHaving(), 
-                select.getOrderBy(), select.getLimit(), select.getBindCount(), select.isAggregate(), select.hasSequence(), select.getSelects(), select.getUdfParseNodes());
+                select.getOrderBy(), select.getLimit(), select.getOffset(), select.getBindCount(), select.isAggregate(), select.hasSequence(), select.getSelects(), select.getUdfParseNodes());
     }
     
     public SelectStatement combine(ParseNode where) {
@@ -75,21 +75,22 @@ public class SelectStatement implements FilterableStatement {
         }
         return new SelectStatement(this.getFrom(), this.getHint(), this.isDistinct(), 
                 this.getSelect(), where, this.getGroupBy(), this.getHaving(), 
-                this.getOrderBy(), this.getLimit(), this.getBindCount(), this.isAggregate(), this.hasSequence(), this.selects, this.udfParseNodes);
+                this.getOrderBy(), this.getLimit(), this.getOffset(), this.getBindCount(), this.isAggregate(), this.hasSequence(), this.selects, this.udfParseNodes);
     }
     
     public static SelectStatement create(SelectStatement select, List<AliasedNode> selects) {
         return new SelectStatement(select.getFrom(), select.getHint(), select.isDistinct(), 
                 selects, select.getWhere(), select.getGroupBy(), select.getHaving(), 
-                select.getOrderBy(), select.getLimit(), select.getBindCount(), select.isAggregate(), select.hasSequence(), select.getSelects(), select.getUdfParseNodes());
+                select.getOrderBy(), select.getLimit(), select.getOffset(), select.getBindCount(), select.isAggregate(), select.hasSequence(), select.getSelects(), select.getUdfParseNodes());
     }
     
     // Copy constructor for sub select statements in a union
-    public static SelectStatement create(SelectStatement select, 
-            List<OrderByNode> orderBy, LimitNode limit, boolean isAggregate) {
-        return new SelectStatement(select.getFrom(), select.getHint(), select.isDistinct(), 
-                select.getSelect(), select.getWhere(), select.getGroupBy(), select.getHaving(), 
-                orderBy, limit, select.getBindCount(), isAggregate, select.hasSequence(), select.getSelects(), select.getUdfParseNodes());
+    public static SelectStatement create(SelectStatement select, List<OrderByNode> orderBy, LimitNode limit,
+            OffsetNode offset, boolean isAggregate) {
+        return new SelectStatement(select.getFrom(), select.getHint(), select.isDistinct(), select.getSelect(),
+                select.getWhere(), select.getGroupBy(), select.getHaving(), orderBy, limit, offset,
+                select.getBindCount(), isAggregate, select.hasSequence(), select.getSelects(),
+                select.getUdfParseNodes());
     }
 
     private final TableNode fromTable;
@@ -107,6 +108,7 @@ public class SelectStatement implements FilterableStatement {
     private final boolean hasWildcard;
     private final List<SelectStatement> selects = new ArrayList<SelectStatement>();
     private final Map<String, UDFParseNode> udfParseNodes;
+    private final OffsetNode offset;
     
     @Override
     public final String toString() {
@@ -155,6 +157,9 @@ public class SelectStatement implements FilterableStatement {
         if (limit != null) {
             buf.append(" LIMIT " + limit.toString());
         }
+        if (offset != null) {
+            buf.append(" OFFSET " + offset.toString());
+        }
     }    
 
     
@@ -221,7 +226,8 @@ public class SelectStatement implements FilterableStatement {
     
     protected SelectStatement(TableNode from, HintNode hint, boolean isDistinct, List<AliasedNode> select,
             ParseNode where, List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit,
-            int bindCount, boolean isAggregate, boolean hasSequence, List<SelectStatement> selects, Map<String, UDFParseNode> udfParseNodes) {
+            OffsetNode offset, int bindCount, boolean isAggregate, boolean hasSequence, List<SelectStatement> selects,
+            Map<String, UDFParseNode> udfParseNodes) {
         this.fromTable = from;
         this.hint = hint == null ? HintNode.EMPTY_HINT_NODE : hint;
         this.isDistinct = isDistinct;
@@ -231,6 +237,7 @@ public class SelectStatement implements FilterableStatement {
         this.having = having;
         this.orderBy = Collections.unmodifiableList(orderBy);
         this.limit = limit;
+        this.offset = offset;
         this.bindCount = bindCount;
         this.isAggregate = isAggregate || groupBy.size() != countConstants(groupBy) || this.having != null;
         this.hasSequence = hasSequence;
@@ -343,4 +350,10 @@ public class SelectStatement implements FilterableStatement {
     public Map<String, UDFParseNode> getUdfParseNodes() {
         return udfParseNodes;
     }
+
+    @Override
+    public OffsetNode getOffset() {
+        return offset;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
index 471ac73..6def7db 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
@@ -138,6 +138,9 @@ public interface QueryConstants {
     public final static String SYSTEM_SCHEMA_NAME = "SYSTEM";
     public final static byte[] SYSTEM_SCHEMA_NAME_BYTES = Bytes.toBytes(SYSTEM_SCHEMA_NAME);
     public final static String PHOENIX_METADATA = "table";
+    public final static String OFFSET_ROW_KEY = "_OFFSET_";
+    public final static byte[] OFFSET_ROW_KEY_BYTES = Bytes.toBytes(OFFSET_ROW_KEY);
+    public final static ImmutableBytesPtr offsetRowKeyPtr = new ImmutableBytesPtr(OFFSET_ROW_KEY_BYTES);
 
     public final static PName SINGLE_COLUMN_NAME = PNameFactory.newNormalizedName("s");
     public final static PName SINGLE_COLUMN_FAMILY_NAME = PNameFactory.newNormalizedName("s");
@@ -328,5 +331,8 @@ public interface QueryConstants {
             // Install split policy to prevent a tenant's metadata from being split across regions.
             HTableDescriptor.SPLIT_POLICY + "='" + MetaDataSplitPolicy.class.getName() + "',\n" + 
             PhoenixDatabaseMetaData.TRANSACTIONAL + "=" + Boolean.FALSE;
+    public static final byte[] OFFSET_FAMILY = "f_offset".getBytes();
+    public static final byte[] OFFSET_COLUMN = "c_offset".getBytes();
+    public static final String LAST_SCAN = "LAST_SCAN";
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java
index 7c0928e..99c4596 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java
@@ -34,17 +34,21 @@ import javax.annotation.Nullable;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
 import org.apache.hadoop.hbase.util.Addressing;
 import org.apache.hadoop.hbase.zookeeper.ZKConfig;
+import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver;
 import org.apache.phoenix.parse.HintNode;
 import org.apache.phoenix.parse.HintNode.Hint;
 import org.apache.phoenix.parse.WildcardParseNode;
+import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.query.QueryServicesOptions;
+import org.apache.phoenix.schema.tuple.Tuple;
 
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
@@ -81,6 +85,7 @@ public final class QueryUtil {
     private static final String FROM = "FROM";
     private static final String WHERE = "WHERE";
     private static final String[] CompareOpString = new String[CompareOp.values().length];
+
     static {
         CompareOpString[CompareOp.EQUAL.ordinal()] = "=";
         CompareOpString[CompareOp.NOT_EQUAL.ordinal()] = "!=";
@@ -353,5 +358,28 @@ public final class QueryUtil {
                 ("\"" + tableName + "\" ") +
                 (WHERE + " " + where);
     }
-    
+
+    public static Integer getOffsetLimit(Integer limit, Integer offset) {
+        if (limit == null) {
+            return null;
+        } else if (offset == null) {
+            return limit;
+        } else {
+            return limit + offset;
+        }
+
+    }
+
+    public static byte[] getUnusedOffset(Tuple offsetTuple) {
+        if (offsetTuple != null) {
+            ImmutableBytesPtr rowKeyPtr = new ImmutableBytesPtr();
+            offsetTuple.getKey(rowKeyPtr);
+            if (QueryConstants.offsetRowKeyPtr.compareTo(rowKeyPtr) == 0) {
+                Cell value = offsetTuple.getValue(QueryConstants.OFFSET_FAMILY, QueryConstants.OFFSET_COLUMN);
+                return value.getValue();
+            }
+        }
+        return null;
+    }
+ 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
index 360db2c..46589b9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
@@ -804,4 +804,8 @@ public class ScanUtil {
         return context.getConnection().getQueryServices().isRenewingLeasesEnabled();
     }
 
+    public static void addOffsetAttribute(Scan scan, Integer offset) {
+        scan.setAttribute(BaseScannerRegionObserver.SCAN_OFFSET, Bytes.toBytes(offset));
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
index a8757ab..6d0930d 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
@@ -172,21 +172,43 @@ public class CorrelatePlanTest {
                 {2, "2", "2", 20},
                 {5, "5", "5", 100},
         };
-        testCorrelatePlan(LEFT_RELATION, rightRelation, 1, 0, JoinType.Inner, expected);        
+        testCorrelatePlan(LEFT_RELATION, rightRelation, 1, 0, JoinType.Inner, expected);
     }
     
-    private void testCorrelatePlan(Object[][] leftRelation, Object[][] rightRelation, int leftCorrelColumn, int rightCorrelColumn, JoinType type, Object[][] expectedResult) throws SQLException {        
+    @Test
+    public void testCorrelatePlanWithSingleValueOnlyAndOffset() throws SQLException {
+        Integer offset = 1;
+        Object[][] rightRelation = new Object[][] {
+                {"6", 60},
+                {"2", 20},
+                {"5", 100},
+                {"1", 10},
+        };
+        Object[][] expected = new Object[][] {
+                {2, "2", "2", 20},
+                {5, "5", "5", 100},
+        };
+        testCorrelatePlan(LEFT_RELATION, rightRelation, 1, 0, JoinType.Inner, expected, offset);
+    }
+
+    private void testCorrelatePlan(Object[][] leftRelation, Object[][] rightRelation, int leftCorrelColumn, int rightCorrelColumn, JoinType type, Object[][] expectedResult) throws SQLException {
+        testCorrelatePlan(leftRelation, rightRelation, leftCorrelColumn, rightCorrelColumn, type, expectedResult, null);
+    }
+
+    private void testCorrelatePlan(Object[][] leftRelation, Object[][] rightRelation, int leftCorrelColumn,
+            int rightCorrelColumn, JoinType type, Object[][] expectedResult, Integer offset) throws SQLException {
         TableRef leftTable = createProjectedTableFromLiterals(leftRelation[0]);
         TableRef rightTable = createProjectedTableFromLiterals(rightRelation[0]);
         String varName = "$cor0";
         RuntimeContext runtimeContext = new RuntimeContextImpl();
         runtimeContext.defineCorrelateVariable(varName, leftTable);
-        QueryPlan leftPlan = newLiteralResultIterationPlan(leftRelation);
-        QueryPlan rightPlan = newLiteralResultIterationPlan(rightRelation);
+        QueryPlan leftPlan = newLiteralResultIterationPlan(leftRelation, offset);
+        QueryPlan rightPlan = newLiteralResultIterationPlan(rightRelation, offset);
         Expression columnExpr = new ColumnRef(rightTable, rightCorrelColumn).newColumnExpression();
         Expression fieldAccess = new CorrelateVariableFieldAccessExpression(runtimeContext, varName, new ColumnRef(leftTable, leftCorrelColumn).newColumnExpression());
         Expression filter = ComparisonExpression.create(CompareOp.EQUAL, Arrays.asList(columnExpr, fieldAccess), CONTEXT.getTempPtr(), false);
-        rightPlan = new ClientScanPlan(CONTEXT, SelectStatement.SELECT_ONE, rightTable, RowProjector.EMPTY_PROJECTOR, null, filter, OrderBy.EMPTY_ORDER_BY, rightPlan);
+        rightPlan = new ClientScanPlan(CONTEXT, SelectStatement.SELECT_ONE, rightTable, RowProjector.EMPTY_PROJECTOR,
+                null, null, filter, OrderBy.EMPTY_ORDER_BY, rightPlan);
         PTable joinedTable = JoinCompiler.joinProjectedTables(leftTable.getTable(), rightTable.getTable(), type);
         CorrelatePlan correlatePlan = new CorrelatePlan(leftPlan, rightPlan, varName, type, false, runtimeContext, joinedTable, leftTable.getTable(), rightTable.getTable(), leftTable.getTable().getColumns().size());
         ResultIterator iter = correlatePlan.iterator();
@@ -202,8 +224,8 @@ public class CorrelatePlanTest {
             }
         }
     }
-    
-    private QueryPlan newLiteralResultIterationPlan(Object[][] rows) {
+
+    private QueryPlan newLiteralResultIterationPlan(Object[][] rows, Integer offset) {
         List<Tuple> tuples = Lists.newArrayList();
         Tuple baseTuple = new SingleKeyValueTuple(KeyValue.LOWESTKEY);
         for (Object[] row : rows) {
@@ -215,7 +237,8 @@ public class CorrelatePlanTest {
             tuples.add(projector.projectResults(baseTuple));
         }
         
-        return new LiteralResultIterationPlan(tuples, CONTEXT, SelectStatement.SELECT_ONE, TableRef.EMPTY_TABLE_REF, RowProjector.EMPTY_PROJECTOR, null, OrderBy.EMPTY_ORDER_BY, null);
+        return new LiteralResultIterationPlan(tuples, CONTEXT, SelectStatement.SELECT_ONE, TableRef.EMPTY_TABLE_REF,
+                RowProjector.EMPTY_PROJECTOR, null, offset, OrderBy.EMPTY_ORDER_BY, null);
     }
 
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
new file mode 100644
index 0000000..8ecf0ee
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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.phoenix.execute;
+
+import static org.apache.phoenix.util.PhoenixRuntime.CONNECTIONLESS;
+import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL;
+import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.compile.ColumnResolver;
+import org.apache.phoenix.compile.FromCompiler;
+import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
+import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.compile.RowProjector;
+import org.apache.phoenix.compile.SequenceManager;
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.compile.TupleProjectionCompiler;
+import org.apache.phoenix.coprocessor.MetaDataProtocol;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.ProjectedColumnExpression;
+import org.apache.phoenix.iterate.ResultIterator;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.parse.ParseNodeFactory;
+import org.apache.phoenix.parse.SelectStatement;
+import org.apache.phoenix.schema.ColumnRef;
+import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PColumnImpl;
+import org.apache.phoenix.schema.PName;
+import org.apache.phoenix.schema.PNameFactory;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableImpl;
+import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.schema.tuple.SingleKeyValueTuple;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+
+public class LiteralResultIteratorPlanTest {
+
+    private static final StatementContext CONTEXT;
+
+    static {
+        try {
+            PhoenixConnection connection = DriverManager
+                    .getConnection(JDBC_PROTOCOL + JDBC_PROTOCOL_SEPARATOR + CONNECTIONLESS)
+                    .unwrap(PhoenixConnection.class);
+            PhoenixStatement stmt = new PhoenixStatement(connection);
+            ColumnResolver resolver = FromCompiler.getResolverForQuery(SelectStatement.SELECT_ONE, connection);
+            CONTEXT = new StatementContext(stmt, resolver, new Scan(), new SequenceManager(stmt));
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static final Object[][] RELATION = new Object[][] {
+        {"2", 20},
+        {"2", 40},
+        {"5", 50},
+        {"6", 60},
+        {"5", 100},
+        {"1", 10},
+        {"3", 30},
+ };
+    PTable table = createProjectedTableFromLiterals(RELATION[0]).getTable();
+
+    @Test
+    public void testLiteralResultIteratorPlanWithOffset() throws SQLException {
+        Object[][] expected = new Object[][] {
+            {"2", 40},
+            {"5", 50},
+            {"6", 60},
+            {"5", 100},
+            {"1", 10},
+            {"3", 30},
+        };
+        testLiteralResultIteratorPlan(expected, 1, null);
+    }
+
+    @Test
+    public void testLiteralResultIteratorPlanWithLimit() throws SQLException {
+        Object[][] expected = new Object[][] {
+            {"2", 20},
+            {"2", 40},
+            {"5", 50},
+            {"6", 60},
+        };
+        testLiteralResultIteratorPlan(expected, null, 4);
+    }
+
+    @Test
+    public void testLiteralResultIteratorPlanWithLimitAndOffset() throws SQLException {
+        Object[][] expected = new Object[][] {
+            {"5", 50},
+            {"6", 60},
+            {"5", 100},
+            {"1", 10},
+            };
+        testLiteralResultIteratorPlan(expected, 2, 4);
+    }
+
+    private void testLiteralResultIteratorPlan(Object[][] expectedResult, Integer offset, Integer limit)
+            throws SQLException {
+
+        QueryPlan plan = newLiteralResultIterationPlan(offset, limit);
+        ResultIterator iter = plan.iterator();
+        ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+        for (Object[] row : expectedResult) {
+            Tuple next = iter.next();
+            assertNotNull(next);
+            for (int i = 0; i < row.length; i++) {
+                PColumn column = table.getColumns().get(i);
+                boolean eval = new ProjectedColumnExpression(column, table, column.getName().getString()).evaluate(next,
+                        ptr);
+                Object o = eval ? column.getDataType().toObject(ptr) : null;
+                assertEquals(row[i], o);
+            }
+        }
+        assertNull(iter.next());
+    }
+
+    private QueryPlan newLiteralResultIterationPlan(Integer offset, Integer limit) {
+        List<Tuple> tuples = Lists.newArrayList();
+
+        Tuple baseTuple = new SingleKeyValueTuple(KeyValue.LOWESTKEY);
+        for (Object[] row : RELATION) {
+            Expression[] exprs = new Expression[row.length];
+            for (int i = 0; i < row.length; i++) {
+                exprs[i] = LiteralExpression.newConstant(row[i]);
+            }
+            TupleProjector projector = new TupleProjector(exprs);
+            tuples.add(projector.projectResults(baseTuple));
+        }
+
+        return new LiteralResultIterationPlan(tuples, CONTEXT, SelectStatement.SELECT_ONE, TableRef.EMPTY_TABLE_REF,
+                RowProjector.EMPTY_PROJECTOR, limit, offset, OrderBy.EMPTY_ORDER_BY, null);
+    }
+
+    private TableRef createProjectedTableFromLiterals(Object[] row) {
+        List<PColumn> columns = Lists.<PColumn> newArrayList();
+        for (int i = 0; i < row.length; i++) {
+            String name = ParseNodeFactory.createTempAlias();
+            Expression expr = LiteralExpression.newConstant(row[i]);
+            columns.add(new PColumnImpl(PNameFactory.newName(name),
+                    PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), expr.getDataType(), expr.getMaxLength(),
+                    expr.getScale(), expr.isNullable(), i, expr.getSortOrder(), null, null, false, name, false, false));
+        }
+        try {
+            PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,
+                    MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM, null, null, columns, null, null,
+                    Collections.<PTable> emptyList(), false, Collections.<PName> emptyList(), null, null, false, false,
+                    false, null, null, null, true, false, 0, 0L);
+            TableRef sourceTable = new TableRef(pTable);
+            List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> newArrayList();
+            for (PColumn column : sourceTable.getTable().getColumns()) {
+                sourceColumnRefs.add(new ColumnRef(sourceTable, column.getPosition()));
+            }
+
+            return new TableRef(TupleProjectionCompiler.createProjectedTable(sourceTable, sourceColumnRefs, false));
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
index 8b2b096..51b8868 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
@@ -112,7 +112,8 @@ public class UnnestArrayPlanTest {
     private void testUnnestArrays(PArrayDataType arrayType, List<Object[]> arrays, boolean withOrdinality) throws Exception {
         PDataType baseType = PDataType.fromTypeId(arrayType.getSqlType() - PDataType.ARRAY_TYPE_BASE);
         List<Tuple> tuples = toTuples(arrayType, arrays);
-        LiteralResultIterationPlan subPlan = new LiteralResultIterationPlan(tuples, CONTEXT, SelectStatement.SELECT_ONE, TableRef.EMPTY_TABLE_REF, RowProjector.EMPTY_PROJECTOR, null, OrderBy.EMPTY_ORDER_BY, null);
+		LiteralResultIterationPlan subPlan = new LiteralResultIterationPlan(tuples, CONTEXT, SelectStatement.SELECT_ONE,
+				TableRef.EMPTY_TABLE_REF, RowProjector.EMPTY_PROJECTOR, null, null, OrderBy.EMPTY_ORDER_BY, null);
         LiteralExpression dummy = LiteralExpression.newConstant(null, arrayType);
         RowKeyValueAccessor accessor = new RowKeyValueAccessor(Arrays.asList(dummy), 0);
         UnnestArrayPlan plan = new UnnestArrayPlan(subPlan, new RowKeyColumnExpression(dummy, accessor), withOrdinality);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java
index 51073dd..ff06ff9 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java
@@ -407,6 +407,11 @@ public class ParallelIteratorsSplitTest extends BaseConnectionlessQueryTest {
             }
 
             @Override
+            public Integer getOffset() {
+                return null;
+            }
+
+            @Override
             public OrderBy getOrderBy() {
                 return OrderBy.EMPTY_ORDER_BY;
             }


[17/52] [abbrv] phoenix git commit: PHOENIX-2822 Addendum to fix failing tests

Posted by sa...@apache.org.
PHOENIX-2822 Addendum to fix failing tests


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

Branch: refs/heads/encodecolumns
Commit: 366e7a779f237ce041cfee1d73872285e6433797
Parents: 4efb4dd
Author: Samarth <sa...@salesforce.com>
Authored: Tue Apr 12 12:16:07 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Tue Apr 12 12:16:07 2016 -0700

----------------------------------------------------------------------
 .../BaseHBaseManagedTimeTableReuseIT.java       |  4 +-
 .../end2end/HBaseManagedTimeTableReuseTest.java | 49 ++++++++++++++++++++
 .../phoenix/end2end/HBaseManagedTimeTest.java   |  4 +-
 .../phoenix/end2end/LikeExpressionIT.java       | 14 +++---
 pom.xml                                         | 18 +++++++
 5 files changed, 80 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/366e7a77/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeTableReuseIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeTableReuseIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeTableReuseIT.java
index 8d9fff9..26c2f3c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeTableReuseIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeTableReuseIT.java
@@ -30,7 +30,7 @@ import java.util.concurrent.locks.ReentrantLock;
  * @since 0.1
  */
 @NotThreadSafe
-@Category(HBaseManagedTimeTest.class)
+@Category(HBaseManagedTimeTableReuseTest.class)
 public class BaseHBaseManagedTimeTableReuseIT extends BaseTest {
 
   protected static Configuration getTestClusterConfig() {
@@ -46,6 +46,8 @@ public class BaseHBaseManagedTimeTableReuseIT extends BaseTest {
   @AfterClass
   public static void doTeardown() throws Exception {
     // no teardown since we are creating unique table names
+    // just destroy our test driver
+    destroyDriver();
   }
 
   @After

http://git-wip-us.apache.org/repos/asf/phoenix/blob/366e7a77/phoenix-core/src/it/java/org/apache/phoenix/end2end/HBaseManagedTimeTableReuseTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HBaseManagedTimeTableReuseTest.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HBaseManagedTimeTableReuseTest.java
new file mode 100644
index 0000000..c36a8f4
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HBaseManagedTimeTableReuseTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * 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 maynot 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 applicablelaw 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.phoenix.end2end;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.phoenix.query.BaseTest;
+
+/**
+ * 
+ * Annotation to denote that the test lets HBase manage timestamp 
+ * itself. Tests in these category do not drop HBase tables at 
+ * the end of every test class. To prevent table name collisions that could happen otherwise,
+ * these tests use random table names generated by {@link BaseTest#generateRandomString}.
+ * 
+ * Tests using a mini cluster need to be classified either 
+ * as {@link HBaseManagedTimeTableReuseTest} or {@link ClientManagedTimeTest}
+ * or {@link NeedsOwnMiniClusterTest} or {@link HBaseManagedTimeTest} otherwise they won't be run
+ * when one runs mvn verify or mvn install.
+ * 
+ * @since 4.1
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Inherited
+public @interface HBaseManagedTimeTableReuseTest {
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/366e7a77/phoenix-core/src/it/java/org/apache/phoenix/end2end/HBaseManagedTimeTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HBaseManagedTimeTest.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HBaseManagedTimeTest.java
index 31cc00b..8ffb8d3 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HBaseManagedTimeTest.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HBaseManagedTimeTest.java
@@ -32,8 +32,8 @@ import java.lang.annotation.Target;
  * 
  * Tests using a mini cluster need to be classified either 
  * as {@link HBaseManagedTimeTest} or {@link ClientManagedTimeTest} 
- * or {@link NeedsOwnMiniClusterTest} otherwise they won't be run 
- * when one runs mvn verify or mvn install.
+ * or {@link NeedsOwnMiniClusterTest} or {@link HBaseManagedTimeTableReuseTest}
+ * otherwise they won't be run when one runs mvn verify or mvn install.
  * 
  * @since 4.1
  */

http://git-wip-us.apache.org/repos/asf/phoenix/blob/366e7a77/phoenix-core/src/it/java/org/apache/phoenix/end2end/LikeExpressionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/LikeExpressionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/LikeExpressionIT.java
index 00a6a64..6f056a7 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/LikeExpressionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/LikeExpressionIT.java
@@ -33,7 +33,7 @@ import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-public class LikeExpressionIT extends BaseHBaseManagedTimeIT {
+public class LikeExpressionIT extends BaseHBaseManagedTimeTableReuseIT {
 
     private static final String TEST_TABLE = generateRandomString();
 
@@ -135,14 +135,16 @@ public class LikeExpressionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testLikeWithEscapenLParen() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE t (k VARCHAR, v VARCHAR, CONSTRAINT pk PRIMARY KEY (k))";
+        String t = generateRandomString();
+        String ddl = "CREATE TABLE " + t + " (k VARCHAR, v VARCHAR, CONSTRAINT pk PRIMARY KEY (k))";
         conn.createStatement().execute(ddl);
-        conn.createStatement().execute("UPSERT INTO t VALUES('aa','bb')");
-        conn.createStatement().execute("UPSERT INTO t VALUES('a\\(d','xx')");
-        conn.createStatement().execute("UPSERT INTO t VALUES('dd',null)");
+        conn.createStatement().execute("UPSERT INTO " + t + " VALUES('aa','bb')");
+        conn.createStatement().execute("UPSERT INTO " + t + " VALUES('a\\(d','xx')");
+        conn.createStatement().execute("UPSERT INTO " + t + " VALUES('dd',null)");
         conn.commit();
         
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t WHERE k not like '%\\(%'");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT * FROM " + t + " WHERE k not like '%\\(%'");
         assertTrue(rs.next());
         assertEquals("aa", rs.getString(1));
         assertEquals("bb", rs.getString(2));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/366e7a77/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7cc250f..16762e9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -284,6 +284,24 @@
                  <goal>verify</goal>
                </goals>
             </execution>
+            <execution>
+              <id>HBaseManagedTimeTableReuseTest</id>
+              <configuration>
+                <encoding>UTF-8</encoding>
+                <forkCount>${numForkedIT}</forkCount>
+                <runOrder>alphabetical</runOrder>
+                <reuseForks>true</reuseForks>
+                <argLine>-enableassertions -Xmx2000m -XX:MaxPermSize=128m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}"</argLine>
+                <redirectTestOutputToFile>${test.output.tofile}</redirectTestOutputToFile>
+                <testSourceDirectory>${basedir}/src/it/java</testSourceDirectory>
+                <groups>org.apache.phoenix.end2end.HBaseManagedTimeTest</groups>
+                <shutdown>kill</shutdown>
+              </configuration>
+              <goals>
+                <goal>integration-test</goal>
+                <goal>verify</goal>
+              </goals>
+            </execution>
 	        <execution>
                <id>NeedTheirOwnClusterTests</id>
                  <configuration>


[05/52] [abbrv] phoenix git commit: PHOENIX-2822 Tests that extend BaseHBaseManagedTimeIT are very slow(Rahul Gidwani)

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropViewIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropViewIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropViewIT.java
index 0e87afd..e52f8cc 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropViewIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropViewIT.java
@@ -33,6 +33,7 @@ import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
+import org.apache.phoenix.end2end.BaseHBaseManagedTimeTableReuseIT;
 import org.apache.phoenix.end2end.Shadower;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.util.PropertiesUtil;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
index 65eeb20..b21655a 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
@@ -32,11 +32,12 @@ import java.sql.SQLException;
 import java.util.Properties;
 
 import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
+import org.apache.phoenix.end2end.BaseHBaseManagedTimeTableReuseIT;
 import org.apache.phoenix.util.PropertiesUtil;
 import org.junit.Test;
 
 
-public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
+public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeTableReuseIT {
 
     @Test
     public void testUpsertIntoSaltedTableFromNormalTable() throws Exception {
@@ -44,26 +45,28 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE IF NOT EXISTS source" + 
+            String source = generateRandomString();
+            String ddl = "CREATE TABLE IF NOT EXISTS " + source +
                     " (pk VARCHAR NOT NULL PRIMARY KEY, col INTEGER)";
             createTestTable(getUrl(), ddl);
-            ddl = "CREATE TABLE IF NOT EXISTS target" + 
+            String target = generateRandomString();
+            ddl = "CREATE TABLE IF NOT EXISTS " + target +
                     " (pk VARCHAR NOT NULL PRIMARY KEY, col INTEGER) SALT_BUCKETS=4";
             createTestTable(getUrl(), ddl);
             
-            String query = "UPSERT INTO source(pk, col) VALUES(?,?)";
+            String query = "UPSERT INTO " + source + "(pk, col) VALUES(?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "1");
             stmt.setInt(2, 1);
             stmt.execute();
             conn.commit();
             
-            query = "UPSERT INTO target(pk, col) SELECT pk, col from source";
+            query = "UPSERT INTO " + target + "(pk, col) SELECT pk, col from " + source;
             stmt = conn.prepareStatement(query);
             stmt.execute();
             conn.commit();
             
-            query = "SELECT * FROM target";
+            query = "SELECT * FROM " + target;
             stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -81,26 +84,28 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE IF NOT EXISTS source" + 
+            String source = generateRandomString();
+            String ddl = "CREATE TABLE IF NOT EXISTS " + source +
                     " (pk VARCHAR NOT NULL PRIMARY KEY, col INTEGER) SALT_BUCKETS=4";
             createTestTable(getUrl(), ddl);
-            ddl = "CREATE TABLE IF NOT EXISTS target" + 
+            String target = generateRandomString();
+            ddl = "CREATE TABLE IF NOT EXISTS " + target +
                     " (pk VARCHAR NOT NULL PRIMARY KEY, col INTEGER)";
             createTestTable(getUrl(), ddl);
             
-            String query = "UPSERT INTO source(pk, col) VALUES(?,?)";
+            String query = "UPSERT INTO " + source + "(pk, col) VALUES(?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "1");
             stmt.setInt(2, 1);
             stmt.execute();
             conn.commit();
-            query = "UPSERT INTO target(pk, col) SELECT pk, col from source";
+            query = "UPSERT INTO " + target + "(pk, col) SELECT pk, col from " + source;
             stmt = conn.prepareStatement(query);
             stmt.execute();
             conn.commit();
-            analyzeTable(conn, "source");
-            analyzeTable(conn, "target");
-            query = "SELECT * FROM target";
+            analyzeTable(conn, source);
+            analyzeTable(conn, target);
+            query = "SELECT * FROM " + target;
             stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -123,26 +128,28 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE IF NOT EXISTS source" + 
+            String source = generateRandomString();
+            String ddl = "CREATE TABLE IF NOT EXISTS " + source +
                     " (pk VARCHAR NOT NULL PRIMARY KEY, col INTEGER) SALT_BUCKETS=4";
             createTestTable(getUrl(), ddl);
-            ddl = "CREATE TABLE IF NOT EXISTS target" + 
+            String target = generateRandomString();
+            ddl = "CREATE TABLE IF NOT EXISTS " + target +
                     " (pk VARCHAR NOT NULL PRIMARY KEY, col INTEGER) SALT_BUCKETS=4";
             createTestTable(getUrl(), ddl);
             
-            String query = "UPSERT INTO source(pk, col) VALUES(?,?)";
+            String query = "UPSERT INTO " + source + "(pk, col) VALUES(?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "1");
             stmt.setInt(2, 1);
             stmt.execute();
             conn.commit();
             
-            query = "UPSERT INTO target(pk, col) SELECT pk, col from source";
+            query = "UPSERT INTO " + target + "(pk, col) SELECT pk, col from " + source;
             stmt = conn.prepareStatement(query);
             stmt.execute();
             conn.commit();
             
-            query = "SELECT * FROM target";
+            query = "SELECT * FROM " + target;
             stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -160,23 +167,24 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE IF NOT EXISTS source" + 
+            String source = generateRandomString();
+            String ddl = "CREATE TABLE IF NOT EXISTS " + source +
                     " (pk VARCHAR NOT NULL PRIMARY KEY, col1 INTEGER, col2 INTEGER) SALT_BUCKETS=4";
             createTestTable(getUrl(), ddl);
             
-            String query = "UPSERT INTO source(pk, col1) VALUES(?,?)";
+            String query = "UPSERT INTO " + source + "(pk, col1) VALUES(?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "1");
             stmt.setInt(2, 1);
             stmt.execute();
             conn.commit();
             
-            query = "UPSERT INTO source(pk, col2) SELECT pk, col1 from source";
+            query = "UPSERT INTO " + source + "(pk, col2) SELECT pk, col1 from " + source;
             stmt = conn.prepareStatement(query);
             stmt.execute();
             conn.commit();
             
-            query = "SELECT col2 FROM source";
+            query = "SELECT col2 FROM " + source;
             stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -193,12 +201,13 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE IF NOT EXISTS source1" + 
+            String source1 = generateRandomString();
+            String ddl = "CREATE TABLE IF NOT EXISTS " + source1 +
                     " (pk1 varchar NULL, pk2 varchar NULL, pk3 integer NOT NULL, col1 INTEGER" + 
                     " CONSTRAINT pk PRIMARY KEY (pk1, pk2, pk3)) SALT_BUCKETS=4";
             createTestTable(getUrl(), ddl);
             
-            String query = "UPSERT INTO source1(pk1, pk2, pk3, col1) VALUES(?,?,?,?)";
+            String query = "UPSERT INTO " + source1 + "(pk1, pk2, pk3, col1) VALUES(?,?,?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "1");
             stmt.setString(2, "2");
@@ -208,12 +217,13 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
             conn.commit();
             
             conn.setAutoCommit(true);
-            query = "UPSERT INTO source1(pk3, col1, pk1) SELECT pk3+1, col1+1, pk2 from source1";
+            query = "UPSERT INTO " + source1
+                + "(pk3, col1, pk1) SELECT pk3+1, col1+1, pk2 from " + source1;
             stmt = conn.prepareStatement(query);
             stmt.execute();
             conn.commit();
-            analyzeTable(conn, "source1");
-            query = "SELECT col1 FROM source1";
+            analyzeTable(conn, source1);
+            query = "SELECT col1 FROM " + source1;
             stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -232,13 +242,14 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE IF NOT EXISTS source1" +
+            String source1 = generateRandomString();
+            String ddl = "CREATE TABLE IF NOT EXISTS " + source1 +
                     " (pk1 varchar NULL, pk2 varchar NULL, pk3 integer NOT NULL, col1 INTEGER" +
                     " CONSTRAINT pk PRIMARY KEY (pk1, pk2, pk3)) SALT_BUCKETS=4";
             createTestTable(getUrl(), ddl);
 
             for (int i = 0; i < 1000; i++) {
-                String upsert = "UPSERT INTO source1(pk1, pk2, pk3, col1) VALUES (?,?,?,?)";
+                String upsert = "UPSERT INTO " + source1 + "(pk1, pk2, pk3, col1) VALUES (?,?,?,?)";
                 PreparedStatement stmt = conn.prepareStatement(upsert);
                 stmt.setString(1, Integer.toString(i));
                 stmt.setString(2, Integer.toString(i));
@@ -248,13 +259,14 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
             }
             conn.commit();
 
-            String ddl2 = "CREATE TABLE IF NOT EXISTS source2" +
+            String source2 = generateRandomString();
+            String ddl2 = "CREATE TABLE IF NOT EXISTS " + source2 +
                     " (pk1 varchar NULL, pk2 varchar NULL, pk3 integer NOT NULL, col1 INTEGER" +
                     " CONSTRAINT pk PRIMARY KEY (pk1, pk2, pk3)) SALT_BUCKETS=4";
             createTestTable(getUrl(), ddl2);
 
             for (int i = 0; i < 1000; i++) {
-                String upsert = "UPSERT INTO source2(pk1, pk2, pk3, col1) VALUES (?,?,?,?)";
+                String upsert = "UPSERT INTO " + source2 + "(pk1, pk2, pk3, col1) VALUES (?,?,?,?)";
                 PreparedStatement stmt = conn.prepareStatement(upsert);
                 stmt.setString(1, Integer.toString(i));
                 stmt.setString(2, Integer.toString(i));
@@ -264,16 +276,22 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
             }
             conn.commit();
 
-            String ddl3 = "CREATE TABLE IF NOT EXISTS dest" +
+            String dest = generateRandomString();
+            String ddl3 = "CREATE TABLE IF NOT EXISTS " + dest +
                     " (pk1 varchar NULL, pk2 varchar NULL, pk3 integer NOT NULL, col1 INTEGER" +
                     " CONSTRAINT pk PRIMARY KEY (pk1, pk2, pk3)) SALT_BUCKETS=4";
             createTestTable(getUrl(), ddl3);
 
-            String query = "UPSERT INTO dest(pk1, pk2, pk3, col1) SELECT S1.pk1, S1.pk2, S2.pk3, S2.col1 FROM source1 AS S1 JOIN source2 AS S2 ON S1.pk1 = S2.pk1 AND S1.pk2 = S2.pk2 AND S1.pk3 = S2.pk3";
+            String query =
+                "UPSERT INTO " + dest
+                    + "(pk1, pk2, pk3, col1) SELECT S1.pk1, S1.pk2, S2.pk3, S2.col1 FROM "
+                    + source1
+                    + " AS S1 JOIN " + source2
+                    + " AS S2 ON S1.pk1 = S2.pk1 AND S1.pk2 = S2.pk2 AND S1.pk3 = S2.pk3";
             conn.createStatement().execute(query);
             conn.commit();
 
-            query = "SELECT COUNT(*) FROM dest";
+            query = "SELECT COUNT(*) FROM " + dest;
             PreparedStatement stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             assertTrue(rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableVarLengthRowKeyIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableVarLengthRowKeyIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableVarLengthRowKeyIT.java
index 53b267c..e94ae3a 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableVarLengthRowKeyIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableVarLengthRowKeyIT.java
@@ -30,11 +30,14 @@ import java.sql.ResultSet;
 import java.util.Properties;
 
 import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
+import org.apache.phoenix.end2end.BaseHBaseManagedTimeTableReuseIT;
 import org.apache.phoenix.util.PropertiesUtil;
 import org.junit.Test;
 
 
-public class SaltedTableVarLengthRowKeyIT extends BaseHBaseManagedTimeIT {
+public class SaltedTableVarLengthRowKeyIT extends BaseHBaseManagedTimeTableReuseIT {
+
+    private static final String TEST_TABLE = generateRandomString();
 
     private static void initTableValues() throws Exception {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
@@ -42,9 +45,9 @@ public class SaltedTableVarLengthRowKeyIT extends BaseHBaseManagedTimeIT {
         conn.setAutoCommit(false);
         
         try {
-            createTestTable(getUrl(), "create table testVarcharKey " +
+            createTestTable(getUrl(), "create table " + TEST_TABLE + " " +
                     " (key_string varchar not null primary key, kv integer) SALT_BUCKETS=4\n");
-            String query = "UPSERT INTO testVarcharKey VALUES(?,?)";
+            String query = "UPSERT INTO " + TEST_TABLE + " VALUES(?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "a");
             stmt.setInt(2, 1);
@@ -74,7 +77,7 @@ public class SaltedTableVarLengthRowKeyIT extends BaseHBaseManagedTimeIT {
             PreparedStatement stmt;
             ResultSet rs;
             
-            query = "SELECT * FROM testVarcharKey where key_string = 'abc'";
+            query = "SELECT * FROM " + TEST_TABLE + " where key_string = 'abc'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/iterate/PhoenixQueryTimeoutIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/iterate/PhoenixQueryTimeoutIT.java b/phoenix-core/src/it/java/org/apache/phoenix/iterate/PhoenixQueryTimeoutIT.java
index 8399362..6bf3790 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/iterate/PhoenixQueryTimeoutIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/iterate/PhoenixQueryTimeoutIT.java
@@ -29,14 +29,18 @@ import java.util.Properties;
 import java.util.Set;
 
 import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
+import org.apache.phoenix.end2end.BaseHBaseManagedTimeTableReuseIT;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
  * Tests to validate that user specified property phoenix.query.timeoutMs
  * works as expected.
  */
-public class PhoenixQueryTimeoutIT extends BaseHBaseManagedTimeIT {
+public class PhoenixQueryTimeoutIT extends BaseHBaseManagedTimeTableReuseIT {
+
+    private static final String QUERY_TIMEOUT_TEST = generateRandomString();
 
     @Test
     /**
@@ -83,32 +87,31 @@ public class PhoenixQueryTimeoutIT extends BaseHBaseManagedTimeIT {
     //-----------------------------------------------------------------
     
     private PreparedStatement loadDataAndPrepareQuery(int timeoutMs, int timeoutSecs) throws Exception, SQLException {
-        createTableAndInsertRows(1000);
         Properties props = new Properties();
         props.setProperty("phoenix.query.timeoutMs", String.valueOf(timeoutMs));
         Connection conn = DriverManager.getConnection(getUrl(), props);
-        PreparedStatement ps = conn.prepareStatement("SELECT * FROM QUERY_TIMEOUT_TEST");
+        PreparedStatement ps = conn.prepareStatement("SELECT * FROM " + QUERY_TIMEOUT_TEST);
         PhoenixStatement phoenixStmt = ps.unwrap(PhoenixStatement.class);
         assertEquals(timeoutMs, phoenixStmt.getQueryTimeoutInMillis());
         assertEquals(timeoutSecs, phoenixStmt.getQueryTimeout());
         return ps;
     }
-    
-    private Set<String> createTableAndInsertRows(int numRows) throws Exception {
-        String ddl = "CREATE TABLE QUERY_TIMEOUT_TEST (K VARCHAR NOT NULL PRIMARY KEY, V VARCHAR)";
+
+    @BeforeClass
+    public static void createTableAndInsertRows() throws Exception {
+        int numRows = 1000;
+        String ddl =
+            "CREATE TABLE " + QUERY_TIMEOUT_TEST + " (K VARCHAR NOT NULL PRIMARY KEY, V VARCHAR)";
         Connection conn = DriverManager.getConnection(getUrl());
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO QUERY_TIMEOUT_TEST VALUES (?, ?)";
+        String dml = "UPSERT INTO " + QUERY_TIMEOUT_TEST + " VALUES (?, ?)";
         PreparedStatement stmt = conn.prepareStatement(dml);
-        final Set<String> expectedKeys = new HashSet<>(numRows);
         for (int i = 1; i <= numRows; i++) {
             String key = "key" + i;
-            expectedKeys.add(key);
             stmt.setString(1, key);
             stmt.setString(2, "value" + i);
             stmt.executeUpdate();
         }
         conn.commit();
-        return expectedKeys;
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/main/java/org/apache/phoenix/memory/GlobalMemoryManager.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/memory/GlobalMemoryManager.java b/phoenix-core/src/main/java/org/apache/phoenix/memory/GlobalMemoryManager.java
index 71d1b69..3e8f9e8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/memory/GlobalMemoryManager.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/memory/GlobalMemoryManager.java
@@ -17,6 +17,7 @@
  */
 package org.apache.phoenix.memory;
 
+import com.google.common.annotations.VisibleForTesting;
 import org.apache.http.annotation.GuardedBy;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -72,17 +73,7 @@ public class GlobalMemoryManager implements MemoryManager {
         long nBytes;
         synchronized(sync) {
             while (usedMemoryBytes + minBytes > maxMemoryBytes) { // Only wait if minBytes not available
-                try {
-                    logger.debug("Waiting for " + (usedMemoryBytes + minBytes - maxMemoryBytes) + " bytes to be free");
-                    long remainingWaitTimeMs = maxWaitMs - (System.currentTimeMillis() - startTimeMs);
-                    if (remainingWaitTimeMs <= 0) { // Ran out of time waiting for some memory to get freed up
-                        throw new InsufficientMemoryException("Requested memory of " + minBytes + " bytes could not be allocated. Using memory of " + usedMemoryBytes + " bytes from global pool of " + maxMemoryBytes + " bytes after waiting for " + maxWaitMs + "ms.");
-                    }
-                    sync.wait(remainingWaitTimeMs);
-                } catch (InterruptedException ie) {
-                    Thread.currentThread().interrupt();
-                    throw new RuntimeException("Interrupted allocation of " + minBytes + " bytes", ie);
-                }
+                waitForBytesToFree(minBytes, startTimeMs);
             }
             // Allocate at most reqBytes, but at least minBytes
             nBytes = Math.min(reqBytes, maxMemoryBytes - usedMemoryBytes);
@@ -94,6 +85,20 @@ public class GlobalMemoryManager implements MemoryManager {
         return nBytes;
     }
 
+    @VisibleForTesting void waitForBytesToFree(long minBytes, long startTimeMs) {
+        try {
+            logger.debug("Waiting for " + (usedMemoryBytes + minBytes - maxMemoryBytes) + " bytes to be free " + startTimeMs);
+            long remainingWaitTimeMs = maxWaitMs - (System.currentTimeMillis() - startTimeMs);
+            if (remainingWaitTimeMs <= 0) { // Ran out of time waiting for some memory to get freed up
+                throw new InsufficientMemoryException("Requested memory of " + minBytes + " bytes could not be allocated. Using memory of " + usedMemoryBytes + " bytes from global pool of " + maxMemoryBytes + " bytes after waiting for " + maxWaitMs + "ms.");
+            }
+            sync.wait(remainingWaitTimeMs);
+        } catch (InterruptedException ie) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException("Interrupted allocation of " + minBytes + " bytes", ie);
+        }
+    }
+
     @Override
     public MemoryChunk allocate(long minBytes, long reqBytes) {
         long nBytes = allocateBytes(minBytes, reqBytes);
@@ -105,7 +110,7 @@ public class GlobalMemoryManager implements MemoryManager {
         return allocate(nBytes,nBytes);
     }
 
-    protected MemoryChunk newMemoryChunk(long sizeBytes) {
+    private MemoryChunk newMemoryChunk(long sizeBytes) {
         return new GlobalMemoryChunk(sizeBytes);
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java
index 94e6c79..916329f 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java
@@ -19,19 +19,26 @@ package org.apache.phoenix.memory;
 
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.spy;
 
+import com.google.common.base.Stopwatch;
 import org.junit.Ignore;
 import org.junit.Test;
 
 import org.apache.phoenix.memory.MemoryManager.MemoryChunk;
+import org.mockito.Mockito;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
- * 
+ *
  * Tests for GlobalMemoryManager and ChildMemoryManager
  * TODO: use our own time keeper so these tests don't flap
  *
- * 
+ *
  * @since 0.1
  */
 public class MemoryManagerTest {
@@ -53,7 +60,7 @@ public class MemoryManagerTest {
             fail();
         } catch (InsufficientMemoryException e) { // expected
         }
-        
+
         c1.close();
         c2.close();
         assertTrue(rmm1.getAvailableMemory() == rmm1.getMaxMemory());
@@ -69,35 +76,38 @@ public class MemoryManagerTest {
     }
 
     @Test
-    public void testWaitForMemoryAvailable() {
-        final GlobalMemoryManager gmm = new GlobalMemoryManager(100,8000);
+    public void testWaitForMemoryAvailable() throws Exception {
+        final GlobalMemoryManager gmm = spy(new GlobalMemoryManager(100, 80));
         final ChildMemoryManager rmm1 = new ChildMemoryManager(gmm,100);
         final ChildMemoryManager rmm2 = new ChildMemoryManager(gmm,100);
+        final CountDownLatch latch = new CountDownLatch(2);
         Thread t1 = new Thread() {
             @Override
             public void run() {
                 MemoryChunk c1 = rmm1.allocate(50);
                 MemoryChunk c2 = rmm1.allocate(50);
-                sleepFor(4000);
+                sleepFor(40);
                 c1.close();
-                sleepFor(2000);
+                sleepFor(20);
                 c2.close();
+                latch.countDown();
             }
         };
         Thread t2 = new Thread() {
             @Override
             public void run() {
-                sleepFor(2000);
+                sleepFor(20);
                 // Will require waiting for a bit of time before t1 frees the requested memory
-                long startTime = System.currentTimeMillis();
+                Stopwatch watch = new Stopwatch().start();
                 MemoryChunk c3 = rmm2.allocate(50);
-                assertTrue(System.currentTimeMillis() - startTime >= 1000);
+                Mockito.verify(gmm, atLeastOnce()).waitForBytesToFree(anyLong(), anyLong());
                 c3.close();
+                latch.countDown();
             }
         };
-        t1.start();
         t2.start();
-        sleepFor(1000);
+        t1.start();
+        latch.await(1, TimeUnit.SECONDS);
         // Main thread competes with others to get all memory, but should wait
         // until both threads are complete (since that's when the memory will
         // again be all available.
@@ -108,39 +118,40 @@ public class MemoryManagerTest {
         assertTrue(rmm1.getAvailableMemory() == rmm1.getMaxMemory());
         assertTrue(rmm2.getAvailableMemory() == rmm2.getMaxMemory());
     }
-    
+
     @Test
-    @Ignore // TODO: get this not to flap
-    public void testResizeWaitForMemoryAvailable() {
-        final GlobalMemoryManager gmm = new GlobalMemoryManager(100,8000);
+    public void testResizeWaitForMemoryAvailable() throws Exception {
+        final GlobalMemoryManager gmm = spy(new GlobalMemoryManager(100, 80));
         final ChildMemoryManager rmm1 = new ChildMemoryManager(gmm,100);
         final ChildMemoryManager rmm2 = new ChildMemoryManager(gmm,100);
+        final CountDownLatch latch = new CountDownLatch(2);
         Thread t1 = new Thread() {
             @Override
             public void run() {
                 MemoryChunk c1 = rmm1.allocate(50);
                 MemoryChunk c2 = rmm1.allocate(40);
-                sleepFor(4000);
+                sleepFor(40);
                 c1.close();
-                sleepFor(2000);
+                sleepFor(20);
                 c2.close();
+                latch.countDown();
             }
         };
         Thread t2 = new Thread() {
             @Override
             public void run() {
-                sleepFor(2000);
+                sleepFor(20);
                 MemoryChunk c3 = rmm2.allocate(10);
                 // Will require waiting for a bit of time before t1 frees the requested memory
-                long startTime = System.currentTimeMillis();
                 c3.resize(50);
-                assertTrue(System.currentTimeMillis() - startTime >= 2000);
+                Mockito.verify(gmm, atLeastOnce()).waitForBytesToFree(anyLong(), anyLong());
                 c3.close();
+                latch.countDown();
             }
         };
         t1.start();
         t2.start();
-        sleepFor(3000);
+        latch.await(1, TimeUnit.SECONDS);
         // Main thread competes with others to get all memory, but should wait
         // until both threads are complete (since that's when the memory will
         // again be all available.
@@ -151,41 +162,47 @@ public class MemoryManagerTest {
         assertTrue(rmm1.getAvailableMemory() == rmm1.getMaxMemory());
         assertTrue(rmm2.getAvailableMemory() == rmm2.getMaxMemory());
     }
-    
-    // @Test commenting out because the test is flapping too often
-    public void broken_testWaitUntilResize() {
-        final GlobalMemoryManager gmm = new GlobalMemoryManager(100,8000);
+
+    @Test
+    public void testWaitUntilResize() throws Exception {
+        final GlobalMemoryManager gmm = spy(new GlobalMemoryManager(100, 80));
         final ChildMemoryManager rmm1 = new ChildMemoryManager(gmm,100);
         final MemoryChunk c1 = rmm1.allocate(70);
+        final CountDownLatch latch = new CountDownLatch(2);
+
         Thread t1 = new Thread() {
             @Override
             public void run() {
                 MemoryChunk c2 = rmm1.allocate(20);
-                sleepFor(4000);
+                sleepFor(40);
                 c1.resize(20); // resize down to test that other thread is notified
-                sleepFor(2000);
+                sleepFor(20);
                 c2.close();
                 c1.close();
                 assertTrue(rmm1.getAvailableMemory() == rmm1.getMaxMemory());
+                latch.countDown();
             }
         };
         Thread t2 = new Thread() {
             @Override
             public void run() {
-                sleepFor(2000);
+                sleepFor(20);
                 ChildMemoryManager rmm2 = new ChildMemoryManager(gmm,100);
                 MemoryChunk c3 = rmm2.allocate(10);
                 long startTime = System.currentTimeMillis();
                 c3.resize(60); // Test that resize waits if memory not available
                 assertTrue(c1.getSize() == 20); // c1 was resized not closed
-                assertTrue(System.currentTimeMillis() - startTime >= 2000); // we waited some time before the allocate happened
+                // we waited some time before the allocate happened
+
+                Mockito.verify(gmm, atLeastOnce()).waitForBytesToFree(anyLong(), anyLong());
                 c3.close();
                 assertTrue(rmm2.getAvailableMemory() == rmm2.getMaxMemory());
+                latch.countDown();
             }
         };
         t1.start();
         t2.start();
-        sleepFor(1000);
+        latch.await(1, TimeUnit.SECONDS);
         // Main thread competes with others to get all memory, but should wait
         // until both threads are complete (since that's when the memory will
         // again be all available.
@@ -197,7 +214,7 @@ public class MemoryManagerTest {
 
     @Test
     public void testChildDecreaseAllocation() throws Exception {
-        MemoryManager gmm = new GlobalMemoryManager(100,1);
+        MemoryManager gmm = spy(new GlobalMemoryManager(100, 1));
         ChildMemoryManager rmm1 = new ChildMemoryManager(gmm,100);
         ChildMemoryManager rmm2 = new ChildMemoryManager(gmm,10);
         MemoryChunk c1 = rmm1.allocate(50);
@@ -209,7 +226,7 @@ public class MemoryManagerTest {
         assertTrue(rmm2.getAvailableMemory() == rmm2.getMaxMemory());
         assertTrue(gmm.getAvailableMemory() == gmm.getMaxMemory());
     }
-    
+
     @Test
     public void testOverChildMemoryLimit() throws Exception {
         MemoryManager gmm = new GlobalMemoryManager(100,1);
@@ -229,7 +246,7 @@ public class MemoryManagerTest {
         // Ensure that you can get back to max for rmn1 after failure
         MemoryChunk c4 = rmm1.allocate(10);
         MemoryChunk c5 = rmm1.allocate(15);
-        
+
         MemoryChunk c6 = rmm4.allocate(25);
         try {
             // This passes % test, but fails the next total memory usage test
@@ -241,7 +258,7 @@ public class MemoryManagerTest {
         // Tests that % test passes (confirming that the 10 above was subtracted back from request memory usage,
         // since we'd be at the max of 35% now
         MemoryChunk c7 = rmm4.allocate(10);
-        
+
         try {
             rmm4.allocate(1);
             fail();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
index d28802f..e3bd4a0 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
@@ -118,6 +118,9 @@ import java.util.concurrent.TimeoutException;
 
 import javax.annotation.Nonnull;
 
+
+import org.apache.commons.lang.RandomStringUtils;
+
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
@@ -125,6 +128,7 @@ import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.IntegrationTestingUtility;
+import org.apache.hadoop.hbase.RandomStringGeneratorImpl;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
@@ -828,6 +832,10 @@ public abstract class BaseTest {
         createTestTable(url, ddl, splits, ts);
     }
 
+    protected static String generateRandomString() {
+      return RandomStringUtils.randomAlphabetic(20).toUpperCase();
+    }
+
     protected static void createTestTable(String url, String ddl) throws SQLException {
         createTestTable(url, ddl, null, null);
     }


[37/52] [abbrv] phoenix git commit: PHOENIX-2856 HBaseManagedTimeTableReuseTest category isn't getting run

Posted by sa...@apache.org.
PHOENIX-2856 HBaseManagedTimeTableReuseTest category isn't getting run


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

Branch: refs/heads/encodecolumns
Commit: 0cec970179beebedc90aff7903345b6ec3329c66
Parents: 5436243
Author: Samarth <sa...@salesforce.com>
Authored: Fri Apr 22 23:20:04 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Fri Apr 22 23:20:04 2016 -0700

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/0cec9701/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 758eb3a..69a0ef8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -296,7 +296,7 @@
                 <argLine>-enableassertions -Xmx2000m -XX:MaxPermSize=128m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}"</argLine>
                 <redirectTestOutputToFile>${test.output.tofile}</redirectTestOutputToFile>
                 <testSourceDirectory>${basedir}/src/it/java</testSourceDirectory>
-                <groups>org.apache.phoenix.end2end.HBaseManagedTimeTest</groups>
+                <groups>org.apache.phoenix.end2end.HBaseManagedTimeTableReuseTest</groups>
                 <shutdown>kill</shutdown>
               </configuration>
               <goals>


[33/52] [abbrv] phoenix git commit: PHOENIX-2840 Ignore flapping MemoryManagerTest.testWaitForMemoryAvailable unit test

Posted by sa...@apache.org.
PHOENIX-2840 Ignore flapping MemoryManagerTest.testWaitForMemoryAvailable unit test

Conflicts:

	phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java


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

Branch: refs/heads/encodecolumns
Commit: f4c84a8a4f3d2f2e73bb993cdace78d60be84c81
Parents: 521b819
Author: James Taylor <ja...@apache.org>
Authored: Fri Apr 22 16:45:08 2016 -0700
Committer: James Taylor <ja...@apache.org>
Committed: Fri Apr 22 18:55:22 2016 -0700

----------------------------------------------------------------------
 .../org/apache/phoenix/memory/MemoryManagerTest.java   | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/f4c84a8a/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java
index 916329f..d050deb 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/memory/MemoryManagerTest.java
@@ -23,16 +23,14 @@ import static org.mockito.Matchers.anyLong;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.spy;
 
-import com.google.common.base.Stopwatch;
-import org.junit.Ignore;
-import org.junit.Test;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.phoenix.memory.MemoryManager.MemoryChunk;
+import org.junit.Ignore;
+import org.junit.Test;
 import org.mockito.Mockito;
 
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
 /**
  *
  * Tests for GlobalMemoryManager and ChildMemoryManager
@@ -75,6 +73,7 @@ public class MemoryManagerTest {
         }
     }
 
+    @Ignore("See PHOENIX-2840")
     @Test
     public void testWaitForMemoryAvailable() throws Exception {
         final GlobalMemoryManager gmm = spy(new GlobalMemoryManager(100, 80));
@@ -98,7 +97,6 @@ public class MemoryManagerTest {
             public void run() {
                 sleepFor(20);
                 // Will require waiting for a bit of time before t1 frees the requested memory
-                Stopwatch watch = new Stopwatch().start();
                 MemoryChunk c3 = rmm2.allocate(50);
                 Mockito.verify(gmm, atLeastOnce()).waitForBytesToFree(anyLong(), anyLong());
                 c3.close();
@@ -189,7 +187,6 @@ public class MemoryManagerTest {
                 sleepFor(20);
                 ChildMemoryManager rmm2 = new ChildMemoryManager(gmm,100);
                 MemoryChunk c3 = rmm2.allocate(10);
-                long startTime = System.currentTimeMillis();
                 c3.resize(60); // Test that resize waits if memory not available
                 assertTrue(c1.getSize() == 20); // c1 was resized not closed
                 // we waited some time before the allocate happened


[16/52] [abbrv] phoenix git commit: PHOENIX-2830 Upgrade code fails when upgrading from a version before 4.3

Posted by sa...@apache.org.
PHOENIX-2830 Upgrade code fails when upgrading from a version before 4.3


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

Branch: refs/heads/encodecolumns
Commit: 4efb4ddffc7f3065a22dc662baea7a796945de4f
Parents: fccbe56
Author: Samarth <sa...@salesforce.com>
Authored: Mon Apr 11 14:02:44 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 11 14:02:44 2016 -0700

----------------------------------------------------------------------
 .../phoenix/query/ConnectionQueryServicesImpl.java    | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/4efb4ddf/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index a8595e9..ebc62de 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -2284,7 +2284,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                                 String columnsToAdd = "";
                                 if(currentServerSideTableTimeStamp < MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_3_0) {
                                     // We know that we always need to add the STORE_NULLS column for 4.3 release
-                                    columnsToAdd += "," + PhoenixDatabaseMetaData.STORE_NULLS + " " + PBoolean.INSTANCE.getSqlTypeName();
+                                    columnsToAdd = addColumn(columnsToAdd, PhoenixDatabaseMetaData.STORE_NULLS + " " + PBoolean.INSTANCE.getSqlTypeName());
                                     try (HBaseAdmin admin = getAdmin()) {
                                         HTableDescriptor[] localIndexTables = admin.listTables(MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX+".*");
                                         for (HTableDescriptor table : localIndexTables) {
@@ -2310,8 +2310,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                                 // we should just have a ALTER TABLE ADD IF NOT EXISTS statement with all 
                                 // the column names that have been added to SYSTEM.CATALOG since 4.0. 
                                 if (currentServerSideTableTimeStamp < MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_1_0) {
-                                    columnsToAdd += ", " + PhoenixDatabaseMetaData.INDEX_TYPE + " " + PUnsignedTinyint.INSTANCE.getSqlTypeName()
-                                            + ", " + PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP + " " + PLong.INSTANCE.getSqlTypeName();
+                                    columnsToAdd = addColumn(columnsToAdd, PhoenixDatabaseMetaData.INDEX_TYPE + " " + PUnsignedTinyint.INSTANCE.getSqlTypeName()
+                                            + ", " + PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP + " " + PLong.INSTANCE.getSqlTypeName());
                                 }
                                 
                                 // If we have some new columns from 4.1-4.3 to add, add them now.
@@ -2486,6 +2486,14 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         }
     }
     
+    private String addColumn(String columnsToAddSoFar, String columns) {
+        if (columnsToAddSoFar == null || columnsToAddSoFar.isEmpty()) {
+            return columns;
+        } else {
+            return columnsToAddSoFar + ", " + columns;
+        }
+    }
+    
     private void scheduleRenewLeaseTasks() {
         if (isRenewingLeasesEnabled()) {
             ThreadFactory threadFactory =


[49/52] [abbrv] phoenix git commit: Tweak statistics tests to take into account column name encoding

Posted by sa...@apache.org.
Tweak statistics tests to take into account column name encoding


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

Branch: refs/heads/encodecolumns
Commit: 2b3acb2ba781da387df63670cb898d3c9c4d78a9
Parents: 227ba1d
Author: Samarth <sa...@salesforce.com>
Authored: Fri Apr 8 09:52:25 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:32 2016 -0700

----------------------------------------------------------------------
 .../java/org/apache/phoenix/end2end/StatsCollectorIT.java |  2 +-
 .../end2end/StatsCollectorWithSplitsAndMultiCFIT.java     | 10 +++++-----
 2 files changed, 6 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/2b3acb2b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
index f0fe346..135cff5 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
@@ -130,7 +130,7 @@ public class StatsCollectorIT extends StatsCollectorAbstractIT {
         rs = conn.createStatement().executeQuery("EXPLAIN SELECT * FROM " + fullTableName);
         explainPlan = QueryUtil.getExplainPlan(rs);
         assertEquals(
-                "CLIENT 4-CHUNK 1 ROWS 34 BYTES PARALLEL 3-WAY FULL SCAN OVER " + fullTableName + "\n" +
+                "CLIENT 4-CHUNK 1 ROWS 28 BYTES PARALLEL 3-WAY FULL SCAN OVER " + fullTableName + "\n" +
                 "CLIENT MERGE SORT",
                 explainPlan);
         rs = conn.createStatement().executeQuery("EXPLAIN SELECT * FROM " + fullTableName + " WHERE k = 'a'");

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2b3acb2b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorWithSplitsAndMultiCFIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorWithSplitsAndMultiCFIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorWithSplitsAndMultiCFIT.java
index d922ad9..046d6c4 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorWithSplitsAndMultiCFIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorWithSplitsAndMultiCFIT.java
@@ -116,25 +116,25 @@ public class StatsCollectorWithSplitsAndMultiCFIT extends StatsCollectorAbstract
         assertTrue(rs.next());
         assertEquals("A", rs.getString(1));
         assertEquals(25, rs.getInt(2));
-        assertEquals(12420, rs.getInt(3));
+        assertEquals(12530, rs.getInt(3));
         assertEquals(25, rs.getInt(4));
 
         assertTrue(rs.next());
         assertEquals("B", rs.getString(1));
         assertEquals(20, rs.getInt(2));
-        assertEquals(5540, rs.getInt(3));
+        assertEquals(5600, rs.getInt(3));
         assertEquals(20, rs.getInt(4));
 
         assertTrue(rs.next());
         assertEquals("C", rs.getString(1));
         assertEquals(25, rs.getInt(2));
-        assertEquals(6930, rs.getInt(3));
+        assertEquals(7005, rs.getInt(3));
         assertEquals(25, rs.getInt(4));
 
         assertTrue(rs.next());
         assertEquals("D", rs.getString(1));
         assertEquals(25, rs.getInt(2));
-        assertEquals(6930, rs.getInt(3));
+        assertEquals(7005, rs.getInt(3));
         assertEquals(25, rs.getInt(4));
 
     }
@@ -166,7 +166,7 @@ public class StatsCollectorWithSplitsAndMultiCFIT extends StatsCollectorAbstract
             int startIndex = r.nextInt(strings.length);
             int endIndex = r.nextInt(strings.length - startIndex) + startIndex;
             long rows = endIndex - startIndex;
-            long c2Bytes = rows * 35;
+            long c2Bytes = rows * 37;
             System.out.println(rows + ":" + startIndex + ":" + endIndex);
             rs = conn.createStatement().executeQuery(
                     "SELECT COLUMN_FAMILY,SUM(GUIDE_POSTS_ROW_COUNT),SUM(GUIDE_POSTS_WIDTH) from SYSTEM.STATS where PHYSICAL_NAME = '"


[21/52] [abbrv] phoenix git commit: PHOENIX-1311 HBase namespaces surfaced in phoenix

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PSchemaProtos.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PSchemaProtos.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PSchemaProtos.java
new file mode 100644
index 0000000..d7dc720
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PSchemaProtos.java
@@ -0,0 +1,666 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: PSchema.proto
+
+package org.apache.phoenix.coprocessor.generated;
+
+public final class PSchemaProtos {
+  private PSchemaProtos() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface PSchemaOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string schemaName = 1;
+    /**
+     * <code>required string schemaName = 1;</code>
+     */
+    boolean hasSchemaName();
+    /**
+     * <code>required string schemaName = 1;</code>
+     */
+    java.lang.String getSchemaName();
+    /**
+     * <code>required string schemaName = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getSchemaNameBytes();
+
+    // required int64 timeStamp = 2;
+    /**
+     * <code>required int64 timeStamp = 2;</code>
+     */
+    boolean hasTimeStamp();
+    /**
+     * <code>required int64 timeStamp = 2;</code>
+     */
+    long getTimeStamp();
+  }
+  /**
+   * Protobuf type {@code PSchema}
+   */
+  public static final class PSchema extends
+      com.google.protobuf.GeneratedMessage
+      implements PSchemaOrBuilder {
+    // Use PSchema.newBuilder() to construct.
+    private PSchema(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private PSchema(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final PSchema defaultInstance;
+    public static PSchema getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public PSchema getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PSchema(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              schemaName_ = input.readBytes();
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000002;
+              timeStamp_ = input.readInt64();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.phoenix.coprocessor.generated.PSchemaProtos.internal_static_PSchema_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.phoenix.coprocessor.generated.PSchemaProtos.internal_static_PSchema_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.class, org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<PSchema> PARSER =
+        new com.google.protobuf.AbstractParser<PSchema>() {
+      public PSchema parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PSchema(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PSchema> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string schemaName = 1;
+    public static final int SCHEMANAME_FIELD_NUMBER = 1;
+    private java.lang.Object schemaName_;
+    /**
+     * <code>required string schemaName = 1;</code>
+     */
+    public boolean hasSchemaName() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string schemaName = 1;</code>
+     */
+    public java.lang.String getSchemaName() {
+      java.lang.Object ref = schemaName_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          schemaName_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string schemaName = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getSchemaNameBytes() {
+      java.lang.Object ref = schemaName_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        schemaName_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required int64 timeStamp = 2;
+    public static final int TIMESTAMP_FIELD_NUMBER = 2;
+    private long timeStamp_;
+    /**
+     * <code>required int64 timeStamp = 2;</code>
+     */
+    public boolean hasTimeStamp() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required int64 timeStamp = 2;</code>
+     */
+    public long getTimeStamp() {
+      return timeStamp_;
+    }
+
+    private void initFields() {
+      schemaName_ = "";
+      timeStamp_ = 0L;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasSchemaName()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasTimeStamp()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getSchemaNameBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeInt64(2, timeStamp_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getSchemaNameBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(2, timeStamp_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema)) {
+        return super.equals(obj);
+      }
+      org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema other = (org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema) obj;
+
+      boolean result = true;
+      result = result && (hasSchemaName() == other.hasSchemaName());
+      if (hasSchemaName()) {
+        result = result && getSchemaName()
+            .equals(other.getSchemaName());
+      }
+      result = result && (hasTimeStamp() == other.hasTimeStamp());
+      if (hasTimeStamp()) {
+        result = result && (getTimeStamp()
+            == other.getTimeStamp());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasSchemaName()) {
+        hash = (37 * hash) + SCHEMANAME_FIELD_NUMBER;
+        hash = (53 * hash) + getSchemaName().hashCode();
+      }
+      if (hasTimeStamp()) {
+        hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + hashLong(getTimeStamp());
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code PSchema}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchemaOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.phoenix.coprocessor.generated.PSchemaProtos.internal_static_PSchema_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.phoenix.coprocessor.generated.PSchemaProtos.internal_static_PSchema_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.class, org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.Builder.class);
+      }
+
+      // Construct using org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        schemaName_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        timeStamp_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.phoenix.coprocessor.generated.PSchemaProtos.internal_static_PSchema_descriptor;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema getDefaultInstanceForType() {
+        return org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.getDefaultInstance();
+      }
+
+      public org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema build() {
+        org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema buildPartial() {
+        org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema result = new org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.schemaName_ = schemaName_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.timeStamp_ = timeStamp_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema) {
+          return mergeFrom((org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema other) {
+        if (other == org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.getDefaultInstance()) return this;
+        if (other.hasSchemaName()) {
+          bitField0_ |= 0x00000001;
+          schemaName_ = other.schemaName_;
+          onChanged();
+        }
+        if (other.hasTimeStamp()) {
+          setTimeStamp(other.getTimeStamp());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasSchemaName()) {
+          
+          return false;
+        }
+        if (!hasTimeStamp()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string schemaName = 1;
+      private java.lang.Object schemaName_ = "";
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public boolean hasSchemaName() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public java.lang.String getSchemaName() {
+        java.lang.Object ref = schemaName_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          schemaName_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getSchemaNameBytes() {
+        java.lang.Object ref = schemaName_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          schemaName_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public Builder setSchemaName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        schemaName_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public Builder clearSchemaName() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        schemaName_ = getDefaultInstance().getSchemaName();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public Builder setSchemaNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        schemaName_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required int64 timeStamp = 2;
+      private long timeStamp_ ;
+      /**
+       * <code>required int64 timeStamp = 2;</code>
+       */
+      public boolean hasTimeStamp() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required int64 timeStamp = 2;</code>
+       */
+      public long getTimeStamp() {
+        return timeStamp_;
+      }
+      /**
+       * <code>required int64 timeStamp = 2;</code>
+       */
+      public Builder setTimeStamp(long value) {
+        bitField0_ |= 0x00000002;
+        timeStamp_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int64 timeStamp = 2;</code>
+       */
+      public Builder clearTimeStamp() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        timeStamp_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:PSchema)
+    }
+
+    static {
+      defaultInstance = new PSchema(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:PSchema)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_PSchema_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_PSchema_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\rPSchema.proto\"0\n\007PSchema\022\022\n\nschemaName" +
+      "\030\001 \002(\t\022\021\n\ttimeStamp\030\002 \002(\003BA\n(org.apache." +
+      "phoenix.coprocessor.generatedB\rPSchemaPr" +
+      "otosH\001\210\001\001\240\001\001"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_PSchema_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_PSchema_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_PSchema_descriptor,
+              new java.lang.String[] { "SchemaName", "TimeStamp", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
index 9fdfe51..126c0dd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
@@ -3338,6 +3338,16 @@ public final class PTableProtos {
      * <code>optional int64 indexDisableTimestamp = 29;</code>
      */
     long getIndexDisableTimestamp();
+
+    // optional bool isNamespaceMapped = 30;
+    /**
+     * <code>optional bool isNamespaceMapped = 30;</code>
+     */
+    boolean hasIsNamespaceMapped();
+    /**
+     * <code>optional bool isNamespaceMapped = 30;</code>
+     */
+    boolean getIsNamespaceMapped();
   }
   /**
    * Protobuf type {@code PTable}
@@ -3553,6 +3563,11 @@ public final class PTableProtos {
               indexDisableTimestamp_ = input.readInt64();
               break;
             }
+            case 240: {
+              bitField0_ |= 0x02000000;
+              isNamespaceMapped_ = input.readBool();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -4163,6 +4178,22 @@ public final class PTableProtos {
       return indexDisableTimestamp_;
     }
 
+    // optional bool isNamespaceMapped = 30;
+    public static final int ISNAMESPACEMAPPED_FIELD_NUMBER = 30;
+    private boolean isNamespaceMapped_;
+    /**
+     * <code>optional bool isNamespaceMapped = 30;</code>
+     */
+    public boolean hasIsNamespaceMapped() {
+      return ((bitField0_ & 0x02000000) == 0x02000000);
+    }
+    /**
+     * <code>optional bool isNamespaceMapped = 30;</code>
+     */
+    public boolean getIsNamespaceMapped() {
+      return isNamespaceMapped_;
+    }
+
     private void initFields() {
       schemaNameBytes_ = com.google.protobuf.ByteString.EMPTY;
       tableNameBytes_ = com.google.protobuf.ByteString.EMPTY;
@@ -4193,6 +4224,7 @@ public final class PTableProtos {
       transactional_ = false;
       updateCacheFrequency_ = 0L;
       indexDisableTimestamp_ = 0L;
+      isNamespaceMapped_ = false;
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -4347,6 +4379,9 @@ public final class PTableProtos {
       if (((bitField0_ & 0x01000000) == 0x01000000)) {
         output.writeInt64(29, indexDisableTimestamp_);
       }
+      if (((bitField0_ & 0x02000000) == 0x02000000)) {
+        output.writeBool(30, isNamespaceMapped_);
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -4477,6 +4512,10 @@ public final class PTableProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeInt64Size(29, indexDisableTimestamp_);
       }
+      if (((bitField0_ & 0x02000000) == 0x02000000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(30, isNamespaceMapped_);
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -4633,6 +4672,11 @@ public final class PTableProtos {
         result = result && (getIndexDisableTimestamp()
             == other.getIndexDisableTimestamp());
       }
+      result = result && (hasIsNamespaceMapped() == other.hasIsNamespaceMapped());
+      if (hasIsNamespaceMapped()) {
+        result = result && (getIsNamespaceMapped()
+            == other.getIsNamespaceMapped());
+      }
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -4762,6 +4806,10 @@ public final class PTableProtos {
         hash = (37 * hash) + INDEXDISABLETIMESTAMP_FIELD_NUMBER;
         hash = (53 * hash) + hashLong(getIndexDisableTimestamp());
       }
+      if (hasIsNamespaceMapped()) {
+        hash = (37 * hash) + ISNAMESPACEMAPPED_FIELD_NUMBER;
+        hash = (53 * hash) + hashBoolean(getIsNamespaceMapped());
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -4944,6 +4992,8 @@ public final class PTableProtos {
         bitField0_ = (bitField0_ & ~0x08000000);
         indexDisableTimestamp_ = 0L;
         bitField0_ = (bitField0_ & ~0x10000000);
+        isNamespaceMapped_ = false;
+        bitField0_ = (bitField0_ & ~0x20000000);
         return this;
       }
 
@@ -5104,6 +5154,10 @@ public final class PTableProtos {
           to_bitField0_ |= 0x01000000;
         }
         result.indexDisableTimestamp_ = indexDisableTimestamp_;
+        if (((from_bitField0_ & 0x20000000) == 0x20000000)) {
+          to_bitField0_ |= 0x02000000;
+        }
+        result.isNamespaceMapped_ = isNamespaceMapped_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -5285,6 +5339,9 @@ public final class PTableProtos {
         if (other.hasIndexDisableTimestamp()) {
           setIndexDisableTimestamp(other.getIndexDisableTimestamp());
         }
+        if (other.hasIsNamespaceMapped()) {
+          setIsNamespaceMapped(other.getIsNamespaceMapped());
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -7054,6 +7111,39 @@ public final class PTableProtos {
         return this;
       }
 
+      // optional bool isNamespaceMapped = 30;
+      private boolean isNamespaceMapped_ ;
+      /**
+       * <code>optional bool isNamespaceMapped = 30;</code>
+       */
+      public boolean hasIsNamespaceMapped() {
+        return ((bitField0_ & 0x20000000) == 0x20000000);
+      }
+      /**
+       * <code>optional bool isNamespaceMapped = 30;</code>
+       */
+      public boolean getIsNamespaceMapped() {
+        return isNamespaceMapped_;
+      }
+      /**
+       * <code>optional bool isNamespaceMapped = 30;</code>
+       */
+      public Builder setIsNamespaceMapped(boolean value) {
+        bitField0_ |= 0x20000000;
+        isNamespaceMapped_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool isNamespaceMapped = 30;</code>
+       */
+      public Builder clearIsNamespaceMapped() {
+        bitField0_ = (bitField0_ & ~0x20000000);
+        isNamespaceMapped_ = false;
+        onChanged();
+        return this;
+      }
+
       // @@protoc_insertion_point(builder_scope:PTable)
     }
 
@@ -7101,7 +7191,7 @@ public final class PTableProtos {
       "\016\n\006values\030\002 \003(\014\022\033\n\023guidePostsByteCount\030\003",
       " \001(\003\022\025\n\rkeyBytesCount\030\004 \001(\003\022\027\n\017guidePost" +
       "sCount\030\005 \001(\005\022!\n\013pGuidePosts\030\006 \001(\0132\014.PGui" +
-      "dePosts\"\303\005\n\006PTable\022\027\n\017schemaNameBytes\030\001 " +
+      "dePosts\"\336\005\n\006PTable\022\027\n\017schemaNameBytes\030\001 " +
       "\002(\014\022\026\n\016tableNameBytes\030\002 \002(\014\022\036\n\ttableType" +
       "\030\003 \002(\0162\013.PTableType\022\022\n\nindexState\030\004 \001(\t\022" +
       "\026\n\016sequenceNumber\030\005 \002(\003\022\021\n\ttimeStamp\030\006 \002" +
@@ -7118,11 +7208,11 @@ public final class PTableProtos {
       "storeNulls\030\030 \001(\010\022\027\n\017baseColumnCount\030\031 \001(" +
       "\005\022\036\n\026rowKeyOrderOptimizable\030\032 \001(\010\022\025\n\rtra" +
       "nsactional\030\033 \001(\010\022\034\n\024updateCacheFrequency" +
-      "\030\034 \001(\003\022\035\n\025indexDisableTimestamp\030\035 \001(\003*A\n",
-      "\nPTableType\022\n\n\006SYSTEM\020\000\022\010\n\004USER\020\001\022\010\n\004VIE" +
-      "W\020\002\022\t\n\005INDEX\020\003\022\010\n\004JOIN\020\004B@\n(org.apache.p" +
-      "hoenix.coprocessor.generatedB\014PTableProt" +
-      "osH\001\210\001\001\240\001\001"
+      "\030\034 \001(\003\022\035\n\025indexDisableTimestamp\030\035 \001(\003\022\031\n",
+      "\021isNamespaceMapped\030\036 \001(\010*A\n\nPTableType\022\n" +
+      "\n\006SYSTEM\020\000\022\010\n\004USER\020\001\022\010\n\004VIEW\020\002\022\t\n\005INDEX\020" +
+      "\003\022\010\n\004JOIN\020\004B@\n(org.apache.phoenix.coproc" +
+      "essor.generatedB\014PTableProtosH\001\210\001\001\240\001\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -7146,7 +7236,7 @@ public final class PTableProtos {
           internal_static_PTable_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_PTable_descriptor,
-              new java.lang.String[] { "SchemaNameBytes", "TableNameBytes", "TableType", "IndexState", "SequenceNumber", "TimeStamp", "PkNameBytes", "BucketNum", "Columns", "Indexes", "IsImmutableRows", "GuidePosts", "DataTableNameBytes", "DefaultFamilyName", "DisableWAL", "MultiTenant", "ViewType", "ViewStatement", "PhysicalNames", "TenantId", "ViewIndexId", "IndexType", "StatsTimeStamp", "StoreNulls", "BaseColumnCount", "RowKeyOrderOptimizable", "Transactional", "UpdateCacheFrequency", "IndexDisableTimestamp", });
+              new java.lang.String[] { "SchemaNameBytes", "TableNameBytes", "TableType", "IndexState", "SequenceNumber", "TimeStamp", "PkNameBytes", "BucketNum", "Columns", "Indexes", "IsImmutableRows", "GuidePosts", "DataTableNameBytes", "DefaultFamilyName", "DisableWAL", "MultiTenant", "ViewType", "ViewStatement", "PhysicalNames", "TenantId", "ViewIndexId", "IndexType", "StatsTimeStamp", "StoreNulls", "BaseColumnCount", "RowKeyOrderOptimizable", "Transactional", "UpdateCacheFrequency", "IndexDisableTimestamp", "IsNamespaceMapped", });
           return null;
         }
       };

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
index 65cb6db..9ac05a4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
@@ -33,6 +33,8 @@ import org.apache.phoenix.schema.ConcurrentTableMutationException;
 import org.apache.phoenix.schema.FunctionAlreadyExistsException;
 import org.apache.phoenix.schema.FunctionNotFoundException;
 import org.apache.phoenix.schema.ReadOnlyTableException;
+import org.apache.phoenix.schema.SchemaAlreadyExistsException;
+import org.apache.phoenix.schema.SchemaNotFoundException;
 import org.apache.phoenix.schema.SequenceAlreadyExistsException;
 import org.apache.phoenix.schema.SequenceNotFoundException;
 import org.apache.phoenix.schema.StaleRegionBoundaryCacheException;
@@ -374,8 +376,23 @@ public enum SQLExceptionCode {
     }),
     UNALLOWED_USER_DEFINED_FUNCTIONS(6003, "42F03",
             "User defined functions are configured to not be allowed. To allow configure "
-                    + QueryServices.ALLOW_USER_DEFINED_FUNCTIONS_ATTRIB + " to true."),
-    ;
+                    + QueryServices.ALLOW_USER_DEFINED_FUNCTIONS_ATTRIB + " to true."), 
+
+    SCHEMA_ALREADY_EXISTS(721, "42M04", "Schema with given name already exists", new Factory() {
+        @Override
+        public SQLException newException(SQLExceptionInfo info) {
+            return new SchemaAlreadyExistsException(info.getSchemaName());
+        }
+    }), SCHEMA_NOT_FOUND(722, "43M05", "Schema does not exists", new Factory() {
+        @Override
+        public SQLException newException(SQLExceptionInfo info) {
+            return new SchemaNotFoundException(info.getSchemaName());
+        }
+    }), CANNOT_MUTATE_SCHEMA(723, "43M06", "Cannot mutate schema as schema has existing tables"), SCHEMA_NOT_ALLOWED(
+            724, "43M07",
+            "Schema name not allowed!!"), CREATE_SCHEMA_NOT_ALLOWED(725, "43M08", "Cannot create schema because config "
+                    + QueryServices.IS_NAMESPACE_MAPPING_ENABLED + " for enabling name space mapping isn't enabled.");
+
 
     private final int errorCode;
     private final String sqlState;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/master/IndexMasterObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/master/IndexMasterObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/master/IndexMasterObserver.java
index 1da5aff..a014da2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/master/IndexMasterObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/master/IndexMasterObserver.java
@@ -87,11 +87,9 @@ public class IndexMasterObserver extends BaseMasterObserver {
             AssignmentManager am = ctx.getEnvironment().getMasterServices().getAssignmentManager();
             RegionStates regionStates = am.getRegionStates();
             String tableName = region.getTable().getNameAsString();
-            String correspondingTable =
-                    region.getTable().getNameAsString()
-                            .startsWith(MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX) ? MetaDataUtil
-                            .getUserTableName(tableName) : MetaDataUtil
-                            .getLocalIndexTableName(tableName);
+            String correspondingTable = MetaDataUtil.isLocalIndex(region.getTable().getNameAsString())
+                    ? MetaDataUtil.getUserTableName(tableName)
+                    : Bytes.toString(MetaDataUtil.getLocalIndexPhysicalName(tableName.getBytes()));
             List<HRegionInfo> regions =
                     regionStates.getRegionsOfTable(TableName.valueOf(correspondingTable));
             for (HRegionInfo hri : regions) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/ParallelWriterIndexCommitter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/ParallelWriterIndexCommitter.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/ParallelWriterIndexCommitter.java
index f72dec0..e52c216 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/ParallelWriterIndexCommitter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/ParallelWriterIndexCommitter.java
@@ -149,7 +149,7 @@ public class ParallelWriterIndexCommitter implements IndexCommitter {
                         // index is pretty hacky. If we're going to keep this, we should revisit that
                         // as well.
                         try {
-                            if (tableReference.getTableName().startsWith(MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX)) {
+                            if (MetaDataUtil.isLocalIndex(tableReference.getTableName())) {
                                 HRegion indexRegion = IndexUtil.getIndexRegion(env);
                                 if (indexRegion != null) {
                                     throwFailureIfDone();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/recovery/TrackingParallelWriterIndexCommitter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/recovery/TrackingParallelWriterIndexCommitter.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/recovery/TrackingParallelWriterIndexCommitter.java
index 9171b53..131b930 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/recovery/TrackingParallelWriterIndexCommitter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/recovery/TrackingParallelWriterIndexCommitter.java
@@ -153,7 +153,7 @@ public class TrackingParallelWriterIndexCommitter implements IndexCommitter {
                             // Also, checking the prefix of the table name to determine if this is a local
                             // index is pretty hacky. If we're going to keep this, we should revisit that
                             // as well.
-                            if (tableReference.getTableName().startsWith(MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX)) {
+                            if (MetaDataUtil.isLocalIndex(tableReference.getTableName())) {
                                 HRegion indexRegion = IndexUtil.getIndexRegion(env);
                                 if (indexRegion != null) {
                                     throwFailureIfDone();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java
index c7ed49b..ea245cc 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java
@@ -33,7 +33,6 @@ import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.Stoppable;
-import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Mutation;
 import org.apache.hadoop.hbase.client.Put;
@@ -139,7 +138,7 @@ public class PhoenixIndexFailurePolicy extends DelegateIndexFailurePolicy {
             }
 
             // its a local index table, so we need to convert it to the index table names we should disable
-            if (ref.getTableName().startsWith(MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX)) {
+            if (MetaDataUtil.isLocalIndex(ref.getTableName())) {
                 for (String tableName : getLocalIndexNames(ref, mutations)) {
                     indexTableNames.put(tableName, minTimeStamp);
                 }
@@ -154,9 +153,8 @@ public class PhoenixIndexFailurePolicy extends DelegateIndexFailurePolicy {
             long minTimeStamp = tableTimeElement.getValue();
             // Disable the index by using the updateIndexState method of MetaDataProtocol end point coprocessor.
             byte[] indexTableKey = SchemaUtil.getTableKeyFromFullName(indexTableName);
-            HTableInterface
-                    systemTable =
-                    env.getTable(TableName.valueOf(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES));
+            HTableInterface systemTable = env.getTable(SchemaUtil
+                    .getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES, env.getConfiguration()));
             // Mimic the Put that gets generated by the client on an update of the index state
             Put put = new Put(indexTableKey);
             if (blockWriteRebuildIndex) 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java
index a17258a..a78565d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java
@@ -74,7 +74,7 @@ public class ChunkedResultIterator implements PeekingResultIterator {
 
         @Override
         public PeekingResultIterator newIterator(StatementContext context, ResultIterator scanner, Scan scan, String tableName) throws SQLException {
-            if (logger.isDebugEnabled()) logger.debug(LogUtil.addCustomAnnotations("ChunkedResultIteratorFactory.newIterator over " + tableRef.getTable().getName().getString() + " with " + scan, ScanUtil.getCustomAnnotations(scan)));
+            if (logger.isDebugEnabled()) logger.debug(LogUtil.addCustomAnnotations("ChunkedResultIteratorFactory.newIterator over " + tableRef.getTable().getPhysicalName().getString() + " with " + scan, ScanUtil.getCustomAnnotations(scan)));
             return new ChunkedResultIterator(delegateFactory, mutationState, context, tableRef, scan, 
                     mutationState.getConnection().getQueryServices().getProps().getLong(
                                 QueryServices.SCAN_RESULT_CHUNK_SIZE,
@@ -93,7 +93,7 @@ public class ChunkedResultIterator implements PeekingResultIterator {
         // Instantiate single chunk iterator and the delegate iterator in constructor
         // to get parallel scans kicked off in separate threads. If we delay this,
         // we'll get serialized behavior (see PHOENIX-
-        if (logger.isDebugEnabled()) logger.debug(LogUtil.addCustomAnnotations("Get first chunked result iterator over " + tableRef.getTable().getName().getString() + " with " + scan, ScanUtil.getCustomAnnotations(scan)));
+        if (logger.isDebugEnabled()) logger.debug(LogUtil.addCustomAnnotations("Get first chunked result iterator over " + tableRef.getTable().getPhysicalName().getString() + " with " + scan, ScanUtil.getCustomAnnotations(scan)));
         ResultIterator singleChunkResultIterator = new SingleChunkResultIterator(scanner, chunkSize);
         String tableName = tableRef.getTable().getPhysicalName().getString();
         resultIterator = delegateIteratorFactory.newIterator(context, singleChunkResultIterator, scan, tableName);
@@ -124,7 +124,7 @@ public class ChunkedResultIterator implements PeekingResultIterator {
             resultIterator.close();
             scan = ScanUtil.newScan(scan);
             scan.setStartRow(ByteUtil.copyKeyBytesIfNecessary(lastKey));
-            if (logger.isDebugEnabled()) logger.debug(LogUtil.addCustomAnnotations("Get next chunked result iterator over " + tableRef.getTable().getName().getString() + " with " + scan, ScanUtil.getCustomAnnotations(scan)));
+            if (logger.isDebugEnabled()) logger.debug(LogUtil.addCustomAnnotations("Get next chunked result iterator over " + tableRef.getTable().getPhysicalName().getString() + " with " + scan, ScanUtil.getCustomAnnotations(scan)));
             String tableName = tableRef.getTable().getPhysicalName().getString();
             long renewLeaseThreshold = context.getConnection().getQueryServices().getRenewLeaseThresholdMilliSeconds();
             ResultIterator singleChunkResultIterator = new SingleChunkResultIterator(

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
index 1351735..ca0eba0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
@@ -130,7 +130,7 @@ public class ParallelIterators extends BaseResultIterators {
                 public TaskExecutionMetricsHolder getTaskExecutionMetric() {
                     return taskMetrics;
                 }
-            }, "Parallel scanner for table: " + tableRef.getTable().getName().getString()));
+            }, "Parallel scanner for table: " + tableRef.getTable().getPhysicalName().getString()));
             // Add our future in the right place so that we can concatenate the
             // results of the inner futures versus merge sorting across all of them.
             nestedFutures.get(scanLocation.getOuterListIndex()).set(scanLocation.getInnerListIndex(), new Pair<Scan,Future<PeekingResultIterator>>(scan,future));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
index f3b9e7d..17c2279 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
@@ -115,7 +115,7 @@ public class SerialIterators extends BaseResultIterators {
                 public TaskExecutionMetricsHolder getTaskExecutionMetric() {
                     return taskMetrics;
                 }
-            }, "Serial scanner for table: " + tableRef.getTable().getName().getString()));
+            }, "Serial scanner for table: " + tableRef.getTable().getPhysicalName().getString()));
             // Add our singleton Future which will execute serially
             nestedFutures.add(Collections.singletonList(new Pair<Scan,Future<PeekingResultIterator>>(overallScan,future)));
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index 457a5df..5c8786d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -72,6 +72,7 @@ import org.apache.phoenix.iterate.TableResultIterator;
 import org.apache.phoenix.iterate.TableResultIteratorFactory;
 import org.apache.phoenix.jdbc.PhoenixStatement.PhoenixStatementParser;
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.query.ConnectionQueryServices;
 import org.apache.phoenix.query.ConnectionQueryServices.Feature;
 import org.apache.phoenix.query.DelegateConnectionQueryServices;
@@ -87,6 +88,7 @@ import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableRef;
 import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.SchemaNotFoundException;
 import org.apache.phoenix.schema.TableNotFoundException;
 import org.apache.phoenix.schema.types.PArrayDataType;
 import org.apache.phoenix.schema.types.PDataType;
@@ -109,8 +111,6 @@ import org.apache.phoenix.util.SQLCloseables;
 import org.cloudera.htrace.Sampler;
 import org.cloudera.htrace.TraceScope;
 
-import co.cask.tephra.TransactionContext;
-
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Objects;
 import com.google.common.base.Strings;
@@ -118,6 +118,8 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.collect.Lists;
 
+import co.cask.tephra.TransactionContext;
+
 
 /**
  * 
@@ -134,6 +136,7 @@ import com.google.common.collect.Lists;
  */
 public class PhoenixConnection implements Connection, MetaDataMutated, SQLCloseable {
     private final String url;
+    private String schema;
     private final ConnectionQueryServices services;
     private final Properties info;
     private final Map<PDataType<?>, Format> formatters = new HashMap<>();
@@ -240,6 +243,10 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
                 this.services.getProps().getBoolean(
                         QueryServices.AUTO_COMMIT_ATTRIB,
                         QueryServicesOptions.DEFAULT_AUTO_COMMIT));
+        // currently we are not resolving schema set through property, so if schema doesn't exists ,connection will not fail
+        // but queries may fail
+        this.schema = JDBCUtil.getSchema(url, this.info,
+                this.services.getProps().get(QueryServices.SCHEMA_ATTRIB, QueryServicesOptions.DEFAULT_SCHEMA));
         this.tenantId = tenantId;
         this.mutateBatchSize = JDBCUtil.getMutateBatchSize(url, this.info, this.services.getProps());
         datePattern = this.services.getProps().get(QueryServices.DATE_FORMAT_ATTRIB, DateUtil.DEFAULT_DATE_FORMAT);
@@ -843,14 +850,17 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
 
     @Override
     public void setSchema(String schema) throws SQLException {
-        // TODO Auto-generated method stub
-        
+        this.schema = schema;
+
     }
 
     @Override
     public String getSchema() throws SQLException {
-        // TODO Auto-generated method stub
-        return null;
+        return this.schema;
+    }
+
+    public PSchema getSchema(PTableKey key) throws SchemaNotFoundException {
+        return metaData.getSchema(key);
     }
 
     @Override
@@ -900,11 +910,25 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
     }
 
     @Override
-    public PMetaData addColumn(PName tenantId, String tableName, List<PColumn> columns, long tableTimeStamp, long tableSeqNum, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls, boolean isTransactional, long updateCacheFrequency, long resolvedTime)
-            throws SQLException {
-        metaData = metaData.addColumn(tenantId, tableName, columns, tableTimeStamp, tableSeqNum, isImmutableRows, isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency, resolvedTime);
-        //Cascade through to connectionQueryServices too
-        getQueryServices().addColumn(tenantId, tableName, columns, tableTimeStamp, tableSeqNum, isImmutableRows, isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency, resolvedTime);
+    public PMetaData addSchema(PSchema schema) throws SQLException {
+        metaData = metaData.addSchema(schema);
+        // Cascade through to connectionQueryServices too
+        getQueryServices().addSchema(schema);
+        return metaData;
+    }
+
+    @Override
+    public PMetaData addColumn(PName tenantId, String tableName, List<PColumn> columns, long tableTimeStamp,
+            long tableSeqNum, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls,
+            boolean isTransactional, long updateCacheFrequency, boolean isNamespaceMapped, long resolvedTime)
+                    throws SQLException {
+        metaData = metaData.addColumn(tenantId, tableName, columns, tableTimeStamp, tableSeqNum, isImmutableRows,
+                isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency, isNamespaceMapped,
+                resolvedTime);
+        // Cascade through to connectionQueryServices too
+        getQueryServices().addColumn(tenantId, tableName, columns, tableTimeStamp, tableSeqNum, isImmutableRows,
+                isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency, isNamespaceMapped,
+                resolvedTime);
         return metaData;
     }
 
@@ -1028,4 +1052,13 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
         checkNotNull(factory);
         this.tableResultIteratorFactory = factory;
     }
+
+    @Override
+    public PMetaData removeSchema(PSchema schema, long schemaTimeStamp) {
+        metaData = metaData.removeSchema(schema, schemaTimeStamp);
+        // Cascade through to connectionQueryServices too
+        getQueryServices().removeSchema(schema, schemaTimeStamp);
+        return metaData;
+
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index f875a77..d98ebe3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -52,6 +52,7 @@ import org.apache.phoenix.iterate.DelegateResultIterator;
 import org.apache.phoenix.iterate.MaterializedResultIterator;
 import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.MetaDataClient;
 import org.apache.phoenix.schema.PDatum;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PTable.LinkType;
@@ -100,6 +101,8 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
     public static final byte[] SYSTEM_CATALOG_NAME_BYTES = Bytes.toBytes(SYSTEM_CATALOG_NAME);
     public static final String SYSTEM_STATS_TABLE = "STATS";
     public static final String SYSTEM_STATS_NAME = SchemaUtil.getTableName(SYSTEM_CATALOG_SCHEMA, SYSTEM_STATS_TABLE);
+    public static final String IS_NAMESPACE_MAPPED = "IS_NAMESPACE_MAPPED";
+    public static final byte[] IS_NAMESPACE_MAPPED_BYTES = Bytes.toBytes(IS_NAMESPACE_MAPPED);
     public static final byte[] SYSTEM_STATS_NAME_BYTES = Bytes.toBytes(SYSTEM_STATS_NAME);
     public static final byte[] SYSTEM_STATS_TABLE_BYTES = Bytes.toBytes(SYSTEM_STATS_TABLE);
     public static final String SYSTEM_CATALOG_ALIAS = "\"SYSTEM.TABLE\"";
@@ -915,10 +918,10 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
                 TENANT_ID + " " + TABLE_CATALOG +
                 " from " + SYSTEM_CATALOG + " " + SYSTEM_CATALOG_ALIAS +
                 " where " + COLUMN_NAME + " is null");
-        this.addTenantIdFilter(buf, catalog);
         if (schemaPattern != null) {
             buf.append(" and " + TABLE_SCHEM + " like '" + StringUtil.escapeStringConstant(schemaPattern) + "'");
         }
+        buf.append(" and " + TABLE_NAME + " = '" + MetaDataClient.EMPTY_TABLE + "'");
         Statement stmt = connection.createStatement();
         return stmt.executeQuery(buf.toString());
     }
@@ -1040,7 +1043,8 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
                 SQLIndexTypeFunction.NAME + "(" + INDEX_TYPE + ") AS " + INDEX_TYPE +
                 " from " + SYSTEM_CATALOG + " " + SYSTEM_CATALOG_ALIAS +
                 " where " + COLUMN_NAME + " is null" +
-                " and " + COLUMN_FAMILY + " is null");
+                " and " + COLUMN_FAMILY + " is null" +
+                " and " + TABLE_NAME + " != '" + MetaDataClient.EMPTY_TABLE + "'");
         addTenantIdFilter(buf, catalog);
         if (schemaPattern != null) {
             buf.append(" and " + TABLE_SCHEM + (schemaPattern.length() == 0 ? " is null" : " like '" + StringUtil.escapeStringConstant(schemaPattern) + "'" ));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
index c365d19..74f3e32 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
@@ -50,6 +50,7 @@ import org.apache.phoenix.compile.ColumnProjector;
 import org.apache.phoenix.compile.ColumnResolver;
 import org.apache.phoenix.compile.CreateFunctionCompiler;
 import org.apache.phoenix.compile.CreateIndexCompiler;
+import org.apache.phoenix.compile.CreateSchemaCompiler;
 import org.apache.phoenix.compile.CreateSequenceCompiler;
 import org.apache.phoenix.compile.CreateTableCompiler;
 import org.apache.phoenix.compile.DeleteCompiler;
@@ -90,6 +91,7 @@ import org.apache.phoenix.parse.ColumnDef;
 import org.apache.phoenix.parse.ColumnName;
 import org.apache.phoenix.parse.CreateFunctionStatement;
 import org.apache.phoenix.parse.CreateIndexStatement;
+import org.apache.phoenix.parse.CreateSchemaStatement;
 import org.apache.phoenix.parse.CreateSequenceStatement;
 import org.apache.phoenix.parse.CreateTableStatement;
 import org.apache.phoenix.parse.DeleteJarStatement;
@@ -97,6 +99,7 @@ import org.apache.phoenix.parse.DeleteStatement;
 import org.apache.phoenix.parse.DropColumnStatement;
 import org.apache.phoenix.parse.DropFunctionStatement;
 import org.apache.phoenix.parse.DropIndexStatement;
+import org.apache.phoenix.parse.DropSchemaStatement;
 import org.apache.phoenix.parse.DropSequenceStatement;
 import org.apache.phoenix.parse.DropTableStatement;
 import org.apache.phoenix.parse.ExplainStatement;
@@ -122,6 +125,7 @@ import org.apache.phoenix.parse.TraceStatement;
 import org.apache.phoenix.parse.UDFParseNode;
 import org.apache.phoenix.parse.UpdateStatisticsStatement;
 import org.apache.phoenix.parse.UpsertStatement;
+import org.apache.phoenix.parse.UseSchemaStatement;
 import org.apache.phoenix.query.HBaseFactoryProvider;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryConstants;
@@ -617,6 +621,19 @@ public class PhoenixStatement implements Statement, SQLCloseable {
         }
     }
 
+    private static class ExecutableCreateSchemaStatement extends CreateSchemaStatement implements CompilableStatement {
+        ExecutableCreateSchemaStatement(String schemaName, boolean ifNotExists) {
+            super(schemaName, ifNotExists);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+            CreateSchemaCompiler compiler = new CreateSchemaCompiler(stmt);
+            return compiler.compile(this);
+        }
+    }
+
     private static class ExecutableCreateFunctionStatement extends CreateFunctionStatement implements CompilableStatement {
 
         public ExecutableCreateFunctionStatement(PFunction functionInfo, boolean temporary, boolean isReplace) {
@@ -866,6 +883,58 @@ public class PhoenixStatement implements Statement, SQLCloseable {
         }
     }
 
+    private static class ExecutableDropSchemaStatement extends DropSchemaStatement implements CompilableStatement {
+
+        ExecutableDropSchemaStatement(String schemaName, boolean ifExists, boolean cascade) {
+            super(schemaName, ifExists, cascade);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+            final StatementContext context = new StatementContext(stmt);
+            return new BaseMutationPlan(context, this.getOperation()) {
+
+                @Override
+                public ExplainPlan getExplainPlan() throws SQLException {
+                    return new ExplainPlan(Collections.singletonList("DROP SCHEMA"));
+                }
+
+                @Override
+                public MutationState execute() throws SQLException {
+                    MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                    return client.dropSchema(ExecutableDropSchemaStatement.this);
+                }
+            };
+        }
+    }
+
+    private static class ExecutableUseSchemaStatement extends UseSchemaStatement implements CompilableStatement {
+
+        ExecutableUseSchemaStatement(String schemaName) {
+            super(schemaName);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+            final StatementContext context = new StatementContext(stmt);
+            return new BaseMutationPlan(context, this.getOperation()) {
+
+                @Override
+                public ExplainPlan getExplainPlan() throws SQLException {
+                    return new ExplainPlan(Collections.singletonList("USE SCHEMA"));
+                }
+
+                @Override
+                public MutationState execute() throws SQLException {
+                    MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                    return client.useSchema(ExecutableUseSchemaStatement.this);
+                }
+            };
+        }
+    }
+
     private static class ExecutableDropIndexStatement extends DropIndexStatement implements CompilableStatement {
 
         public ExecutableDropIndexStatement(NamedNode indexName, TableName tableName, boolean ifExists) {
@@ -877,7 +946,7 @@ public class PhoenixStatement implements Statement, SQLCloseable {
         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
             final StatementContext context = new StatementContext(stmt);
             return new BaseMutationPlan(context, this.getOperation()) {
-                
+
                 @Override
                 public ExplainPlan getExplainPlan() throws SQLException {
                     return new ExplainPlan(Collections.singletonList("DROP INDEX"));
@@ -1033,7 +1102,12 @@ public class PhoenixStatement implements Statement, SQLCloseable {
                 List<ParseNode> splits, PTableType tableType, boolean ifNotExists, TableName baseTableName, ParseNode tableTypeIdNode, int bindCount) {
             return new ExecutableCreateTableStatement(tableName, props, columns, pkConstraint, splits, tableType, ifNotExists, baseTableName, tableTypeIdNode, bindCount);
         }
-        
+
+        @Override
+        public CreateSchemaStatement createSchema(String schemaName, boolean ifNotExists) {
+            return new ExecutableCreateSchemaStatement(schemaName, ifNotExists);
+        }
+
         @Override
         public CreateSequenceStatement createSequence(TableName tableName, ParseNode startsWith,
                 ParseNode incrementBy, ParseNode cacheSize, ParseNode minValue, ParseNode maxValue,
@@ -1090,6 +1164,16 @@ public class PhoenixStatement implements Statement, SQLCloseable {
         }
 
         @Override
+        public DropSchemaStatement dropSchema(String schemaName, boolean ifExists, boolean cascade) {
+            return new ExecutableDropSchemaStatement(schemaName, ifExists, cascade);
+        }
+
+        @Override
+        public UseSchemaStatement useSchema(String schemaName) {
+            return new ExecutableUseSchemaStatement(schemaName);
+        }
+
+        @Override
         public DropFunctionStatement dropFunction(String functionName, boolean ifExists) {
             return new ExecutableDropFunctionStatement(functionName, ifExists);
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java
index ff73530..0525de9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java
@@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.client.HTable;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles;
+import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.mapreduce.Job;
 import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
 import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
@@ -231,7 +232,8 @@ public abstract class AbstractBulkLoadTool extends Configured implements Tool {
         }
 
         List<TargetTableRef> tablesToBeLoaded = new ArrayList<TargetTableRef>();
-        tablesToBeLoaded.add(new TargetTableRef(qualifiedTableName));
+        PTable table = PhoenixRuntime.getTable(conn, qualifiedTableName);
+        tablesToBeLoaded.add(new TargetTableRef(qualifiedTableName, table.getPhysicalName().getString()));
         // using conn after it's been closed... o.O
         tablesToBeLoaded.addAll(getIndexTables(conn, schemaName, qualifiedTableName));
 
@@ -310,7 +312,7 @@ public abstract class AbstractBulkLoadTool extends Configured implements Tool {
             tableNames.add(table.getPhysicalName());
             LoadIncrementalHFiles loader = new LoadIncrementalHFiles(conf);
             String tableName = table.getPhysicalName();
-            Path tableOutputPath = new Path(outputPath,tableName);
+            Path tableOutputPath = CsvBulkImportUtil.getOutputPath(outputPath, tableName);
             HTable htable = new HTable(conf,tableName);
             LOG.info("Loading HFiles for {} from {}", tableName , tableOutputPath);
             loader.doBulkLoad(tableOutputPath, htable);
@@ -394,12 +396,11 @@ public abstract class AbstractBulkLoadTool extends Configured implements Tool {
         List<TargetTableRef> indexTables = new ArrayList<TargetTableRef>();
         for(PTable indexTable : table.getIndexes()){
             if (indexTable.getIndexType() == PTable.IndexType.LOCAL) {
-                indexTables.add(new TargetTableRef(getQualifiedTableName(schemaName, indexTable
-                        .getTableName().getString()), MetaDataUtil
-                        .getLocalIndexTableName(qualifiedTableName)));
+                indexTables.add(new TargetTableRef(indexTable.getName().getString(),
+                        Bytes.toString(MetaDataUtil.getLocalIndexPhysicalName(table.getPhysicalName().getBytes()))));
             } else {
-                indexTables.add(new TargetTableRef(getQualifiedTableName(schemaName,
-                        indexTable.getTableName().getString())));
+                indexTables.add(
+                        new TargetTableRef(indexTable.getName().getString(), indexTable.getPhysicalName().getString()));
             }
         }
         return indexTables;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/CsvBulkImportUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/CsvBulkImportUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/CsvBulkImportUtil.java
index bdc67f9..9289dbf 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/CsvBulkImportUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/CsvBulkImportUtil.java
@@ -18,8 +18,10 @@
 package org.apache.phoenix.mapreduce;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.util.Base64;
 import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
+import org.apache.phoenix.query.QueryConstants;
 
 import com.google.common.annotations.VisibleForTesting;
 
@@ -72,4 +74,9 @@ public class CsvBulkImportUtil {
         }
         return new String(Base64.decode(strValue)).charAt(0);
     }
+
+    public static Path getOutputPath(Path outputdir, String tableName) {
+        return new Path(outputdir,
+                tableName.replace(QueryConstants.NAMESPACE_SEPARATOR, QueryConstants.NAME_SEPARATOR));
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/MultiHfileOutputFormat.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/MultiHfileOutputFormat.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/MultiHfileOutputFormat.java
index cd81192..f48a690 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/MultiHfileOutputFormat.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/MultiHfileOutputFormat.java
@@ -159,7 +159,7 @@ public class MultiHfileOutputFormat extends FileOutputFormat<TableRowkeyPair, Ce
                 // If this is a new column family, verify that the directory exists
                 if (wl == null) {
                     // phoenix-2216: start : create a directory for table and family within the output dir 
-                    Path tableOutputPath = new Path(outputdir, tableName);
+                    Path tableOutputPath = CsvBulkImportUtil.getOutputPath(outputdir, tableName);
                     fs.mkdirs(new Path(tableOutputPath, Bytes.toString(family)));
                     // phoenix-2216: end
                 }
@@ -215,7 +215,7 @@ public class MultiHfileOutputFormat extends FileOutputFormat<TableRowkeyPair, Ce
               throws IOException {
           
               WriterLength wl = new WriterLength();
-              Path tableOutputPath = new Path(outputdir, tableName);
+              Path tableOutputPath = CsvBulkImportUtil.getOutputPath(outputdir, tableName);
               Path familydir = new Path(tableOutputPath, Bytes.toString(family));
             
               // phoenix-2216: start : fetching the configuration properties that were set to the table.

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexTool.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexTool.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexTool.java
index f5117fc..34694c6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexTool.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexTool.java
@@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.mapreduce.HFileOutputFormat;
 import org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles;
 import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
 import org.apache.hadoop.hbase.mapreduce.TableOutputFormat;
+import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.IntWritable;
 import org.apache.hadoop.io.NullWritable;
 import org.apache.hadoop.mapreduce.Job;
@@ -51,6 +52,7 @@ import org.apache.hadoop.util.Tool;
 import org.apache.hadoop.util.ToolRunner;
 import org.apache.phoenix.compile.PostIndexDDLCompiler;
 import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.mapreduce.CsvBulkImportUtil;
 import org.apache.phoenix.mapreduce.util.ColumnInfoToStringEncoderDecoder;
 import org.apache.phoenix.mapreduce.util.ConnectionUtil;
 import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
@@ -202,9 +204,10 @@ public class IndexTool extends Configured implements Tool {
 
             // check if the index type is LOCAL, if so, derive and set the physicalIndexName that is
             // computed from the qDataTable name.
-            String physicalIndexTable = qIndexTable;
+            String physicalIndexTable = pindexTable.getPhysicalName().getString();
             if (IndexType.LOCAL.equals(pindexTable.getIndexType())) {
-                physicalIndexTable = MetaDataUtil.getLocalIndexTableName(qDataTable);
+                physicalIndexTable = Bytes
+                        .toString(MetaDataUtil.getLocalIndexPhysicalName(pdataTable.getPhysicalName().getBytes()));
             }
 
             final PhoenixConnection pConnection = connection.unwrap(PhoenixConnection.class);
@@ -226,8 +229,8 @@ public class IndexTool extends Configured implements Tool {
                     PhoenixRuntime.generateColumnInfo(connection, qIndexTable, indexColumns);
             ColumnInfoToStringEncoderDecoder.encode(configuration, columnMetadataList);
 
-            final Path outputPath =
-                    new Path(cmdLine.getOptionValue(OUTPUT_PATH_OPTION.getOpt()), physicalIndexTable);
+            final Path outputPath = CsvBulkImportUtil
+                    .getOutputPath(new Path(cmdLine.getOptionValue(OUTPUT_PATH_OPTION.getOpt())), physicalIndexTable);
             FileSystem.get(configuration).delete(outputPath, true);
             
             final String jobName = String.format(INDEX_JOB_NAME_TEMPLATE, dataTable, indexTable);
@@ -280,9 +283,9 @@ public class IndexTool extends Configured implements Tool {
         job.setMapOutputKeyClass(ImmutableBytesWritable.class);
         job.setMapOutputValueClass(KeyValue.class);
         final Configuration configuration = job.getConfiguration();
-        final String logicalIndexTable =
+        final String physicalIndexTable =
                 PhoenixConfigurationUtil.getPhysicalTableName(configuration);
-        final HTable htable = new HTable(configuration, logicalIndexTable);
+        final HTable htable = new HTable(configuration, physicalIndexTable);
         HFileOutputFormat.configureIncrementalLoad(job, htable);
         boolean status = job.waitForCompletion(true);
         if (!status) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSchemaStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSchemaStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSchemaStatement.java
new file mode 100644
index 0000000..c186137
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/CreateSchemaStatement.java
@@ -0,0 +1,25 @@
+package org.apache.phoenix.parse;
+
+public class CreateSchemaStatement extends MutableStatement {
+	private final String schemaName;
+	private final boolean ifNotExists;
+	
+	public CreateSchemaStatement(String schemaName,boolean ifNotExists) {
+		this.schemaName=schemaName;
+		this.ifNotExists = ifNotExists;
+	}
+	
+	@Override
+	public int getBindCount() {
+		return 0;
+	}
+
+	public String getSchemaName() {
+		return schemaName;
+	}
+
+	public boolean isIfNotExists() {
+		return ifNotExists;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSchemaStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSchemaStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSchemaStatement.java
new file mode 100644
index 0000000..8e4642d
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DropSchemaStatement.java
@@ -0,0 +1,38 @@
+package org.apache.phoenix.parse;
+
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
+
+public class DropSchemaStatement extends MutableStatement {
+    private final String schemaName;
+    private final boolean ifExists;
+    private final boolean cascade;
+
+    public DropSchemaStatement(String schemaName, boolean ifExists, boolean cascade) {
+        this.schemaName = schemaName;
+        this.ifExists = ifExists;
+        this.cascade = cascade;
+    }
+
+    @Override
+    public int getBindCount() {
+        return 0;
+    }
+
+    public String getSchemaName() {
+        return schemaName;
+    }
+
+    public boolean ifExists() {
+        return ifExists;
+    }
+
+    public boolean cascade() {
+        return cascade;
+    }
+
+    @Override
+    public Operation getOperation() {
+        return Operation.DELETE;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/parse/PSchema.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/PSchema.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/PSchema.java
new file mode 100644
index 0000000..7a0ddc8
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/PSchema.java
@@ -0,0 +1,86 @@
+/*
+ * 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.phoenix.parse;
+
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.phoenix.coprocessor.generated.PSchemaProtos;
+import org.apache.phoenix.schema.PMetaDataEntity;
+import org.apache.phoenix.schema.PName;
+import org.apache.phoenix.schema.PNameFactory;
+import org.apache.phoenix.schema.PTableKey;
+import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.SizedUtil;
+
+public class PSchema implements PMetaDataEntity {
+
+    private final PName schemaName;
+    private PTableKey schemaKey;
+    private long timeStamp;
+    private int estimatedSize;
+
+    public PSchema(long timeStamp) { // For index delete marker
+        this.timeStamp = timeStamp;
+        this.schemaName = null;
+    }
+
+    public PSchema(String schemaName) {
+        this(schemaName, HConstants.LATEST_TIMESTAMP);
+    }
+
+    public PSchema(String schemaName, long timeStamp) {
+        this.schemaName = PNameFactory.newName(SchemaUtil.normalizeIdentifier(schemaName));
+        this.schemaKey = new PTableKey(null, this.schemaName.getString());
+        this.timeStamp = timeStamp;
+        this.estimatedSize = SizedUtil.INT_SIZE + SizedUtil.LONG_SIZE + PNameFactory.getEstimatedSize(this.schemaName);
+    }
+
+    public PSchema(PSchema schema) {
+        this(schema.getSchemaName().toString(), schema.getTimeStamp());
+    }
+
+    public String getSchemaName() {
+        return schemaName == null ? null : schemaName.getString();
+    }
+
+    public PTableKey getSchemaKey() {
+        return schemaKey;
+    }
+
+    public long getTimeStamp() {
+        return timeStamp;
+    }
+
+    public static PSchemaProtos.PSchema toProto(PSchema schema) {
+        PSchemaProtos.PSchema.Builder builder = PSchemaProtos.PSchema.newBuilder();
+        builder.setSchemaName(schema.getSchemaName());
+        builder.setTimeStamp(schema.getTimeStamp());
+        return builder.build();
+    }
+
+    public static PSchema createFromProto(PSchemaProtos.PSchema schema) {
+        long timeStamp = schema.getTimeStamp();
+        String schemaName = schema.getSchemaName();
+        return new PSchema(schemaName, timeStamp);
+    }
+
+    public int getEstimatedSize() {
+        return estimatedSize;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
index a4815aa..282ec62 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
@@ -287,6 +287,10 @@ public class ParseNodeFactory {
         return new CreateTableStatement(tableName, props, columns, pkConstraint, splits, tableType, ifNotExists, baseTableName, tableTypeIdNode, bindCount);
     }
 
+    public CreateSchemaStatement createSchema(String schemaName, boolean ifNotExists) {
+        return new CreateSchemaStatement(schemaName, ifNotExists);
+    }
+
     public CreateIndexStatement createIndex(NamedNode indexName, NamedTableNode dataTable, IndexKeyConstraint ikConstraint, List<ColumnName> includeColumns, List<ParseNode> splits, ListMultimap<String,Pair<String,Object>> props, boolean ifNotExists, IndexType indexType,boolean async, int bindCount, Map<String, UDFParseNode> udfParseNodes) {
         return new CreateIndexStatement(indexName, dataTable, ikConstraint, includeColumns, splits, props, ifNotExists, indexType, async, bindCount, udfParseNodes);
     }
@@ -832,4 +836,12 @@ public class ParseNodeFactory {
     public OffsetNode offset(LiteralParseNode l) {
         return new OffsetNode(l);
     }
+
+    public DropSchemaStatement dropSchema(String schemaName, boolean ifExists, boolean cascade) {
+        return new DropSchemaStatement(schemaName, ifExists, cascade);
+    }
+
+    public UseSchemaStatement useSchema(String schemaName) {
+        return new UseSchemaStatement(schemaName);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/parse/UseSchemaStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/UseSchemaStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/UseSchemaStatement.java
new file mode 100644
index 0000000..3c5d0f0
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/UseSchemaStatement.java
@@ -0,0 +1,19 @@
+package org.apache.phoenix.parse;
+
+public class UseSchemaStatement extends MutableStatement {
+    private final String schemaName;
+
+    public UseSchemaStatement(String schemaName) {
+        this.schemaName = schemaName;
+    }
+
+    @Override
+    public int getBindCount() {
+        return 0;
+    }
+
+    public String getSchemaName() {
+        return schemaName;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/protobuf/ProtobufUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/protobuf/ProtobufUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/protobuf/ProtobufUtil.java
index 5df0492..0a69ae4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/protobuf/ProtobufUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/protobuf/ProtobufUtil.java
@@ -32,14 +32,14 @@ import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto;
 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.MutationType;
 import org.apache.hadoop.hbase.util.ByteStringer;
 import org.apache.hadoop.util.StringUtils;
-
-import com.google.protobuf.ByteString;
-import com.google.protobuf.RpcController;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos;
-import org.apache.phoenix.coprocessor.generated.ServerCachingProtos;
 import org.apache.phoenix.coprocessor.generated.PTableProtos;
+import org.apache.phoenix.coprocessor.generated.ServerCachingProtos;
 import org.apache.phoenix.schema.PTableType;
 
+import com.google.protobuf.ByteString;
+import com.google.protobuf.RpcController;
+
 public class ProtobufUtil {
 
     /**
@@ -71,6 +71,10 @@ public class ProtobufUtil {
         return getMutations(request.getTableMetadataMutationsList());
     }
 
+    public static List<Mutation> getMutations(MetaDataProtos.DropSchemaRequest request) throws IOException {
+        return getMutations(request.getSchemaMetadataMutationsList());
+    }
+
     public static List<Mutation> getMutations(MetaDataProtos.DropFunctionRequest request)
             throws IOException {
         return getMutations(request.getTableMetadataMutationsList());
@@ -101,6 +105,10 @@ public class ProtobufUtil {
         return getMutations(request.getTableMetadataMutationsList());
     }
 
+    public static List<Mutation> getMutations(MetaDataProtos.CreateSchemaRequest request) throws IOException {
+        return getMutations(request.getTableMetadataMutationsList());
+    }
+
     /**
      * Each ByteString entry is a byte array serialized from MutationProto instance
      * @param mutations


[23/52] [abbrv] phoenix git commit: PHOENIX-1311 HBase namespaces surfaced in phoenix

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateSchemaCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateSchemaCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateSchemaCompiler.java
new file mode 100644
index 0000000..40d1fee
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateSchemaCompiler.java
@@ -0,0 +1,65 @@
+/*
+ * 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.phoenix.compile;
+
+import java.sql.SQLException;
+import java.util.Collections;
+
+import org.apache.phoenix.execute.MutationState;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.parse.CreateSchemaStatement;
+import org.apache.phoenix.schema.MetaDataClient;
+
+public class CreateSchemaCompiler {
+    private final PhoenixStatement statement;
+
+    public CreateSchemaCompiler(PhoenixStatement statement) {
+        this.statement = statement;
+    }
+
+    public MutationPlan compile(final CreateSchemaStatement create) throws SQLException {
+        final PhoenixConnection connection = statement.getConnection();
+        final StatementContext context = new StatementContext(statement);
+        final MetaDataClient client = new MetaDataClient(connection);
+
+        return new BaseMutationPlan(context, create.getOperation()) {
+
+            @Override
+            public MutationState execute() throws SQLException {
+                try {
+                    return client.createSchema(create);
+                } finally {
+                    if (client.getConnection() != connection) {
+                        client.getConnection().close();
+                    }
+                }
+            }
+
+            @Override
+            public ExplainPlan getExplainPlan() throws SQLException {
+                return new ExplainPlan(Collections.singletonList("CREATE SCHEMA"));
+            }
+
+            @Override
+            public StatementContext getContext() {
+                return context;
+            }
+        };
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
index ffe9621..a2fc371 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
@@ -42,6 +42,7 @@ import org.apache.phoenix.parse.FamilyWildcardParseNode;
 import org.apache.phoenix.parse.JoinTableNode;
 import org.apache.phoenix.parse.NamedTableNode;
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.parse.ParseNode;
 import org.apache.phoenix.parse.ParseNodeFactory;
 import org.apache.phoenix.parse.SelectStatement;
@@ -51,6 +52,7 @@ import org.apache.phoenix.parse.TableNode;
 import org.apache.phoenix.parse.TableNodeVisitor;
 import org.apache.phoenix.parse.TableWildcardParseNode;
 import org.apache.phoenix.parse.UDFParseNode;
+import org.apache.phoenix.parse.UseSchemaStatement;
 import org.apache.phoenix.parse.WildcardParseNode;
 import org.apache.phoenix.query.ConnectionQueryServices;
 import org.apache.phoenix.query.QueryConstants;
@@ -73,6 +75,7 @@ import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.ProjectedColumn;
+import org.apache.phoenix.schema.SchemaNotFoundException;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableNotFoundException;
 import org.apache.phoenix.schema.TableRef;
@@ -124,17 +127,36 @@ public class FromCompiler {
         
         public PFunction resolveFunction(String functionName) throws SQLException {
             throw new FunctionNotFoundException(functionName);
-        };
+        }
 
         public boolean hasUDFs() {
             return false;
-        };
+        }
+
+        @Override
+        public PSchema resolveSchema(String schemaName) throws SQLException {
+            throw new SchemaNotFoundException(schemaName);
+        }
+
+        @Override
+        public List<PSchema> getSchemas() {
+            return Collections.emptyList();
+        }
+
     };
 
     public static ColumnResolver getResolverForCreation(final CreateTableStatement statement, final PhoenixConnection connection)
             throws SQLException {
+    	
         TableName baseTable = statement.getBaseTableName();
+        String schemaName;
         if (baseTable == null) {
+            if (SchemaUtil.isSchemaCheckRequired(statement.getTableType(), connection.getQueryServices().getProps())) {
+                schemaName = statement.getTableName().getSchemaName();
+                if (schemaName != null) {
+                    new SchemaResolver(connection, statement.getTableName().getSchemaName(), true);
+                }
+            }
             return EMPTY_TABLE_RESOLVER;
         }
         NamedTableNode tableNode = NamedTableNode.create(null, baseTable, Collections.<ColumnDef>emptyList());
@@ -148,7 +170,9 @@ public class FromCompiler {
             // A tenant-specific connection may not create a mapped VIEW.
             if (connection.getTenantId() == null && statement.getTableType() == PTableType.VIEW) {
                 ConnectionQueryServices services = connection.getQueryServices();
-                byte[] fullTableName = SchemaUtil.getTableNameAsBytes(baseTable.getSchemaName(), baseTable.getTableName());
+                byte[] fullTableName = SchemaUtil.getPhysicalName(
+                        SchemaUtil.getTableNameAsBytes(baseTable.getSchemaName(), baseTable.getTableName()),
+                        connection.getQueryServices().getProps()).getName();
                 HTableInterface htable = null;
                 try {
                     htable = services.getTable(fullTableName);
@@ -190,6 +214,11 @@ public class FromCompiler {
         return visitor;
     }
 
+    public static ColumnResolver getResolverForSchema(UseSchemaStatement statement, PhoenixConnection connection)
+            throws SQLException {
+        return new SchemaResolver(connection, SchemaUtil.normalizeIdentifier(statement.getSchemaName()), true);
+    }
+
     public static ColumnResolver getResolver(NamedTableNode tableNode, PhoenixConnection connection) throws SQLException {
         SingleTableColumnResolver visitor = new SingleTableColumnResolver(connection, tableNode, true);
         return visitor;
@@ -254,9 +283,47 @@ public class FromCompiler {
         return new ProjectedTableColumnResolver(projectedTable, connection, udfParseNodes);
     }
 
+    private static class SchemaResolver extends BaseColumnResolver {
+        private final List<PSchema> schemas;
+
+        public SchemaResolver(PhoenixConnection conn, String schemaName, boolean updateCacheImmediately)
+                throws SQLException {
+            super(conn, 0);
+            schemaName = connection.getSchema() != null && schemaName == null ? connection.getSchema() : schemaName;
+            schemas = ImmutableList.of(createSchemaRef(schemaName, updateCacheImmediately));
+        }
+
+        @Override
+        public List<TableRef> getTables() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public TableRef resolveTable(String schemaName, String tableName) throws SQLException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ColumnRef resolveColumn(String schemaName, String tableName, String colName) throws SQLException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public PSchema resolveSchema(String schemaName) throws SQLException {
+            return schemas.get(0);
+        }
+
+        @Override
+        public List<PSchema> getSchemas() {
+            return schemas;
+        }
+
+    }
+
     private static class SingleTableColumnResolver extends BaseColumnResolver {
     	private final List<TableRef> tableRefs;
     	private final String alias;
+        private final List<PSchema> schemas;
 
        public SingleTableColumnResolver(PhoenixConnection connection, NamedTableNode table, long timeStamp, Map<String, UDFParseNode> udfParseNodes) throws SQLException  {
            super(connection, 0, false, udfParseNodes);
@@ -265,12 +332,18 @@ public class FromCompiler {
                if (def.getColumnDefName().getFamilyName() != null) {
                    families.add(new PColumnFamilyImpl(PNameFactory.newName(def.getColumnDefName().getFamilyName()),Collections.<PColumn>emptyList()));
                }
-           }
-           Long scn = connection.getSCN();
-           PTable theTable = new PTableImpl(connection.getTenantId(), table.getName().getSchemaName(), table.getName().getTableName(), scn == null ? HConstants.LATEST_TIMESTAMP : scn, families);
+            }
+            Long scn = connection.getSCN();
+            String schema = table.getName().getSchemaName();
+            if (connection.getSchema() != null) {
+                schema = schema != null ? schema : connection.getSchema();
+            }
+            PTable theTable = new PTableImpl(connection.getTenantId(), schema, table.getName().getTableName(),
+                    scn == null ? HConstants.LATEST_TIMESTAMP : scn, families);
            theTable = this.addDynamicColumns(table.getDynamicColumns(), theTable);
            alias = null;
            tableRefs = ImmutableList.of(new TableRef(alias, theTable, timeStamp, !table.getDynamicColumns().isEmpty()));
+           schemas = ImmutableList.of(new PSchema(theTable.getSchemaName().toString(), timeStamp));
        }
 
         public SingleTableColumnResolver(PhoenixConnection connection, NamedTableNode tableNode, boolean updateCacheImmediately) throws SQLException {
@@ -282,29 +355,36 @@ public class FromCompiler {
                 Map<String, UDFParseNode> udfParseNodes) throws SQLException {
             super(connection, tsAddition, updateCacheImmediately, udfParseNodes);
             alias = tableNode.getAlias();
-            TableRef tableRef = createTableRef(tableNode, updateCacheImmediately);
+            TableRef tableRef = createTableRef(tableNode.getName().getSchemaName(), tableNode, updateCacheImmediately);
+			PSchema schema = new PSchema(tableRef.getTable().getSchemaName().toString());
             tableRefs = ImmutableList.of(tableRef);
+            schemas = ImmutableList.of(schema);
         }
 
         public SingleTableColumnResolver(PhoenixConnection connection, TableRef tableRef) {
             super(connection, 0);
             alias = tableRef.getTableAlias();
             tableRefs = ImmutableList.of(tableRef);
+            schemas = ImmutableList.of(new PSchema(tableRef.getTable().getSchemaName().toString()));
         }
 
         public SingleTableColumnResolver(PhoenixConnection connection, TableRef tableRef, Map<String, UDFParseNode> udfParseNodes) throws SQLException {
             super(connection, 0, false, udfParseNodes);
             alias = tableRef.getTableAlias();
             tableRefs = ImmutableList.of(tableRef);
+            schemas = ImmutableList.of(new PSchema(tableRef.getTable().getSchemaName().toString()));
         }
 
         public SingleTableColumnResolver(TableRef tableRef) throws SQLException {
             super(null, 0);
             alias = tableRef.getTableAlias();
             tableRefs = ImmutableList.of(tableRef);
+            schemas = ImmutableList.of(new PSchema(tableRef.getTable().getSchemaName().toString()));
         }
 
-        @Override
+		
+
+		@Override
 		public List<TableRef> getTables() {
 			return tableRefs;
 		}
@@ -364,6 +444,16 @@ public class FromCompiler {
         			: tableRef.getTable().getColumn(colName);
             return new ColumnRef(tableRef, column.getPosition());
 		}
+
+        @Override
+        public PSchema resolveSchema(String schemaName) throws SQLException {
+            return schemas.get(0);
+        }
+
+        @Override
+        public List<PSchema> getSchemas() {
+            return schemas;
+        }
     }
 
     private static abstract class BaseColumnResolver implements ColumnResolver {
@@ -399,9 +489,37 @@ public class FromCompiler {
             }
         }
 
-        protected TableRef createTableRef(NamedTableNode tableNode, boolean updateCacheImmediately) throws SQLException {
+        protected PSchema createSchemaRef(String schemaName, boolean updateCacheImmediately) throws SQLException {
+            long timeStamp = QueryConstants.UNSET_TIMESTAMP;
+            PSchema theSchema = null;
+            MetaDataClient client = new MetaDataClient(connection);
+            if (updateCacheImmediately) {
+                MetaDataMutationResult result = client.updateCache(schemaName, true);
+                timeStamp = TransactionUtil.getResolvedTimestamp(connection, result);
+                theSchema = result.getSchema();
+                if (theSchema == null) { throw new SchemaNotFoundException(schemaName, timeStamp); }
+            } else {
+                try {
+                    theSchema = connection.getSchema(new PTableKey(null, schemaName));
+                } catch (SchemaNotFoundException e1) {}
+                // We always attempt to update the cache in the event of a
+                // SchemaNotFoundException
+                if (theSchema == null) {
+                    MetaDataMutationResult result = client.updateCache(schemaName, true);
+                    if (result.wasUpdated()) {
+                        timeStamp = TransactionUtil.getResolvedTimestamp(connection, result);
+                        theSchema = result.getSchema();
+                    }
+                }
+                if (theSchema == null) { throw new SchemaNotFoundException(schemaName, timeStamp); }
+            }
+            return theSchema;
+        }
+
+        protected TableRef createTableRef(String connectionSchemaName, NamedTableNode tableNode, boolean updateCacheImmediately) throws SQLException {
             String tableName = tableNode.getName().getTableName();
             String schemaName = tableNode.getName().getSchemaName();
+            schemaName = connection.getSchema() != null && schemaName == null ? connection.getSchema() : schemaName;
             long timeStamp = QueryConstants.UNSET_TIMESTAMP;
             String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
             PName tenantId = connection.getTenantId();
@@ -573,11 +691,17 @@ public class FromCompiler {
     private static class MultiTableColumnResolver extends BaseColumnResolver implements TableNodeVisitor<Void> {
         protected final ListMultimap<String, TableRef> tableMap;
         protected final List<TableRef> tables;
+        private String connectionSchemaName;
 
         private MultiTableColumnResolver(PhoenixConnection connection, int tsAddition) {
         	super(connection, tsAddition);
             tableMap = ArrayListMultimap.<String, TableRef> create();
             tables = Lists.newArrayList();
+            try {
+                connectionSchemaName = connection.getSchema();
+            } catch (SQLException e) {
+                // ignore
+            }
         }
 
         private MultiTableColumnResolver(PhoenixConnection connection, int tsAddition, Map<String, UDFParseNode> udfParseNodes) throws SQLException {
@@ -606,7 +730,7 @@ public class FromCompiler {
         @Override
         public Void visit(NamedTableNode tableNode) throws SQLException {
             String alias = tableNode.getAlias();
-            TableRef tableRef = createTableRef(tableNode, true);
+            TableRef tableRef = createTableRef(connectionSchemaName, tableNode, true);
             PTable theTable = tableRef.getTable();
 
             if (alias != null) {
@@ -648,11 +772,11 @@ public class FromCompiler {
                         null, 0, 0, true, position++, SortOrder.ASC, null, null, false, null, false, false);
                 columns.add(column);
             }
-            PTable t = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME,
-                    PTableType.SUBQUERY, null, MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM,
-                    null, null, columns, null, null, Collections.<PTable>emptyList(),
-                    false, Collections.<PName>emptyList(), null, null, false, false, false, null,
-                    null, null, false, false, 0, 0L);
+            PTable t = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,
+                    MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM, null, null, columns, null, null,
+                    Collections.<PTable> emptyList(), false, Collections.<PName> emptyList(), null, null, false, false,
+                    false, null, null, null, false, false, 0, 0L, SchemaUtil
+                            .isNamespaceMappingEnabled(PTableType.SUBQUERY, connection.getQueryServices().getProps()));
 
             String alias = subselectNode.getAlias();
             TableRef tableRef = new TableRef(alias, t, MetaDataProtocol.MIN_TABLE_TIMESTAMP, false);
@@ -750,6 +874,18 @@ public class FromCompiler {
                 }
             }
         }
+
+        @Override
+        public PSchema resolveSchema(String schemaName) throws SQLException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public List<PSchema> getSchemas() {
+            // TODO Auto-generated method stub
+            return null;
+        }
     }
     
     private static class ProjectedTableColumnResolver extends MultiTableColumnResolver {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
index e6c5970..93b32de 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
@@ -1302,11 +1302,12 @@ public class JoinCompiler {
         
         return PTableImpl.makePTable(left.getTenantId(), left.getSchemaName(),
                 PNameFactory.newName(SchemaUtil.getTableName(left.getName().getString(), right.getName().getString())),
-                left.getType(), left.getIndexState(), left.getTimeStamp(), left.getSequenceNumber(), left.getPKName(), 
-                left.getBucketNum(), merged,left.getParentSchemaName(), left.getParentTableName(), left.getIndexes(),
-                left.isImmutableRows(), Collections.<PName>emptyList(), null, null, PTable.DEFAULT_DISABLE_WAL,
-                left.isMultiTenant(), left.getStoreNulls(), left.getViewType(), left.getViewIndexId(), left.getIndexType(),
-                left.rowKeyOrderOptimizable(), left.isTransactional(), left.getUpdateCacheFrequency(), left.getIndexDisableTimestamp());
+                left.getType(), left.getIndexState(), left.getTimeStamp(), left.getSequenceNumber(), left.getPKName(),
+                left.getBucketNum(), merged, left.getParentSchemaName(), left.getParentTableName(), left.getIndexes(),
+                left.isImmutableRows(), Collections.<PName> emptyList(), null, null, PTable.DEFAULT_DISABLE_WAL,
+                left.isMultiTenant(), left.getStoreNulls(), left.getViewType(), left.getViewIndexId(),
+                left.getIndexType(), left.rowKeyOrderOptimizable(), left.isTransactional(),
+                left.getUpdateCacheFrequency(), left.getIndexDisableTimestamp(), left.isNamespaceMapped());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
index 752e1a5..a786438 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
@@ -35,6 +35,7 @@ import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.parse.SelectStatement;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.AmbiguousColumnException;
@@ -44,6 +45,7 @@ import org.apache.phoenix.schema.ColumnRef;
 import org.apache.phoenix.schema.FunctionNotFoundException;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PColumnFamily;
+import org.apache.phoenix.schema.SchemaNotFoundException;
 import org.apache.phoenix.schema.TableNotFoundException;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.tuple.Tuple;
@@ -118,6 +120,16 @@ public class PostDDLCompiler {
 					public boolean hasUDFs() {
 						return false;
 					}
+
+					@Override
+					public PSchema resolveSchema(String schemaName) throws SQLException {
+						throw new SchemaNotFoundException(schemaName);
+					}
+
+					@Override
+					public List<PSchema> getSchemas() {
+						throw new UnsupportedOperationException();
+					}
                     
                 },
                 scan,
@@ -177,7 +189,17 @@ public class PostDDLCompiler {
                             @Override
                             public boolean hasUDFs() {
                                 return false;
-                            };
+                            }
+
+                            @Override
+                            public List<PSchema> getSchemas() {
+                                throw new UnsupportedOperationException();
+                            }
+
+                            @Override
+                            public PSchema resolveSchema(String schemaName) throws SQLException {
+                                throw new SchemaNotFoundException(schemaName);
+                            }
                         };
                         PhoenixStatement statement = new PhoenixStatement(connection);
                         StatementContext context = new StatementContext(statement, resolver, scan, new SequenceManager(statement));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
index 4be78a9..a9199c6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
@@ -147,12 +147,13 @@ public class TupleProjectionCompiler {
             projectedColumns.add(column);
         }
         
-        return PTableImpl.makePTable(table.getTenantId(), table.getSchemaName(), table.getTableName(), PTableType.PROJECTED,
-                table.getIndexState(), table.getTimeStamp(), table.getSequenceNumber(), table.getPKName(),
-                table.getBucketNum(), projectedColumns, table.getParentSchemaName(),
-                table.getParentName(), table.getIndexes(), table.isImmutableRows(), Collections.<PName>emptyList(), null, null,
-                table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
-                table.getIndexType(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp());
+        return PTableImpl.makePTable(table.getTenantId(), table.getSchemaName(), table.getTableName(),
+                PTableType.PROJECTED, table.getIndexState(), table.getTimeStamp(), table.getSequenceNumber(),
+                table.getPKName(), table.getBucketNum(), projectedColumns, table.getParentSchemaName(),
+                table.getParentName(), table.getIndexes(), table.isImmutableRows(), Collections.<PName> emptyList(),
+                null, null, table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(),
+                table.getViewIndexId(),
+                table.getIndexType(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
     }
 
     public static PTable createProjectedTable(TableRef tableRef, List<ColumnRef> sourceColumnRefs, boolean retainPKColumns) throws SQLException {
@@ -175,11 +176,12 @@ public class TupleProjectionCompiler {
             projectedColumns.add(column);
         }
         return PTableImpl.makePTable(table.getTenantId(), PROJECTED_TABLE_SCHEMA, table.getName(), PTableType.PROJECTED,
-                    null, table.getTimeStamp(), table.getSequenceNumber(), table.getPKName(),
-                    retainPKColumns ? table.getBucketNum() : null, projectedColumns, null,
-                    null, Collections.<PTable>emptyList(), table.isImmutableRows(), Collections.<PName>emptyList(), null, null,
-                    table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
-                    null, table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp());
+                null, table.getTimeStamp(), table.getSequenceNumber(), table.getPKName(),
+                retainPKColumns ? table.getBucketNum() : null, projectedColumns, null, null,
+                Collections.<PTable> emptyList(), table.isImmutableRows(), Collections.<PName> emptyList(), null, null,
+                table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(),
+                table.getViewIndexId(), null, table.rowKeyOrderOptimizable(), table.isTransactional(),
+                table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
     }
 
     // For extracting column references from single select statement

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
index b25baf7..32fa8fe 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
@@ -36,6 +36,7 @@ import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.util.SchemaUtil;
 
 public class UnionCompiler {
     private static final PName UNION_FAMILY_NAME = PNameFactory.newName("unionFamilyName");
@@ -79,10 +80,12 @@ public class UnionCompiler {
             projectedColumns.add(projectedColumn);
         }
         Long scn = statement.getConnection().getSCN();
-        PTable tempTable = PTableImpl.makePTable(statement.getConnection().getTenantId(), UNION_SCHEMA_NAME, UNION_TABLE_NAME, 
-                PTableType.SUBQUERY, null, HConstants.LATEST_TIMESTAMP, scn == null ? HConstants.LATEST_TIMESTAMP : scn, null, null,
-                        projectedColumns, null, null, null,
-                        true, null, null, null, true, true, true, null, null, null, false, false, 0, 0L);
+        PTable tempTable = PTableImpl.makePTable(statement.getConnection().getTenantId(), UNION_SCHEMA_NAME,
+                UNION_TABLE_NAME, PTableType.SUBQUERY, null, HConstants.LATEST_TIMESTAMP,
+                scn == null ? HConstants.LATEST_TIMESTAMP : scn, null, null, projectedColumns, null, null, null, true,
+                null, null, null, true, true, true, null, null, null, false, false, 0, 0L,
+                SchemaUtil.isNamespaceMappingEnabled(PTableType.SUBQUERY,
+                        statement.getConnection().getQueryServices().getProps()));
         TableRef tableRef = new TableRef(null, tempTable, 0, false);
         return tableRef;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 770917f..1fd4f44 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -39,6 +39,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_STATE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_TYPE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_ARRAY_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_CONSTANT_BYTES;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_NAMESPACE_MAPPED_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_ROW_TIMESTAMP_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_VIEW_REFERENCED_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.JAR_PATH_BYTES;
@@ -127,11 +128,14 @@ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearCacheRespons
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearTableFromCacheRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearTableFromCacheResponse;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest;
+import org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateSchemaRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropColumnRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropFunctionRequest;
+import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropSchemaRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropTableRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetFunctionsRequest;
+import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetTableRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetVersionRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetVersionResponse;
@@ -156,6 +160,7 @@ import org.apache.phoenix.metrics.Metrics;
 import org.apache.phoenix.parse.LiteralParseNode;
 import org.apache.phoenix.parse.PFunction;
 import org.apache.phoenix.parse.PFunction.FunctionArgument;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.parse.ParseNode;
 import org.apache.phoenix.parse.SQLParser;
 import org.apache.phoenix.protobuf.ProtobufUtil;
@@ -259,6 +264,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final KeyValue ROW_KEY_ORDER_OPTIMIZABLE_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, ROW_KEY_ORDER_OPTIMIZABLE_BYTES);
     private static final KeyValue TRANSACTIONAL_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, TRANSACTIONAL_BYTES);
     private static final KeyValue UPDATE_CACHE_FREQUENCY_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, UPDATE_CACHE_FREQUENCY_BYTES);
+    private static final KeyValue IS_NAMESPACE_MAPPED_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY,
+            TABLE_FAMILY_BYTES, IS_NAMESPACE_MAPPED_BYTES);
     
     private static final List<KeyValue> TABLE_KV_COLUMNS = Arrays.<KeyValue>asList(
             EMPTY_KEYVALUE_KV,
@@ -282,7 +289,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             BASE_COLUMN_COUNT_KV,
             ROW_KEY_ORDER_OPTIMIZABLE_KV,
             TRANSACTIONAL_KV,
-            UPDATE_CACHE_FREQUENCY_KV
+            UPDATE_CACHE_FREQUENCY_KV,
+            IS_NAMESPACE_MAPPED_KV
             );
     static {
         Collections.sort(TABLE_KV_COLUMNS, KeyValue.COMPARATOR);
@@ -309,6 +317,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final int TRANSACTIONAL_INDEX = TABLE_KV_COLUMNS.indexOf(TRANSACTIONAL_KV);
     private static final int UPDATE_CACHE_FREQUENCY_INDEX = TABLE_KV_COLUMNS.indexOf(UPDATE_CACHE_FREQUENCY_KV);
     private static final int INDEX_DISABLE_TIMESTAMP = TABLE_KV_COLUMNS.indexOf(INDEX_DISABLE_TIMESTAMP_KV);
+    private static final int IS_NAMESPACE_MAPPED_INDEX = TABLE_KV_COLUMNS.indexOf(IS_NAMESPACE_MAPPED_KV);
 
     // KeyValues for Column
     private static final KeyValue DECIMAL_DIGITS_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, DECIMAL_DIGITS_BYTES);
@@ -573,6 +582,39 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         }
     }
 
+    private List<PSchema> buildSchemas(List<byte[]> keys, HRegion region, long clientTimeStamp,
+            ImmutableBytesPtr cacheKey) throws IOException, SQLException {
+        List<KeyRange> keyRanges = Lists.newArrayListWithExpectedSize(keys.size());
+        for (byte[] key : keys) {
+            byte[] stopKey = ByteUtil.concat(key, QueryConstants.SEPARATOR_BYTE_ARRAY);
+            ByteUtil.nextKey(stopKey, stopKey.length);
+            keyRanges.add(PVarbinary.INSTANCE.getKeyRange(key, true, stopKey, false));
+        }
+        Scan scan = new Scan();
+        scan.setTimeRange(MIN_TABLE_TIMESTAMP, clientTimeStamp);
+        ScanRanges scanRanges = ScanRanges.createPointLookup(keyRanges);
+        scanRanges.initializeScan(scan);
+        scan.setFilter(scanRanges.getSkipScanFilter());
+
+        RegionScanner scanner = region.getScanner(scan);
+
+        Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache = GlobalCache.getInstance(this.env).getMetaDataCache();
+        List<PSchema> schemas = new ArrayList<PSchema>();
+        PSchema schema = null;
+        try {
+            for (int i = 0; i < keys.size(); i++) {
+                schema = null;
+                schema = getSchema(scanner, clientTimeStamp);
+                if (schema == null) { return null; }
+                metaDataCache.put(cacheKey, schema);
+                schemas.add(schema);
+            }
+            return schemas;
+        } finally {
+            scanner.close();
+        }
+    }
+
     private void addIndexToTable(PName tenantId, PName schemaName, PName indexName, PName tableName, long clientTimeStamp, List<PTable> indexes) throws IOException, SQLException {
         byte[] key = SchemaUtil.getTableKey(tenantId == null ? ByteUtil.EMPTY_BYTE_ARRAY : tenantId.getBytes(), schemaName.getBytes(), indexName.getBytes());
         PTable indexTable = doGetTable(key, clientTimeStamp);
@@ -853,7 +895,11 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         Cell indexDisableTimestampKv = tableKeyValues[INDEX_DISABLE_TIMESTAMP];
         long indexDisableTimestamp = indexDisableTimestampKv == null ? 0L : PLong.INSTANCE.getCodec().decodeLong(indexDisableTimestampKv.getValueArray(),
                 indexDisableTimestampKv.getValueOffset(), SortOrder.getDefault());
-        
+        Cell isNamespaceMappedKv = tableKeyValues[IS_NAMESPACE_MAPPED_INDEX];
+        boolean isNamespaceMapped = isNamespaceMappedKv == null ? false
+                : Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(isNamespaceMappedKv.getValueArray(),
+                        isNamespaceMappedKv.getValueOffset(), isNamespaceMappedKv.getValueLength()));
+
         List<PColumn> columns = Lists.newArrayListWithExpectedSize(columnCount);
         List<PTable> indexes = new ArrayList<PTable>();
         List<PName> physicalTables = new ArrayList<PName>();
@@ -879,26 +925,50 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
               addColumnToTable(results, colName, famName, colKeyValues, columns, saltBucketNum != null);
           }
         }
-        PName physicalTableName = physicalTables.isEmpty() ? PNameFactory.newName(SchemaUtil.getTableName(
-                schemaName.getString(), tableName.getString())) : physicalTables.get(0);
+        PName physicalTableName = physicalTables.isEmpty() ? PNameFactory.newName(SchemaUtil.getPhysicalTableName(
+                Bytes.toBytes(SchemaUtil.getTableName(schemaName.getBytes(), tableName.getBytes())), isNamespaceMapped)
+                .getNameAsString()) : physicalTables.get(0);
         PTableStats stats = PTableStats.EMPTY_STATS;
         if (tenantId == null) {
             HTableInterface statsHTable = null;
             try {
-                statsHTable = ServerUtil.getHTableForCoprocessorScan(env, PhoenixDatabaseMetaData.SYSTEM_STATS_NAME_BYTES);
+                statsHTable = ServerUtil.getHTableForCoprocessorScan(env,
+                        SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME_BYTES, env.getConfiguration())
+                                .getName());
                 stats = StatisticsUtil.readStatistics(statsHTable, physicalTableName.getBytes(), clientTimeStamp);
                 timeStamp = Math.max(timeStamp, stats.getTimestamp());
             } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
-                logger.warn(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME + " not online yet?");
+                logger.warn(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME_BYTES,
+                        env.getConfiguration()) + " not online yet?");
             } finally {
                 if (statsHTable != null) statsHTable.close();
             }
         }
-        return PTableImpl.makePTable(tenantId, schemaName, tableName, tableType, indexState, timeStamp,
-            tableSeqNum, pkName, saltBucketNum, columns, tableType == INDEX ? schemaName : null,
-            tableType == INDEX ? dataTableName : null, indexes, isImmutableRows, physicalTables, defaultFamilyName, viewStatement,
-            disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, rowKeyOrderOptimizable, transactional, updateCacheFrequency,
-            stats, baseColumnCount, indexDisableTimestamp);
+        return PTableImpl.makePTable(tenantId, schemaName, tableName, tableType, indexState, timeStamp, tableSeqNum,
+                pkName, saltBucketNum, columns, tableType == INDEX ? schemaName : null,
+                tableType == INDEX ? dataTableName : null, indexes, isImmutableRows, physicalTables, defaultFamilyName,
+                viewStatement, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType,
+                rowKeyOrderOptimizable, transactional, updateCacheFrequency, stats, baseColumnCount,
+                indexDisableTimestamp, isNamespaceMapped);
+    }
+
+    private PSchema getSchema(RegionScanner scanner, long clientTimeStamp) throws IOException, SQLException {
+        List<Cell> results = Lists.newArrayList();
+        scanner.next(results);
+        if (results.isEmpty()) { return null; }
+
+        Cell keyValue = results.get(0);
+        byte[] keyBuffer = keyValue.getRowArray();
+        int keyLength = keyValue.getRowLength();
+        int keyOffset = keyValue.getRowOffset();
+        PName tenantId = newPName(keyBuffer, keyOffset, keyLength);
+        int tenantIdLength = (tenantId == null) ? 0 : tenantId.getBytes().length;
+        if (tenantIdLength == 0) {
+            tenantId = null;
+        }
+        PName schemaName = newPName(keyBuffer, keyOffset + tenantIdLength + 1, keyLength - tenantIdLength - 1);
+        long timeStamp = keyValue.getTimestamp();
+        return new PSchema(schemaName.getString(), timeStamp);
     }
 
     private PFunction getFunction(RegionScanner scanner, final boolean isReplace, long clientTimeStamp, List<Mutation> deleteMutationsForReplace)
@@ -1070,6 +1140,30 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         return null;
     }
 
+    private PSchema buildDeletedSchema(byte[] key, ImmutableBytesPtr cacheKey, HRegion region, long clientTimeStamp)
+            throws IOException {
+        if (clientTimeStamp == HConstants.LATEST_TIMESTAMP) { return null; }
+
+        Scan scan = MetaDataUtil.newTableRowsScan(key, clientTimeStamp, HConstants.LATEST_TIMESTAMP);
+        scan.setFilter(new FirstKeyOnlyFilter());
+        scan.setRaw(true);
+        List<Cell> results = Lists.<Cell> newArrayList();
+        try (RegionScanner scanner = region.getScanner(scan);) {
+            scanner.next(results);
+        }
+        // HBase ignores the time range on a raw scan (HBASE-7362)
+        if (!results.isEmpty() && results.get(0).getTimestamp() > clientTimeStamp) {
+            Cell kv = results.get(0);
+            if (kv.getTypeByte() == Type.Delete.getCode()) {
+                Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache = GlobalCache.getInstance(this.env)
+                        .getMetaDataCache();
+                PSchema schema = newDeletedSchemaMarker(kv.getTimestamp());
+                metaDataCache.put(cacheKey, schema);
+                return schema;
+            }
+        }
+        return null;
+    }
 
     private static PTable newDeletedTableMarker(long timestamp) {
         return new PTableImpl(timestamp);
@@ -1079,6 +1173,10 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         return new PFunction(timestamp);
     }
 
+    private static PSchema newDeletedSchemaMarker(long timestamp) {
+        return new PSchema(timestamp);
+    }
+
     private static boolean isTableDeleted(PTable table) {
         return table.getName() == null;
     }
@@ -1343,6 +1441,24 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
 
     private static final byte[] PHYSICAL_TABLE_BYTES = new byte[] {PTable.LinkType.PHYSICAL_TABLE.getSerializedValue()};
 
+    private PSchema loadSchema(RegionCoprocessorEnvironment env, byte[] key, ImmutableBytesPtr cacheKey,
+            long clientTimeStamp, long asOfTimeStamp) throws IOException, SQLException {
+        HRegion region = env.getRegion();
+        Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache = GlobalCache.getInstance(this.env).getMetaDataCache();
+        PSchema schema = (PSchema)metaDataCache.getIfPresent(cacheKey);
+        // We always cache the latest version - fault in if not in cache
+        if (schema != null) { return schema; }
+        ArrayList<byte[]> arrayList = new ArrayList<byte[]>(1);
+        arrayList.add(key);
+        List<PSchema> schemas = buildSchemas(arrayList, region, asOfTimeStamp, cacheKey);
+        if (schemas != null) return schemas.get(0);
+        // if not found then check if newer schema already exists and add delete marker for timestamp
+        // found
+        if (schema == null
+                && (schema = buildDeletedSchema(key, cacheKey, region, clientTimeStamp)) != null) { return schema; }
+        return null;
+    }
+
     /**
      * @param tableName parent table's name
      * Looks for whether child views exist for the table specified by table.
@@ -1365,7 +1481,9 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         }
         SingleColumnValueFilter linkFilter = new SingleColumnValueFilter(TABLE_FAMILY_BYTES, LINK_TYPE_BYTES, CompareOp.EQUAL, linkTypeBytes);
         linkFilter.setFilterIfMissing(true);
-        byte[] suffix = ByteUtil.concat(QueryConstants.SEPARATOR_BYTE_ARRAY, SchemaUtil.getTableNameAsBytes(schemaName, tableName));
+        byte[] suffix = ByteUtil.concat(QueryConstants.SEPARATOR_BYTE_ARRAY, SchemaUtil
+                .getPhysicalTableName(SchemaUtil.getTableNameAsBytes(schemaName, tableName), table.isNamespaceMapped())
+                .getName());
         SuffixFilter rowFilter = new SuffixFilter(suffix);
         Filter filter = new FilterList(linkFilter, rowFilter);
         scan.setFilter(filter);
@@ -1378,7 +1496,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         // TableName systemCatalogTableName = region.getTableDesc().getTableName();
         // HTableInterface hTable = env.getTable(systemCatalogTableName);
         // These deprecated calls work around the issue
-        HTableInterface hTable = ServerUtil.getHTableForCoprocessorScan(env, PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES);
+        HTableInterface hTable = ServerUtil.getHTableForCoprocessorScan(env,
+                region.getTableDesc().getTableName().getName());
         try {
             boolean allViewsInCurrentRegion = true;
             int numOfChildViews = 0;
@@ -1578,7 +1697,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
 
             // Add to list of HTables to delete, unless it's a view or its a shared index
             if (tableType != PTableType.VIEW && table.getViewIndexId()==null) { 
-                tableNamesToDelete.add(table.getName().getBytes());
+                tableNamesToDelete.add(table.getPhysicalName().getBytes());
             }
             else {
                 sharedTablesToDelete.add(new SharedTableState(table));
@@ -3125,7 +3244,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         }
     }
 
-    private static MetaDataMutationResult checkTableKeyInRegion(byte[] key, HRegion region) {
+    private static MetaDataMutationResult checkKeyInRegion(byte[] key, HRegion region, MutationCode code) {
         byte[] startKey = region.getStartKey();
         byte[] endKey = region.getEndKey();
         if (Bytes.compareTo(startKey, key) <= 0
@@ -3133,20 +3252,21 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                     endKey) < 0)) {
             return null; // normal case;
         }
-        return new MetaDataMutationResult(MutationCode.TABLE_NOT_IN_REGION,
-                EnvironmentEdgeManager.currentTimeMillis(), null);
+        return new MetaDataMutationResult(code, EnvironmentEdgeManager.currentTimeMillis(), null);
+    }
+
+    private static MetaDataMutationResult checkTableKeyInRegion(byte[] key, HRegion region) {
+        return checkKeyInRegion(key, region, MutationCode.TABLE_NOT_IN_REGION);
+
     }
 
     private static MetaDataMutationResult checkFunctionKeyInRegion(byte[] key, HRegion region) {
-        byte[] startKey = region.getStartKey();
-        byte[] endKey = region.getEndKey();
-        if (Bytes.compareTo(startKey, key) <= 0
-                && (Bytes.compareTo(HConstants.LAST_ROW, endKey) == 0 || Bytes.compareTo(key,
-                    endKey) < 0)) {
-            return null; // normal case;
-        }
-        return new MetaDataMutationResult(MutationCode.FUNCTION_NOT_IN_REGION,
-                EnvironmentEdgeManager.currentTimeMillis(), null);
+        return checkKeyInRegion(key, region, MutationCode.FUNCTION_NOT_IN_REGION);
+    }
+
+    private static MetaDataMutationResult checkSchemaKeyInRegion(byte[] key, HRegion region) {
+        return checkKeyInRegion(key, region, MutationCode.SCHEMA_NOT_IN_REGION);
+
     }
 
     /**
@@ -3210,6 +3330,46 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     }
 
     @Override
+    public void getSchema(RpcController controller, GetSchemaRequest request, RpcCallback<MetaDataResponse> done) {
+        MetaDataResponse.Builder builder = MetaDataResponse.newBuilder();
+        HRegion region = env.getRegion();
+        String schemaName = request.getSchemaName();
+        byte[] lockKey = SchemaUtil.getSchemaKey(schemaName);
+        MetaDataMutationResult result = checkSchemaKeyInRegion(lockKey, region);
+        if (result != null) {
+            done.run(MetaDataMutationResult.toProto(result));
+            return;
+        }
+        long clientTimeStamp = request.getClientTimestamp();
+        List<RowLock> locks = Lists.newArrayList();
+        try {
+            acquireLock(region, lockKey, locks);
+            // Get as of latest timestamp so we can detect if we have a
+            // newer schema that already
+            // exists without making an additional query
+            ImmutableBytesPtr cacheKey = new ImmutableBytesPtr(lockKey);
+            PSchema schema = loadSchema(env, lockKey, cacheKey, clientTimeStamp, clientTimeStamp);
+            if (schema != null) {
+                if (schema.getTimeStamp() < clientTimeStamp) {
+                    builder.setReturnCode(MetaDataProtos.MutationCode.SCHEMA_ALREADY_EXISTS);
+                    builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
+                    builder.setSchema(PSchema.toProto(schema));
+                    done.run(builder.build());
+                    return;
+                }
+            }
+        } catch (Exception e) {
+            long currentTime = EnvironmentEdgeManager.currentTimeMillis();
+            builder.setReturnCode(MetaDataProtos.MutationCode.SCHEMA_NOT_FOUND);
+            builder.setMutationTime(currentTime);
+            done.run(builder.build());
+            return;
+        } finally {
+            region.releaseRowLocks(locks);
+        }
+    }
+
+    @Override
     public void getFunctions(RpcController controller, GetFunctionsRequest request,
             RpcCallback<MetaDataResponse> done) {
         MetaDataResponse.Builder builder = MetaDataResponse.newBuilder();
@@ -3428,5 +3588,154 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         return new MetaDataMutationResult(MutationCode.FUNCTION_NOT_FOUND,
                 EnvironmentEdgeManager.currentTimeMillis(), null);
     }
+    
+    @Override
+    public void createSchema(RpcController controller, CreateSchemaRequest request,
+            RpcCallback<MetaDataResponse> done) {
+        MetaDataResponse.Builder builder = MetaDataResponse.newBuilder();
+        String schemaName = null;
+        try {
+            List<Mutation> schemaMutations = ProtobufUtil.getMutations(request);
+            schemaName = request.getSchemaName();
+            Mutation m = MetaDataUtil.getPutOnlyTableHeaderRow(schemaMutations);
+
+            byte[] lockKey = m.getRow();
+            HRegion region = env.getRegion();
+            MetaDataMutationResult result = checkSchemaKeyInRegion(lockKey, region);
+            if (result != null) {
+                done.run(MetaDataMutationResult.toProto(result));
+                return;
+            }
+            List<RowLock> locks = Lists.newArrayList();
+            long clientTimeStamp = MetaDataUtil.getClientTimeStamp(schemaMutations);
+            try {
+                acquireLock(region, lockKey, locks);
+                // Get as of latest timestamp so we can detect if we have a newer schema that already exists without
+                // making an additional query
+                ImmutableBytesPtr cacheKey = new ImmutableBytesPtr(lockKey);
+                PSchema schema = loadSchema(env, lockKey, cacheKey, clientTimeStamp, clientTimeStamp);
+                if (schema != null) {
+                    if (schema.getTimeStamp() < clientTimeStamp) {
+                        builder.setReturnCode(MetaDataProtos.MutationCode.SCHEMA_ALREADY_EXISTS);
+                        builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
+                        builder.setSchema(PSchema.toProto(schema));
+                        done.run(builder.build());
+                        return;
+                    } else {
+                        builder.setReturnCode(MetaDataProtos.MutationCode.NEWER_SCHEMA_FOUND);
+                        builder.setMutationTime(EnvironmentEdgeManager.currentTimeMillis());
+                        builder.setSchema(PSchema.toProto(schema));
+                        done.run(builder.build());
+                        return;
+                    }
+                }
+                region.mutateRowsWithLocks(schemaMutations, Collections.<byte[]> emptySet(), HConstants.NO_NONCE,
+                        HConstants.NO_NONCE);
+
+                // Invalidate the cache - the next getSchema call will add it
+                Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache = GlobalCache.getInstance(this.env)
+                        .getMetaDataCache();
+                if (cacheKey != null) {
+                    metaDataCache.invalidate(cacheKey);
+                }
+
+                // Get timeStamp from mutations - the above method sets it if
+                // it's unset
+                long currentTimeStamp = MetaDataUtil.getClientTimeStamp(schemaMutations);
+                builder.setReturnCode(MetaDataProtos.MutationCode.SCHEMA_NOT_FOUND);
+                builder.setMutationTime(currentTimeStamp);
+                done.run(builder.build());
+                return;
+            } finally {
+                region.releaseRowLocks(locks);
+            }
+        } catch (Throwable t) {
+            logger.error("Creating the schema" + schemaName + "failed", t);
+            ProtobufUtil.setControllerException(controller, ServerUtil.createIOException(schemaName, t));
+        }
+    }
+
+    @Override
+    public void dropSchema(RpcController controller, DropSchemaRequest request, RpcCallback<MetaDataResponse> done) {
+        String schemaName = null;
+        try {
+            List<Mutation> schemaMetaData = ProtobufUtil.getMutations(request);
+            schemaName = request.getSchemaName();
+            byte[] lockKey = SchemaUtil.getSchemaKey(schemaName);
+            HRegion region = env.getRegion();
+            MetaDataMutationResult result = checkSchemaKeyInRegion(lockKey, region);
+            if (result != null) {
+                done.run(MetaDataMutationResult.toProto(result));
+                return;
+            }
+            List<RowLock> locks = Lists.newArrayList();
+            long clientTimeStamp = MetaDataUtil.getClientTimeStamp(schemaMetaData);
+            try {
+                acquireLock(region, lockKey, locks);
+                List<ImmutableBytesPtr> invalidateList = new ArrayList<ImmutableBytesPtr>(1);
+                result = doDropSchema(clientTimeStamp, schemaName, lockKey, schemaMetaData, invalidateList);
+                if (result.getMutationCode() != MutationCode.SCHEMA_ALREADY_EXISTS) {
+                    done.run(MetaDataMutationResult.toProto(result));
+                    return;
+                }
+                region.mutateRowsWithLocks(schemaMetaData, Collections.<byte[]> emptySet(), HConstants.NO_NONCE,
+                        HConstants.NO_NONCE);
+                Cache<ImmutableBytesPtr, PMetaDataEntity> metaDataCache = GlobalCache.getInstance(this.env)
+                        .getMetaDataCache();
+                long currentTime = MetaDataUtil.getClientTimeStamp(schemaMetaData);
+                for (ImmutableBytesPtr ptr : invalidateList) {
+                    metaDataCache.invalidate(ptr);
+                    metaDataCache.put(ptr, newDeletedSchemaMarker(currentTime));
+                }
+                done.run(MetaDataMutationResult.toProto(result));
+                return;
+            } finally {
+                region.releaseRowLocks(locks);
+            }
+        } catch (Throwable t) {
+            logger.error("drop schema failed:", t);
+            ProtobufUtil.setControllerException(controller, ServerUtil.createIOException(schemaName, t));
+        }
+    }
+
+    private MetaDataMutationResult doDropSchema(long clientTimeStamp, String schemaName, byte[] key,
+            List<Mutation> schemaMutations, List<ImmutableBytesPtr> invalidateList) throws IOException, SQLException {
+        PSchema schema = loadSchema(env, key, new ImmutableBytesPtr(key), clientTimeStamp, clientTimeStamp);
+        boolean areTablesExists = false;
+        if (schema == null) { return new MetaDataMutationResult(MutationCode.SCHEMA_NOT_FOUND,
+                EnvironmentEdgeManager.currentTimeMillis(), null); }
+        if (schema.getTimeStamp() < clientTimeStamp) {
+            HRegion region = env.getRegion();
+            Scan scan = MetaDataUtil.newTableRowsScan(SchemaUtil.getKeyForSchema(null, schemaName), MIN_TABLE_TIMESTAMP,
+                    clientTimeStamp);
+            List<Cell> results = Lists.newArrayList();
+            try (RegionScanner scanner = region.getScanner(scan);) {
+                scanner.next(results);
+                if (results.isEmpty()) { // Should not be possible
+                    return new MetaDataMutationResult(MutationCode.SCHEMA_NOT_FOUND,
+                            EnvironmentEdgeManager.currentTimeMillis(), null);
+                }
+                do {
+                    Cell kv = results.get(0);
+                    if (Bytes.compareTo(kv.getRowArray(), kv.getRowOffset(), kv.getRowLength(), key, 0,
+                            key.length) != 0) {
+                        areTablesExists = true;
+                        break;
+                    }
+                    results.clear();
+                    scanner.next(results);
+                } while (!results.isEmpty());
+            }
+            if (areTablesExists) { return new MetaDataMutationResult(MutationCode.TABLES_EXIST_ON_SCHEMA, schema,
+                    EnvironmentEdgeManager.currentTimeMillis()); }
+
+            return new MetaDataMutationResult(MutationCode.SCHEMA_ALREADY_EXISTS, schema,
+                    EnvironmentEdgeManager.currentTimeMillis());
+        }
+        return new MetaDataMutationResult(MutationCode.SCHEMA_NOT_FOUND, EnvironmentEdgeManager.currentTimeMillis(),
+                null);
+
+    }
+
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
index f8b4c79..0ebcd64 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
@@ -28,6 +28,7 @@ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.MetaDataService;
 import org.apache.phoenix.coprocessor.generated.PFunctionProtos;
 import org.apache.phoenix.hbase.index.util.VersionUtil;
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PColumnImpl;
 import org.apache.phoenix.schema.PName;
@@ -78,8 +79,9 @@ public abstract class MetaDataProtocol extends MetaDataService {
     public static final long MIN_SYSTEM_TABLE_TIMESTAMP_4_5_0 = MIN_TABLE_TIMESTAMP + 8;
     public static final long MIN_SYSTEM_TABLE_TIMESTAMP_4_6_0 = MIN_TABLE_TIMESTAMP + 9;
     public static final long MIN_SYSTEM_TABLE_TIMESTAMP_4_7_0 = MIN_TABLE_TIMESTAMP + 15;
+    public static final long MIN_SYSTEM_TABLE_TIMESTAMP_4_8_0 = MIN_TABLE_TIMESTAMP + 16;
     // MIN_SYSTEM_TABLE_TIMESTAMP needs to be set to the max of all the MIN_SYSTEM_TABLE_TIMESTAMP_* constants
-    public static final long MIN_SYSTEM_TABLE_TIMESTAMP = MIN_SYSTEM_TABLE_TIMESTAMP_4_7_0;
+    public static final long MIN_SYSTEM_TABLE_TIMESTAMP = MIN_SYSTEM_TABLE_TIMESTAMP_4_8_0;
     // TODO: pare this down to minimum, as we don't need duplicates for both table and column errors, nor should we need
     // a different code for every type of error.
     // ENTITY_ALREADY_EXISTS, ENTITY_NOT_FOUND, NEWER_ENTITY_FOUND, ENTITY_NOT_IN_REGION, CONCURRENT_MODIFICATION
@@ -99,6 +101,12 @@ public abstract class MetaDataProtocol extends MetaDataService {
         FUNCTION_NOT_FOUND,
         NEWER_FUNCTION_FOUND,
         FUNCTION_NOT_IN_REGION,
+        SCHEMA_ALREADY_EXISTS, 
+        NEWER_SCHEMA_FOUND,
+        SCHEMA_NOT_FOUND,
+        SCHEMA_NOT_IN_REGION,
+        TABLES_EXIST_ON_SCHEMA,
+        UNALLOWED_SCHEMA_MUTATION,
         NO_OP
     };
 
@@ -176,6 +184,8 @@ public abstract class MetaDataProtocol extends MetaDataService {
         private byte[] columnName;
         private byte[] familyName;
         private boolean wasUpdated;
+        private PSchema schema;
+
         private List<PFunction> functions = new ArrayList<PFunction>(1);
 
         public MetaDataMutationResult() {
@@ -200,6 +210,12 @@ public abstract class MetaDataProtocol extends MetaDataService {
             this.wasUpdated = wasUpdated;
          }
 
+        public MetaDataMutationResult(MutationCode returnCode, PSchema schema, long currentTime) {
+            this.returnCode = returnCode;
+            this.mutationTime = currentTime;
+            this.schema = schema;
+        }
+
         // For testing, so that connectionless can set wasUpdated so ColumnResolver doesn't complain
         public MetaDataMutationResult(MutationCode returnCode, long currentTime, PTable table, boolean wasUpdated) {
             this(returnCode, currentTime, table, Collections.<byte[]> emptyList());
@@ -297,6 +313,9 @@ public abstract class MetaDataProtocol extends MetaDataService {
                 result.sharedTablesToDelete.add(new SharedTableState(sharedTable));
                 }
           }
+          if (proto.hasSchema()) {
+            result.schema = PSchema.createFromProto(proto.getSchema());
+          }
           return result;
         }
 
@@ -340,8 +359,15 @@ public abstract class MetaDataProtocol extends MetaDataService {
                 builder.addSharedTablesToDelete(sharedTableStateBuilder.build());
               }
             }
+            if (result.getSchema() != null) {
+              builder.setSchema(PSchema.toProto(result.schema));
+            }
           }
           return builder.build();
         }
+
+        public PSchema getSchema() {
+            return schema;
+        }
     }
 }


[51/52] [abbrv] phoenix git commit: Changes to AlterTableIT

Posted by sa...@apache.org.
Changes to AlterTableIT


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

Branch: refs/heads/encodecolumns
Commit: ba8d6abbc0812d486e3537c122ac20b88376adbb
Parents: 390bd39
Author: Samarth <sa...@salesforce.com>
Authored: Mon Apr 25 11:49:49 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:32 2016 -0700

----------------------------------------------------------------------
 .../apache/phoenix/end2end/AlterTableIT.java    | 104 +++++++++----------
 1 file changed, 51 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/ba8d6abb/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index ca1f8cf..900a040 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -2226,59 +2226,57 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
 	}
 	
 	@Test
-    public void testClientAndServerMetadataForEncodedColumns() throws Exception {
-        String schemaName = "XYZ";
-        String baseTableName = "testClientAndServerMetadataForEncodedColumns".toUpperCase();
-        String viewName = "VIEW1";
-        String fullTableName = schemaName + "." + baseTableName;
-        String fullViewName = schemaName + "." + viewName;
-        for (int i = 0; i < 2; i++) {
-            try (Connection conn = DriverManager.getConnection(getUrl())) {
-                PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
-                conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + fullTableName + " ("
-                        + " ID char(1) NOT NULL,"
-                        + " COL1 integer NOT NULL,"
-                        + " COL2 bigint NOT NULL,"
-                        + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
-                        + " )");
-                PTable baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
-                long initBaseTableSeqNumber = baseTable.getSequenceNumber(); 
-
-                // assert that the client side cache is updated.
-                Map<String, Integer> cqCounters = baseTable.getEncodedCQCounters();
-                assertEquals(1, cqCounters.size());
-                int counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
-                assertEquals(1, counter);
-
-                // assert that the server side metadata is updated correctly.
-                assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 1);
-                assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber);
-
-                // now create a view and validate client and server side metadata
-                String viewDDL = "CREATE VIEW " + fullViewName + " ( VIEW_COL1 INTEGER, A.VIEW_COL2 VARCHAR ) AS SELECT * FROM " + fullTableName;
-                conn.createStatement().execute(viewDDL);
-                baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
-                PTable view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
-
-                // verify that the client side cache is updated. Base table's cq counters should be updated.
-                cqCounters = baseTable.getEncodedCQCounters();
-                counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
-                assertEquals(2, counter);
-                counter = cqCounters.get("A");
-                assertEquals(2, counter);
-                cqCounters = view.getEncodedCQCounters();
-                assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
-
-                // assert that the server side metadata for the base table and the view is also updated correctly.
-                assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 2);
-                assertEncodedCQCounter("A", schemaName, baseTableName, 2);
-                assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "VIEW_COL1", schemaName, viewName, 1);
-                assertEncodedCQValue("A", "VIEW_COL2", schemaName, viewName, 1);
-                assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 1);
-                assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM);
-            }
-        }
-    }
+	public void testClientAndServerMetadataForEncodedColumns() throws Exception {
+	    String schemaName = "XYZ";
+	    String baseTableName = "testClientAndServerMetadataForEncodedColumns".toUpperCase();
+	    String viewName = "VIEW1";
+	    String fullTableName = schemaName + "." + baseTableName;
+	    String fullViewName = schemaName + "." + viewName;
+	    try (Connection conn = DriverManager.getConnection(getUrl())) {
+	        PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
+	        conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + fullTableName + " ("
+	                + " ID char(1) NOT NULL,"
+	                + " COL1 integer NOT NULL,"
+	                + " COL2 bigint NOT NULL,"
+	                + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
+	                + " )");
+	        PTable baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+	        long initBaseTableSeqNumber = baseTable.getSequenceNumber(); 
+
+	        // assert that the client side cache is updated.
+	        Map<String, Integer> cqCounters = baseTable.getEncodedCQCounters();
+	        assertEquals(1, cqCounters.size());
+	        int counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+	        assertEquals(1, counter);
+
+	        // assert that the server side metadata is updated correctly.
+	        assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 1);
+	        assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber);
+
+	        // now create a view and validate client and server side metadata
+	        String viewDDL = "CREATE VIEW " + fullViewName + " ( VIEW_COL1 INTEGER, A.VIEW_COL2 VARCHAR ) AS SELECT * FROM " + fullTableName;
+	        conn.createStatement().execute(viewDDL);
+	        baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+	        PTable view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
+
+	        // verify that the client side cache is updated. Base table's cq counters should be updated.
+	        cqCounters = baseTable.getEncodedCQCounters();
+	        counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+	        assertEquals(2, counter);
+	        counter = cqCounters.get("A");
+	        assertEquals(2, counter);
+	        cqCounters = view.getEncodedCQCounters();
+	        assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
+
+	        // assert that the server side metadata for the base table and the view is also updated correctly.
+	        assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 2);
+	        assertEncodedCQCounter("A", schemaName, baseTableName, 2);
+	        assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "VIEW_COL1", schemaName, viewName, 1);
+	        assertEncodedCQValue("A", "VIEW_COL2", schemaName, viewName, 1);
+	        assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 1);
+	        assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM);
+	    }
+	}
 	
 	@Test
     public void testAddingColumnsToTablesAndViewsWithEncodedColumns() throws Exception {


[18/52] [abbrv] phoenix git commit: PHOENIX-1311 HBase namespaces surfaced in phoenix

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
index 523f684..dbc65d4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
@@ -41,7 +41,9 @@ import java.util.TreeSet;
 
 import javax.annotation.Nullable;
 
+import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.exception.SQLExceptionCode;
@@ -52,14 +54,19 @@ import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.query.QueryServicesOptions;
 import org.apache.phoenix.schema.AmbiguousColumnException;
 import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
 import org.apache.phoenix.schema.ColumnNotFoundException;
+import org.apache.phoenix.schema.MetaDataClient;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PColumnFamily;
 import org.apache.phoenix.schema.PDatum;
 import org.apache.phoenix.schema.PName;
+import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.RowKeySchema;
 import org.apache.phoenix.schema.RowKeySchema.RowKeySchemaBuilder;
 import org.apache.phoenix.schema.SaltingUtil;
@@ -115,6 +122,10 @@ public class SchemaUtil {
         
     };
     public static final RowKeySchema VAR_BINARY_SCHEMA = new RowKeySchemaBuilder(1).addField(VAR_BINARY_DATUM, false, SortOrder.getDefault()).build();
+    public static final String SCHEMA_FOR_DEFAULT_NAMESPACE = "DEFAULT";
+    public static final String HBASE_NAMESPACE = "HBASE";
+    public static final List<String> NOT_ALLOWED_SCHEMA_LIST = Arrays.asList(SCHEMA_FOR_DEFAULT_NAMESPACE,
+            HBASE_NAMESPACE);
     
     /**
      * May not be instantiated
@@ -236,6 +247,12 @@ public class SchemaUtil {
         return ByteUtil.concat(tenantId, QueryConstants.SEPARATOR_BYTE_ARRAY, functionName);
     }
 
+    public static byte[] getKeyForSchema(String tenantId, String schemaName) {
+        return ByteUtil.concat(tenantId == null ? ByteUtil.EMPTY_BYTE_ARRAY : Bytes.toBytes(tenantId),
+                QueryConstants.SEPARATOR_BYTE_ARRAY,
+                schemaName == null ? ByteUtil.EMPTY_BYTE_ARRAY : Bytes.toBytes(schemaName));
+    }
+
     public static byte[] getTableKey(String tenantId, String schemaName, String tableName) {
         return ByteUtil.concat(tenantId == null  ? ByteUtil.EMPTY_BYTE_ARRAY : Bytes.toBytes(tenantId), QueryConstants.SEPARATOR_BYTE_ARRAY, schemaName == null ? ByteUtil.EMPTY_BYTE_ARRAY : Bytes.toBytes(schemaName), QueryConstants.SEPARATOR_BYTE_ARRAY, Bytes.toBytes(tableName));
     }
@@ -253,6 +270,11 @@ public class SchemaUtil {
         return cf + QueryConstants.NAME_SEPARATOR + cq;
     }
 
+    private static String getName(String name, boolean caseSensitive) {
+        String cq = caseSensitive ? "\"" + name + "\"" : name;
+        return cq;
+    }
+
     public static String getTableName(byte[] schemaName, byte[] tableName) {
         return getName(schemaName, tableName);
     }
@@ -276,9 +298,13 @@ public class SchemaUtil {
             }
             return getName(familyName, columnName, false);
         }
+        if ((familyName == null || familyName.isEmpty()) && (columnName == null || columnName.isEmpty())
+                && (tableName == null || tableName.equals(MetaDataClient.EMPTY_TABLE))) { return getName(schemaName,
+                        false); }
         if ((familyName == null || familyName.isEmpty()) && (columnName == null || columnName.isEmpty())) {
             return getName(schemaName, tableName, false);
         }
+
         return getName(getName(schemaName, tableName, false), getName(familyName, columnName, false), false);
     }
 
@@ -414,19 +440,24 @@ public class SchemaUtil {
     }
 
     public static boolean isMetaTable(byte[] tableName) {
-        return Bytes.compareTo(tableName, SYSTEM_CATALOG_NAME_BYTES) == 0;
+        return Bytes.compareTo(tableName, SYSTEM_CATALOG_NAME_BYTES) == 0 || Bytes.compareTo(tableName,
+                SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, true).getName()) == 0;
     }
 
     public static boolean isFunctionTable(byte[] tableName) {
-        return Bytes.compareTo(tableName, SYSTEM_FUNCTION_NAME_BYTES) == 0;
+        return Bytes.compareTo(tableName, SYSTEM_FUNCTION_NAME_BYTES) == 0 || Bytes.compareTo(tableName,
+                SchemaUtil.getPhysicalTableName(SYSTEM_FUNCTION_NAME_BYTES, true).getName()) == 0;
     }
 
     public static boolean isStatsTable(byte[] tableName) {
-        return Bytes.compareTo(tableName, SYSTEM_STATS_NAME_BYTES) == 0;
+        return Bytes.compareTo(tableName, SYSTEM_STATS_NAME_BYTES) == 0 || Bytes.compareTo(tableName,
+                SchemaUtil.getPhysicalTableName(SYSTEM_STATS_NAME_BYTES, true).getName()) == 0;
     }
-    
+
     public static boolean isSequenceTable(byte[] tableName) {
-        return Bytes.compareTo(tableName, PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES) == 0;
+        return Bytes.compareTo(tableName, PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES) == 0
+                || Bytes.compareTo(tableName, SchemaUtil
+                        .getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES, true).getName()) == 0;
     }
 
     public static boolean isSequenceTable(PTable table) {
@@ -564,9 +595,15 @@ public class SchemaUtil {
             return true;
         }
     }
-    
+
     public static String getSchemaNameFromFullName(String tableName) {
-        int index = tableName.indexOf(QueryConstants.NAME_SEPARATOR);
+        if (tableName
+                .contains(":")) { return getSchemaNameFromFullName(tableName, QueryConstants.NAMESPACE_SEPARATOR); }
+        return getSchemaNameFromFullName(tableName, QueryConstants.NAME_SEPARATOR);
+    }
+
+    public static String getSchemaNameFromFullName(String tableName, String separator) {
+        int index = tableName.indexOf(separator);
         if (index < 0) {
             return StringUtil.EMPTY_STRING; 
         }
@@ -588,7 +625,8 @@ public class SchemaUtil {
         }
         int index = indexOf(tableName, QueryConstants.NAME_SEPARATOR_BYTE);
         if (index < 0) {
-            return StringUtil.EMPTY_STRING; 
+            index = indexOf(tableName, QueryConstants.NAMESPACE_SEPARATOR_BYTE);
+            if (index < 0) { return StringUtil.EMPTY_STRING; }
         }
         return Bytes.toString(tableName, 0, index);
     }
@@ -599,13 +637,19 @@ public class SchemaUtil {
         }
         int index = indexOf(tableName, QueryConstants.NAME_SEPARATOR_BYTE);
         if (index < 0) {
-            return Bytes.toString(tableName); 
+            index = indexOf(tableName, QueryConstants.NAMESPACE_SEPARATOR_BYTE);
+            if (index < 0) { return Bytes.toString(tableName); }
         }
         return Bytes.toString(tableName, index+1, tableName.length - index - 1);
     }
 
     public static String getTableNameFromFullName(String tableName) {
-        int index = tableName.indexOf(QueryConstants.NAME_SEPARATOR);
+        if (tableName.contains(":")) { return getTableNameFromFullName(tableName, QueryConstants.NAMESPACE_SEPARATOR); }
+        return getTableNameFromFullName(tableName, QueryConstants.NAME_SEPARATOR);
+    }
+
+    public static String getTableNameFromFullName(String tableName, String separator) {
+        int index = tableName.indexOf(separator);
         if (index < 0) {
             return tableName; 
         }
@@ -615,7 +659,8 @@ public class SchemaUtil {
     public static byte[] getTableKeyFromFullName(String fullTableName) {
         int index = fullTableName.indexOf(QueryConstants.NAME_SEPARATOR);
         if (index < 0) {
-            return getTableKey(null, null, fullTableName); 
+            index = fullTableName.indexOf(QueryConstants.NAMESPACE_SEPARATOR);
+            if (index < 0) { return getTableKey(null, null, fullTableName); }
         }
         String schemaName = fullTableName.substring(0, index);
         String tableName = fullTableName.substring(index+1);
@@ -897,4 +942,78 @@ public class SchemaUtil {
         PName schemaName = dataTable.getSchemaName();
         return getTableKey(tenantId == null ? ByteUtil.EMPTY_BYTE_ARRAY : tenantId.getBytes(), schemaName == null ? ByteUtil.EMPTY_BYTE_ARRAY : schemaName.getBytes(), dataTable.getTableName().getBytes());
     }
+
+    public static byte[] getSchemaKey(String schemaName) {
+        return SchemaUtil.getTableKey(null, schemaName, MetaDataClient.EMPTY_TABLE);
+    }
+
+    public static PName getPhysicalHBaseTableName(PName pName, boolean isNamespaceMapped, PTableType type) {
+        return getPhysicalHBaseTableName(pName.toString(), isNamespaceMapped, type);
+    }
+
+    public static PName getPhysicalHBaseTableName(byte[] tableName, boolean isNamespaceMapped, PTableType type) {
+        return getPhysicalHBaseTableName(Bytes.toString(tableName), isNamespaceMapped, type);
+    }
+
+    public static TableName getPhysicalTableName(String fullTableName, ReadOnlyProps readOnlyProps) {
+        return getPhysicalName(Bytes.toBytes(fullTableName), readOnlyProps);
+    }
+
+    public static TableName getPhysicalTableName(byte[] fullTableName, Configuration conf) {
+        return getPhysicalTableName(fullTableName, isNamespaceMappingEnabled(
+                isSystemTable(fullTableName) ? PTableType.SYSTEM : null, new ReadOnlyProps(conf.iterator())));
+    }
+
+    public static TableName getPhysicalName(byte[] fullTableName, ReadOnlyProps readOnlyProps) {
+        return getPhysicalTableName(fullTableName,
+                isNamespaceMappingEnabled(isSystemTable(fullTableName) ? PTableType.SYSTEM : null, readOnlyProps));
+    }
+
+    public static TableName getPhysicalTableName(byte[] fullTableName, boolean isNamespaceMappingEnabled) {
+        if (indexOf(fullTableName, QueryConstants.NAMESPACE_SEPARATOR_BYTE) > 0
+                || !isNamespaceMappingEnabled) { return TableName.valueOf(fullTableName); }
+        String tableName = getTableNameFromFullName(fullTableName);
+        String schemaName = getSchemaNameFromFullName(fullTableName);
+        return TableName.valueOf(schemaName, tableName);
+    }
+
+    public static PName getPhysicalHBaseTableName(String tableName, boolean isNamespaceMapped, PTableType type) {
+        if (!isNamespaceMapped) { return PNameFactory.newName(tableName); }
+        return PNameFactory
+                .newName(tableName.replace(QueryConstants.NAME_SEPARATOR, QueryConstants.NAMESPACE_SEPARATOR));
+    }
+
+    public static boolean isSchemaCheckRequired(PTableType tableType, ReadOnlyProps props) {
+        return PTableType.TABLE.equals(tableType) && isNamespaceMappingEnabled(tableType, props);
+    }
+
+    public static boolean isNamespaceMappingEnabled(PTableType type, ReadOnlyProps readOnlyProps) {
+        return readOnlyProps.getBoolean(QueryServices.IS_NAMESPACE_MAPPING_ENABLED,
+                QueryServicesOptions.DEFAULT_IS_NAMESPACE_MAPPING_ENABLED)
+                && (type == null || !PTableType.SYSTEM.equals(type)
+                        || readOnlyProps.getBoolean(QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE,
+                                QueryServicesOptions.DEFAULT_IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE));
+    }
+
+    public static byte[] getParentTableNameFromIndexTable(byte[] physicalTableName, String indexPrefix) {
+        String tableName = Bytes.toString(physicalTableName);
+        return getParentTableNameFromIndexTable(tableName, indexPrefix).getBytes();
+    }
+
+    public static String getParentTableNameFromIndexTable(String physicalTableName, String indexPrefix) {
+        if (physicalTableName.contains(QueryConstants.NAMESPACE_SEPARATOR)) {
+            String schemaNameFromFullName = getSchemaNameFromFullName(physicalTableName,
+                    QueryConstants.NAMESPACE_SEPARATOR);
+            String tableNameFromFullName = getTableNameFromFullName(physicalTableName,
+                    QueryConstants.NAMESPACE_SEPARATOR);
+            return schemaNameFromFullName + QueryConstants.NAMESPACE_SEPARATOR
+                    + getStrippedName(tableNameFromFullName, indexPrefix);
+        }
+        return getStrippedName(physicalTableName, indexPrefix);
+    }
+
+    private static String getStrippedName(String physicalTableName, String indexPrefix) {
+        return physicalTableName.indexOf(indexPrefix) == 0 ? physicalTableName.substring(indexPrefix.length())
+                : physicalTableName;
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/util/UpgradeUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/UpgradeUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/UpgradeUtil.java
index de1a2c7..b82e0c1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/UpgradeUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/UpgradeUtil.java
@@ -28,8 +28,11 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.LINK_TYPE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ORDINAL_POSITION;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SORT_ORDER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TENANT_ID;
 import static org.apache.phoenix.query.QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT;
 import static org.apache.phoenix.query.QueryConstants.DIVERGED_VIEW_BASE_COLUMN_COUNT;
@@ -67,12 +70,17 @@ import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.ResultScanner;
 import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.coprocessor.MetaDataEndpointImpl;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
+import org.apache.phoenix.coprocessor.MetaDataProtocol.MetaDataMutationResult;
+import org.apache.phoenix.coprocessor.MetaDataProtocol.MutationCode;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.MetaDataClient;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
@@ -81,6 +89,7 @@ import org.apache.phoenix.schema.PTable.LinkType;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.SaltingUtil;
 import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.TableNotFoundException;
 import org.apache.phoenix.schema.types.PBinary;
 import org.apache.phoenix.schema.types.PBoolean;
 import org.apache.phoenix.schema.types.PChar;
@@ -124,6 +133,22 @@ public class UpgradeUtil {
             + "TABLE_NAME = ? "
             ;
     
+    private static final String UPDATE_LINK =
+            "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
+            TENANT_ID + "," +
+            TABLE_SCHEM + "," +
+            TABLE_NAME + "," +
+            COLUMN_FAMILY + "," +
+            LINK_TYPE + "," +
+            TABLE_SEQ_NUM +
+            ") SELECT " + TENANT_ID + "," + TABLE_SCHEM + "," + TABLE_NAME + ",'%s' AS "
+            + COLUMN_FAMILY + " ," + LINK_TYPE + "," + TABLE_SEQ_NUM + " FROM " + SYSTEM_CATALOG_SCHEMA + ".\""
+            + SYSTEM_CATALOG_TABLE + "\" WHERE  " + COLUMN_FAMILY + "=? AND " + LINK_TYPE + " = "
+            + LinkType.PHYSICAL_TABLE.getSerializedValue();
+
+    private static final String DELETE_LINK = "DELETE FROM " + SYSTEM_CATALOG_SCHEMA + "." + SYSTEM_CATALOG_TABLE
+            + " WHERE " + COLUMN_FAMILY + "=? AND " + LINK_TYPE + " = " + LinkType.PHYSICAL_TABLE.getSerializedValue();
+
     private UpgradeUtil() {
     }
 
@@ -1279,4 +1304,156 @@ public class UpgradeUtil {
         }
         return false;
     }
+
+    private static void mapTableToNamespace(HBaseAdmin admin, HTableInterface metatable, String srcTableName,
+            String destTableName, ReadOnlyProps props, Long ts, String phoenixTableName, PTableType pTableType)
+                    throws SnapshotCreationException, IllegalArgumentException, IOException, InterruptedException,
+                    SQLException {
+        srcTableName = SchemaUtil.normalizeIdentifier(srcTableName);
+        if (!SchemaUtil.isNamespaceMappingEnabled(pTableType,
+                props)) { throw new IllegalArgumentException(SchemaUtil.isSystemTable(srcTableName.getBytes())
+                        ? "For system table " + QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE
+                                + " also needs to be enabled along with " + QueryServices.IS_NAMESPACE_MAPPING_ENABLED
+                        : QueryServices.IS_NAMESPACE_MAPPING_ENABLED + " is not enabled"); }
+        // we need to move physical table in actual namespace for TABLE and Index
+        if (admin.tableExists(srcTableName) && (PTableType.TABLE.equals(pTableType)
+                || PTableType.INDEX.equals(pTableType) || PTableType.SYSTEM.equals(pTableType))) {
+            String snapshotName = QueryConstants.UPGRADE_TABLE_SNAPSHOT_PREFIX + srcTableName;
+            logger.info("Disabling table " + srcTableName + " ..");
+            admin.disableTable(srcTableName);
+            logger.info(String.format("Taking snapshot %s of table %s..", snapshotName, srcTableName));
+            admin.snapshot(snapshotName, srcTableName);
+            logger.info(String.format("Restoring snapshot %s in destination table %s..", snapshotName, destTableName));
+            admin.cloneSnapshot(Bytes.toBytes(snapshotName), Bytes.toBytes(destTableName));
+            logger.info(String.format("deleting old table %s..", srcTableName));
+            admin.deleteTable(srcTableName);
+            logger.info(String.format("deleting snapshot %s..", snapshotName));
+            admin.deleteSnapshot(snapshotName);
+        }
+        // Update flag to represent table is mapped to namespace
+        logger.info(String.format("Updating meta information of phoenix table '%s' to map to namespace..", phoenixTableName));
+        Put put = new Put(SchemaUtil.getTableKey(null, SchemaUtil.getSchemaNameFromFullName(phoenixTableName),
+                SchemaUtil.getTableNameFromFullName(phoenixTableName)), ts);
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, PhoenixDatabaseMetaData.IS_NAMESPACE_MAPPED_BYTES,
+                PBoolean.INSTANCE.toBytes(Boolean.TRUE));
+        metatable.put(put);
+    }
+
+    /*
+     * Method to map existing phoenix table to a namespace. Should not be use if tables has views and indexes ,instead
+     * use map table utility in psql.py
+     */
+    public static void mapTableToNamespace(HBaseAdmin admin, HTableInterface metatable, String tableName,
+            ReadOnlyProps props, Long ts, PTableType pTableType) throws SnapshotCreationException,
+                    IllegalArgumentException, IOException, InterruptedException, SQLException {
+        String destTablename = SchemaUtil
+                .normalizeIdentifier(SchemaUtil.getPhysicalTableName(tableName, props).getNameAsString());
+        mapTableToNamespace(admin, metatable, tableName, destTablename, props, ts, tableName, pTableType);
+    }
+
+    public static void upgradeTable(PhoenixConnection conn, String srcTable) throws SQLException,
+            SnapshotCreationException, IllegalArgumentException, IOException, InterruptedException {
+        ReadOnlyProps readOnlyProps = conn.getQueryServices().getProps();
+        if (conn.getClientInfo(PhoenixRuntime.TENANT_ID_ATTRIB) != null) { throw new SQLException(
+                "May not specify the TENANT_ID_ATTRIB property when upgrading"); }
+        if (conn.getSchema() != null) { throw new IllegalArgumentException(
+                "Schema should not be set for connection!!"); }
+        try (HBaseAdmin admin = conn.getQueryServices().getAdmin();
+                HTableInterface metatable = conn.getQueryServices()
+                        .getTable(SchemaUtil
+                                .getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES, readOnlyProps)
+                                .getName());) {
+            String tableName = SchemaUtil.normalizeIdentifier(srcTable);
+            String schemaName = SchemaUtil.getSchemaNameFromFullName(tableName);
+
+            // Upgrade is not required if schemaName is not present.
+            if (schemaName.equals("")) { throw new IllegalArgumentException("Table doesn't have schema name"); }
+
+            // Confirm table is not already upgraded
+            PTable table = PhoenixRuntime.getTable(conn, tableName);
+            if (table.isNamespaceMapped()) { throw new IllegalArgumentException("Table is already upgraded"); }
+            logger.info(String.format("Creating schema %s..", schemaName));
+            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName);
+            String newPhysicalTablename = SchemaUtil.normalizeIdentifier(SchemaUtil
+                    .getPhysicalTableName(table.getPhysicalName().getString(), readOnlyProps).getNameAsString());
+            logger.info(String.format("Upgrading %s %s..", table.getType(), tableName));
+            // Upgrade the data or main table
+            mapTableToNamespace(admin, metatable, tableName, newPhysicalTablename, readOnlyProps,
+                    PhoenixRuntime.getCurrentScn(readOnlyProps), tableName, table.getType());
+
+            // clear the cache and get new table
+            conn.getQueryServices().clearTableFromCache(ByteUtil.EMPTY_BYTE_ARRAY, table.getSchemaName().getBytes(),
+                    table.getTableName().getBytes(), PhoenixRuntime.getCurrentScn(readOnlyProps));
+            MetaDataMutationResult result = new MetaDataClient(conn).updateCache(schemaName,
+                    SchemaUtil.getTableNameFromFullName(tableName));
+            if (result.getMutationCode() != MutationCode.TABLE_ALREADY_EXISTS) { throw new TableNotFoundException(
+                    tableName); }
+            table = result.getTable();
+            // check whether table is properly upgraded before upgrading indexes
+            if (table.isNamespaceMapped()) {
+                for (PTable index : table.getIndexes()) {
+                    String srcTableName = index.getPhysicalName().getString();
+                    if (srcTableName.contains(QueryConstants.NAMESPACE_SEPARATOR)
+                            || (!MetaDataUtil.isViewIndex(srcTableName) && PTableType.VIEW.equals(table.getType()))) {
+                        // this condition occurs in case of multiple views on same table
+                        // as all view indexes uses the same physical table, so if one view is already migrated then we
+                        // can skip migrating the physical table again
+                        logger.info(String.format("skipping as it seems index '%s' is already upgraded..", index.getName()));
+                        continue;
+                    }
+                    String destTableName = null;
+                    String phoenixTableName = index.getName().getString();
+                    boolean updateLink = false;
+                    if (MetaDataUtil.isLocalIndex(srcTableName)) {
+                        logger.info(String.format("local index '%s' found with physical hbase table name ''..",
+                                index.getName(), srcTableName));
+                        destTableName = Bytes
+                                .toString(MetaDataUtil.getLocalIndexPhysicalName(newPhysicalTablename.getBytes()));
+                        // update parent_table property in local index table descriptor
+                        conn.createStatement()
+                                .execute(String.format("ALTER TABLE %s set " + MetaDataUtil.PARENT_TABLE_KEY + "='%s'",
+                                        phoenixTableName, table.getPhysicalName()));
+                        updateLink = true;
+                    } else if (MetaDataUtil.isViewIndex(srcTableName)) {
+                        logger.info(String.format("View index '%s' found with physical hbase table name ''..",
+                                index.getName(), srcTableName));
+                        destTableName = Bytes
+                                .toString(MetaDataUtil.getViewIndexPhysicalName(newPhysicalTablename.getBytes()));
+                        updateLink = true;
+                    } else {
+                        logger.info(String.format("Global index '%s' found with physical hbase table name ''..",
+                                index.getName(), srcTableName));
+                        destTableName = SchemaUtil
+                                .getPhysicalTableName(index.getPhysicalName().getString(), readOnlyProps)
+                                .getNameAsString();
+                    }
+                    logger.info(String.format("Upgrading index %s..", index.getName()));
+                    mapTableToNamespace(admin, metatable, srcTableName, destTableName, readOnlyProps,
+                            PhoenixRuntime.getCurrentScn(readOnlyProps), phoenixTableName, index.getType());
+                    if (updateLink) {
+                        logger.info(String.format("Updating link information for index '%s' ..", index.getName()));
+                        updateLink(conn, srcTableName, destTableName);
+                    }
+                    conn.getQueryServices().clearTableFromCache(ByteUtil.EMPTY_BYTE_ARRAY,
+                            index.getSchemaName().getBytes(), index.getTableName().getBytes(),
+                            PhoenixRuntime.getCurrentScn(readOnlyProps));
+                }
+
+            } else {
+                throw new RuntimeException("Error: problem occured during upgrade. Table is not upgraded successfully");
+            }
+        }
+    }
+
+    private static void updateLink(PhoenixConnection conn, String srcTableName, String destTableName)
+            throws SQLException {
+        PreparedStatement deleteLinkStatment = conn.prepareStatement(DELETE_LINK);
+        deleteLinkStatment.setString(1, srcTableName);
+        PreparedStatement updateLinkStatment = conn.prepareStatement(String.format(UPDATE_LINK, destTableName));
+        updateLinkStatment.setString(1, srcTableName);
+        deleteLinkStatment.execute();
+        updateLinkStatment.execute();
+        conn.commit();
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
index 6d0930d..4660e38 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
@@ -256,7 +256,7 @@ public class CorrelatePlanTest {
                     PTableType.SUBQUERY, null, MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM,
                     null, null, columns, null, null, Collections.<PTable>emptyList(),
                     false, Collections.<PName>emptyList(), null, null, false, false, false, null,
-                    null, null, true, false, 0, 0L);
+                    null, null, true, false, 0, 0L, Boolean.FALSE);
             TableRef sourceTable = new TableRef(pTable);
             List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> newArrayList();
             for (PColumn column : sourceTable.getTable().getColumns()) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
index 8ecf0ee..aba4be4 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
@@ -177,7 +177,7 @@ public class LiteralResultIteratorPlanTest {
             PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,
                     MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM, null, null, columns, null, null,
                     Collections.<PTable> emptyList(), false, Collections.<PName> emptyList(), null, null, false, false,
-                    false, null, null, null, true, false, 0, 0L);
+                    false, null, null, null, true, false, 0, 0L, false);
             TableRef sourceTable = new TableRef(pTable);
             List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> newArrayList();
             for (PColumn column : sourceTable.getTable().getColumns()) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
index e3bd4a0..d8651ae 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
@@ -118,9 +118,7 @@ import java.util.concurrent.TimeoutException;
 
 import javax.annotation.Nonnull;
 
-
 import org.apache.commons.lang.RandomStringUtils;
-
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
@@ -128,7 +126,6 @@ import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.IntegrationTestingUtility;
-import org.apache.hadoop.hbase.RandomStringGeneratorImpl;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
@@ -147,6 +144,7 @@ import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.exception.SQLExceptionInfo;
 import org.apache.phoenix.hbase.index.balancer.IndexLoadBalancer;
 import org.apache.phoenix.hbase.index.master.IndexMasterObserver;
+import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.jdbc.PhoenixDriver;
 import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver;
@@ -829,6 +827,7 @@ public abstract class BaseTest {
 
     protected static void ensureTableCreated(String url, String tableName, byte[][] splits, Long ts) throws SQLException {
         String ddl = tableDDLMap.get(tableName);
+        createSchema(url,tableName, ts);
         createTestTable(url, ddl, splits, ts);
     }
 
@@ -843,7 +842,23 @@ public abstract class BaseTest {
     protected static void createTestTable(String url, String ddl, byte[][] splits, Long ts) throws SQLException {
         createTestTable(url, ddl, splits, ts, true);
     }
-    
+
+    public static void createSchema(String url, String tableName, Long ts) throws SQLException {
+        String schema = SchemaUtil.getSchemaNameFromFullName(tableName);
+        if (!schema.equals("")) {
+            Properties props = new Properties();
+            if (ts != null) {
+                props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
+            }
+            try (Connection conn = DriverManager.getConnection(url, props);) {
+                if (SchemaUtil.isNamespaceMappingEnabled(null,
+                        conn.unwrap(PhoenixConnection.class).getQueryServices().getProps())) {
+                    conn.createStatement().executeUpdate("CREATE SCHEMA IF NOT EXISTS " + schema);
+                }
+            }
+        }
+    }
+
     protected static void createTestTable(String url, String ddl, byte[][] splits, Long ts, boolean swallowTableAlreadyExistsException) throws SQLException {
         assertNotNull(ddl);
         StringBuilder buf = new StringBuilder(ddl);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java
index ff06ff9..47101b2 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java
@@ -54,6 +54,7 @@ import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
 import org.apache.phoenix.parse.FilterableStatement;
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.parse.SelectStatement;
 import org.apache.phoenix.schema.ColumnRef;
 import org.apache.phoenix.schema.PDatum;
@@ -348,6 +349,16 @@ public class ParallelIteratorsSplitTest extends BaseConnectionlessQueryTest {
             public boolean hasUDFs() {
                 return false;
             }
+
+            @Override
+            public PSchema resolveSchema(String schemaName) throws SQLException {
+                return null;
+            }
+
+            @Override
+            public List<PSchema> getSchemas() {
+                return null;
+            }
         };
         PhoenixConnection connection = DriverManager.getConnection(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).unwrap(PhoenixConnection.class);
         final PhoenixStatement statement = new PhoenixStatement(connection);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/test/java/org/apache/phoenix/util/JDBCUtilTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/JDBCUtilTest.java b/phoenix-core/src/test/java/org/apache/phoenix/util/JDBCUtilTest.java
index 74b397f..8c270c3 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/JDBCUtilTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/JDBCUtilTest.java
@@ -21,6 +21,7 @@ import static org.apache.phoenix.util.PhoenixRuntime.ANNOTATION_ATTRIB_PREFIX;
 import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.Map;
@@ -89,6 +90,13 @@ public class JDBCUtilTest {
     }
 
     @Test
+    public void testSchema() {
+        assertTrue(JDBCUtil.getSchema("localhost;schema=TEST", new Properties(), null).equals("TEST"));
+        assertNull(JDBCUtil.getSchema("localhost;schema=", new Properties(), null));
+        assertNull(JDBCUtil.getSchema("localhost;", new Properties(), null));
+    }
+
+    @Test
     public void testGetAutoCommit_TrueInProperties() {
         Properties props = new Properties();
         props.setProperty("AutoCommit", "true");

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-protocol/src/main/MetaDataService.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/MetaDataService.proto b/phoenix-protocol/src/main/MetaDataService.proto
index d1dcf9a..9d7b209 100644
--- a/phoenix-protocol/src/main/MetaDataService.proto
+++ b/phoenix-protocol/src/main/MetaDataService.proto
@@ -26,6 +26,7 @@ option optimize_for = SPEED;
 
 import "PTable.proto";
 import "PFunction.proto";
+import "PSchema.proto";
 
 enum MutationCode {
   TABLE_ALREADY_EXISTS = 0;
@@ -42,6 +43,12 @@ enum MutationCode {
   FUNCTION_NOT_FOUND = 11;
   NEWER_FUNCTION_FOUND = 12;
   FUNCTION_NOT_IN_REGION = 13;
+  SCHEMA_ALREADY_EXISTS = 14;
+  NEWER_SCHEMA_FOUND = 15;
+  SCHEMA_NOT_FOUND = 16;
+  SCHEMA_NOT_IN_REGION = 17;
+  TABLES_EXIST_ON_SCHEMA = 18;
+  UNALLOWED_SCHEMA_MUTATION = 19;
 };
 
 message SharedTableState {
@@ -63,6 +70,7 @@ message MetaDataResponse {
   optional bytes functionName = 7;
   repeated PFunction function = 8;
   repeated SharedTableState sharedTablesToDelete = 9;
+  optional PSchema schema = 10;
 }
 
 message GetTableRequest {
@@ -82,6 +90,12 @@ message GetFunctionsRequest {
   optional int32 clientVersion = 5;
 }
 
+message GetSchemaRequest {
+  required string schemaName = 1;
+  required int64 clientTimestamp = 2;
+  required int32 clientVersion = 3;
+}
+
 // each byte array represents a MutationProto instance
 message CreateTableRequest {
   repeated bytes tableMetadataMutations = 1;
@@ -96,6 +110,12 @@ message CreateFunctionRequest {
   optional int32 clientVersion = 4;
 }
 
+message CreateSchemaRequest {
+  repeated bytes tableMetadataMutations = 1;
+  required string schemaName = 2;
+  required int32 clientVersion = 3;
+}
+
 message DropTableRequest {
   repeated bytes tableMetadataMutations = 1;
   required string tableType = 2;
@@ -103,6 +123,12 @@ message DropTableRequest {
   optional int32 clientVersion = 4;
 }
 
+message DropSchemaRequest {
+  repeated bytes schemaMetadataMutations = 1;
+  required string schemaName = 2;
+  required int32 clientVersion = 3;
+}
+
 message AddColumnRequest {
   repeated bytes tableMetadataMutations = 1;
   optional int32 clientVersion = 2;
@@ -158,15 +184,24 @@ service MetaDataService {
   rpc getFunctions(GetFunctionsRequest)
     returns (MetaDataResponse);
 
+  rpc getSchema(GetSchemaRequest)
+    returns (MetaDataResponse);
+
   rpc createTable(CreateTableRequest)
     returns (MetaDataResponse);
 
   rpc createFunction(CreateFunctionRequest)
     returns (MetaDataResponse);
-    
+
+  rpc createSchema(CreateSchemaRequest)
+	 returns (MetaDataResponse);
+
   rpc dropTable(DropTableRequest)
     returns (MetaDataResponse);
-    
+
+  rpc dropSchema(DropSchemaRequest)
+    returns (MetaDataResponse);
+
   rpc dropFunction(DropFunctionRequest)
     returns (MetaDataResponse);
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-protocol/src/main/PSchema.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PSchema.proto b/phoenix-protocol/src/main/PSchema.proto
new file mode 100644
index 0000000..91e12f59
--- /dev/null
+++ b/phoenix-protocol/src/main/PSchema.proto
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+option java_package = "org.apache.phoenix.coprocessor.generated";
+option java_outer_classname = "PSchemaProtos";
+option java_generic_services = true;
+option java_generate_equals_and_hash = true;
+option optimize_for = SPEED;
+
+message PSchema {
+  required string schemaName = 1;
+  required int64 timeStamp = 2;
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-protocol/src/main/PTable.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PTable.proto b/phoenix-protocol/src/main/PTable.proto
index 09bdeb6..c86f6b6 100644
--- a/phoenix-protocol/src/main/PTable.proto
+++ b/phoenix-protocol/src/main/PTable.proto
@@ -90,4 +90,5 @@ message PTable {
   optional bool transactional = 27;
   optional int64 updateCacheFrequency = 28;
   optional int64 indexDisableTimestamp = 29;
+  optional bool isNamespaceMapped = 30;
 }


[34/52] [abbrv] phoenix git commit: PHOENIX-2846 Fix CreateTableIT.testCreateTableWithoutSchema()

Posted by sa...@apache.org.
PHOENIX-2846 Fix CreateTableIT.testCreateTableWithoutSchema()


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

Branch: refs/heads/encodecolumns
Commit: 4d5c4123840784db1e413cd2ed6258a6635a5221
Parents: f4c84a8
Author: James Taylor <ja...@apache.org>
Authored: Fri Apr 22 16:54:52 2016 -0700
Committer: James Taylor <ja...@apache.org>
Committed: Fri Apr 22 18:56:22 2016 -0700

----------------------------------------------------------------------
 .../org/apache/phoenix/end2end/CreateTableIT.java    | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/4d5c4123/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
index af25373..30bdb41 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
@@ -42,7 +42,9 @@ import org.apache.phoenix.schema.NewerTableAlreadyExistsException;
 import org.apache.phoenix.schema.SchemaNotFoundException;
 import org.apache.phoenix.schema.TableAlreadyExistsException;
 import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.TestUtil;
 import org.junit.Test;
 
 
@@ -468,11 +470,13 @@ public class CreateTableIT extends BaseClientManagedTimeIT {
 
     @Test
     public void testCreateTableWithoutSchema() throws Exception {
+        long ts = nextTimestamp();
+        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
         String createSchemaDDL = "CREATE SCHEMA T_SCHEMA";
         String createTableDDL = "CREATE TABLE T_SCHEMA.TEST(pk INTEGER PRIMARY KEY)";
         String dropTableDDL = "DROP TABLE T_SCHEMA.TEST";
-        Properties props = new Properties();
-        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
         try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
             try {
                 conn.createStatement().execute(createTableDDL);
@@ -481,9 +485,16 @@ public class CreateTableIT extends BaseClientManagedTimeIT {
                 //expected
             }
             conn.createStatement().execute(createSchemaDDL);
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts+10));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
             conn.createStatement().execute(createTableDDL);
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts+20));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
             conn.createStatement().execute(dropTableDDL);
         }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts+30));
         props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(false));
         try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
             conn.createStatement().execute(createTableDDL);


[27/52] [abbrv] phoenix git commit: PHOENIX-2841 UDF not working with sort merge join

Posted by sa...@apache.org.
PHOENIX-2841 UDF not working with sort merge join


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

Branch: refs/heads/encodecolumns
Commit: 87f47b82a754e652d48b7eb9d43de2af2d45b4a6
Parents: 6d6c8c4
Author: Ankit Singhal <an...@gmail.com>
Authored: Tue Apr 19 20:47:28 2016 +0530
Committer: Ankit Singhal <an...@gmail.com>
Committed: Tue Apr 19 20:47:28 2016 +0530

----------------------------------------------------------------------
 .../phoenix/end2end/UserDefinedFunctionsIT.java | 58 ++++++++++++++++++++
 .../apache/phoenix/compile/QueryCompiler.java   |  4 +-
 .../java/org/apache/phoenix/query/BaseTest.java |  2 +-
 3 files changed, 60 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/87f47b82/phoenix-core/src/it/java/org/apache/phoenix/end2end/UserDefinedFunctionsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UserDefinedFunctionsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UserDefinedFunctionsIT.java
index 4eee422..27c9e47 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UserDefinedFunctionsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UserDefinedFunctionsIT.java
@@ -24,9 +24,12 @@ import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL;
 import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR;
 import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL_TERMINATOR;
 import static org.apache.phoenix.util.PhoenixRuntime.PHOENIX_TEST_DRIVER_URL_PARAM;
+import static org.apache.phoenix.util.TestUtil.JOIN_ITEM_TABLE_FULL_NAME;
+import static org.apache.phoenix.util.TestUtil.JOIN_SUPPLIER_TABLE_FULL_NAME;
 import static org.apache.phoenix.util.TestUtil.LOCALHOST;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -785,6 +788,61 @@ public class UserDefinedFunctionsIT extends BaseOwnClusterIT{
     }
 
     @Test
+    public void testUdfWithJoin() throws Exception {
+        String query = "SELECT /*+ USE_SORT_MERGE_JOIN*/ item.\"item_id\", item.name, supp.\"supplier_id\", myreverse8(supp.name) FROM "
+                + JOIN_SUPPLIER_TABLE_FULL_NAME + " supp RIGHT JOIN " + JOIN_ITEM_TABLE_FULL_NAME
+                + " item ON myreverse8(item.\"supplier_id\") = myreverse8(supp.\"supplier_id\") ORDER BY \"item_id\"";
+        Connection conn = driver.connect(url, EMPTY_PROPS);
+        initJoinTableValues(url, null, null);
+        conn.createStatement().execute(
+                "create function myreverse8(VARCHAR) returns VARCHAR as 'org.apache.phoenix.end2end.MyReverse' using jar "
+                        + "'" + util.getConfiguration().get(DYNAMIC_JARS_DIR_KEY) + "/myjar1.jar" + "'");
+        try {
+            PreparedStatement statement = conn.prepareStatement(query);
+            ResultSet rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "0000000001");
+            assertEquals(rs.getString(2), "T1");
+            assertEquals(rs.getString(3), "0000000001");
+            assertEquals(rs.getString(4), "1S");
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "0000000002");
+            assertEquals(rs.getString(2), "T2");
+            assertEquals(rs.getString(3), "0000000001");
+            assertEquals(rs.getString(4), "1S");
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "0000000003");
+            assertEquals(rs.getString(2), "T3");
+            assertEquals(rs.getString(3), "0000000002");
+            assertEquals(rs.getString(4), "2S");
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "0000000004");
+            assertEquals(rs.getString(2), "T4");
+            assertEquals(rs.getString(3), "0000000002");
+            assertEquals(rs.getString(4), "2S");
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "0000000005");
+            assertEquals(rs.getString(2), "T5");
+            assertEquals(rs.getString(3), "0000000005");
+            assertEquals(rs.getString(4), "5S");
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "0000000006");
+            assertEquals(rs.getString(2), "T6");
+            assertEquals(rs.getString(3), "0000000006");
+            assertEquals(rs.getString(4), "6S");
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "invalid001");
+            assertEquals(rs.getString(2), "INVALID-1");
+            assertNull(rs.getString(3));
+            assertNull(rs.getString(4));
+
+            assertFalse(rs.next());
+        } finally {
+            conn.close();
+        }
+    }
+
+    @Test
     public void testReplaceFunction() throws Exception {
         Connection conn = driver.connect(url, EMPTY_PROPS);
         Statement stmt = conn.createStatement();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/87f47b82/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
index 82e2e92..c5b12f6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
@@ -21,7 +21,6 @@ import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Set;
 
@@ -64,7 +63,6 @@ import org.apache.phoenix.parse.SQLParser;
 import org.apache.phoenix.parse.SelectStatement;
 import org.apache.phoenix.parse.SubqueryParseNode;
 import org.apache.phoenix.parse.TableNode;
-import org.apache.phoenix.parse.UDFParseNode;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.AmbiguousColumnException;
 import org.apache.phoenix.schema.ColumnNotFoundException;
@@ -435,7 +433,7 @@ public class QueryCompiler {
         int fieldPosition = needsMerge ? lhsProjTable.getColumns().size() - lhsProjTable.getPKColumns().size() : 0;
         PTable projectedTable = needsMerge ? JoinCompiler.joinProjectedTables(lhsProjTable, rhsProjTable, type == JoinType.Right ? JoinType.Left : type) : lhsProjTable;
 
-        ColumnResolver resolver = FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), new HashMap<String,UDFParseNode>(1));
+        ColumnResolver resolver = FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), joinTable.getStatement().getUdfParseNodes());
         TableRef tableRef = resolver.getTables().get(0);
         StatementContext subCtx = new StatementContext(statement, resolver, ScanUtil.newScan(originalScan), new SequenceManager(statement));
         subCtx.setCurrentTable(tableRef);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/87f47b82/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
index d8651ae..e286da3 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
@@ -1506,7 +1506,7 @@ public abstract class BaseTest {
         if (ts != null) {
             props.setProperty(CURRENT_SCN_ATTRIB, ts.toString());
         }
-        Connection conn = DriverManager.getConnection(getUrl(), props);
+        Connection conn = DriverManager.getConnection(url, props);
         try {
             conn.createStatement().execute("CREATE SEQUENCE my.seq");
             // Insert into customer table


[08/52] [abbrv] phoenix git commit: PHOENIX-2822 Tests that extend BaseHBaseManagedTimeIT are very slow(Rahul Gidwani)

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/DynamicFamilyIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DynamicFamilyIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DynamicFamilyIT.java
index d2b0af5..f7d2b52 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DynamicFamilyIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DynamicFamilyIT.java
@@ -61,8 +61,8 @@ import org.junit.Test;
 @edu.umd.cs.findbugs.annotations.SuppressWarnings(
         value="RV_RETURN_VALUE_IGNORED", 
         justification="Designed to ignore.")
-public class DynamicFamilyIT extends BaseHBaseManagedTimeIT {
-    private static final String WEB_STATS = "WEB_STATS";
+public class DynamicFamilyIT extends BaseHBaseManagedTimeTableReuseIT {
+    private static final String WEB_STATS = generateRandomString();
     private static final String WEB_STATS_SCHEMA_NAME = "";
     private static final byte[] A_CF = Bytes.toBytes(SchemaUtil.normalizeIdentifier("A"));
     private static final byte[] B_CF = Bytes.toBytes(SchemaUtil.normalizeIdentifier("B"));
@@ -175,7 +175,7 @@ public class DynamicFamilyIT extends BaseHBaseManagedTimeIT {
      */
     // FIXME @Test
     public void testGetAllDynColsInFamily() throws Exception {
-        String query = "SELECT A.* FROM WEB_STATS WHERE entry='entry1'";
+        String query = "SELECT A.* FROM " + WEB_STATS + " WHERE entry='entry1'";
         String url = getUrl() + ";";
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(url, props);
@@ -203,7 +203,7 @@ public class DynamicFamilyIT extends BaseHBaseManagedTimeIT {
      */
     // FIXME @Test
     public void testGetAllDynCols() throws Exception {
-        String query = "SELECT * FROM WEB_STATS WHERE entry='entry1'";
+        String query = "SELECT * FROM " + WEB_STATS + "WHERE entry='entry1'";
         String url = getUrl() + ";";
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(url, props);
@@ -228,7 +228,7 @@ public class DynamicFamilyIT extends BaseHBaseManagedTimeIT {
      */
     @Test
     public void testGetCaseInsensitiveDynCol() throws Exception {
-        String query = "SELECT B.* FROM WEB_STATS(" + 
+        String query = "SELECT B.* FROM "+ WEB_STATS+ "(" +
                 "B." + LAST_LOGIN_TIME_PREFIX + USER_ID2 + " TIME," + 
                 "B." + LAST_LOGIN_TIME_PREFIX + USER_ID3 + " TIME) WHERE entry='entry2'";
         String url = getUrl() + ";";
@@ -253,7 +253,7 @@ public class DynamicFamilyIT extends BaseHBaseManagedTimeIT {
      */
     // FIXME @Test
     public void testGetCaseSensitiveDynCol() throws Exception {
-        String query = "SELECT B.* FROM WEB_STATS(" + 
+        String query = "SELECT B.* FROM "+WEB_STATS +"(" +
                 "B.\"" + LAST_LOGIN_TIME_PREFIX + USER_ID2 + "\"" + " TIME," + 
                 "B.\"" + LAST_LOGIN_TIME_PREFIX + USER_ID3 + "\"" + " TIME) WHERE entry='entry2'";
         String url = getUrl() + ";";
@@ -280,7 +280,7 @@ public class DynamicFamilyIT extends BaseHBaseManagedTimeIT {
      */
     // FIXME @Test
     public void testProjectStaticAndDynamic() throws Exception {
-        String query = "SELECT ENTRY, A.DUMMY, B.DUMMY, A.*,B.* FROM WEB_STATS WHERE entry='entry3'";
+        String query = "SELECT ENTRY, A.DUMMY, B.DUMMY, A.*,B.* FROM "+ WEB_STATS +" WHERE entry='entry3'";
         String url = getUrl() + ";";
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(url, props);
@@ -307,7 +307,7 @@ public class DynamicFamilyIT extends BaseHBaseManagedTimeIT {
 
     @Test(expected = ColumnFamilyNotFoundException.class)
     public void testDynamicFamilyException() throws Exception {
-        String query = "SELECT C.* FROM WEB_STATS";
+        String query = "SELECT C.* FROM " + WEB_STATS;
         String url = getUrl() + ";";
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(url, props);
@@ -321,7 +321,7 @@ public class DynamicFamilyIT extends BaseHBaseManagedTimeIT {
 
     @Test(expected = PhoenixParserException.class)
     public void testDynamicFamilyFunctionException() throws Exception {
-        String query = "SELECT count(C.*) FROM WEB_STATS";
+        String query = "SELECT count(C.*) FROM " + WEB_STATS;
         String url = getUrl() + ";";
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(url, props);
@@ -338,21 +338,24 @@ public class DynamicFamilyIT extends BaseHBaseManagedTimeIT {
         ResultSet rs;
         Connection conn = DriverManager.getConnection(getUrl());
         conn.setAutoCommit(true);
-        conn.createStatement().execute("CREATE TABLE TESTTABLE (Id VARCHAR NOT NULL PRIMARY KEY, COLFAM1.A VARCHAR, COLFAM1.B VARCHAR, COLFAM2.A VARCHAR )");
-        conn.createStatement().execute("UPSERT INTO TESTTABLE (Id, COLFAM1.A, COLFAM1.B, COLFAM2.A) values ('row-2', '100', '200', '300')");
-        rs = conn.createStatement().executeQuery("SELECT COLFAM1.A,COLFAM1.B FROM TESTTABLE");
+        String tableName = generateRandomString();
+        conn.createStatement().execute("CREATE TABLE " + tableName
+            + " (Id VARCHAR NOT NULL PRIMARY KEY, COLFAM1.A VARCHAR, COLFAM1.B VARCHAR, COLFAM2.A VARCHAR )");
+        conn.createStatement().execute("UPSERT INTO " + tableName
+            + " (Id, COLFAM1.A, COLFAM1.B, COLFAM2.A) values ('row-2', '100', '200', '300')");
+        rs = conn.createStatement().executeQuery("SELECT COLFAM1.A,COLFAM1.B FROM " + tableName);
         assertTrue(rs.next());
         assertEquals("100",rs.getString(1));
         assertEquals("200",rs.getString(2));
         assertFalse(rs.next());
 
-        rs = conn.createStatement().executeQuery("SELECT COLFAM1.* FROM TESTTABLE");
+        rs = conn.createStatement().executeQuery("SELECT COLFAM1.* FROM " + tableName);
         assertTrue(rs.next());
         assertEquals("100",rs.getString(1));
         assertEquals("200",rs.getString(2));
         assertFalse(rs.next());
 
-        rs = conn.createStatement().executeQuery("SELECT COLFAM1.*,COLFAM1.A FROM TESTTABLE");
+        rs = conn.createStatement().executeQuery("SELECT COLFAM1.*,COLFAM1.A FROM " + tableName);
         assertTrue(rs.next());
         assertEquals("100",rs.getString(1));
         assertEquals("200",rs.getString(2));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/FirstValueFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/FirstValueFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/FirstValueFunctionIT.java
index 6c080d3..7978291 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/FirstValueFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/FirstValueFunctionIT.java
@@ -27,26 +27,33 @@ import java.sql.ResultSet;
 
 import org.junit.Test;
 
-public class FirstValueFunctionIT extends BaseHBaseManagedTimeIT {
+public class FirstValueFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
 
     @Test
     public void signedLongAsBigInt() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS first_value_table "
+        String tableName = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + tableName + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " date BIGINT, \"value\" BIGINT)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (1, 8, 1, 3)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (2, 8, 2, 7)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (3, 8, 3, 9)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (5, 8, 5, 158)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (4, 8, 4, 5)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (1, 8, 1, 3)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (2, 8, 2, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (3, 8, 3, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (5, 8, 5, 158)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (4, 8, 4, 5)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY date ASC) FROM first_value_table GROUP BY page_id");
+            "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY date ASC) FROM " + tableName
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getLong(1), 3);
@@ -57,20 +64,27 @@ public class FirstValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void testSortOrderInSortCol() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS first_value_table "
+        String tableName = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + tableName + " "
                 + "(id INTEGER NOT NULL, page_id UNSIGNED_LONG,"
                 + " dates BIGINT NOT NULL, \"value\" BIGINT CONSTRAINT pk PRIMARY KEY (id, dates DESC))";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, dates, \"value\") VALUES (1, 8, 1, 3)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, dates, \"value\") VALUES (2, 8, 2, 7)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, dates, \"value\") VALUES (3, 8, 3, 9)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, dates, \"value\") VALUES (5, 8, 5, 158)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, dates, \"value\") VALUES (4, 8, 4, 5)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, dates, \"value\") VALUES (1, 8, 1, 3)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, dates, \"value\") VALUES (2, 8, 2, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, dates, \"value\") VALUES (3, 8, 3, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, dates, \"value\") VALUES (5, 8, 5, 158)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, dates, \"value\") VALUES (4, 8, 4, 5)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY dates ASC) FROM first_value_table GROUP BY page_id");
+            "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY dates ASC) FROM " + tableName
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getLong(1), 3);
@@ -81,20 +95,27 @@ public class FirstValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void testSortOrderInDataCol() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS first_value_table "
+        String tableName = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + tableName + " "
                 + "(id INTEGER NOT NULL, page_id UNSIGNED_LONG,"
                 + " dates BIGINT NOT NULL, \"value\" BIGINT NOT NULL CONSTRAINT pk PRIMARY KEY (id, dates, \"value\" DESC))";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, dates, \"value\") VALUES (1, 8, 1, 3)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, dates, \"value\") VALUES (2, 8, 2, 7)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, dates, \"value\") VALUES (3, 8, 3, 9)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, dates, \"value\") VALUES (5, 8, 5, 158)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, dates, \"value\") VALUES (4, 8, 4, 5)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, dates, \"value\") VALUES (1, 8, 1, 3)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, dates, \"value\") VALUES (2, 8, 2, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, dates, \"value\") VALUES (3, 8, 3, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, dates, \"value\") VALUES (5, 8, 5, 158)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, dates, \"value\") VALUES (4, 8, 4, 5)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY dates ASC) FROM first_value_table GROUP BY page_id");
+            "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY dates ASC) FROM " + tableName
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getLong(1), 3);
@@ -105,20 +126,27 @@ public class FirstValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void doubleDataType() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS first_value_table "
+        String tableName = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + tableName + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG, "
                 + "date DOUBLE, \"value\" DOUBLE)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (1, 8, 1, 300)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (2, 8, 2, 7)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (3, 8, 3, 9)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (5, 8, 4, 2)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (4, 8, 5, 400)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (1, 8, 1, 300)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (2, 8, 2, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (3, 8, 3, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (5, 8, 4, 2)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (4, 8, 5, 400)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY date ASC) FROM first_value_table GROUP BY page_id");
+            "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY date ASC) FROM " + tableName
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals("doubles", rs.getDouble(1), 300, 0.00001);
@@ -129,20 +157,27 @@ public class FirstValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void varcharFixedLenghtDatatype() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS first_value_table "
+        String table_name = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + table_name + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG, "
                 + "date VARCHAR(3), \"value\" VARCHAR(3))";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (1, 8, '1', '3')");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (2, 8, '2', '7')");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (3, 8, '3', '9')");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (5, 8, '4', '2')");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (4, 8, '5', '4')");
+        conn.createStatement().execute(
+            "UPSERT INTO " + table_name + " (id, page_id, date, \"value\") VALUES (1, 8, '1', '3')");
+        conn.createStatement().execute(
+            "UPSERT INTO " + table_name + " (id, page_id, date, \"value\") VALUES (2, 8, '2', '7')");
+        conn.createStatement().execute(
+            "UPSERT INTO " + table_name + " (id, page_id, date, \"value\") VALUES (3, 8, '3', '9')");
+        conn.createStatement().execute(
+            "UPSERT INTO " + table_name + " (id, page_id, date, \"value\") VALUES (5, 8, '4', '2')");
+        conn.createStatement().execute(
+            "UPSERT INTO " + table_name + " (id, page_id, date, \"value\") VALUES (4, 8, '5', '4')");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY date ASC) FROM first_value_table GROUP BY page_id");
+            "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY date ASC) FROM " + table_name
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getString(1), "3");
@@ -153,20 +188,27 @@ public class FirstValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void floatDataType() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS first_value_table "
+        String tableName = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + tableName + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " date FLOAT, \"value\" FLOAT)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (1, 8, 1, 300)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (2, 8, 2, 7)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (3, 8, 3, 9)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (5, 8, 4, 2)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id, date, \"value\") VALUES (4, 8, 5, 400)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (1, 8, 1, 300)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (2, 8, 2, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (3, 8, 3, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (5, 8, 4, 2)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " (id, page_id, date, \"value\") VALUES (4, 8, 5, 400)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY date ASC) FROM first_value_table GROUP BY page_id");
+            "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY date ASC) FROM " + tableName
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getFloat(1), 300.0, 0.000001);
@@ -178,20 +220,22 @@ public class FirstValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void allColumnsNull() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS first_value_table "
+        String tableName = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + tableName + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " date FLOAT, \"value\" FLOAT)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id) VALUES (1, 8)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id) VALUES (2, 8)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id) VALUES (3, 8)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id) VALUES (5, 8)");
-        conn.createStatement().execute("UPSERT INTO first_value_table (id, page_id) VALUES (4, 8)");
+        conn.createStatement().execute("UPSERT INTO " + tableName + " (id, page_id) VALUES (1, 8)");
+        conn.createStatement().execute("UPSERT INTO " + tableName + " (id, page_id) VALUES (2, 8)");
+        conn.createStatement().execute("UPSERT INTO " + tableName + " (id, page_id) VALUES (3, 8)");
+        conn.createStatement().execute("UPSERT INTO " + tableName + " (id, page_id) VALUES (5, 8)");
+        conn.createStatement().execute("UPSERT INTO " + tableName + " (id, page_id) VALUES (4, 8)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY date ASC) FROM first_value_table GROUP BY page_id");
+            "SELECT FIRST_VALUE(\"value\") WITHIN GROUP (ORDER BY date ASC) FROM " + tableName
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         byte[] nothing = rs.getBytes(1);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/GetSetByteBitFunctionEnd2EndIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/GetSetByteBitFunctionEnd2EndIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/GetSetByteBitFunctionEnd2EndIT.java
index a7f7ca3..734f2c4 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/GetSetByteBitFunctionEnd2EndIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/GetSetByteBitFunctionEnd2EndIT.java
@@ -32,24 +32,27 @@ import org.apache.phoenix.expression.function.GetByteFunction;
 import org.apache.phoenix.expression.function.SetBitFunction;
 import org.apache.phoenix.expression.function.SetByteFunction;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
  * End to end tests for {@link GetByteFunction} {@link SetByteFunction} {@link GetBitFunction}
  * {@link SetBitFunction}
  */
-public class GetSetByteBitFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
+public class GetSetByteBitFunctionEnd2EndIT extends BaseHBaseManagedTimeTableReuseIT {
 
     private static final String KEY = "key";
+    private static final String TABLE_NAME = generateRandomString();
 
-    @Before
-    public void initTable() throws Exception {
+    @BeforeClass
+    public static void initTable() throws Exception {
         Connection conn = null;
         PreparedStatement stmt = null;
         try {
             conn = DriverManager.getConnection(getUrl());
             String ddl;
-            ddl = "CREATE TABLE ta (k VARCHAR NOT NULL PRIMARY KEY, b BINARY(4), vb VARBINARY)";
+            ddl = "CREATE TABLE " + TABLE_NAME
+                + " (k VARCHAR NOT NULL PRIMARY KEY, b BINARY(4), vb VARBINARY)";
             conn.createStatement().execute(ddl);
             conn.commit();
         } finally {
@@ -60,7 +63,8 @@ public class GetSetByteBitFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void test() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO ta VALUES (?, ?, ?)");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + TABLE_NAME + " VALUES (?, ?, ?)");
         stmt.setString(1, KEY);
         stmt.setBytes(2, new byte[] { 1, 2, 3, 4 });
         stmt.setBytes(3, new byte[] { 1, 2, 3, 4 });
@@ -68,30 +72,30 @@ public class GetSetByteBitFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
         conn.commit();
         ResultSet rs =
                 conn.createStatement()
-                        .executeQuery(
-                            "SELECT GET_BYTE(vb, 1), GET_BYTE(b, 1) FROM ta WHERE GET_BYTE(vb, 1)=2 and GET_BYTE(b, 1)=2");
+                        .executeQuery("SELECT GET_BYTE(vb, 1), GET_BYTE(b, 1) FROM " + TABLE_NAME
+                            + " WHERE GET_BYTE(vb, 1)=2 and GET_BYTE(b, 1)=2");
         assertTrue(rs.next());
         assertEquals(2, rs.getInt(1));
         assertEquals(2, rs.getInt(2));
         assertTrue(!rs.next());
         rs =
                 conn.createStatement()
-                        .executeQuery(
-                            "SELECT GET_BIT(b, 0),GET_BIT(b, 9) FROM ta WHERE GET_BIT(vb, 0)=1 and GET_BIT(vb, 9)=1");
+                        .executeQuery("SELECT GET_BIT(b, 0),GET_BIT(b, 9) FROM " + TABLE_NAME
+                            + " WHERE GET_BIT(vb, 0)=1 and GET_BIT(vb, 9)=1");
         assertTrue(rs.next());
         assertEquals(1, rs.getInt(1));
         assertEquals(1, rs.getInt(2));
         assertTrue(!rs.next());
         rs =
                 conn.createStatement().executeQuery(
-                    "SELECT SET_BYTE(vb, 1, 1), SET_BYTE(b, 1, 1) FROM ta");
+                    "SELECT SET_BYTE(vb, 1, 1), SET_BYTE(b, 1, 1) FROM " + TABLE_NAME);
         assertTrue(rs.next());
         assertArrayEquals(new byte[] { 1, 1, 3, 4 }, rs.getBytes(1));
         assertArrayEquals(new byte[] { 1, 1, 3, 4 }, rs.getBytes(2));
         assertTrue(!rs.next());
         rs =
                 conn.createStatement().executeQuery(
-                    "SELECT SET_BIT(vb, 8, 1), SET_BIT(b, 8, 1) FROM ta");
+                    "SELECT SET_BIT(vb, 8, 1), SET_BIT(b, 8, 1) FROM " + TABLE_NAME);
         assertTrue(rs.next());
         assertArrayEquals(new byte[] { 1, 3, 3, 4 }, rs.getBytes(1));
         assertArrayEquals(new byte[] { 1, 3, 3, 4 }, rs.getBytes(2));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/LikeExpressionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/LikeExpressionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/LikeExpressionIT.java
index ecd1e8c..00a6a64 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/LikeExpressionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/LikeExpressionIT.java
@@ -30,17 +30,21 @@ import java.sql.SQLException;
 import java.sql.Statement;
 
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class LikeExpressionIT extends BaseHBaseManagedTimeIT {
-    @Before
-    public void doBeforeTestSetup() throws Exception {
+
+    private static final String TEST_TABLE = generateRandomString();
+
+    @BeforeClass
+    public static void doBeforeTestSetup() throws Exception {
         Connection conn = null;
         PreparedStatement stmt = null;
         try {
             conn = DriverManager.getConnection(getUrl());
             String ddl;
-            ddl = "CREATE TABLE testTable (k VARCHAR NOT NULL PRIMARY KEY, i INTEGER)";
+            ddl = "CREATE TABLE " + TEST_TABLE + " (k VARCHAR NOT NULL PRIMARY KEY, i INTEGER)";
             conn.createStatement().execute(ddl);
             conn.commit();
         } finally {
@@ -54,8 +58,9 @@ public class LikeExpressionIT extends BaseHBaseManagedTimeIT {
         insertRow(conn, "321n7-App-2-", 32);
     }
 
-    private void insertRow(Connection conn, String k, int i) throws SQLException {
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO testTable VALUES (?, ?)");
+    private static void insertRow(Connection conn, String k, int i) throws SQLException {
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + TEST_TABLE + " VALUES (?, ?)");
         stmt.setString(1, k);
         stmt.setInt(2, i);
         stmt.executeUpdate();
@@ -64,7 +69,7 @@ public class LikeExpressionIT extends BaseHBaseManagedTimeIT {
 
     private void testLikeExpression(Connection conn, String likeStr, int numResult, int expectedSum)
             throws Exception {
-        String cmd = "select k, i from testTable where k like '" + likeStr + "'";
+        String cmd = "select k, i from " + TEST_TABLE + " where k like '" + likeStr + "'";
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery(cmd);
         int sum = 0;
@@ -89,15 +94,18 @@ public class LikeExpressionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testLikeEverythingExpression() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE t (k1 VARCHAR, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1,k2))";
+        String table = generateRandomString();
+        String ddl = "CREATE TABLE " + table
+            + " (k1 VARCHAR, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1,k2))";
         conn.createStatement().execute(ddl);
-        conn.createStatement().execute("UPSERT INTO t VALUES('aa','bb')");
-        conn.createStatement().execute("UPSERT INTO t VALUES('ab','bc')");
-        conn.createStatement().execute("UPSERT INTO t VALUES(null,'cc')");
-        conn.createStatement().execute("UPSERT INTO t VALUES('dd',null)");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES('aa','bb')");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES('ab','bc')");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES(null,'cc')");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES('dd',null)");
         conn.commit();
         
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t WHERE k1 LIKE '%'");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT * FROM " + table + " WHERE k1 LIKE '%'");
         assertTrue(rs.next());
         assertEquals("aa", rs.getString(1));
         assertEquals("bb", rs.getString(2));
@@ -109,7 +117,7 @@ public class LikeExpressionIT extends BaseHBaseManagedTimeIT {
         assertEquals(null, rs.getString(2));
         assertFalse(rs.next());
         
-        rs = conn.createStatement().executeQuery("SELECT * FROM t WHERE k2 LIKE '%'");
+        rs = conn.createStatement().executeQuery("SELECT * FROM " + table + " WHERE k2 LIKE '%'");
         assertTrue(rs.next());
         assertEquals(null, rs.getString(1));
         assertEquals("cc", rs.getString(2));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/MD5FunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MD5FunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MD5FunctionIT.java
index a6107df..0b63aa8 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MD5FunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MD5FunctionIT.java
@@ -30,20 +30,22 @@ import java.sql.ResultSet;
 import org.junit.Test;
 
 
-public class MD5FunctionIT extends BaseHBaseManagedTimeIT {
+public class MD5FunctionIT extends BaseHBaseManagedTimeTableReuseIT {
   
   @Test
   public void testRetrieve() throws Exception {
       String testString = "mwalsh";
       
       Connection conn = DriverManager.getConnection(getUrl());
-      String ddl = "CREATE TABLE IF NOT EXISTS MD5_RETRIEVE_TEST (pk VARCHAR NOT NULL PRIMARY KEY)";
+      String md5_retrieve_test = generateRandomString();
+      String ddl =
+          "CREATE TABLE IF NOT EXISTS " + md5_retrieve_test + " (pk VARCHAR NOT NULL PRIMARY KEY)";
       conn.createStatement().execute(ddl);
-      String dml = String.format("UPSERT INTO MD5_RETRIEVE_TEST VALUES('%s')", testString);
+      String dml = String.format("UPSERT INTO " + md5_retrieve_test + " VALUES('%s')", testString);
       conn.createStatement().execute(dml);
       conn.commit();
       
-      ResultSet rs = conn.createStatement().executeQuery("SELECT MD5(pk) FROM MD5_RETRIEVE_TEST");
+      ResultSet rs = conn.createStatement().executeQuery("SELECT MD5(pk) FROM " + md5_retrieve_test);
       assertTrue(rs.next());
       byte[] first = MessageDigest.getInstance("MD5").digest(testString.getBytes());
       byte[] second = rs.getBytes(1);
@@ -56,13 +58,16 @@ public class MD5FunctionIT extends BaseHBaseManagedTimeIT {
       String testString = "FOOBAR";
       
       Connection conn = DriverManager.getConnection(getUrl());
-      String ddl = "CREATE TABLE IF NOT EXISTS MD5_RETRIEVE_TEST (k1 CHAR(3) NOT NULL, k2 CHAR(3) NOT NULL, CONSTRAINT PK PRIMARY KEY (K1,K2))";
+      String md5_retrieve_test = generateRandomString();
+      String ddl = "CREATE TABLE IF NOT EXISTS " + md5_retrieve_test
+          + " (k1 CHAR(3) NOT NULL, k2 CHAR(3) NOT NULL, CONSTRAINT PK PRIMARY KEY (K1,K2))";
       conn.createStatement().execute(ddl);
-      String dml = "UPSERT INTO MD5_RETRIEVE_TEST VALUES('FOO','BAR')";
+      String dml = "UPSERT INTO " + md5_retrieve_test + " VALUES('FOO','BAR')";
       conn.createStatement().execute(dml);
       conn.commit();
       
-      ResultSet rs = conn.createStatement().executeQuery("SELECT MD5((K1,K2)) FROM MD5_RETRIEVE_TEST");
+      ResultSet rs = conn.createStatement().executeQuery(
+          "SELECT MD5((K1,K2)) FROM " + md5_retrieve_test);
       assertTrue(rs.next());
       byte[] first = MessageDigest.getInstance("MD5").digest(testString.getBytes());
       byte[] second = rs.getBytes(1);
@@ -76,20 +81,23 @@ public class MD5FunctionIT extends BaseHBaseManagedTimeIT {
       String testString2 = "mwalsh2";
       
       Connection conn = DriverManager.getConnection(getUrl());
-      String ddl = "CREATE TABLE IF NOT EXISTS MD5_UPSERT_TEST (k1 binary(16) NOT NULL,k2 binary(16) NOT NULL  CONSTRAINT pk PRIMARY KEY (k1, k2))";
+      String md5_upsert_test = generateRandomString();
+      String ddl = "CREATE TABLE IF NOT EXISTS " + md5_upsert_test
+          + " (k1 binary(16) NOT NULL,k2 binary(16) NOT NULL  CONSTRAINT pk PRIMARY KEY (k1, k2))";
       conn.createStatement().execute(ddl);
-      String dml = String.format("UPSERT INTO MD5_UPSERT_TEST VALUES(md5('%s'),md5('%s'))", testString1, testString2);
+      String dml = String.format("UPSERT INTO " + md5_upsert_test + " VALUES(md5('%s'),md5('%s'))", testString1, testString2);
       conn.createStatement().execute(dml);
       conn.commit();
       
-      ResultSet rs = conn.createStatement().executeQuery("SELECT k1,k2 FROM MD5_UPSERT_TEST");
+      ResultSet rs = conn.createStatement().executeQuery("SELECT k1,k2 FROM " + md5_upsert_test);
       assertTrue(rs.next());
       byte[] pk1 = MessageDigest.getInstance("MD5").digest(testString1.getBytes());
       byte[] pk2 = MessageDigest.getInstance("MD5").digest(testString2.getBytes());
       assertArrayEquals(pk1, rs.getBytes(1));
       assertArrayEquals(pk2, rs.getBytes(2));
       assertFalse(rs.next());
-      PreparedStatement stmt = conn.prepareStatement("SELECT k1,k2 FROM MD5_UPSERT_TEST WHERE k1=md5(?)");
+      PreparedStatement stmt = conn.prepareStatement(
+          "SELECT k1,k2 FROM " + md5_upsert_test + " WHERE k1=md5(?)");
       stmt.setString(1, testString1);
       rs = stmt.executeQuery();
       assertTrue(rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/MappingTableDataTypeIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MappingTableDataTypeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MappingTableDataTypeIT.java
index 9617e37..6c51ebd 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MappingTableDataTypeIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MappingTableDataTypeIT.java
@@ -52,7 +52,8 @@ import org.junit.Test;
 public class MappingTableDataTypeIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testMappingHbaseTableToPhoenixTable() throws Exception {
-        final TableName tableName = TableName.valueOf("MTEST");
+        String mtest = generateRandomString();
+        final TableName tableName = TableName.valueOf(mtest);
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         PhoenixConnection conn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class);
         
@@ -65,13 +66,13 @@ public class MappingTableDataTypeIT extends BaseHBaseManagedTimeIT {
             descriptor.addFamily(columnDescriptor1);
             descriptor.addFamily(columnDescriptor2);
             admin.createTable(descriptor);
-            HTableInterface t = conn.getQueryServices().getTable(Bytes.toBytes("MTEST"));
+            HTableInterface t = conn.getQueryServices().getTable(Bytes.toBytes(mtest));
             insertData(tableName.getName(), admin, t);
             t.close();
             // create phoenix table that maps to existing HBase table
-            createPhoenixTable();
+            createPhoenixTable(mtest);
             
-            String selectSql = "SELECT * FROM MTEST";
+            String selectSql = "SELECT * FROM " + mtest;
             ResultSet rs = conn.createStatement().executeQuery(selectSql);
             ResultSetMetaData rsMetaData = rs.getMetaData();
             assertTrue("Expected single row", rs.next());
@@ -81,7 +82,7 @@ public class MappingTableDataTypeIT extends BaseHBaseManagedTimeIT {
             assertFalse("Expected single row ", rs.next());
             
             // delete the row
-            String deleteSql = "DELETE FROM MTEST WHERE id = 'row'";
+            String deleteSql = "DELETE FROM " + mtest + " WHERE id = 'row'";
             conn.createStatement().executeUpdate(deleteSql);
             conn.commit();
             
@@ -116,8 +117,8 @@ public class MappingTableDataTypeIT extends BaseHBaseManagedTimeIT {
     /**
      * Create a table in Phoenix that only maps column family cf1
      */
-    private void createPhoenixTable() throws SQLException {
-        String ddl = "create table IF NOT EXISTS MTEST (" + " id varchar NOT NULL primary key,"
+    private void createPhoenixTable(String tableName) throws SQLException {
+        String ddl = "create table IF NOT EXISTS " + tableName+ " (" + " id varchar NOT NULL primary key,"
                 + " \"cf1\".\"q1\" varchar" + " ) ";
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/MinMaxAggregateFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MinMaxAggregateFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MinMaxAggregateFunctionIT.java
index ca7a676..3a5088d 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/MinMaxAggregateFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/MinMaxAggregateFunctionIT.java
@@ -23,7 +23,9 @@ import java.util.Properties;
 import org.apache.phoenix.util.PropertiesUtil;
 import org.junit.Test;
 
-public class MinMaxAggregateFunctionIT extends BaseHBaseManagedTimeIT {
+public class MinMaxAggregateFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
+
+    private static final String TABLE_NAME = generateRandomString();
 
     @Test
     public void testMinMaxAggregateFunctions() throws SQLException {
@@ -32,7 +34,7 @@ public class MinMaxAggregateFunctionIT extends BaseHBaseManagedTimeIT {
         conn.setAutoCommit(false);
         try {
             conn.prepareStatement(
-                "create table TT("
+                "create table " + TABLE_NAME + "("
                         + "VAL1 integer not null, "
                         + "VAL2 char(2), "
                         + "VAL3 varchar, "
@@ -40,30 +42,30 @@ public class MinMaxAggregateFunctionIT extends BaseHBaseManagedTimeIT {
                         + "constraint PK primary key (VAL1))").execute();
             conn.commit();
 
-            conn.prepareStatement("upsert into TT values (0, '00', '00', '0')").execute();
-            conn.prepareStatement("upsert into TT values (1, '01', '01', '1')").execute();
-            conn.prepareStatement("upsert into TT values (2, '02', '02', '2')").execute();
+            conn.prepareStatement("upsert into " + TABLE_NAME + " values (0, '00', '00', '0')").execute();
+            conn.prepareStatement("upsert into " + TABLE_NAME + " values (1, '01', '01', '1')").execute();
+            conn.prepareStatement("upsert into " + TABLE_NAME + " values (2, '02', '02', '2')").execute();
             conn.commit();
 
-            ResultSet rs = conn.prepareStatement("select min(VAL2) from TT").executeQuery();
+            ResultSet rs = conn.prepareStatement("select min(VAL2) from " + TABLE_NAME).executeQuery();
             assertTrue(rs.next());
             assertEquals("00", rs.getString(1));
 
-            rs = conn.prepareStatement("select min(VAL3) from TT").executeQuery();
+            rs = conn.prepareStatement("select min(VAL3) from " + TABLE_NAME).executeQuery();
             assertTrue(rs.next());
             assertEquals("00", rs.getString(1));
 
-            rs = conn.prepareStatement("select max(VAL2)from TT").executeQuery();
+            rs = conn.prepareStatement("select max(VAL2)from " + TABLE_NAME).executeQuery();
             assertTrue(rs.next());
             assertEquals("02", rs.getString(1));
 
-            rs = conn.prepareStatement("select max(VAL3)from TT").executeQuery();
+            rs = conn.prepareStatement("select max(VAL3)from " + TABLE_NAME).executeQuery();
             assertTrue(rs.next());
             assertEquals("02", rs.getString(1));
 
             rs =
                     conn.prepareStatement(
-                        "select min(VAL1), min(VAL2), min(VAL3), min(VAL4) from TT").executeQuery();
+                        "select min(VAL1), min(VAL2), min(VAL3), min(VAL4) from " + TABLE_NAME).executeQuery();
             assertTrue(rs.next());
             assertEquals(0, rs.getInt(1));
             assertEquals("00", rs.getString(2));
@@ -72,7 +74,7 @@ public class MinMaxAggregateFunctionIT extends BaseHBaseManagedTimeIT {
 
             rs =
                     conn.prepareStatement(
-                        "select max(VAL1), max(VAL2), max(VAL3), max(VAL4) from TT").executeQuery();
+                        "select max(VAL1), max(VAL2), max(VAL3), max(VAL4) from " + TABLE_NAME).executeQuery();
 
             assertTrue(rs.next());
             assertEquals(2, rs.getInt(1));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/NthValueFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/NthValueFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/NthValueFunctionIT.java
index 11ecc0d..697c04c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/NthValueFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/NthValueFunctionIT.java
@@ -29,24 +29,31 @@ import java.util.ArrayList;
 import org.junit.Test;
 
 
-public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
+public class NthValueFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
 
     @Test
     public void simpleTest() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nthValue "
+        String nthValue = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nthValue + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " dates INTEGER, val INTEGER)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (2, 8, 1, 7)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (3, 8, 2, 9)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (4, 8, 3, 4)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (5, 8, 4, 2)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (2, 8, 1, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (3, 8, 2, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (4, 8, 3, 4)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (5, 8, 4, 2)");
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT NTH_VALUE(val, 2) WITHIN GROUP (ORDER BY dates DESC) FROM nthValue GROUP BY page_id");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT NTH_VALUE(val, 2) WITHIN GROUP (ORDER BY dates DESC) FROM " + nthValue
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getInt(1), 4);
@@ -57,21 +64,30 @@ public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void offsetValueAscOrder() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nth_test_table "
+        String nth_test_table = generateRandomString();
+
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nth_test_table + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " date INTEGER, \"value\" UNSIGNED_LONG)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (1, 8, 0, 300)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (2, 8, 1, 7)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (3, 8, 2, 9)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (4, 8, 3, 4)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (5, 8, 4, 2)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (6, 8, 5, 150)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, date, \"value\") VALUES (1, 8, 0, 300)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (2, 8, 1, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (3, 8, 2, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (4, 8, 3, 4)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (5, 8, 4, 2)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, date, \"value\") VALUES (6, 8, 5, 150)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT NTH_VALUE(\"value\", 2)  WITHIN GROUP (ORDER BY date ASC) FROM nth_test_table GROUP BY page_id");
+            "SELECT NTH_VALUE(\"value\", 2)  WITHIN GROUP (ORDER BY date ASC) FROM "
+                + nth_test_table + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getLong(1), 7);
@@ -82,21 +98,29 @@ public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void offsetValueDescOrder() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nth_test_table "
+        String nth_test_table = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nth_test_table + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " date INTEGER, \"value\" UNSIGNED_LONG)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (1, 8, 0, 300)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (2, 8, 1, 7)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (3, 8, 2, 9)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (4, 8, 3, 4)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (5, 8, 4, 2)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (6, 8, 5, 150)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, date, \"value\") VALUES (1, 8, 0, 300)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (2, 8, 1, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (3, 8, 2, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (4, 8, 3, 4)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (5, 8, 4, 2)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, date, \"value\") VALUES (6, 8, 5, 150)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT NTH_VALUE(\"value\", 2)  WITHIN GROUP (ORDER BY date DESC) FROM nth_test_table GROUP BY page_id");
+            "SELECT NTH_VALUE(\"value\", 2)  WITHIN GROUP (ORDER BY date DESC) FROM "
+                + nth_test_table + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getLong(1), 2);
@@ -107,21 +131,29 @@ public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void offsetValueLastMismatchByColumn() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nth_test_table "
+        String nth_test_table = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nth_test_table + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " date INTEGER, \"value\" UNSIGNED_LONG)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (1, 8, 5, 8)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (2, 8, 2, 7)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (3, 8, 1, 9)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (4, 8, 4, 4)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (5, 8, 3, 2)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, date, \"value\") VALUES (6, 8, 0, 1)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (1, 8, 5, 8)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (2, 8, 2, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (3, 8, 1, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (4, 8, 4, 4)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (5, 8, 3, 2)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nth_test_table + " (id, page_id, date, \"value\") VALUES (6, 8, 0, 1)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT NTH_VALUE(\"value\", 2)  WITHIN GROUP (ORDER BY date DESC) FROM nth_test_table GROUP BY page_id");
+            "SELECT NTH_VALUE(\"value\", 2)  WITHIN GROUP (ORDER BY date DESC) FROM "
+                + nth_test_table + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getLong(1), 4);
@@ -132,20 +164,27 @@ public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void testSortOrderInDataColWithOffset() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nth_test_table "
+        String nth_test_table = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nth_test_table + " "
                 + "(id INTEGER NOT NULL, page_id UNSIGNED_LONG,"
                 + " dates BIGINT NOT NULL, \"value\" BIGINT NOT NULL CONSTRAINT pk PRIMARY KEY (id, dates, \"value\" DESC))";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, dates, \"value\") VALUES (1, 8, 1, 3)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, dates, \"value\") VALUES (2, 8, 2, 7)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, dates, \"value\") VALUES (3, 8, 3, 9)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, dates, \"value\") VALUES (5, 8, 5, 158)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, dates, \"value\") VALUES (4, 8, 4, 5)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, dates, \"value\") VALUES (1, 8, 1, 3)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, dates, \"value\") VALUES (2, 8, 2, 7)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, dates, \"value\") VALUES (3, 8, 3, 9)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, dates, \"value\") VALUES (5, 8, 5, 158)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, dates, \"value\") VALUES (4, 8, 4, 5)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT NTH_VALUE(\"value\", 2)  WITHIN GROUP (ORDER BY dates ASC) FROM nth_test_table GROUP BY page_id");
+            "SELECT NTH_VALUE(\"value\", 2)  WITHIN GROUP (ORDER BY dates ASC) FROM "
+                + nth_test_table + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getLong(1), 7);
@@ -156,19 +195,27 @@ public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void nonUniqueValuesInOrderByAsc() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nthValue "
+        String nthValue = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nthValue + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " dates INTEGER, val INTEGER)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (2, 8, 1, 7)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (3, 8, 2, 9)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (4, 8, 2, 4)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (5, 8, 2, 2)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (6, 8, 3, 3)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (2, 8, 1, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (3, 8, 2, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (4, 8, 2, 4)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (5, 8, 2, 2)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (6, 8, 3, 3)");
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT NTH_VALUE(val, 3) WITHIN GROUP (ORDER BY dates ASC) FROM nthValue GROUP BY page_id");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT NTH_VALUE(val, 3) WITHIN GROUP (ORDER BY dates ASC) FROM " + nthValue
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertInIntArray(new int[]{2, 4, 9}, rs.getInt(1));
@@ -179,19 +226,27 @@ public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void nonUniqueValuesInOrderByAscSkipDuplicit() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nthValue "
+        String nthValue = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nthValue + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " dates INTEGER, val INTEGER)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (2, 8, 1, 7)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (3, 8, 2, 9)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (4, 8, 2, 4)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (5, 8, 2, 2)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (6, 8, 3, 3)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (2, 8, 1, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (3, 8, 2, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (4, 8, 2, 4)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (5, 8, 2, 2)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (6, 8, 3, 3)");
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT NTH_VALUE(val, 5) WITHIN GROUP (ORDER BY dates ASC) FROM nthValue GROUP BY page_id");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT NTH_VALUE(val, 5) WITHIN GROUP (ORDER BY dates ASC) FROM " + nthValue
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(3, rs.getInt(1));
@@ -202,19 +257,27 @@ public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void nonUniqueValuesInOrderByDesc() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nthValue "
+        String nthValue = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nthValue + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " dates INTEGER, val INTEGER)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (2, 8, 1, 7)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (3, 8, 2, 9)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (4, 8, 2, 4)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (5, 8, 2, 2)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (6, 8, 3, 3)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (2, 8, 1, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (3, 8, 2, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (4, 8, 2, 4)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (5, 8, 2, 2)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (6, 8, 3, 3)");
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT NTH_VALUE(val, 3) WITHIN GROUP (ORDER BY dates DESC) FROM nthValue GROUP BY page_id");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT NTH_VALUE(val, 3) WITHIN GROUP (ORDER BY dates DESC) FROM " + nthValue
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertInIntArray(new int[]{2, 4, 9}, rs.getInt(1));
@@ -225,20 +288,29 @@ public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void nonUniqueValuesInOrderNextValueDesc() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nthValue "
+        String nthValue = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nthValue + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " dates INTEGER, val INTEGER)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (2, 8, 0, 7)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (3, 8, 1, 9)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (4, 8, 2, 4)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (5, 8, 2, 2)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (6, 8, 3, 3)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (7, 8, 3, 5)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (2, 8, 0, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (3, 8, 1, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (4, 8, 2, 4)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (5, 8, 2, 2)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (6, 8, 3, 3)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (7, 8, 3, 5)");
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT NTH_VALUE(val, 2) WITHIN GROUP (ORDER BY dates DESC) FROM nthValue GROUP BY page_id");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT NTH_VALUE(val, 2) WITHIN GROUP (ORDER BY dates DESC) FROM " + nthValue
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertInIntArray(new int[]{3, 5}, rs.getInt(1));
@@ -249,20 +321,29 @@ public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void nonUniqueValuesInOrderNextValueAsc() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nthValue "
+        String nthValue = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nthValue + " "
                 + "(id INTEGER NOT NULL PRIMARY KEY, page_id UNSIGNED_LONG,"
                 + " dates INTEGER, val INTEGER)";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (2, 8, 0, 7)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (3, 8, 1, 9)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (4, 8, 2, 4)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (5, 8, 2, 2)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (6, 8, 3, 3)");
-        conn.createStatement().execute("UPSERT INTO nthValue (id, page_id, dates, val) VALUES (7, 8, 3, 5)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (2, 8, 0, 7)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (3, 8, 1, 9)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (4, 8, 2, 4)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (5, 8, 2, 2)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (6, 8, 3, 3)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + nthValue + " (id, page_id, dates, val) VALUES (7, 8, 3, 5)");
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT NTH_VALUE(val, 5) WITHIN GROUP (ORDER BY dates ASC) FROM nthValue GROUP BY page_id");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT NTH_VALUE(val, 5) WITHIN GROUP (ORDER BY dates ASC) FROM " + nthValue
+                + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertInIntArray(new int[]{3, 5}, rs.getInt(1));
@@ -273,20 +354,27 @@ public class NthValueFunctionIT extends BaseHBaseManagedTimeIT {
     public void ignoreNullValues() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE IF NOT EXISTS nth_test_table "
+        String nth_test_table = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + nth_test_table + " "
                 + "(id INTEGER NOT NULL, page_id UNSIGNED_LONG,"
                 + " dates BIGINT NOT NULL, \"value\" BIGINT NULL CONSTRAINT pk PRIMARY KEY (id, dates))";
         conn.createStatement().execute(ddl);
 
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, dates, \"value\") VALUES (1, 8, 1, 1)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, dates, \"value\") VALUES (2, 8, 2, NULL)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, dates, \"value\") VALUES (3, 8, 3, NULL)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, dates, \"value\") VALUES (5, 8, 4, 4)");
-        conn.createStatement().execute("UPSERT INTO nth_test_table (id, page_id, dates, \"value\") VALUES (4, 8, 5, 5)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, dates, \"value\") VALUES (1, 8, 1, 1)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, dates, \"value\") VALUES (2, 8, 2, NULL)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, dates, \"value\") VALUES (3, 8, 3, NULL)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, dates, \"value\") VALUES (5, 8, 4, 4)");
+        conn.createStatement().execute("UPSERT INTO " + nth_test_table
+            + " (id, page_id, dates, \"value\") VALUES (4, 8, 5, 5)");
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT NTH_VALUE(\"value\", 2)  WITHIN GROUP (ORDER BY dates DESC) FROM nth_test_table GROUP BY page_id");
+            "SELECT NTH_VALUE(\"value\", 2)  WITHIN GROUP (ORDER BY dates DESC) FROM "
+                + nth_test_table + " GROUP BY page_id");
 
         assertTrue(rs.next());
         assertEquals(rs.getLong(1), 4);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/OctetLengthFunctionEnd2EndIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/OctetLengthFunctionEnd2EndIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/OctetLengthFunctionEnd2EndIT.java
index 1239e7a..7977ab5 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/OctetLengthFunctionEnd2EndIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/OctetLengthFunctionEnd2EndIT.java
@@ -33,9 +33,10 @@ import org.junit.Test;
 /**
  * End to end tests for {@link OctetLengthFunction}
  */
-public class OctetLengthFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
+public class OctetLengthFunctionEnd2EndIT extends BaseHBaseManagedTimeTableReuseIT {
 
     private static final String KEY = "key";
+    private static final String TABLE_NAME = generateRandomString();
 
     @Before
     public void initTable() throws Exception {
@@ -44,7 +45,8 @@ public class OctetLengthFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
         try {
             conn = DriverManager.getConnection(getUrl());
             String ddl;
-            ddl = "CREATE TABLE ta (k VARCHAR NOT NULL PRIMARY KEY, b BINARY(4), vb VARBINARY)";
+            ddl = "CREATE TABLE " + TABLE_NAME
+                + " (k VARCHAR NOT NULL PRIMARY KEY, b BINARY(4), vb VARBINARY)";
             conn.createStatement().execute(ddl);
             conn.commit();
         } finally {
@@ -55,7 +57,8 @@ public class OctetLengthFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void test() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO ta VALUES (?, ?, ?)");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + TABLE_NAME + " VALUES (?, ?, ?)");
         stmt.setString(1, KEY);
         stmt.setBytes(2, new byte[] { 1, 2, 3, 4 });
         stmt.setBytes(3, new byte[] { 1, 2, 3, 4 });
@@ -63,8 +66,8 @@ public class OctetLengthFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
         conn.commit();
         ResultSet rs =
                 conn.createStatement()
-                        .executeQuery(
-                            "SELECT OCTET_LENGTH(vb), OCTET_LENGTH(b) FROM ta WHERE OCTET_LENGTH(vb)=4 and OCTET_LENGTH(b)=4");
+                        .executeQuery("SELECT OCTET_LENGTH(vb), OCTET_LENGTH(b) FROM " + TABLE_NAME
+                            + " WHERE OCTET_LENGTH(vb)=4 and OCTET_LENGTH(b)=4");
         assertTrue(rs.next());
         assertEquals(4, rs.getInt(1));
         assertEquals(4, rs.getInt(2));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/PowerFunctionEnd2EndIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PowerFunctionEnd2EndIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PowerFunctionEnd2EndIT.java
index 691fb61..cb120bd 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PowerFunctionEnd2EndIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PowerFunctionEnd2EndIT.java
@@ -27,15 +27,18 @@ import java.sql.ResultSet;
 
 import org.apache.phoenix.expression.function.PowerFunction;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
  * End to end tests for {@link PowerFunction}
  */
-public class PowerFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
+public class PowerFunctionEnd2EndIT extends BaseHBaseManagedTimeTableReuseIT {
 
     private static final String KEY = "key";
     private static final double ZERO = 1e-9;
+    private static final String TEST_SIGNED = generateRandomString();
+    private static final String TEST_UNSIGNED = generateRandomString();
 
     private static boolean twoDoubleEquals(double a, double b) {
         if (Double.isNaN(a) ^ Double.isNaN(b)) return false;
@@ -52,18 +55,18 @@ public class PowerFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
         }
     }
 
-    @Before
-    public void initTable() throws Exception {
+    @BeforeClass
+    public static void initTable() throws Exception {
         Connection conn = null;
         PreparedStatement stmt = null;
         try {
             conn = DriverManager.getConnection(getUrl());
             String ddl;
-            ddl =
-                    "CREATE TABLE testSigned (k VARCHAR NOT NULL PRIMARY KEY, doub DOUBLE, fl FLOAT, inte INTEGER, lon BIGINT, smalli SMALLINT, tinyi TINYINT)";
+            ddl = "CREATE TABLE " + TEST_SIGNED
+                + " (k VARCHAR NOT NULL PRIMARY KEY, doub DOUBLE, fl FLOAT, inte INTEGER, lon BIGINT, smalli SMALLINT, tinyi TINYINT)";
             conn.createStatement().execute(ddl);
-            ddl =
-                    "CREATE TABLE testUnsigned (k VARCHAR NOT NULL PRIMARY KEY, doub UNSIGNED_DOUBLE, fl UNSIGNED_FLOAT, inte UNSIGNED_INT, lon UNSIGNED_LONG, smalli UNSIGNED_SMALLINT, tinyi UNSIGNED_TINYINT)";
+            ddl = "CREATE TABLE " + TEST_UNSIGNED
+                + " (k VARCHAR NOT NULL PRIMARY KEY, doub UNSIGNED_DOUBLE, fl UNSIGNED_FLOAT, inte UNSIGNED_INT, lon UNSIGNED_LONG, smalli UNSIGNED_SMALLINT, tinyi UNSIGNED_TINYINT)";
             conn.createStatement().execute(ddl);
             conn.commit();
         } finally {
@@ -137,8 +140,8 @@ public class PowerFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
     public void test() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         for (double d : new double[] { 0.0, 1.0, -1.0, 123.1234, -123.1234 }) {
-            testNumberSpec(conn, d, "testSigned");
-            if (d >= 0) testNumberSpec(conn, d, "testUnsigned");
+            testNumberSpec(conn, d, TEST_SIGNED);
+            if (d >= 0) testNumberSpec(conn, d, TEST_UNSIGNED);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/PrimitiveTypeIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PrimitiveTypeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PrimitiveTypeIT.java
index cc92ea9..b78d144 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PrimitiveTypeIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PrimitiveTypeIT.java
@@ -29,15 +29,23 @@ import java.util.Properties;
 
 import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.TestUtil;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 
-public class PrimitiveTypeIT extends BaseHBaseManagedTimeIT {
-    private static void initTableValues(Connection conn) throws Exception {
-        conn.createStatement().execute("create table T (l bigint not null primary key, b boolean)");
+public class PrimitiveTypeIT extends BaseHBaseManagedTimeTableReuseIT {
+
+    private static final String TABLE_NAME = generateRandomString();
+    private static final Properties PROPS = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
+    private static Connection conn;
+
+    @BeforeClass
+    public static void initTableValues() throws Exception {
+        conn = DriverManager.getConnection(getUrl(), PROPS);
+        conn.createStatement().execute(
+            "create table " + TABLE_NAME + " (l bigint not null primary key, b boolean)");
         PreparedStatement stmt = conn.prepareStatement(
-                "upsert into " +
-                "T VALUES(?)");
+                "upsert into " + TABLE_NAME + " VALUES(?)");
         stmt.setLong(1, 2);
         stmt.execute();
         conn.commit();
@@ -45,10 +53,7 @@ public class PrimitiveTypeIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testCompareLongGTDecimal() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        initTableValues(conn);
-        String query = "SELECT l FROM T where l > 1.5";
+        String query = "SELECT l FROM " + TABLE_NAME + " where l > 1.5";
         try {
             PreparedStatement statement = conn.prepareStatement(query);
             ResultSet rs = statement.executeQuery();
@@ -62,10 +67,7 @@ public class PrimitiveTypeIT extends BaseHBaseManagedTimeIT {
     
     @Test
     public void testCompareLongGTEDecimal() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        initTableValues(conn);
-        String query = "SELECT l FROM T where l >= 1.5";
+        String query = "SELECT l FROM " + TABLE_NAME + " where l >= 1.5";
         try {
             PreparedStatement statement = conn.prepareStatement(query);
             ResultSet rs = statement.executeQuery();
@@ -86,10 +88,7 @@ public class PrimitiveTypeIT extends BaseHBaseManagedTimeIT {
     
     @Test
     public void testCompareLongLTDecimal() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        initTableValues(conn);
-        String query = "SELECT l FROM T where l < 1.5";
+        String query = "SELECT l FROM " + TABLE_NAME + " where l < 1.5";
         try {
             PreparedStatement statement = conn.prepareStatement(query);
             ResultSet rs = statement.executeQuery();
@@ -108,10 +107,7 @@ public class PrimitiveTypeIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testCompareLongLTEDecimal() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        initTableValues(conn);
-        String query = "SELECT l FROM T where l <= 1.5";
+        String query = "SELECT l FROM " + TABLE_NAME + " where l <= 1.5";
         try {
             PreparedStatement statement = conn.prepareStatement(query);
             ResultSet rs = statement.executeQuery();
@@ -129,10 +125,7 @@ public class PrimitiveTypeIT extends BaseHBaseManagedTimeIT {
     }
     @Test
     public void testCompareLongGTDecimal2() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        initTableValues(conn);
-        String query = "SELECT l FROM T where l > 2.5";
+        String query = "SELECT l FROM " + TABLE_NAME + " where l > 2.5";
         try {
             PreparedStatement statement = conn.prepareStatement(query);
             ResultSet rs = statement.executeQuery();
@@ -151,10 +144,7 @@ public class PrimitiveTypeIT extends BaseHBaseManagedTimeIT {
     
     @Test
     public void testCompareLongGTEDecimal2() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        initTableValues(conn);
-        String query = "SELECT l FROM T where l >= 2.5";
+        String query = "SELECT l FROM " + TABLE_NAME + " where l >= 2.5";
         try {
             PreparedStatement statement = conn.prepareStatement(query);
             ResultSet rs = statement.executeQuery();
@@ -173,10 +163,7 @@ public class PrimitiveTypeIT extends BaseHBaseManagedTimeIT {
     
     @Test
     public void testCompareLongLTDecimal2() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        initTableValues(conn);
-        String query = "SELECT l FROM T where l < 2.5";
+        String query = "SELECT l FROM " + TABLE_NAME + " where l < 2.5";
         try {
             PreparedStatement statement = conn.prepareStatement(query);
             ResultSet rs = statement.executeQuery();
@@ -199,8 +186,7 @@ public class PrimitiveTypeIT extends BaseHBaseManagedTimeIT {
     public void testCompareLongLTEDecimal2() throws Exception {
         Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);
-        initTableValues(conn);
-        String query = "SELECT l FROM T where l <= 2.5";
+        String query = "SELECT l FROM " + TABLE_NAME + " where l <= 2.5";
         try {
             PreparedStatement statement = conn.prepareStatement(query);
             ResultSet rs = statement.executeQuery();
@@ -221,16 +207,13 @@ public class PrimitiveTypeIT extends BaseHBaseManagedTimeIT {
     
     @Test
     public void testBooleanAsObject() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        initTableValues(conn);
-        String query = "upsert into T values (2, ?)";
+        String query = "upsert into " + TABLE_NAME + " values (2, ?)";
         try {
             PreparedStatement statement = conn.prepareStatement(query);
             statement.setObject(1, new Boolean("false"));
             statement.execute();
             conn.commit();
-            statement = conn.prepareStatement("SELECT l,b,? FROM T");
+            statement = conn.prepareStatement("SELECT l,b,? FROM " + TABLE_NAME);
             statement.setObject(1, new Boolean("false"));
             ResultSet rs = statement.executeQuery();
             assertTrue(rs.next());


[09/52] [abbrv] phoenix git commit: PHOENIX-2822 Tests that extend BaseHBaseManagedTimeIT are very slow(Rahul Gidwani)

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToStringFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToStringFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToStringFunctionIT.java
index 3b3f1d5..0439033 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToStringFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayToStringFunctionIT.java
@@ -23,13 +23,22 @@ import static org.junit.Assert.assertTrue;
 
 import java.sql.*;
 
+import org.junit.BeforeClass;
 import org.junit.Test;
 
-public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
-    private void initTables(Connection conn) throws Exception {
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[],integers INTEGER[],doubles DOUBLE[],bigints BIGINT[],chars CHAR(15)[],double1 DOUBLE,varchar1 VARCHAR,nullcheck INTEGER,chars2 CHAR(15)[])";
+public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
+    private static final String REGIONS = generateRandomString();
+    private static Connection conn = null;
+
+    @BeforeClass
+    public static void initTables() throws Exception {
+        conn = DriverManager.getConnection(getUrl());
+        String ddl = "CREATE TABLE " + REGIONS
+            + " (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[],integers INTEGER[],doubles DOUBLE[],bigints BIGINT[],chars CHAR(15)[],double1 DOUBLE,varchar1 VARCHAR,nullcheck INTEGER,chars2 CHAR(15)[])";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO regions(region_name,varchars,integers,doubles,bigints,chars,double1,varchar1,nullcheck,chars2) VALUES('SF Bay Area'," +
+        String dml = "UPSERT INTO " + REGIONS
+            + "(region_name,varchars,integers,doubles,bigints,chars,double1,varchar1,nullcheck,chars2) VALUES('SF Bay Area',"
+            +
                 "ARRAY['2345','46345','23234']," +
                 "ARRAY[2345,46345,23234,456]," +
                 "ARRAY[23.45,46.345,23.234,45.6,5.78]," +
@@ -47,11 +56,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionVarchar1() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(varchars, ',','*') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(varchars, ',','*') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "2345,46345,23234";
@@ -62,11 +70,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionVarchar2() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(varchars, ',') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(varchars, ',') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "2345,46345,23234";
@@ -77,11 +84,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionVarchar3() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY['hello', 'hello'], ',') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY['hello', 'hello'], ',') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "hello,hello";
@@ -92,11 +98,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionInt() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(integers, ',') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(integers, ',') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "2345,46345,23234,456";
@@ -107,11 +112,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionDouble1() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(doubles, ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(doubles, ', ') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "23.45, 46.345, 23.234, 45.6, 5.78";
@@ -122,11 +126,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionDouble2() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY[2.3, 4.5], ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY[2.3, 4.5], ', ') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "2.3, 4.5";
@@ -137,11 +140,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionBigint() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(bigints, ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(bigints, ', ') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "12, 34, 56, 78, 910";
@@ -152,11 +154,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionChar1() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(chars, ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(chars, ', ') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "a   , bbbb, c   , ddd , e   ";
@@ -167,11 +168,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionChar2() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(chars2, ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(chars2, ', ') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "a   , bbbb, c   , ddd , e   , foo ";
@@ -182,11 +182,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionChar3() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(chars2, varchar1) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(chars2, varchar1) FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "a   , bbbb, c   , ddd , e   , foo ";
@@ -197,11 +196,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNestedFunctions1() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY[integers[1],integers[1]], ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY[integers[1],integers[1]], ', ') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "2345, 2345";
@@ -212,11 +210,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNestedFunctions2() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY[ARRAY_ELEM(ARRAY[2,4],1),ARRAY_ELEM(ARRAY[2,4],2)], ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY[ARRAY_ELEM(ARRAY[2,4],1),ARRAY_ELEM(ARRAY[2,4],2)], ', ') FROM "
+                + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "2, 4";
@@ -227,11 +224,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNestedFunctions3() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY[ARRAY_ELEM(doubles, 1), ARRAY_ELEM(doubles, 1)], ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY[ARRAY_ELEM(doubles, 1), ARRAY_ELEM(doubles, 1)], ', ') FROM "
+                + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "23.45, 23.45";
@@ -242,11 +238,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNestedFunctions4() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_ELEM(ARRAY_APPEND(ARRAY['abc','bcd'], ARRAY_TO_STRING(ARRAY['a','b'], 'c')), 3) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_ELEM(ARRAY_APPEND(ARRAY['abc','bcd'], ARRAY_TO_STRING(ARRAY['a','b'], 'c')), 3) FROM "
+                + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "acb";
@@ -257,17 +252,19 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithUpsert1() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
+        String table = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + table + " (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO regions(region_name,varchar) VALUES('SF Bay Area',ARRAY_TO_STRING(ARRAY['hello','world'],','))";
+        String dml = "UPSERT INTO " + table
+            + "(region_name,varchar) VALUES('SF Bay Area',ARRAY_TO_STRING(ARRAY['hello','world'],','))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchar FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT varchar FROM " + table + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "hello,world";
@@ -278,17 +275,19 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithUpsert2() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
+        String tableName = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO regions(region_name,varchar) VALUES('SF Bay Area',ARRAY_TO_STRING(ARRAY[3, 4, 5],', '))";
+        String dml = "UPSERT INTO " + tableName
+            + "(region_name,varchar) VALUES('SF Bay Area',ARRAY_TO_STRING(ARRAY[3, 4, 5],', '))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchar FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT varchar FROM " + tableName + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "3, 4, 5";
@@ -299,17 +298,19 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithUpsert3() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
+        String tableName = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO regions(region_name,varchar) VALUES('SF Bay Area',ARRAY_TO_STRING(ARRAY[3.1, 4.2, 5.5],', '))";
+        String dml = "UPSERT INTO " + tableName
+            + "(region_name,varchar) VALUES('SF Bay Area',ARRAY_TO_STRING(ARRAY[3.1, 4.2, 5.5],', '))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchar FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT varchar FROM " + tableName + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "3.1, 4.2, 5.5";
@@ -320,17 +321,19 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithUpsert4() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
+        String tableName = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO regions(region_name,varchar) VALUES('SF Bay Area',ARRAY_TO_STRING(ARRAY[true, false, true],', '))";
+        String dml = "UPSERT INTO " + tableName
+            + "(region_name,varchar) VALUES('SF Bay Area',ARRAY_TO_STRING(ARRAY[true, false, true],', '))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchar FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT varchar FROM " + tableName + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "true, false, true";
@@ -341,27 +344,33 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithUpsertSelect1() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-
-        String ddl = "CREATE TABLE source (region_name VARCHAR PRIMARY KEY,doubles DOUBLE[])";
+        String source = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + source + " (region_name VARCHAR PRIMARY KEY,doubles DOUBLE[])";
         conn.createStatement().execute(ddl);
 
-        ddl = "CREATE TABLE target (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
+        String target = generateRandomString();
+        ddl = "CREATE TABLE " + target + " (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO source(region_name,doubles) VALUES('SF Bay Area', ARRAY[5.67, 7.87])";
+        String dml = "UPSERT INTO " + source
+            + "(region_name,doubles) VALUES('SF Bay Area', ARRAY[5.67, 7.87])";
         conn.createStatement().execute(dml);
 
-        dml = "UPSERT INTO source(region_name,doubles) VALUES('SF Bay Area2', ARRAY[9.2, 3.4])";
+        dml = "UPSERT INTO " + source
+            + "(region_name,doubles) VALUES('SF Bay Area2', ARRAY[9.2, 3.4])";
         conn.createStatement().execute(dml);
         conn.commit();
 
-        dml = "UPSERT INTO target(region_name, varchar) SELECT region_name, ARRAY_TO_STRING(doubles, ', ') FROM source";
+        dml =
+            "UPSERT INTO " + target
+                + "(region_name, varchar) SELECT region_name, ARRAY_TO_STRING(doubles, ', ') FROM "
+                + source;
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchar FROM target");
+        rs = conn.createStatement().executeQuery("SELECT varchar FROM " + target);
         assertTrue(rs.next());
 
         String expected = "5.67, 7.87";
@@ -375,27 +384,33 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithUpsertSelect2() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-
-        String ddl = "CREATE TABLE source (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
+        String source = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + source + " (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
         conn.createStatement().execute(ddl);
 
-        ddl = "CREATE TABLE target (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
+        String target = generateRandomString();
+        ddl = "CREATE TABLE " + target + " (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO source(region_name,varchars) VALUES('SF Bay Area', ARRAY['hello', '-)'])";
+        String dml = "UPSERT INTO " + source
+            + "(region_name,varchars) VALUES('SF Bay Area', ARRAY['hello', '-)'])";
         conn.createStatement().execute(dml);
 
-        dml = "UPSERT INTO source(region_name,varchars) VALUES('SF Bay Area2', ARRAY['hello', '-('])";
+        dml = "UPSERT INTO " + source
+            + "(region_name,varchars) VALUES('SF Bay Area2', ARRAY['hello', '-('])";
         conn.createStatement().execute(dml);
         conn.commit();
 
-        dml = "UPSERT INTO target(region_name, varchar) SELECT region_name, ARRAY_TO_STRING(varchars, ':') FROM source";
+        dml =
+            "UPSERT INTO " + target
+                + "(region_name, varchar) SELECT region_name, ARRAY_TO_STRING(varchars, ':') FROM "
+                + source;
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchar FROM target");
+        rs = conn.createStatement().executeQuery("SELECT varchar FROM " + target);
         assertTrue(rs.next());
 
         String expected = "hello:-)";
@@ -409,27 +424,33 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithUpsertSelect3() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-
-        String ddl = "CREATE TABLE source (region_name VARCHAR PRIMARY KEY,booleans BOOLEAN[])";
+        String source = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + source + " (region_name VARCHAR PRIMARY KEY,booleans BOOLEAN[])";
         conn.createStatement().execute(ddl);
 
-        ddl = "CREATE TABLE target (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
+        String target = generateRandomString();
+        ddl = "CREATE TABLE " + target + " (region_name VARCHAR PRIMARY KEY,varchar VARCHAR)";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO source(region_name, booleans) VALUES('SF Bay Area', ARRAY[true, true])";
+        String dml = "UPSERT INTO " + source
+            + "(region_name, booleans) VALUES('SF Bay Area', ARRAY[true, true])";
         conn.createStatement().execute(dml);
 
-        dml = "UPSERT INTO source(region_name, booleans) VALUES('SF Bay Area2', ARRAY[false, false])";
+        dml = "UPSERT INTO " + source
+            + "(region_name, booleans) VALUES('SF Bay Area2', ARRAY[false, false])";
         conn.createStatement().execute(dml);
         conn.commit();
 
-        dml = "UPSERT INTO target(region_name, varchar) SELECT region_name, ARRAY_TO_STRING(booleans, ', ') FROM source";
+        dml =
+            "UPSERT INTO " + target
+                + "(region_name, varchar) SELECT region_name, ARRAY_TO_STRING(booleans, ', ') FROM "
+                + source;
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchar FROM target");
+        rs = conn.createStatement().executeQuery("SELECT varchar FROM " + target);
         assertTrue(rs.next());
 
         String expected = "true, true";
@@ -443,11 +464,9 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionInWhere1() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE '2345,46345,23234,456' = ARRAY_TO_STRING(integers,',')");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + REGIONS
+            + " WHERE '2345,46345,23234,456' = ARRAY_TO_STRING(integers,',')");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -456,11 +475,9 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionInWhere2() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE 'a,b,c' = ARRAY_TO_STRING(ARRAY['a', 'b', 'c'], ',')");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + REGIONS
+            + " WHERE 'a,b,c' = ARRAY_TO_STRING(ARRAY['a', 'b', 'c'], ',')");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -469,11 +486,9 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionInWhere3() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE '1.1,2.2,3.3' = ARRAY_TO_STRING(ARRAY[1.1, 2.2, 3.3], ',')");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + REGIONS
+            + " WHERE '1.1,2.2,3.3' = ARRAY_TO_STRING(ARRAY[1.1, 2.2, 3.3], ',')");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -482,11 +497,9 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionInWhere4() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE 'true,true,true' = ARRAY_TO_STRING(ARRAY[true, true, true], ',')");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + REGIONS
+            + " WHERE 'true,true,true' = ARRAY_TO_STRING(ARRAY[true, true, true], ',')");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -495,11 +508,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionInWhere5() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE 'a, bbbb, c, ddd, e' = ARRAY_TO_STRING(ARRAY['a', 'bbbb', 'c' , 'ddd', 'e'], ', ')");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + REGIONS
+            + " WHERE 'a, bbbb, c, ddd, e' = ARRAY_TO_STRING(ARRAY['a', 'bbbb', 'c' , 'ddd', 'e'], ', ')");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -508,11 +520,9 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionInWhere6() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY_TO_STRING(ARRAY[1,2,3], varchar1) = '1, 2, 3'");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + REGIONS
+            + " WHERE ARRAY_TO_STRING(ARRAY[1,2,3], varchar1) = '1, 2, 3'");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -521,11 +531,9 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionInWhere7() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY_TO_STRING(varchars, varchar1) = '2345, 46345, 23234'");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + REGIONS
+            + " WHERE ARRAY_TO_STRING(varchars, varchar1) = '2345, 46345, 23234'");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -534,11 +542,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNulls1() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY['a', NULL, 'b'], ', ','*') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY['a', NULL, 'b'], ', ','*') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "a, *, b";
@@ -549,11 +556,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNulls2() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY['a', NULL, 'b'], ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY['a', NULL, 'b'], ', ') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "a, b";
@@ -564,11 +570,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNulls3() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY[NULL, 'a', 'b'], ', ', '*') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY[NULL, 'a', 'b'], ', ', '*') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "*, a, b";
@@ -579,11 +584,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNulls4() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY[NULL, 'a', 'b'], ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY[NULL, 'a', 'b'], ', ') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "a, b";
@@ -594,11 +598,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNulls5() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY['a', 'b', NULL], ', ', '*') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY['a', 'b', NULL], ', ', '*') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "a, b, *";
@@ -609,11 +612,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNulls6() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY['a', 'b', NULL], ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY['a', 'b', NULL], ', ') FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "a, b";
@@ -624,11 +626,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNulls7() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY[NULL, NULL, 'a', 'b', NULL, 'c', 'd', NULL, 'e', NULL, NULL], ', ', '*') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY[NULL, NULL, 'a', 'b', NULL, 'c', 'd', NULL, 'e', NULL, NULL], ', ', '*') FROM "
+                + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "*, *, a, b, *, c, d, *, e, *, *";
@@ -639,11 +640,10 @@ public class ArrayToStringFunctionIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testArrayToStringFunctionWithNulls8() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
-
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_TO_STRING(ARRAY[NULL, NULL, 'a', 'b', NULL, 'c', 'd', NULL, 'e', NULL, NULL], ', ') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_TO_STRING(ARRAY[NULL, NULL, 'a', 'b', NULL, 'c', 'd', NULL, 'e', NULL, NULL], ', ') FROM "
+                + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String expected = "a, b, c, d, e";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArraysWithNullsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArraysWithNullsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArraysWithNullsIT.java
index e95a386..5444e7f 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArraysWithNullsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArraysWithNullsIT.java
@@ -26,18 +26,21 @@ import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.schema.types.PhoenixArray;
 import org.junit.Test;
 
-public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
+public class ArraysWithNullsIT extends BaseHBaseManagedTimeTableReuseIT {
 
     @Test
     public void testArrayUpsertIntWithNulls() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t1 ( k VARCHAR PRIMARY KEY, a INTEGER[])");
+        String t1 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t1 + " ( k VARCHAR PRIMARY KEY, a INTEGER[])");
 
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t1 VALUES('a',ARRAY[null,3,null])");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + t1 + " VALUES('a',ARRAY[null,3,null])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t1 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery("Select a from " + t1 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("INTEGER",new Object[]{null,3,null});
 
@@ -51,13 +54,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertVarcharWithNulls() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t2 ( k VARCHAR PRIMARY KEY, a VARCHAR[])");
+        String t2 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t2 + " ( k VARCHAR PRIMARY KEY, a VARCHAR[])");
 
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t2 VALUES('a',ARRAY['10',null])");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + t2 + " VALUES('a',ARRAY['10',null])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t2 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery("Select a from " + t2 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("VARCHAR",new Object[]{"10",null});
 
@@ -69,13 +75,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertBigIntWithNulls() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t3 ( k VARCHAR PRIMARY KEY, a BIGINT[])");
+        String t3 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t3 + " ( k VARCHAR PRIMARY KEY, a BIGINT[])");
 
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t3 VALUES('a',ARRAY[2,null,32335,4])");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + t3 + " VALUES('a',ARRAY[2,null,32335,4])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t3 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery("Select a from " + t3 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("BIGINT",new Object[]{(long)2,null,(long)32335,(long)4});
 
@@ -87,13 +96,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertFloatWithNulls() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t4 ( k VARCHAR PRIMARY KEY, a FLOAT[])");
+        String t4 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t4 + " ( k VARCHAR PRIMARY KEY, a FLOAT[])");
 
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t4 VALUES('a',ARRAY[1.1,2.2,null,3.4])");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + t4 + " VALUES('a',ARRAY[1.1,2.2,null,3.4])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t4 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery("Select a from " + t4 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("FLOAT",new Object[]{(float)1.1,(float)2.2,null,(float)3.4});
 
@@ -105,13 +117,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertSmallIntWithNulls() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t5 ( k VARCHAR PRIMARY KEY, a SMALLINT[])");
+        String t5 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t5 + " ( k VARCHAR PRIMARY KEY, a SMALLINT[])");
 
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t5 VALUES('a',ARRAY[123,456,null,456])");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + t5 + " VALUES('a',ARRAY[123,456,null,456])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t5 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery("Select a from " + t5 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("SMALLINT",new Object[]{(short)123,(short)456,null,(short)456});
 
@@ -123,13 +138,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertTinyIntWithNulls() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t6 ( k VARCHAR PRIMARY KEY, a TINYINT[])");
+        String t6 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t6 + " ( k VARCHAR PRIMARY KEY, a TINYINT[])");
 
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t6 VALUES('a',ARRAY[123,45,null,45])");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + t6 + " VALUES('a',ARRAY[123,45,null,45])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t6 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery("Select a from " + t6 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("TINYINT",new Object[]{(byte)123,(byte)45,null,(byte)45});
 
@@ -141,13 +159,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertBooleanWithNulls() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t7 ( k VARCHAR PRIMARY KEY, a BOOLEAN[])");
+        String t7 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t7 + " ( k VARCHAR PRIMARY KEY, a BOOLEAN[])");
 
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t7 VALUES('a',ARRAY[true,false,null,true])");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + t7 + " VALUES('a',ARRAY[true,false,null,true])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t7 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery("Select a from " + t7 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("BOOLEAN",new Object[]{true,false,null,true});
 
@@ -159,13 +180,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertDoubleWithNulls() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t8 ( k VARCHAR PRIMARY KEY, a DOUBLE[])");
+        String t8 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t8 + " ( k VARCHAR PRIMARY KEY, a DOUBLE[])");
 
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t8 VALUES('a',ARRAY[1.2,2.3,null,3.4])");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + t8 + " VALUES('a',ARRAY[1.2,2.3,null,3.4])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t8 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery("Select a from " + t8 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("DOUBLE",new Object[]{1.2,2.3,null,3.4});
 
@@ -177,12 +201,14 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertDateWithNulls1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t9 ( k VARCHAR PRIMARY KEY, a DATE[])");
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t9 VALUES('a',ARRAY[TO_DATE('2015-05-20 06:12:14.184'),null,TO_DATE('2015-05-20 06:12:14.184'),null])");
+        String t9 = generateRandomString();
+        conn.createStatement().execute("CREATE TABLE " + t9 + " ( k VARCHAR PRIMARY KEY, a DATE[])");
+        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + t9
+            + " VALUES('a',ARRAY[TO_DATE('2015-05-20 06:12:14.184'),null,TO_DATE('2015-05-20 06:12:14.184'),null])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t9 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery("Select a from " + t9 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("DATE",new Date[]{new Date(1432102334184l),new Date(0l),new Date(1432102334184l),new Date(0l)});
 
@@ -193,12 +219,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertDateWithNulls2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t10 ( k VARCHAR PRIMARY KEY, a DATE[])");
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t10 VALUES('a',ARRAY[TO_DATE('1970-01-01 00:00:00.000'), TO_DATE('2015-05-20 06:12:14.184'),TO_DATE('2015-05-20 06:12:14.184')])");
+        String t10 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t10 + " ( k VARCHAR PRIMARY KEY, a DATE[])");
+        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + t10
+            + " VALUES('a',ARRAY[TO_DATE('1970-01-01 00:00:00.000'), TO_DATE('2015-05-20 06:12:14.184'),TO_DATE('2015-05-20 06:12:14.184')])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t10 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "Select a from " + t10 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("DATE",new Date[]{new Date(0l), new Date(1432102334184l), new Date(1432102334184l)});
 
@@ -209,12 +239,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertTimeWithNulls1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t11 ( k VARCHAR PRIMARY KEY, a TIME[])");
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t11 VALUES('a',ARRAY[TO_TIME('2015-05-20 06:12:14.184'),null,TO_TIME('2015-05-20 06:12:14.184'),null])");
+        String t11 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t11 + " ( k VARCHAR PRIMARY KEY, a TIME[])");
+        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + t11
+            + " VALUES('a',ARRAY[TO_TIME('2015-05-20 06:12:14.184'),null,TO_TIME('2015-05-20 06:12:14.184'),null])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t11 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "Select a from " + t11 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("TIME",new Time[]{new Time(1432102334184l),new Time(0l),new Time(1432102334184l),new Time(0l)});
 
@@ -225,12 +259,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertTimeWithNulls2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t12 ( k VARCHAR PRIMARY KEY, a TIME[])");
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t12 VALUES('a',ARRAY[TO_TIME('1970-01-01 00:00:00.000'), TO_TIME('2015-05-20 06:12:14.184'),null,TO_TIME('2015-05-20 06:12:14.184'),null])");
+        String t12 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t12 + " ( k VARCHAR PRIMARY KEY, a TIME[])");
+        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + t12
+            + " VALUES('a',ARRAY[TO_TIME('1970-01-01 00:00:00.000'), TO_TIME('2015-05-20 06:12:14.184'),null,TO_TIME('2015-05-20 06:12:14.184'),null])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t12 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "Select a from " + t12 + " where k = 'a'");
         rs.next();
         Array array = conn.createArrayOf("TIME",new Time[]{new Time(0l),new Time(1432102334184l),new Time(0l),new Time(1432102334184l),new Time(0l)});
 
@@ -241,12 +279,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertTimeStampWithNulls1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t13 ( k VARCHAR PRIMARY KEY, a TIMESTAMP[])");
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t13 VALUES('a',ARRAY[TO_TIMESTAMP('2015-05-20 06:12:14.184'),null,TO_TIMESTAMP('2015-05-20 06:12:14.184'),TO_TIMESTAMP('1970-01-01 00:00:00.000')])");
+        String t13 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t13 + " ( k VARCHAR PRIMARY KEY, a TIMESTAMP[])");
+        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + t13
+            + " VALUES('a',ARRAY[TO_TIMESTAMP('2015-05-20 06:12:14.184'),null,TO_TIMESTAMP('2015-05-20 06:12:14.184'),TO_TIMESTAMP('1970-01-01 00:00:00.000')])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t13 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "Select a from " + t13 + " where k = 'a'");
         rs.next();
 
         assertEquals(rs.getArray(1),conn.createArrayOf("TIMESTAMP",new Timestamp[]{new Timestamp(1432102334184l),new Timestamp(0l),new Timestamp(1432102334184l),new Timestamp(0l)}));
@@ -256,12 +298,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertTimeStampWithNulls2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t14 ( k VARCHAR PRIMARY KEY, a TIMESTAMP[])");
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t14 VALUES('a',ARRAY[TO_TIMESTAMP('1970-01-01 00:00:00.000'),TO_TIMESTAMP('2015-05-20 06:12:14.184'),TO_TIMESTAMP('1970-01-01 00:00:00.000'),TO_TIMESTAMP('2015-05-20 06:12:14.184'),TO_TIMESTAMP('1970-01-01 00:00:00.000')])");
+        String t14 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t14 + " ( k VARCHAR PRIMARY KEY, a TIMESTAMP[])");
+        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + t14
+            + " VALUES('a',ARRAY[TO_TIMESTAMP('1970-01-01 00:00:00.000'),TO_TIMESTAMP('2015-05-20 06:12:14.184'),TO_TIMESTAMP('1970-01-01 00:00:00.000'),TO_TIMESTAMP('2015-05-20 06:12:14.184'),TO_TIMESTAMP('1970-01-01 00:00:00.000')])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t14 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "Select a from " + t14 + " where k = 'a'");
         rs.next();
 
         assertEquals(rs.getArray(1),conn.createArrayOf("TIMESTAMP",new Timestamp[]{new Timestamp(0l),new Timestamp(1432102334184l),new Timestamp(0l),new Timestamp(1432102334184l),new Timestamp(0l)}));
@@ -271,12 +317,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertCharWithNulls1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t15 ( k VARCHAR PRIMARY KEY, a CHAR(15)[])");
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t15 VALUES('a',ARRAY['foo',null,'fo','foo'])");
+        String t15 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t15 + " ( k VARCHAR PRIMARY KEY, a CHAR(15)[])");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + t15 + " VALUES('a',ARRAY['foo',null,'fo','foo'])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t15 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "Select a from " + t15 + " where k = 'a'");
         rs.next();
 
         assertEquals(rs.getArray(1),conn.createArrayOf("CHAR",new String[]{"foo","","fo","foo"}));
@@ -286,12 +336,16 @@ public class ArraysWithNullsIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayUpsertCharWithNulls2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        conn.createStatement().execute("CREATE TABLE t16 ( k VARCHAR PRIMARY KEY, a CHAR(15)[])");
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO t16 VALUES('a',ARRAY[null,'foo',null,'fo','foo'])");
+        String t16 = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + t16 + " ( k VARCHAR PRIMARY KEY, a CHAR(15)[])");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + t16 + " VALUES('a',ARRAY[null,'foo',null,'fo','foo'])");
         stmt.execute();
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("Select a from t16 where k = 'a'");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "Select a from " + t16 + " where k = 'a'");
         rs.next();
 
         assertEquals(rs.getArray(1),conn.createArrayOf("CHAR",new String[]{"","foo","","fo","foo"}));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoCommitIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoCommitIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoCommitIT.java
index 469f2de..3797884 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoCommitIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoCommitIT.java
@@ -32,7 +32,7 @@ import org.apache.phoenix.util.PropertiesUtil;
 import org.junit.Test;
 
 
-public class AutoCommitIT extends BaseHBaseManagedTimeIT {
+public class AutoCommitIT extends BaseHBaseManagedTimeTableReuseIT {
 
     @Test
     public void testMutationJoin() throws Exception {
@@ -40,42 +40,43 @@ public class AutoCommitIT extends BaseHBaseManagedTimeIT {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(true);
-        
-        String ddl = "CREATE TABLE test_table " +
+
+            String testTable = generateRandomString();
+            String ddl = "CREATE TABLE " + testTable + " " +
                 "  (r varchar not null, col1 integer" +
                 "  CONSTRAINT pk PRIMARY KEY (r))\n";
         createTestTable(getUrl(), ddl);
         
-        String query = "UPSERT INTO test_table(r, col1) VALUES('row1', 1)";
+        String query = "UPSERT INTO " + testTable + "(r, col1) VALUES('row1', 1)";
         PreparedStatement statement = conn.prepareStatement(query);
         statement.executeUpdate();
         conn.commit();
         
         conn.setAutoCommit(false);
-        query = "UPSERT INTO test_table(r, col1) VALUES('row1', 2)";
+        query = "UPSERT INTO " + testTable + "(r, col1) VALUES('row1', 2)";
         statement = conn.prepareStatement(query);
         statement.executeUpdate();
         
-        query = "DELETE FROM test_table WHERE r='row1'";
+        query = "DELETE FROM " + testTable + " WHERE r='row1'";
         statement = conn.prepareStatement(query);
         statement.executeUpdate();
         conn.commit();
         
-        query = "SELECT * FROM test_table";
+        query = "SELECT * FROM " + testTable;
         statement = conn.prepareStatement(query);
         ResultSet rs = statement.executeQuery();
         assertFalse(rs.next());
 
-        query = "DELETE FROM test_table WHERE r='row1'";
+        query = "DELETE FROM " + testTable + " WHERE r='row1'";
         statement = conn.prepareStatement(query);
         statement.executeUpdate();
 
-        query = "UPSERT INTO test_table(r, col1) VALUES('row1', 3)";
+        query = "UPSERT INTO " + testTable + "(r, col1) VALUES('row1', 3)";
         statement = conn.prepareStatement(query);
         statement.executeUpdate();
         conn.commit();
         
-        query = "SELECT * FROM test_table";
+        query = "SELECT * FROM " + testTable;
         statement = conn.prepareStatement(query);
         rs = statement.executeQuery();
         assertTrue(rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeIT.java
index 679f29d..3a811a8 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeIT.java
@@ -34,7 +34,10 @@ import org.junit.experimental.categories.Category;
  * to set timestamps, because we create/destroy the Phoenix tables
  * between tests and only allow a table time stamp to increase.
  * Without this separation table deletion/creation would fail.
- * 
+ *
+ * Try and use (@link BaseHBaseManagedTimeTableReuseIT) and only
+ * extend this class if really necessary.  It is very slow as
+ * we have to delete tables which takes up to 10 seconds per test case.
  * All tests extending this class use the mini cluster that is
  * different from the mini cluster used by test classes extending 
  * {@link BaseClientManagedTimeIT}.

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeTableReuseIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeTableReuseIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeTableReuseIT.java
new file mode 100644
index 0000000..8d9fff9
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BaseHBaseManagedTimeTableReuseIT.java
@@ -0,0 +1,56 @@
+package org.apache.phoenix.end2end;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.phoenix.query.BaseTest;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.experimental.categories.Category;
+
+import javax.annotation.concurrent.NotThreadSafe;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Base class for tests that let HBase set timestamps.
+ * We need to separate these from tests that rely on clients
+ * to set timestamps, because we create/destroy the Phoenix tables
+ * between tests and only allow a table time stamp to increase.
+ * Without this separation table deletion/creation would fail.
+ *
+ * All tests extending this class use the mini cluster that is
+ * shared by all classes extending this class
+ *
+ * Remember to use BaseTest.generateRandomString() to generate table
+ * names for your tests otherwise there might be naming collisions between
+ * other tests.
+ * {@link BaseClientManagedTimeIT}.
+ *
+ * @since 0.1
+ */
+@NotThreadSafe
+@Category(HBaseManagedTimeTest.class)
+public class BaseHBaseManagedTimeTableReuseIT extends BaseTest {
+
+  protected static Configuration getTestClusterConfig() {
+    // don't want callers to modify config.
+    return new Configuration(config);
+  }
+
+  @BeforeClass
+  public static void doSetup() throws Exception {
+    setUpTestDriver(ReadOnlyProps.EMPTY_PROPS);
+  }
+
+  @AfterClass
+  public static void doTeardown() throws Exception {
+    // no teardown since we are creating unique table names
+  }
+
+  @After
+  public void cleanUpAfterTest() throws Exception {
+    // no cleanup since we are using unique table names
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/CbrtFunctionEnd2EndIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CbrtFunctionEnd2EndIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CbrtFunctionEnd2EndIT.java
index a632104..25fc43f 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CbrtFunctionEnd2EndIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CbrtFunctionEnd2EndIT.java
@@ -28,26 +28,31 @@ import java.sql.ResultSet;
 
 import org.apache.phoenix.expression.function.CbrtFunction;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
  * End to end tests for {@link CbrtFunction}
  */
-public class CbrtFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
+public class CbrtFunctionEnd2EndIT extends BaseHBaseManagedTimeTableReuseIT {
 
     private static final String KEY = "key";
     private static final double ZERO = 1e-8;
+    private static final String TEST_SIGNED = generateRandomString();
+    private static final String TEST_UNSIGNED = generateRandomString();
 
-    @Before
-    public void initTable() throws Exception {
+    @BeforeClass
+    public static void initTable() throws Exception {
         Connection conn = null;
         PreparedStatement stmt = null;
         try {
             conn = DriverManager.getConnection(getUrl());
             String ddl;
-            ddl = "CREATE TABLE testSigned (k VARCHAR NOT NULL PRIMARY KEY, doub DOUBLE, fl FLOAT, inte INTEGER, lon BIGINT, smalli SMALLINT, tinyi TINYINT)";
+            ddl = "CREATE TABLE " + TEST_SIGNED
+                + " (k VARCHAR NOT NULL PRIMARY KEY, doub DOUBLE, fl FLOAT, inte INTEGER, lon BIGINT, smalli SMALLINT, tinyi TINYINT)";
             conn.createStatement().execute(ddl);
-            ddl = "CREATE TABLE testUnsigned (k VARCHAR NOT NULL PRIMARY KEY, doub UNSIGNED_DOUBLE, fl UNSIGNED_FLOAT, inte UNSIGNED_INT, lon UNSIGNED_LONG, smalli UNSIGNED_SMALLINT, tinyi UNSIGNED_TINYINT)";
+            ddl = "CREATE TABLE " + TEST_UNSIGNED
+                + " (k VARCHAR NOT NULL PRIMARY KEY, doub UNSIGNED_DOUBLE, fl UNSIGNED_FLOAT, inte UNSIGNED_INT, lon UNSIGNED_LONG, smalli UNSIGNED_SMALLINT, tinyi UNSIGNED_TINYINT)";
             conn.createStatement().execute(ddl);
             conn.commit();
         } finally {
@@ -56,7 +61,8 @@ public class CbrtFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
     }
 
     private void updateSignedTable(Connection conn, double data) throws Exception {
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO testSigned VALUES (?, ?, ?, ?, ?, ?, ?)");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + TEST_SIGNED + " VALUES (?, ?, ?, ?, ?, ?, ?)");
         stmt.setString(1, KEY);
         Double d = Double.valueOf(data);
         stmt.setDouble(2, d.doubleValue());
@@ -70,7 +76,8 @@ public class CbrtFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
     }
 
     private void updateUnsignedTable(Connection conn, double data) throws Exception {
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO testUnsigned VALUES (?, ?, ?, ?, ?, ?, ?)");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + TEST_UNSIGNED + " VALUES (?, ?, ?, ?, ?, ?, ?)");
         stmt.setString(1, KEY);
         Double d = Double.valueOf(data);
         stmt.setDouble(2, d.doubleValue());
@@ -85,7 +92,9 @@ public class CbrtFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
 
     private void testSignedNumberSpec(Connection conn, double data) throws Exception {
         updateSignedTable(conn, data);
-        ResultSet rs = conn.createStatement().executeQuery("SELECT CBRT(doub),CBRT(fl),CBRT(inte),CBRT(lon),CBRT(smalli),CBRT(tinyi) FROM testSigned");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT CBRT(doub),CBRT(fl),CBRT(inte),CBRT(lon),CBRT(smalli),CBRT(tinyi) FROM "
+                + TEST_SIGNED);
         assertTrue(rs.next());
         Double d = Double.valueOf(data);
         assertTrue(Math.abs(rs.getDouble(1) - Math.cbrt(d.doubleValue())) < ZERO);
@@ -95,7 +104,8 @@ public class CbrtFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
         assertTrue(Math.abs(rs.getDouble(5) - Math.cbrt(d.shortValue())) < ZERO);
         assertTrue(Math.abs(rs.getDouble(6) - Math.cbrt(d.byteValue())) < ZERO);
         assertTrue(!rs.next());
-        PreparedStatement stmt = conn.prepareStatement("SELECT k FROM testSigned WHERE CBRT(doub)>0 AND CBRT(fl)>0 AND CBRT(inte)>0 AND CBRT(lon)>0 AND CBRT(smalli)>0 AND CBRT(tinyi)>0");
+        PreparedStatement stmt = conn.prepareStatement("SELECT k FROM " + TEST_SIGNED
+            + " WHERE CBRT(doub)>0 AND CBRT(fl)>0 AND CBRT(inte)>0 AND CBRT(lon)>0 AND CBRT(smalli)>0 AND CBRT(tinyi)>0");
         rs = stmt.executeQuery();
         if (data > 0) {
             assertTrue(rs.next());
@@ -106,7 +116,9 @@ public class CbrtFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
 
     private void testUnsignedNumberSpec(Connection conn, double data) throws Exception {
         updateUnsignedTable(conn, data);
-        ResultSet rs = conn.createStatement().executeQuery("SELECT CBRT(doub),CBRT(fl),CBRT(inte),CBRT(lon),CBRT(smalli),CBRT(tinyi) FROM testUnsigned");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT CBRT(doub),CBRT(fl),CBRT(inte),CBRT(lon),CBRT(smalli),CBRT(tinyi) FROM "
+                + TEST_UNSIGNED);
         assertTrue(rs.next());
         Double d = Double.valueOf(data);
         assertTrue(Math.abs(rs.getDouble(1) - Math.cbrt(d.doubleValue())) < ZERO);
@@ -116,7 +128,8 @@ public class CbrtFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
         assertTrue(Math.abs(rs.getDouble(5) - Math.cbrt(d.shortValue())) < ZERO);
         assertTrue(Math.abs(rs.getDouble(6) - Math.cbrt(d.byteValue())) < ZERO);
         assertTrue(!rs.next());
-        PreparedStatement stmt = conn.prepareStatement("SELECT k FROM testUnsigned WHERE CBRT(doub)>0 AND CBRT(fl)>0 AND CBRT(inte)>0 AND CBRT(lon)>0 AND CBRT(smalli)>0 AND CBRT(tinyi)>0");
+        PreparedStatement stmt = conn.prepareStatement("SELECT k FROM " + TEST_UNSIGNED
+            + " WHERE CBRT(doub)>0 AND CBRT(fl)>0 AND CBRT(inte)>0 AND CBRT(lon)>0 AND CBRT(smalli)>0 AND CBRT(tinyi)>0");
         rs = stmt.executeQuery();
         if (data > 0) {
             assertTrue(rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/ConvertTimezoneFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ConvertTimezoneFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ConvertTimezoneFunctionIT.java
index f415dc6..6f09c45 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ConvertTimezoneFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ConvertTimezoneFunctionIT.java
@@ -34,19 +34,23 @@ import org.junit.Test;
  *
  */
 
-public class ConvertTimezoneFunctionIT extends BaseHBaseManagedTimeIT {
+public class ConvertTimezoneFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
 
     @Test
     public void testConvertTimezoneEurope() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
+        String timezone_offset_test = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test
+            + " (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))";
+        String dml = "UPSERT INTO " + timezone_offset_test
+            + " (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT k1, dates, CONVERT_TZ(dates, 'UTC', 'Europe/Prague') FROM TIMEZONE_OFFSET_TEST");
+            "SELECT k1, dates, CONVERT_TZ(dates, 'UTC', 'Europe/Prague') FROM "
+                + timezone_offset_test);
 
         assertTrue(rs.next());
         assertEquals(1393635600000L, rs.getDate(3).getTime()); //Sat, 01 Mar 2014 01:00:00
@@ -55,14 +59,18 @@ public class ConvertTimezoneFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testConvertTimezoneAmerica() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
+        String timezone_offset_test = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test
+            + " (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))";
+        String dml = "UPSERT INTO " + timezone_offset_test
+            + " (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT k1, dates, CONVERT_TZ(dates, 'UTC', 'America/Adak') FROM TIMEZONE_OFFSET_TEST");
+            "SELECT k1, dates, CONVERT_TZ(dates, 'UTC', 'America/Adak') FROM "
+                + timezone_offset_test);
 
         assertTrue(rs.next());
         assertEquals(1393596000000L, rs.getDate(3).getTime()); //Fri, 28 Feb 2014 14:00:00
@@ -71,14 +79,17 @@ public class ConvertTimezoneFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void nullInDateParameter() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
+        String timezone_offset_test = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test
+            + " (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1) VALUES (1)";
+        String dml = "UPSERT INTO " + timezone_offset_test + " (k1) VALUES (1)";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT k1, dates, CONVERT_TZ(dates, 'UTC', 'America/Adak') FROM TIMEZONE_OFFSET_TEST");
+            "SELECT k1, dates, CONVERT_TZ(dates, 'UTC', 'America/Adak') FROM "
+                + timezone_offset_test);
 
         assertTrue(rs.next());
         rs.getDate(3);
@@ -88,14 +99,17 @@ public class ConvertTimezoneFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void nullInFirstTimezoneParameter() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST (k1 INTEGER NOT NULL, dates DATE, tz VARCHAR, CONSTRAINT pk PRIMARY KEY (k1))";
+        String timezone_offset_test = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test
+            + " (k1 INTEGER NOT NULL, dates DATE, tz VARCHAR, CONSTRAINT pk PRIMARY KEY (k1))";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))";
+        String dml = "UPSERT INTO " + timezone_offset_test
+            + " (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT k1, dates, CONVERT_TZ(dates, tz, 'America/Adak') FROM TIMEZONE_OFFSET_TEST");
+            "SELECT k1, dates, CONVERT_TZ(dates, tz, 'America/Adak') FROM " + timezone_offset_test);
 
         assertTrue(rs.next());
         rs.getDate(3);
@@ -105,14 +119,17 @@ public class ConvertTimezoneFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void nullInSecondTimezoneParameter() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST (k1 INTEGER NOT NULL, dates DATE, tz VARCHAR, CONSTRAINT pk PRIMARY KEY (k1))";
+        String timezone_offset_test = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test
+            + " (k1 INTEGER NOT NULL, dates DATE, tz VARCHAR, CONSTRAINT pk PRIMARY KEY (k1))";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))";
+        String dml = "UPSERT INTO " + timezone_offset_test
+            + " (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT k1, dates, CONVERT_TZ(dates, 'America/Adak', tz) FROM TIMEZONE_OFFSET_TEST");
+            "SELECT k1, dates, CONVERT_TZ(dates, 'America/Adak', tz) FROM " + timezone_offset_test);
 
         assertTrue(rs.next());
         rs.getDate(3);
@@ -122,15 +139,19 @@ public class ConvertTimezoneFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void unknownTimezone() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
+        String timezone_offset_test = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test
+            + " (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))";
+        String dml = "UPSERT INTO " + timezone_offset_test
+            + " (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         try {
             ResultSet rs = conn.createStatement().executeQuery(
-                    "SELECT k1, dates, CONVERT_TZ(dates, 'UNKNOWN_TIMEZONE', 'America/Adak') FROM TIMEZONE_OFFSET_TEST");
+                "SELECT k1, dates, CONVERT_TZ(dates, 'UNKNOWN_TIMEZONE', 'America/Adak') FROM "
+                    + timezone_offset_test);
 
             rs.next();
             rs.getDate(3).getTime();
@@ -143,15 +164,19 @@ public class ConvertTimezoneFunctionIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void testConvertMultipleRecords() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
+      String timezone_offset_test = generateRandomString();
+      String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test
+          + " (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
 		Statement stmt = conn.createStatement();
 		stmt.execute(ddl);
-		stmt.execute("UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))");
-		stmt.execute("UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (2, TO_DATE('2014-03-01 00:00:00'))");
+		stmt.execute("UPSERT INTO " + timezone_offset_test
+        + " (k1, dates) VALUES (1, TO_DATE('2014-03-01 00:00:00'))");
+		stmt.execute("UPSERT INTO " + timezone_offset_test
+        + " (k1, dates) VALUES (2, TO_DATE('2014-03-01 00:00:00'))");
 		conn.commit();
 
 		ResultSet rs = stmt.executeQuery(
-				"SELECT k1, dates, CONVERT_TZ(dates, 'UTC', 'America/Adak') FROM TIMEZONE_OFFSET_TEST");
+        "SELECT k1, dates, CONVERT_TZ(dates, 'UTC', 'America/Adak') FROM " + timezone_offset_test);
 
 		assertTrue(rs.next());
 		assertEquals(1393596000000L, rs.getDate(3).getTime()); //Fri, 28 Feb 2014 14:00:00

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/DecodeFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DecodeFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DecodeFunctionIT.java
index 93205a7..041649b 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DecodeFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DecodeFunctionIT.java
@@ -35,16 +35,19 @@ import org.apache.phoenix.schema.types.PUnsignedLong;
 import org.junit.Test;
 
 
-public class DecodeFunctionIT extends BaseHBaseManagedTimeIT {
+public class DecodeFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
 
 	@Test
 	public void shouldPass() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
 
-		String ddl = "CREATE TABLE test_table ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
+		String testTable = generateRandomString();
+		String ddl = "CREATE TABLE " + testTable
+				+ " ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
 
 		conn.createStatement().execute(ddl);
-		PreparedStatement ps = conn.prepareStatement("UPSERT INTO test_table (some_column) VALUES (?)");
+		PreparedStatement ps = conn.prepareStatement(
+				"UPSERT INTO " + testTable + " (some_column) VALUES (?)");
 
 		byte[] kk = Bytes.add(PUnsignedLong.INSTANCE.toBytes(2232594215l), PInteger.INSTANCE.toBytes(-8));
 		ps.setBytes(1, kk);
@@ -52,7 +55,8 @@ public class DecodeFunctionIT extends BaseHBaseManagedTimeIT {
 		ps.execute();
 		conn.commit();
 
-		ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM test_table WHERE some_column = DECODE('000000008512af277ffffff8', 'hex')");
+		ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + testTable
+				+ " WHERE some_column = DECODE('000000008512af277ffffff8', 'hex')");
 		assertTrue(rs.next());
 	}
 
@@ -60,10 +64,13 @@ public class DecodeFunctionIT extends BaseHBaseManagedTimeIT {
 	public void upperCaseHexEncoding() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
 
-		String ddl = "CREATE TABLE test_table ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
+		String testTable = generateRandomString();
+		String ddl = "CREATE TABLE " + testTable
+				+ " ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
 
 		conn.createStatement().execute(ddl);
-		PreparedStatement ps = conn.prepareStatement("UPSERT INTO test_table (some_column) VALUES (?)");
+		PreparedStatement ps = conn.prepareStatement(
+				"UPSERT INTO " + testTable + " (some_column) VALUES (?)");
 
 		byte[] kk = Bytes.add(PUnsignedLong.INSTANCE.toBytes(2232594215l), PInteger.INSTANCE.toBytes(-8));
 		ps.setBytes(1, kk);
@@ -71,19 +78,23 @@ public class DecodeFunctionIT extends BaseHBaseManagedTimeIT {
 		ps.execute();
 		conn.commit();
 
-		ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM test_table WHERE some_column = DECODE('000000008512af277ffffff8', 'HEX')");
+		ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + testTable
+				+ " WHERE some_column = DECODE('000000008512af277ffffff8', 'HEX')");
 		assertTrue(rs.next());
 	}
 
 	@Test
 	public void invalidCharacters() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE test_table ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
+		String testTable = generateRandomString();
+		String ddl = "CREATE TABLE " + testTable
+				+ " ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
 
 		conn.createStatement().execute(ddl);
 
 		try {
-			conn.createStatement().executeQuery("SELECT * FROM test_table WHERE some_column = DECODE('zzxxuuyyzzxxuuyy', 'hex')");
+			conn.createStatement().executeQuery(
+					"SELECT * FROM " + testTable + " WHERE some_column = DECODE('zzxxuuyyzzxxuuyy', 'hex')");
 	        fail();
 		} catch (SQLException e) {
 			assertEquals(SQLExceptionCode.ILLEGAL_DATA.getErrorCode(), e.getErrorCode());
@@ -93,12 +104,15 @@ public class DecodeFunctionIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void invalidLength() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE test_table ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
+		String testTable = generateRandomString();
+		String ddl = "CREATE TABLE " + testTable
+				+ " ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
 
 		conn.createStatement().execute(ddl);
 
 		try {
-			conn.createStatement().executeQuery("SELECT * FROM test_table WHERE some_column = DECODE('8', 'hex')");
+			conn.createStatement().executeQuery(
+					"SELECT * FROM " + testTable + " WHERE some_column = DECODE('8', 'hex')");
             fail();
         } catch (SQLException e) {
             assertEquals(SQLExceptionCode.ILLEGAL_DATA.getErrorCode(), e.getErrorCode());
@@ -108,23 +122,28 @@ public class DecodeFunctionIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void nullEncoding() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE test_table ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
+		String testTable = generateRandomString();
+		String ddl = "CREATE TABLE " + testTable
+				+ " ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
 
 		conn.createStatement().execute(ddl);
 
-		ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM test_table WHERE some_column = DECODE('8', NULL)");
+		ResultSet rs = conn.createStatement().executeQuery(
+				"SELECT * FROM " + testTable + " WHERE some_column = DECODE('8', NULL)");
 		assertFalse(rs.next());
 	}
 
 	@Test
 	public void invalidEncoding() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE test_table ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
+		String testTable = generateRandomString();
+		String ddl = "CREATE TABLE " + testTable
+				+ " ( some_column BINARY(12) NOT NULL CONSTRAINT PK PRIMARY KEY (some_column))";
 
 		conn.createStatement().execute(ddl);
 
 		try {
-			conn.createStatement().executeQuery("SELECT * FROM test_table WHERE some_column = DECODE('8', 'someNonexistFormat')");
+			conn.createStatement().executeQuery("SELECT * FROM "+ testTable + " WHERE some_column = DECODE('8', 'someNonexistFormat')");
             fail();
         } catch (SQLException e) {
             assertEquals(SQLExceptionCode.TYPE_MISMATCH.getErrorCode(), e.getErrorCode());


[36/52] [abbrv] phoenix git commit: PHOENIX-2724 Query with large number of guideposts is slower compared to no stats

Posted by sa...@apache.org.
PHOENIX-2724 Query with large number of guideposts is slower compared to no stats


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

Branch: refs/heads/encodecolumns
Commit: 54362430d71be788d515944573572624628a09b6
Parents: 559dfa7
Author: Samarth <sa...@salesforce.com>
Authored: Fri Apr 22 23:13:57 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Fri Apr 22 23:13:57 2016 -0700

----------------------------------------------------------------------
 .../phoenix/end2end/QueryWithOffsetIT.java      |  33 ++---
 .../phoenix/end2end/SerialIteratorsIT.java      |  90 ++++++++++++
 .../phoenix/coprocessor/ScanRegionObserver.java |   9 +-
 .../org/apache/phoenix/execute/ScanPlan.java    |  17 ++-
 .../phoenix/iterate/BaseResultIterators.java    |   4 +-
 .../phoenix/iterate/ChunkedResultIterator.java  |  13 +-
 .../phoenix/iterate/OffsetResultIterator.java   |   2 +-
 .../phoenix/iterate/ParallelIterators.java      |   4 +-
 .../apache/phoenix/iterate/SerialIterators.java | 142 ++++++++++++++-----
 .../phoenix/iterate/SpoolingResultIterator.java |  18 ++-
 .../phoenix/iterate/TableResultIterator.java    |  22 +--
 .../apache/phoenix/jdbc/PhoenixConnection.java  |   2 +-
 .../apache/phoenix/query/QueryConstants.java    |   2 +-
 .../org/apache/phoenix/schema/PTableImpl.java   |   1 +
 .../java/org/apache/phoenix/util/QueryUtil.java |  10 +-
 15 files changed, 278 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithOffsetIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithOffsetIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithOffsetIT.java
index c609581..7f360de 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithOffsetIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithOffsetIT.java
@@ -89,9 +89,10 @@ public class QueryWithOffsetIT extends BaseOwnClusterHBaseManagedTimeIT {
         rs = conn.createStatement()
                 .executeQuery("SELECT t_id from " + tableName + " order by t_id limit " + limit + " offset " + offset);
         int i = 0;
-        while (i++ < limit) {
+        while (i < limit) {
             assertTrue(rs.next());
-            assertEquals(strings[offset + i - 1], rs.getString(1));
+            assertEquals("Expected string didn't match for i = " + i, strings[offset + i], rs.getString(1));
+            i++;
         }
 
         limit = 35;
@@ -176,20 +177,6 @@ public class QueryWithOffsetIT extends BaseOwnClusterHBaseManagedTimeIT {
         conn.close();
     }
 
-    private void initTableValues(Connection conn) throws SQLException {
-        for (int i = 0; i < 26; i++) {
-            conn.createStatement().execute("UPSERT INTO " + tableName + " values('" + strings[i] + "'," + i + ","
-                    + (i + 1) + "," + (i + 2) + ",'" + strings[25 - i] + "')");
-        }
-        conn.commit();
-    }
-
-    private void updateStatistics(Connection conn) throws SQLException {
-        String query = "UPDATE STATISTICS " + tableName + " SET \"" + QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB
-                + "\"=" + Long.toString(500);
-        conn.createStatement().execute(query);
-    }
-
     @Test
     public void testMetaDataWithOffset() throws SQLException {
         Connection conn;
@@ -207,5 +194,19 @@ public class QueryWithOffsetIT extends BaseOwnClusterHBaseManagedTimeIT {
         ResultSetMetaData md = rs.getMetaData();
         assertEquals(5, md.getColumnCount());
     }
+    
+    private void initTableValues(Connection conn) throws SQLException {
+        for (int i = 0; i < 26; i++) {
+            conn.createStatement().execute("UPSERT INTO " + tableName + " values('" + strings[i] + "'," + i + ","
+                    + (i + 1) + "," + (i + 2) + ",'" + strings[25 - i] + "')");
+        }
+        conn.commit();
+    }
+
+    private void updateStatistics(Connection conn) throws SQLException {
+        String query = "UPDATE STATISTICS " + tableName + " SET \"" + QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB
+                + "\"=" + Long.toString(500);
+        conn.createStatement().execute(query);
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/it/java/org/apache/phoenix/end2end/SerialIteratorsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SerialIteratorsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SerialIteratorsIT.java
new file mode 100644
index 0000000..d4c71af
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SerialIteratorsIT.java
@@ -0,0 +1,90 @@
+/*
+ * 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.phoenix.end2end;
+
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+
+public class SerialIteratorsIT extends BaseHBaseManagedTimeTableReuseIT {
+    private String tableName = generateRandomString();
+    private final String[] strings = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
+            "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
+    private final String ddl = "CREATE TABLE " + tableName + " (t_id VARCHAR NOT NULL,\n" + "k1 INTEGER NOT NULL,\n"
+            + "k2 INTEGER NOT NULL,\n" + "C3.k3 INTEGER,\n" + "C2.v1 VARCHAR,\n"
+            + "CONSTRAINT pk PRIMARY KEY (t_id, k1, k2)) SPLIT ON ('e','i','o')";
+
+    @BeforeClass
+    public static void doSetup() throws Exception {
+        Map<String,String> props = Maps.newHashMapWithExpectedSize(3);
+        // Don't force row key order
+        props.put(QueryServices.FORCE_ROW_KEY_ORDER_ATTRIB, Boolean.toString(false));
+        setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+    }
+    
+    @Test
+    public void testConcatenatingSerialIterators() throws Exception {
+        Connection conn;
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        conn = DriverManager.getConnection(getUrl(), props);
+        createTestTable(getUrl(), ddl);
+        initTableValues(conn);
+        String query = "SELECT t_id from " + tableName + " order by t_id desc limit " + 10;
+        PhoenixStatement stmt = conn.createStatement().unwrap(PhoenixStatement.class);
+        ResultSet rs = stmt.executeQuery(query);
+        int i = 25;
+        while (i >= 16) {
+            assertTrue(rs.next());
+            assertEquals(strings[i--], rs.getString(1));
+        }
+        query = "SELECT t_id from " + tableName + " order by t_id limit " + 10;
+        stmt = conn.createStatement().unwrap(PhoenixStatement.class);
+        rs = stmt.executeQuery(query);
+        i = 0;
+        while (i < 10) {
+            assertTrue(rs.next());
+            assertEquals(strings[i++], rs.getString(1));
+        }
+        conn.close();
+    }
+    
+    private void initTableValues(Connection conn) throws SQLException {
+        for (int i = 0; i < 26; i++) {
+            conn.createStatement().execute("UPSERT INTO " + tableName + " values('" + strings[i] + "'," + i + ","
+                    + (i + 1) + "," + (i + 2) + ",'" + strings[25 - i] + "')");
+        }
+        conn.commit();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
index 3333d9c..72f6d09 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
@@ -60,6 +60,7 @@ import org.apache.phoenix.schema.KeyValueSchema.KeyValueSchemaBuilder;
 import org.apache.phoenix.schema.ValueBitSet;
 import org.apache.phoenix.schema.tuple.ResultTuple;
 import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.ScanUtil;
 import org.apache.phoenix.util.ServerUtil;
@@ -192,7 +193,7 @@ public class ScanRegionObserver extends BaseScannerRegionObserver {
         byte[] scanOffsetBytes = scan.getAttribute(BaseScannerRegionObserver.SCAN_OFFSET);
         Integer scanOffset = null;
         if (scanOffsetBytes != null) {
-            scanOffset = Bytes.toInt(scanOffsetBytes);
+            scanOffset = (Integer) PInteger.INSTANCE.toObject(scanOffsetBytes);
         }
         RegionScanner innerScanner = s;
 
@@ -246,15 +247,11 @@ public class ScanRegionObserver extends BaseScannerRegionObserver {
         final HRegion region = c.getEnvironment().getRegion();
         region.startRegionOperation();
         try {
-            // Once we return from the first call to next, we've run through and
-            // cached
-            // the topN rows, so we no longer need to start/stop a region
-            // operation.
             Tuple tuple = iterator.next();
             if (tuple == null && !isLastScan) {
                 List<KeyValue> kvList = new ArrayList<KeyValue>(1);
                 KeyValue kv = new KeyValue(QueryConstants.OFFSET_ROW_KEY_BYTES, QueryConstants.OFFSET_FAMILY,
-                        QueryConstants.OFFSET_COLUMN, Bytes.toBytes(iterator.getUnusedOffset()));
+                        QueryConstants.OFFSET_COLUMN, PInteger.INSTANCE.toBytes(iterator.getRemainingOffset()));
                 kvList.add(kv);
                 Result r = new Result(kvList);
                 firstTuple = new ResultTuple(r);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
index 93ae5d6..c5dabfe 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
@@ -18,6 +18,9 @@
 package org.apache.phoenix.execute;
 
 
+import static org.apache.phoenix.util.ScanUtil.isPacingScannersPossible;
+import static org.apache.phoenix.util.ScanUtil.isRoundRobinPossible;
+
 import java.sql.SQLException;
 import java.util.Collections;
 import java.util.List;
@@ -113,6 +116,15 @@ public class ScanPlan extends BaseQueryPlan {
             return false;
         }
         PTable table = tableRef.getTable();
+        /*
+         * For salted or local index tables, if rows are requested in a row key order, then we
+         * cannot execute a query serially. We need to be able to do a merge sort across all scans
+         * which isn't possible with SerialIterators. For other kinds of tables though we are ok
+         * since SerialIterators execute scans in the correct order.
+         */
+        if ((table.getBucketNum() != null || table.getIndexType() == IndexType.LOCAL) && ScanUtil.shouldRowsBeInRowKeyOrder(orderBy, context)) {
+            return false;
+        }
         GuidePostsInfo gpsInfo = table.getTableStats().getGuidePosts().get(SchemaUtil.getEmptyColumnFamily(table));
         long estRowSize = SchemaUtil.estimateRowSize(table);
         long estRegionSize;
@@ -147,8 +159,9 @@ public class ScanPlan extends BaseQueryPlan {
             TableRef table, OrderBy orderBy, Integer limit,Integer offset, boolean allowPageFilter) throws SQLException {
 
         if ((isSerial(context, statement, table, orderBy, limit, offset, allowPageFilter)
-                || ScanUtil.isRoundRobinPossible(orderBy, context) || ScanUtil.isPacingScannersPossible(context))
-                && offset == null) { return ParallelIteratorFactory.NOOP_FACTORY; }
+                || isRoundRobinPossible(orderBy, context) || isPacingScannersPossible(context))) {
+            return ParallelIteratorFactory.NOOP_FACTORY;
+        }
         ParallelIteratorFactory spoolingResultIteratorFactory =
                 new SpoolingResultIterator.SpoolingResultIteratorFactory(
                         context.getConnection().getQueryServices());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
index 0299f18..043bd30 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
@@ -676,7 +676,7 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
         SQLException toThrow = null;
         int queryTimeOut = context.getStatement().getQueryTimeoutInMillis();
         try {
-            submitWork(scan, futures, allIterators, splitSize);
+            submitWork(scan, futures, allIterators, splitSize, isReverse);
             boolean clearedCache = false;
             for (List<Pair<Scan,Future<PeekingResultIterator>>> future : reverseIfNecessary(futures,isReverse)) {
                 List<PeekingResultIterator> concatIterators = Lists.newArrayListWithExpectedSize(future.size());
@@ -868,7 +868,7 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
 
     abstract protected String getName();    
     abstract protected void submitWork(List<List<Scan>> nestedScans, List<List<Pair<Scan,Future<PeekingResultIterator>>>> nestedFutures,
-            Queue<PeekingResultIterator> allIterators, int estFlattenedSize) throws SQLException;
+            Queue<PeekingResultIterator> allIterators, int estFlattenedSize, boolean isReverse) throws SQLException;
     
     @Override
     public int size() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java
index a78565d..7a830de 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java
@@ -44,7 +44,13 @@ import com.google.common.base.Preconditions;
 /**
  * {@code PeekingResultIterator} implementation that loads data in chunks. This is intended for
  * basic scan plans, to avoid loading large quantities of data from HBase in one go.
+ * 
+ * <p>
+ * Chunking is deprecated and shouldn't be used while implementing new features. As of HBase 0.98.17, 
+ * we rely on pacing the server side scanners instead of pulling rows from the server in chunks.
+ * </p>
  */
+@Deprecated
 public class ChunkedResultIterator implements PeekingResultIterator {
     private static final Logger logger = LoggerFactory.getLogger(ChunkedResultIterator.class);
 
@@ -56,7 +62,12 @@ public class ChunkedResultIterator implements PeekingResultIterator {
     private final MutationState mutationState;
     private Scan scan;
     private PeekingResultIterator resultIterator;
-
+    
+    /**
+     * Chunking is deprecated and shouldn't be used while implementing new features. As of HBase 0.98.17, 
+     * we rely on pacing the server side scanners instead of pulling rows from the server in chunks.
+     */
+    @Deprecated
     public static class ChunkedResultIteratorFactory implements ParallelIteratorFactory {
 
         private final ParallelIteratorFactory delegateFactory;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/iterate/OffsetResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/OffsetResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/OffsetResultIterator.java
index ef8eacf..db53806 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/OffsetResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/OffsetResultIterator.java
@@ -56,7 +56,7 @@ public class OffsetResultIterator extends DelegateResultIterator {
         return "OffsetResultIterator [rowCount=" + rowCount + ", offset=" + offset + "]";
     }
 
-    public Integer getUnusedOffset() {
+    public Integer getRemainingOffset() {
         return (offset - rowCount) > 0 ? (offset - rowCount) : 0;
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
index ca0eba0..a5664c7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
@@ -67,7 +67,7 @@ public class ParallelIterators extends BaseResultIterators {
 
     @Override
     protected void submitWork(List<List<Scan>> nestedScans, List<List<Pair<Scan,Future<PeekingResultIterator>>>> nestedFutures,
-            final Queue<PeekingResultIterator> allIterators, int estFlattenedSize) throws SQLException {
+            final Queue<PeekingResultIterator> allIterators, int estFlattenedSize, boolean isReverse) throws SQLException {
         // Pre-populate nestedFutures lists so that we can shuffle the scans
         // and add the future to the right nested list. By shuffling the scans
         // we get better utilization of the cluster since our thread executor
@@ -99,7 +99,7 @@ public class ParallelIterators extends BaseResultIterators {
             final CombinableMetric scanMetrics = readMetrics.allotMetric(MetricType.SCAN_BYTES, physicalTableName);
             final TaskExecutionMetricsHolder taskMetrics = new TaskExecutionMetricsHolder(readMetrics, physicalTableName);
             final TableResultIterator tableResultItr = context.getConnection().getTableResultIteratorFactory().newIterator(mutationState, tableRef, scan, scanMetrics, renewLeaseThreshold);
-            context.getConnection().addIterator(tableResultItr);
+            context.getConnection().addIteratorForLeaseRenewal(tableResultItr);
             Future<PeekingResultIterator> future = executor.submit(Tracing.wrap(new JobCallable<PeekingResultIterator>() {
                 
                 @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
index 17c2279..d2c89b9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
@@ -30,13 +30,16 @@ import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.job.JobManager.JobCallable;
 import org.apache.phoenix.monitoring.TaskExecutionMetricsHolder;
 import org.apache.phoenix.parse.HintNode;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.trace.util.Tracing;
-import org.apache.phoenix.util.ScanUtil;
+import org.apache.phoenix.util.QueryUtil;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
@@ -53,11 +56,13 @@ import com.google.common.collect.Lists;
 public class SerialIterators extends BaseResultIterators {
 	private static final String NAME = "SERIAL";
     private final ParallelIteratorFactory iteratorFactory;
+    private final Integer offset;
     
     public SerialIterators(QueryPlan plan, Integer perScanLimit, Integer offset,
             ParallelIteratorFactory iteratorFactory, ParallelScanGrouper scanGrouper)
             throws SQLException {
         super(plan, perScanLimit, offset, scanGrouper);
+        this.offset = offset;
         // must be a offset or a limit specified or a SERIAL hint
         Preconditions.checkArgument(
                 offset != null || perScanLimit != null || plan.getStatement().getHint().hasHint(HintNode.Hint.SERIAL));
@@ -65,40 +70,28 @@ public class SerialIterators extends BaseResultIterators {
     }
 
     @Override
-    protected void submitWork(List<List<Scan>> nestedScans, List<List<Pair<Scan,Future<PeekingResultIterator>>>> nestedFutures,
-            final Queue<PeekingResultIterator> allIterators, int estFlattenedSize) {
-        // Pre-populate nestedFutures lists so that we can shuffle the scans
-        // and add the future to the right nested list. By shuffling the scans
-        // we get better utilization of the cluster since our thread executor
-        // will spray the scans across machines as opposed to targeting a
-        // single one since the scans are in row key order.
+    protected void submitWork(final List<List<Scan>> nestedScans, List<List<Pair<Scan,Future<PeekingResultIterator>>>> nestedFutures,
+            final Queue<PeekingResultIterator> allIterators, int estFlattenedSize, boolean isReverse) {
         ExecutorService executor = context.getConnection().getQueryServices().getExecutor();
-        
-        for (final List<Scan> scans : nestedScans) {
-            Scan firstScan = scans.get(0);
-            Scan lastScan = scans.get(scans.size()-1);
-            final Scan overallScan = ScanUtil.newScan(firstScan);
-            overallScan.setStopRow(lastScan.getStopRow());
-            final String tableName = tableRef.getTable().getPhysicalName().getString();
-            final TaskExecutionMetricsHolder taskMetrics = new TaskExecutionMetricsHolder(context.getReadMetricsQueue(), tableName);
-            final PhoenixConnection conn = context.getConnection();
-            final long renewLeaseThreshold = conn.getQueryServices().getRenewLeaseThresholdMilliSeconds();
-            lastScan.setAttribute(QueryConstants.LAST_SCAN, Bytes.toBytes(Boolean.TRUE));
+        final String tableName = tableRef.getTable().getPhysicalName().getString();
+        final TaskExecutionMetricsHolder taskMetrics = new TaskExecutionMetricsHolder(context.getReadMetricsQueue(), tableName);
+        final PhoenixConnection conn = context.getConnection();
+        final long renewLeaseThreshold = conn.getQueryServices().getRenewLeaseThresholdMilliSeconds();
+        int expectedListSize = nestedScans.size() * 10;
+        List<Scan> flattenedScans = Lists.newArrayListWithExpectedSize(expectedListSize);
+        for (List<Scan> list : nestedScans) {
+            flattenedScans.addAll(list);
+        }
+        if (!flattenedScans.isEmpty()) { 
+            if (isReverse) {
+                flattenedScans = Lists.reverse(flattenedScans);
+            }
+            final List<Scan> finalScans = flattenedScans;
             Future<PeekingResultIterator> future = executor.submit(Tracing.wrap(new JobCallable<PeekingResultIterator>() {
                 @Override
                 public PeekingResultIterator call() throws Exception {
-                    PeekingResultIterator previousIterator = null;
-                	List<PeekingResultIterator> concatIterators = Lists.newArrayListWithExpectedSize(scans.size());
-                	for (final Scan scan : scans) {
-                	    TableResultIterator scanner = new TableResultIterator(mutationState, tableRef, scan, context.getReadMetricsQueue().allotMetric(SCAN_BYTES, tableName), renewLeaseThreshold, previousIterator);
-                	    conn.addIterator(scanner);
-                	    PeekingResultIterator iterator = iteratorFactory.newIterator(context, scanner, scan, tableName);
-                	    concatIterators.add(iterator);
-                	    previousIterator = iterator;
-                	}
-                	PeekingResultIterator concatIterator = ConcatResultIterator.newIterator(concatIterators);
-                    allIterators.add(concatIterator);
-                    return concatIterator;
+                    PeekingResultIterator itr = new SerialIterator(finalScans, tableName, renewLeaseThreshold, offset);
+                    return itr;
                 }
 
                 /**
@@ -117,7 +110,7 @@ public class SerialIterators extends BaseResultIterators {
                 }
             }, "Serial scanner for table: " + tableRef.getTable().getPhysicalName().getString()));
             // Add our singleton Future which will execute serially
-            nestedFutures.add(Collections.singletonList(new Pair<Scan,Future<PeekingResultIterator>>(overallScan,future)));
+            nestedFutures.add(Collections.singletonList(new Pair<Scan, Future<PeekingResultIterator>>(flattenedScans.get(0), future)));
         }
     }
 
@@ -125,4 +118,89 @@ public class SerialIterators extends BaseResultIterators {
     protected String getName() {
         return NAME;
     }
+    
+    /**
+     * 
+     * Iterator that creates iterators for scans only when needed.
+     * This helps reduce the cost of pre-constructing all the iterators
+     * which we may not even use.
+     */
+    private class SerialIterator implements PeekingResultIterator {
+        private final List<Scan> scans;
+        private final String tableName;
+        private final long renewLeaseThreshold;
+        private int index;
+        private PeekingResultIterator currentIterator;
+        private Integer remainingOffset;
+        
+        private SerialIterator(List<Scan> flattenedScans, String tableName, long renewLeaseThreshold, Integer offset) throws SQLException {
+            this.scans = Lists.newArrayListWithExpectedSize(flattenedScans.size());
+            this.tableName = tableName;
+            this.renewLeaseThreshold = renewLeaseThreshold;
+            this.scans.addAll(flattenedScans);
+            this.remainingOffset = offset;
+            if (this.remainingOffset != null) {
+                // mark the last scan for offset purposes
+                this.scans.get(this.scans.size() - 1).setAttribute(QueryConstants.LAST_SCAN, Bytes.toBytes(Boolean.TRUE));
+            }
+        }
+        
+        private PeekingResultIterator currentIterator() throws SQLException {
+            if (currentIterator == null) {
+                return currentIterator = nextIterator();
+            }
+            if (currentIterator.peek() == null) {
+                currentIterator.close();
+                currentIterator = nextIterator();
+            }
+            return currentIterator;
+        }
+        
+        private PeekingResultIterator nextIterator() throws SQLException {
+            if (index >= scans.size()) {
+                return EMPTY_ITERATOR;
+            }
+            while (index < scans.size()) {
+                Scan currentScan = scans.get(index++);
+                if (remainingOffset != null) {
+                    currentScan.setAttribute(BaseScannerRegionObserver.SCAN_OFFSET, PInteger.INSTANCE.toBytes(remainingOffset));
+                }
+                TableResultIterator itr = new TableResultIterator(mutationState, tableRef, currentScan, context.getReadMetricsQueue().allotMetric(SCAN_BYTES, tableName), renewLeaseThreshold);
+                PeekingResultIterator peekingItr = iteratorFactory.newIterator(context, itr, currentScan, tableName);
+                Tuple tuple;
+                if ((tuple = peekingItr.peek()) == null) {
+                    peekingItr.close();
+                    continue;
+                } else if ((remainingOffset = QueryUtil.getRemainingOffset(tuple)) != null) {
+                    peekingItr.next();
+                    peekingItr.close();
+                    continue;
+                }
+                context.getConnection().addIteratorForLeaseRenewal(itr);
+                return peekingItr;
+            }
+            return EMPTY_ITERATOR;
+        }
+        
+        @Override
+        public Tuple next() throws SQLException {
+            return currentIterator().next();
+        }
+
+        @Override
+        public void explain(List<String> planSteps) {}
+
+        @Override
+        public void close() throws SQLException {
+            if (currentIterator != null) {
+                currentIterator.close();
+            }
+        }
+
+        @Override
+        public Tuple peek() throws SQLException {
+            return currentIterator().peek();
+        }
+        
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/iterate/SpoolingResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/SpoolingResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/SpoolingResultIterator.java
index 540b410..48ebed4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/SpoolingResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/SpoolingResultIterator.java
@@ -57,16 +57,28 @@ import org.apache.phoenix.util.TupleUtil;
  *
  * Result iterator that spools the results of a scan to disk once an in-memory threshold has been reached.
  * If the in-memory threshold is not reached, the results are held in memory with no disk writing perfomed.
- *
- *
+ * 
+ * <p>
+ * Spooling is deprecated and shouldn't be used while implementing new features. As of HBase 0.98.17, 
+ * we rely on pacing the server side scanners instead of pulling rows from the server and  potentially 
+ * spooling to a temporary file created on clients.
+ * </p>
+ *  
  * @since 0.1
  */
+@Deprecated
 public class SpoolingResultIterator implements PeekingResultIterator {
     
     private final PeekingResultIterator spoolFrom;
     private final SpoolingMetricsHolder spoolMetrics;
     private final MemoryMetricsHolder memoryMetrics;
-
+    
+    /**
+     * Spooling is deprecated and shouldn't be used while implementing new features. As of HBase
+     * 0.98.17, we rely on pacing the server side scanners instead of pulling rows from the server
+     * and potentially spooling to a temporary file created on clients.
+     */
+    @Deprecated
     public static class SpoolingResultIteratorFactory implements ParallelIteratorFactory {
         private final QueryServices services;
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
index f5a9dc4..029987a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
@@ -32,14 +32,12 @@ import javax.annotation.concurrent.GuardedBy;
 import org.apache.hadoop.hbase.client.AbstractClientScanner;
 import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Scan;
-import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
 import org.apache.phoenix.execute.MutationState;
 import org.apache.phoenix.monitoring.CombinableMetric;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.Closeables;
-import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.ServerUtil;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -70,8 +68,7 @@ public class TableResultIterator implements ResultIterator {
 
     @GuardedBy("this")
     private long renewLeaseTime = 0;
-    private PeekingResultIterator previousIterator;
-
+    
     @VisibleForTesting // Exposed for testing. DON'T USE ANYWHERE ELSE!
     TableResultIterator() {
         this.scanMetrics = null;
@@ -85,19 +82,13 @@ public class TableResultIterator implements ResultIterator {
     };
 
     public TableResultIterator(MutationState mutationState, TableRef tableRef, Scan scan, CombinableMetric scanMetrics,
-			long renewLeaseThreshold) throws SQLException {
-    	this(mutationState,tableRef,scan,scanMetrics,renewLeaseThreshold,null);
-    }
-    
-    public TableResultIterator(MutationState mutationState, TableRef tableRef, Scan scan, CombinableMetric scanMetrics,
-            long renewLeaseThreshold, PeekingResultIterator previousIterator) throws SQLException {
+            long renewLeaseThreshold) throws SQLException {
         this.scan = scan;
         this.scanMetrics = scanMetrics;
         PTable table = tableRef.getTable();
         htable = mutationState.getHTable(table);
         this.scanIterator = UNINITIALIZED_SCANNER;
         this.renewLeaseThreshold = renewLeaseThreshold;
-        this.previousIterator = previousIterator;
     }
 
     @Override
@@ -129,15 +120,6 @@ public class TableResultIterator implements ResultIterator {
         ResultIterator delegate = this.scanIterator;
         if (delegate == UNINITIALIZED_SCANNER) {
             try {
-                if (previousIterator != null && scan.getAttribute(BaseScannerRegionObserver.SCAN_OFFSET) != null) {
-                    byte[] unusedOffset = QueryUtil.getUnusedOffset(previousIterator.peek());
-                    if (unusedOffset != null) {
-                        scan.setAttribute(BaseScannerRegionObserver.SCAN_OFFSET, unusedOffset);
-                        previousIterator.next();
-                    } else {
-                        scan.setAttribute(BaseScannerRegionObserver.SCAN_OFFSET, null);
-                    }
-                }
                 this.scanIterator =
                         new ScanningResultIterator(htable.getScanner(scan), scanMetrics);
             } catch (IOException e) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index 80179ae..08b300b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -1033,7 +1033,7 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
         this.parallelIteratorFactory = parallelIteratorFactory;
     }
     
-    public void addIterator(@Nonnull TableResultIterator itr) {
+    public void addIteratorForLeaseRenewal(@Nonnull TableResultIterator itr) {
         if (services.supportsFeature(Feature.RENEW_LEASE)) {
             checkNotNull(itr);
             scannerQueue.add(new WeakReference<TableResultIterator>(itr));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
index 450ccfe..36aa8cd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
@@ -144,7 +144,7 @@ public interface QueryConstants {
     public final static String PHOENIX_METADATA = "table";
     public final static String OFFSET_ROW_KEY = "_OFFSET_";
     public final static byte[] OFFSET_ROW_KEY_BYTES = Bytes.toBytes(OFFSET_ROW_KEY);
-    public final static ImmutableBytesPtr offsetRowKeyPtr = new ImmutableBytesPtr(OFFSET_ROW_KEY_BYTES);
+    public final static ImmutableBytesPtr OFFSET_ROW_KEY_PTR = new ImmutableBytesPtr(OFFSET_ROW_KEY_BYTES);
 
     public final static PName SINGLE_COLUMN_NAME = PNameFactory.newNormalizedName("s");
     public final static PName SINGLE_COLUMN_FAMILY_NAME = PNameFactory.newNormalizedName("s");

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index 665e77f..f4300fd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -1226,6 +1226,7 @@ public class PTableImpl implements PTable {
         return isTransactional;
     }
 
+    @Override
     public int getBaseColumnCount() {
         return baseColumnCount;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/54362430/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java
index 99c4596..a0c367d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/QueryUtil.java
@@ -48,7 +48,9 @@ import org.apache.phoenix.parse.WildcardParseNode;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.query.QueryServicesOptions;
+import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.schema.types.PInteger;
 
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
@@ -370,13 +372,13 @@ public final class QueryUtil {
 
     }
 
-    public static byte[] getUnusedOffset(Tuple offsetTuple) {
+    public static Integer getRemainingOffset(Tuple offsetTuple) {
         if (offsetTuple != null) {
             ImmutableBytesPtr rowKeyPtr = new ImmutableBytesPtr();
             offsetTuple.getKey(rowKeyPtr);
-            if (QueryConstants.offsetRowKeyPtr.compareTo(rowKeyPtr) == 0) {
-                Cell value = offsetTuple.getValue(QueryConstants.OFFSET_FAMILY, QueryConstants.OFFSET_COLUMN);
-                return value.getValue();
+            if (QueryConstants.OFFSET_ROW_KEY_PTR.compareTo(rowKeyPtr) == 0) {
+                Cell cell = offsetTuple.getValue(QueryConstants.OFFSET_FAMILY, QueryConstants.OFFSET_COLUMN);
+                return PInteger.INSTANCE.toObject(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength(), PInteger.INSTANCE, SortOrder.ASC, null, null);
             }
         }
         return null;


[43/52] [abbrv] phoenix git commit: Metadata changes to support encoding of column names

Posted by sa...@apache.org.
Metadata changes to support encoding of column names


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

Branch: refs/heads/encodecolumns
Commit: cd891030f4b23d185269d3d23bf719472ddc70e9
Parents: 0cec970
Author: Samarth <sa...@salesforce.com>
Authored: Tue Mar 8 13:48:24 2016 -0800
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:31 2016 -0700

----------------------------------------------------------------------
 .../apache/phoenix/end2end/AlterTableIT.java    |  30 ++++
 .../apache/phoenix/compile/FromCompiler.java    |   8 +-
 .../phoenix/compile/ListJarsQueryPlan.java      |   2 +-
 .../apache/phoenix/compile/TraceQueryPlan.java  |   2 +-
 .../apache/phoenix/compile/UnionCompiler.java   |   3 +-
 .../coprocessor/MetaDataEndpointImpl.java       |  11 +-
 .../coprocessor/generated/PTableProtos.java     | 147 +++++++++++++++----
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java   |   2 +
 .../query/ConnectionQueryServicesImpl.java      |   1 +
 .../apache/phoenix/query/QueryConstants.java    |   2 +
 .../apache/phoenix/schema/DelegateColumn.java   |   5 +
 .../apache/phoenix/schema/MetaDataClient.java   |  41 ++++--
 .../java/org/apache/phoenix/schema/PColumn.java |   7 +-
 .../org/apache/phoenix/schema/PColumnImpl.java  |  24 ++-
 .../apache/phoenix/schema/PMetaDataImpl.java    |   2 +-
 .../org/apache/phoenix/schema/SaltingUtil.java  |   2 +-
 .../org/apache/phoenix/util/SchemaUtil.java     |  14 ++
 .../phoenix/execute/CorrelatePlanTest.java      |   2 +-
 .../execute/LiteralResultIteratorPlanTest.java  |   2 +-
 .../phoenix/execute/UnnestArrayPlanTest.java    |   4 +-
 .../expression/ColumnExpressionTest.java        |   8 +-
 .../iterate/AggregateResultScannerTest.java     |   4 +
 phoenix-protocol/src/main/PTable.proto          |   1 +
 23 files changed, 260 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index e09dcea..bad6200 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -44,6 +44,7 @@ import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.KeepDeletedCells;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.ResultScanner;
 import org.apache.hadoop.hbase.client.Scan;
@@ -2216,5 +2217,34 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
 		}
 	}
 	
+	@Test
+    public void testColumnQualifierForUpsertedValues() throws Exception {
+        String schemaName = "A";
+        String tableName = "TEST";
+        String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
+        String ddl = "create table " + fullTableName 
+                + " (" 
+                + " K varchar primary key,"
+                + " CF1.V1 varchar)";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            conn.createStatement().execute(ddl);
+        }
+        String dml = "UPSERT INTO " + fullTableName + " VALUES (?, ?)";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PreparedStatement stmt = conn.prepareStatement(dml);
+            stmt.setString(1, "KEY1");
+            stmt.setString(2, "VALUE1");
+            stmt.executeUpdate();
+            conn.commit();
+        }
+        // Issue a raw hbase scan using the column qualifier 0 for column CF1.V1.
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            HTableInterface table = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes(fullTableName));
+            ResultScanner scanner = table.getScanner(new Scan());
+            Result next = scanner.next();
+            assertTrue(next.containsColumn(Bytes.toBytes("CF1"), Bytes.toBytes("V1")));
+        }
+    }
+    
 }
  

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
index a2fc371..abcf432 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
@@ -250,7 +250,7 @@ public class FromCompiler {
             Expression sourceExpression = projector.getColumnProjector(column.getPosition()).getExpression();
             PColumnImpl projectedColumn = new PColumnImpl(column.getName(), column.getFamilyName(),
                     sourceExpression.getDataType(), sourceExpression.getMaxLength(), sourceExpression.getScale(), sourceExpression.isNullable(),
-                    column.getPosition(), sourceExpression.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic());
+                    column.getPosition(), sourceExpression.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic(), column.getColumnQualifier());
             projectedColumns.add(projectedColumn);
         }
         PTable t = PTableImpl.makePTable(table, projectedColumns);
@@ -664,8 +664,9 @@ public class FromCompiler {
                         theTable.getColumnFamily(family); // Verifies that column family exists
                         familyName = PNameFactory.newName(family);
                     }
+                    // Dynamic columns don't have a corresponding column qualifier
                     allcolumns.add(new PColumnImpl(name, familyName, dynColumn.getDataType(), dynColumn.getMaxLength(),
-                            dynColumn.getScale(), dynColumn.isNull(), position, dynColumn.getSortOrder(), dynColumn.getArraySize(), null, false, dynColumn.getExpression(), false, true));
+                            dynColumn.getScale(), dynColumn.isNull(), position, dynColumn.getSortOrder(), dynColumn.getArraySize(), null, false, dynColumn.getExpression(), false, true, null));
                     position++;
                 }
                 theTable = PTableImpl.makePTable(theTable, allcolumns);
@@ -767,9 +768,10 @@ public class FromCompiler {
                     // referenced by an outer wild-card select.
                     alias = String.valueOf(position);
                 }
+                //TODO: samarth confirm this is the right change i.e. using null for column qualifier
                 PColumnImpl column = new PColumnImpl(PNameFactory.newName(alias),
                         PNameFactory.newName(QueryConstants.DEFAULT_COLUMN_FAMILY),
-                        null, 0, 0, true, position++, SortOrder.ASC, null, null, false, null, false, false);
+                        null, 0, 0, true, position++, SortOrder.ASC, null, null, false, null, false, false, null);
                 columns.add(column);
             }
             PTable t = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
index 1047334..cceef9a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
@@ -80,7 +80,7 @@ public class ListJarsQueryPlan implements QueryPlan {
         PColumn column =
                 new PColumnImpl(PNameFactory.newName("jar_location"), null,
                         PVarchar.INSTANCE, null, null, false, 0, SortOrder.getDefault(), 0, null,
-                        false, null, false, false);
+                        false, null, false, false, null);
         List<PColumn> columns = new ArrayList<PColumn>();
         columns.add(column);
         Expression expression =

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
index 699643b..79d212f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
@@ -78,7 +78,7 @@ public class TraceQueryPlan implements QueryPlan {
         PColumn column =
                 new PColumnImpl(PNameFactory.newName(MetricInfo.TRACE.columnName), null,
                         PLong.INSTANCE, null, null, false, 0, SortOrder.getDefault(), 0, null,
-                        false, null, false, false);
+                        false, null, false, false, null);
         List<PColumn> columns = new ArrayList<PColumn>();
         columns.add(column);
         Expression expression =

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
index 32fa8fe..f720e9d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
@@ -74,9 +74,10 @@ public class UnionCompiler {
             ColumnProjector colProj = plan.getProjector().getColumnProjector(i);
             Expression sourceExpression = colProj.getExpression();
             String name = selectNodes == null ? colProj.getName() : selectNodes.get(i).getAlias();
+            //TODO: samarth confirm this is the right change
             PColumnImpl projectedColumn = new PColumnImpl(PNameFactory.newName(name), UNION_FAMILY_NAME,
                     sourceExpression.getDataType(), sourceExpression.getMaxLength(), sourceExpression.getScale(), sourceExpression.isNullable(),
-                    i, sourceExpression.getSortOrder(), 500, null, false, sourceExpression.toString(), false, false);
+                    i, sourceExpression.getSortOrder(), 500, null, false, sourceExpression.toString(), false, false, null);
             projectedColumns.add(projectedColumn);
         }
         Long scn = statement.getConnection().getSCN();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 1fd4f44..a9dd9ea 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -25,6 +25,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CLASS_NAME_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME_INDEX;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TYPE_BYTES;
@@ -331,6 +332,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final KeyValue IS_VIEW_REFERENCED_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, IS_VIEW_REFERENCED_BYTES);
     private static final KeyValue COLUMN_DEF_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_DEF_BYTES);
     private static final KeyValue IS_ROW_TIMESTAMP_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, IS_ROW_TIMESTAMP_BYTES);
+    private static final KeyValue COLUMN_QUALIFIER_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_QUALIFIER_BYTES);
     private static final List<KeyValue> COLUMN_KV_COLUMNS = Arrays.<KeyValue>asList(
             DECIMAL_DIGITS_KV,
             COLUMN_SIZE_KV,
@@ -343,7 +345,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             VIEW_CONSTANT_KV,
             IS_VIEW_REFERENCED_KV,
             COLUMN_DEF_KV,
-            IS_ROW_TIMESTAMP_KV
+            IS_ROW_TIMESTAMP_KV,
+            COLUMN_QUALIFIER_KV
             );
     static {
         Collections.sort(COLUMN_KV_COLUMNS, KeyValue.COMPARATOR);
@@ -359,6 +362,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final int IS_VIEW_REFERENCED_INDEX = COLUMN_KV_COLUMNS.indexOf(IS_VIEW_REFERENCED_KV);
     private static final int COLUMN_DEF_INDEX = COLUMN_KV_COLUMNS.indexOf(COLUMN_DEF_KV);
     private static final int IS_ROW_TIMESTAMP_INDEX = COLUMN_KV_COLUMNS.indexOf(IS_ROW_TIMESTAMP_KV);
+    private static final int COLUMN_QUALIFIER_INDEX = COLUMN_KV_COLUMNS.indexOf(COLUMN_QUALIFIER_KV);
     
     private static final int LINK_TYPE_INDEX = 0;
 
@@ -697,8 +701,11 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 isRowTimestampKV == null ? false : Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(
                         isRowTimestampKV.getValueArray(), isRowTimestampKV.getValueOffset(),
                         isRowTimestampKV.getValueLength()));
+        Cell columnQualifierKV = colKeyValues[COLUMN_QUALIFIER_INDEX];
+        Integer columnQualifier = columnQualifierKV == null ? null :
+            PInteger.INSTANCE.getCodec().decodeInt(columnQualifierKV.getValueArray(), columnQualifierKV.getValueOffset(), SortOrder.getDefault());
 
-        PColumn column = new PColumnImpl(colName, famName, dataType, maxLength, scale, isNullable, position-1, sortOrder, arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, false);
+        PColumn column = new PColumnImpl(colName, famName, dataType, maxLength, scale, isNullable, position-1, sortOrder, arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, false, columnQualifier);
         columns.add(column);
     }
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
index 126c0dd..24bb841 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
@@ -269,6 +269,16 @@ public final class PTableProtos {
      * <code>optional bool isDynamic = 14;</code>
      */
     boolean getIsDynamic();
+
+    // optional int32 columnQualifier = 15;
+    /**
+     * <code>optional int32 columnQualifier = 15;</code>
+     */
+    boolean hasColumnQualifier();
+    /**
+     * <code>optional int32 columnQualifier = 15;</code>
+     */
+    int getColumnQualifier();
   }
   /**
    * Protobuf type {@code PColumn}
@@ -391,6 +401,11 @@ public final class PTableProtos {
               isDynamic_ = input.readBool();
               break;
             }
+            case 120: {
+              bitField0_ |= 0x00004000;
+              columnQualifier_ = input.readInt32();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -709,6 +724,22 @@ public final class PTableProtos {
       return isDynamic_;
     }
 
+    // optional int32 columnQualifier = 15;
+    public static final int COLUMNQUALIFIER_FIELD_NUMBER = 15;
+    private int columnQualifier_;
+    /**
+     * <code>optional int32 columnQualifier = 15;</code>
+     */
+    public boolean hasColumnQualifier() {
+      return ((bitField0_ & 0x00004000) == 0x00004000);
+    }
+    /**
+     * <code>optional int32 columnQualifier = 15;</code>
+     */
+    public int getColumnQualifier() {
+      return columnQualifier_;
+    }
+
     private void initFields() {
       columnNameBytes_ = com.google.protobuf.ByteString.EMPTY;
       familyNameBytes_ = com.google.protobuf.ByteString.EMPTY;
@@ -724,6 +755,7 @@ public final class PTableProtos {
       expression_ = "";
       isRowTimestamp_ = false;
       isDynamic_ = false;
+      columnQualifier_ = 0;
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -799,6 +831,9 @@ public final class PTableProtos {
       if (((bitField0_ & 0x00002000) == 0x00002000)) {
         output.writeBool(14, isDynamic_);
       }
+      if (((bitField0_ & 0x00004000) == 0x00004000)) {
+        output.writeInt32(15, columnQualifier_);
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -864,6 +899,10 @@ public final class PTableProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeBoolSize(14, isDynamic_);
       }
+      if (((bitField0_ & 0x00004000) == 0x00004000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(15, columnQualifier_);
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -957,6 +996,11 @@ public final class PTableProtos {
         result = result && (getIsDynamic()
             == other.getIsDynamic());
       }
+      result = result && (hasColumnQualifier() == other.hasColumnQualifier());
+      if (hasColumnQualifier()) {
+        result = result && (getColumnQualifier()
+            == other.getColumnQualifier());
+      }
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -1026,6 +1070,10 @@ public final class PTableProtos {
         hash = (37 * hash) + ISDYNAMIC_FIELD_NUMBER;
         hash = (53 * hash) + hashBoolean(getIsDynamic());
       }
+      if (hasColumnQualifier()) {
+        hash = (37 * hash) + COLUMNQUALIFIER_FIELD_NUMBER;
+        hash = (53 * hash) + getColumnQualifier();
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -1163,6 +1211,8 @@ public final class PTableProtos {
         bitField0_ = (bitField0_ & ~0x00001000);
         isDynamic_ = false;
         bitField0_ = (bitField0_ & ~0x00002000);
+        columnQualifier_ = 0;
+        bitField0_ = (bitField0_ & ~0x00004000);
         return this;
       }
 
@@ -1247,6 +1297,10 @@ public final class PTableProtos {
           to_bitField0_ |= 0x00002000;
         }
         result.isDynamic_ = isDynamic_;
+        if (((from_bitField0_ & 0x00004000) == 0x00004000)) {
+          to_bitField0_ |= 0x00004000;
+        }
+        result.columnQualifier_ = columnQualifier_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -1309,6 +1363,9 @@ public final class PTableProtos {
         if (other.hasIsDynamic()) {
           setIsDynamic(other.getIsDynamic());
         }
+        if (other.hasColumnQualifier()) {
+          setColumnQualifier(other.getColumnQualifier());
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -1909,6 +1966,39 @@ public final class PTableProtos {
         return this;
       }
 
+      // optional int32 columnQualifier = 15;
+      private int columnQualifier_ ;
+      /**
+       * <code>optional int32 columnQualifier = 15;</code>
+       */
+      public boolean hasColumnQualifier() {
+        return ((bitField0_ & 0x00004000) == 0x00004000);
+      }
+      /**
+       * <code>optional int32 columnQualifier = 15;</code>
+       */
+      public int getColumnQualifier() {
+        return columnQualifier_;
+      }
+      /**
+       * <code>optional int32 columnQualifier = 15;</code>
+       */
+      public Builder setColumnQualifier(int value) {
+        bitField0_ |= 0x00004000;
+        columnQualifier_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int32 columnQualifier = 15;</code>
+       */
+      public Builder clearColumnQualifier() {
+        bitField0_ = (bitField0_ & ~0x00004000);
+        columnQualifier_ = 0;
+        onChanged();
+        return this;
+      }
+
       // @@protoc_insertion_point(builder_scope:PColumn)
     }
 
@@ -7179,7 +7269,7 @@ public final class PTableProtos {
       descriptor;
   static {
     java.lang.String[] descriptorData = {
-      "\n\014PTable.proto\032\021PGuidePosts.proto\"\246\002\n\007PC" +
+      "\n\014PTable.proto\032\021PGuidePosts.proto\"\277\002\n\007PC" +
       "olumn\022\027\n\017columnNameBytes\030\001 \002(\014\022\027\n\017family" +
       "NameBytes\030\002 \001(\014\022\020\n\010dataType\030\003 \002(\t\022\021\n\tmax" +
       "Length\030\004 \001(\005\022\r\n\005scale\030\005 \001(\005\022\020\n\010nullable\030" +
@@ -7187,32 +7277,33 @@ public final class PTableProtos {
       "(\005\022\021\n\tarraySize\030\t \001(\005\022\024\n\014viewConstant\030\n " +
       "\001(\014\022\026\n\016viewReferenced\030\013 \001(\010\022\022\n\nexpressio" +
       "n\030\014 \001(\t\022\026\n\016isRowTimestamp\030\r \001(\010\022\021\n\tisDyn" +
-      "amic\030\016 \001(\010\"\232\001\n\013PTableStats\022\013\n\003key\030\001 \002(\014\022" +
-      "\016\n\006values\030\002 \003(\014\022\033\n\023guidePostsByteCount\030\003",
-      " \001(\003\022\025\n\rkeyBytesCount\030\004 \001(\003\022\027\n\017guidePost" +
-      "sCount\030\005 \001(\005\022!\n\013pGuidePosts\030\006 \001(\0132\014.PGui" +
-      "dePosts\"\336\005\n\006PTable\022\027\n\017schemaNameBytes\030\001 " +
-      "\002(\014\022\026\n\016tableNameBytes\030\002 \002(\014\022\036\n\ttableType" +
-      "\030\003 \002(\0162\013.PTableType\022\022\n\nindexState\030\004 \001(\t\022" +
-      "\026\n\016sequenceNumber\030\005 \002(\003\022\021\n\ttimeStamp\030\006 \002" +
-      "(\003\022\023\n\013pkNameBytes\030\007 \001(\014\022\021\n\tbucketNum\030\010 \002" +
-      "(\005\022\031\n\007columns\030\t \003(\0132\010.PColumn\022\030\n\007indexes" +
-      "\030\n \003(\0132\007.PTable\022\027\n\017isImmutableRows\030\013 \002(\010" +
-      "\022 \n\nguidePosts\030\014 \003(\0132\014.PTableStats\022\032\n\022da",
-      "taTableNameBytes\030\r \001(\014\022\031\n\021defaultFamilyN" +
-      "ame\030\016 \001(\014\022\022\n\ndisableWAL\030\017 \002(\010\022\023\n\013multiTe" +
-      "nant\030\020 \002(\010\022\020\n\010viewType\030\021 \001(\014\022\025\n\rviewStat" +
-      "ement\030\022 \001(\014\022\025\n\rphysicalNames\030\023 \003(\014\022\020\n\010te" +
-      "nantId\030\024 \001(\014\022\023\n\013viewIndexId\030\025 \001(\005\022\021\n\tind" +
-      "exType\030\026 \001(\014\022\026\n\016statsTimeStamp\030\027 \001(\003\022\022\n\n" +
-      "storeNulls\030\030 \001(\010\022\027\n\017baseColumnCount\030\031 \001(" +
-      "\005\022\036\n\026rowKeyOrderOptimizable\030\032 \001(\010\022\025\n\rtra" +
-      "nsactional\030\033 \001(\010\022\034\n\024updateCacheFrequency" +
-      "\030\034 \001(\003\022\035\n\025indexDisableTimestamp\030\035 \001(\003\022\031\n",
-      "\021isNamespaceMapped\030\036 \001(\010*A\n\nPTableType\022\n" +
-      "\n\006SYSTEM\020\000\022\010\n\004USER\020\001\022\010\n\004VIEW\020\002\022\t\n\005INDEX\020" +
-      "\003\022\010\n\004JOIN\020\004B@\n(org.apache.phoenix.coproc" +
-      "essor.generatedB\014PTableProtosH\001\210\001\001\240\001\001"
+      "amic\030\016 \001(\010\022\027\n\017columnQualifier\030\017 \001(\005\"\232\001\n\013" +
+      "PTableStats\022\013\n\003key\030\001 \002(\014\022\016\n\006values\030\002 \003(\014",
+      "\022\033\n\023guidePostsByteCount\030\003 \001(\003\022\025\n\rkeyByte" +
+      "sCount\030\004 \001(\003\022\027\n\017guidePostsCount\030\005 \001(\005\022!\n" +
+      "\013pGuidePosts\030\006 \001(\0132\014.PGuidePosts\"\336\005\n\006PTa" +
+      "ble\022\027\n\017schemaNameBytes\030\001 \002(\014\022\026\n\016tableNam" +
+      "eBytes\030\002 \002(\014\022\036\n\ttableType\030\003 \002(\0162\013.PTable" +
+      "Type\022\022\n\nindexState\030\004 \001(\t\022\026\n\016sequenceNumb" +
+      "er\030\005 \002(\003\022\021\n\ttimeStamp\030\006 \002(\003\022\023\n\013pkNameByt" +
+      "es\030\007 \001(\014\022\021\n\tbucketNum\030\010 \002(\005\022\031\n\007columns\030\t" +
+      " \003(\0132\010.PColumn\022\030\n\007indexes\030\n \003(\0132\007.PTable" +
+      "\022\027\n\017isImmutableRows\030\013 \002(\010\022 \n\nguidePosts\030",
+      "\014 \003(\0132\014.PTableStats\022\032\n\022dataTableNameByte" +
+      "s\030\r \001(\014\022\031\n\021defaultFamilyName\030\016 \001(\014\022\022\n\ndi" +
+      "sableWAL\030\017 \002(\010\022\023\n\013multiTenant\030\020 \002(\010\022\020\n\010v" +
+      "iewType\030\021 \001(\014\022\025\n\rviewStatement\030\022 \001(\014\022\025\n\r" +
+      "physicalNames\030\023 \003(\014\022\020\n\010tenantId\030\024 \001(\014\022\023\n" +
+      "\013viewIndexId\030\025 \001(\005\022\021\n\tindexType\030\026 \001(\014\022\026\n" +
+      "\016statsTimeStamp\030\027 \001(\003\022\022\n\nstoreNulls\030\030 \001(" +
+      "\010\022\027\n\017baseColumnCount\030\031 \001(\005\022\036\n\026rowKeyOrde" +
+      "rOptimizable\030\032 \001(\010\022\025\n\rtransactional\030\033 \001(" +
+      "\010\022\034\n\024updateCacheFrequency\030\034 \001(\003\022\035\n\025index",
+      "DisableTimestamp\030\035 \001(\003\022\031\n\021isNamespaceMap" +
+      "ped\030\036 \001(\010*A\n\nPTableType\022\n\n\006SYSTEM\020\000\022\010\n\004U" +
+      "SER\020\001\022\010\n\004VIEW\020\002\022\t\n\005INDEX\020\003\022\010\n\004JOIN\020\004B@\n(" +
+      "org.apache.phoenix.coprocessor.generated" +
+      "B\014PTableProtosH\001\210\001\001\240\001\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -7224,7 +7315,7 @@ public final class PTableProtos {
           internal_static_PColumn_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_PColumn_descriptor,
-              new java.lang.String[] { "ColumnNameBytes", "FamilyNameBytes", "DataType", "MaxLength", "Scale", "Nullable", "Position", "SortOrder", "ArraySize", "ViewConstant", "ViewReferenced", "Expression", "IsRowTimestamp", "IsDynamic", });
+              new java.lang.String[] { "ColumnNameBytes", "FamilyNameBytes", "DataType", "MaxLength", "Scale", "Nullable", "Position", "SortOrder", "ArraySize", "ViewConstant", "ViewReferenced", "Expression", "IsRowTimestamp", "IsDynamic", "ColumnQualifier", });
           internal_static_PTableStats_descriptor =
             getDescriptor().getMessageTypes().get(1);
           internal_static_PTableStats_fieldAccessorTable = new

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index d98ebe3..92c907e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -205,6 +205,8 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
     public static final byte[] BASE_COLUMN_COUNT_BYTES = Bytes.toBytes(BASE_COLUMN_COUNT);
     public static final String IS_ROW_TIMESTAMP = "IS_ROW_TIMESTAMP";
     public static final byte[] IS_ROW_TIMESTAMP_BYTES = Bytes.toBytes(IS_ROW_TIMESTAMP);
+    public static final String COLUMN_QUALIFIER = "COLUMN_QUALIFIER";
+    public static final byte[] COLUMN_QUALIFIER_BYTES = Bytes.toBytes(COLUMN_QUALIFIER);
 
     public static final String TABLE_FAMILY = QueryConstants.DEFAULT_COLUMN_FAMILY;
     public static final byte[] TABLE_FAMILY_BYTES = QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index dec11af..d0c7769 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -575,6 +575,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         }
     }
     
+    @Override
     public PMetaData updateResolvedTimestamp(PTable table, long resolvedTime) throws SQLException {
     	synchronized (latestMetaDataLock) {
             throwConnectionClosedIfNullMetaData();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
index 36aa8cd..057d059 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
@@ -29,6 +29,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CURRENT_VALUE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CYCLE_FLAG;
@@ -267,6 +268,7 @@ public interface QueryConstants {
             TRANSACTIONAL + " BOOLEAN," +
             UPDATE_CACHE_FREQUENCY + " BIGINT," +
             IS_NAMESPACE_MAPPED + " BOOLEAN," +
+            COLUMN_QUALIFIER + " INTEGER " +
             "CONSTRAINT " + SYSTEM_TABLE_PK_NAME + " PRIMARY KEY (" + TENANT_ID + ","
             + TABLE_SCHEM + "," + TABLE_NAME + "," + COLUMN_NAME + "," + COLUMN_FAMILY + "))\n" +
             HConstants.VERSIONS + "=" + MetaDataProtocol.DEFAULT_MAX_META_DATA_VERSIONS + ",\n" +

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
index a60229e..65e362c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
@@ -90,4 +90,9 @@ public class DelegateColumn extends DelegateDatum implements PColumn {
 	public boolean isDynamic() {
 		return getDelegate().isDynamic();
 	}
+
+    @Override
+    public Integer getColumnQualifier() {
+        return getDelegate().getColumnQualifier();
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index ac40554..7eb2336 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -33,6 +33,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TYPE;
@@ -333,8 +334,9 @@ public class MetaDataClient {
         PK_NAME + "," +  // write this both in the column and table rows for access by metadata APIs
         KEY_SEQ + "," +
         COLUMN_DEF + "," +
-        IS_ROW_TIMESTAMP + 
-        ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+        COLUMN_QUALIFIER + "," +
+        IS_ROW_TIMESTAMP +
+        ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
     private static final String INSERT_COLUMN_ALTER_TABLE =
             "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
             TENANT_ID + "," +
@@ -782,8 +784,13 @@ public class MetaDataClient {
         } else {
             colUpsert.setString(18, column.getExpressionStr());
         }
-        if (colUpsert.getParameterMetaData().getParameterCount() > 18) {
-            colUpsert.setBoolean(19, column.isRowTimestamp());
+        if (column.getColumnQualifier() == null) {
+            colUpsert.setNull(19, Types.INTEGER);
+        } else {
+            colUpsert.setInt(19, column.getColumnQualifier());
+        }
+        if (colUpsert.getParameterMetaData().getParameterCount() > 19) {
+            colUpsert.setBoolean(20, column.isRowTimestamp());
         }
         colUpsert.execute();
     }
@@ -802,7 +809,7 @@ public class MetaDataClient {
         argUpsert.execute();
     }
 
-    private PColumn newColumn(int position, ColumnDef def, PrimaryKeyConstraint pkConstraint, String defaultColumnFamily, boolean addingToPK) throws SQLException {
+    private PColumn newColumn(int position, ColumnDef def, PrimaryKeyConstraint pkConstraint, String defaultColumnFamily, boolean addingToPK, Map<String, Integer> columnQualifierTracker) throws SQLException {
         try {
             ColumnName columnDefName = def.getColumnDefName();
             SortOrder sortOrder = def.getSortOrder();
@@ -850,15 +857,24 @@ public class MetaDataClient {
                 }
                 isNull = false;
             }
-
+            Integer columnQualifier = null;
+            if (!isPK) {
+                columnQualifier = columnQualifierTracker.get(familyName);
+                if (columnQualifier == null) {
+                    columnQualifier = 0;
+                } else {
+                    columnQualifier++;
+                }
+                columnQualifierTracker.put(familyName.toString(), columnQualifier);
+            }
             PColumn column = new PColumnImpl(PNameFactory.newName(columnName), familyName, def.getDataType(),
-                    def.getMaxLength(), def.getScale(), isNull, position, sortOrder, def.getArraySize(), null, false, def.getExpression(), isRowTimestamp, false);
+                    def.getMaxLength(), def.getScale(), isNull, position, sortOrder, def.getArraySize(), null, false, def.getExpression(), isRowTimestamp, false, columnQualifier);
             return column;
         } catch (IllegalArgumentException e) { // Based on precondition check in constructor
             throw new SQLException(e);
         }
     }
-
+    
     public MutationState createTable(CreateTableStatement statement, byte[][] splits, PTable parent, String viewStatement, ViewType viewType, byte[][] viewColumnConstants, BitSet isViewColumnReferenced) throws SQLException {
         PTable table = createTableInternal(statement, splits, parent, viewStatement, viewType, viewColumnConstants, isViewColumnReferenced, null, null, null);
         if (table == null || table.getType() == PTableType.VIEW || table.isTransactional()) {
@@ -1887,7 +1903,7 @@ public class MetaDataClient {
             }
             int pkPositionOffset = pkColumns.size();
             int position = positionOffset;
-            
+            Map<String, Integer> columnQualifierTracker = Maps.newHashMapWithExpectedSize(colDefs.size());
             for (ColumnDef colDef : colDefs) {
                 rowTimeStampColumnAlreadyFound = checkAndValidateRowTimestampCol(colDef, pkConstraint, rowTimeStampColumnAlreadyFound, tableType);
                 if (colDef.isPK()) { // i.e. the column is declared as CREATE TABLE COLNAME DATATYPE PRIMARY KEY...
@@ -1906,7 +1922,7 @@ public class MetaDataClient {
                                 .setColumnName(colDef.getColumnDefName().getColumnName()).build().buildException();
                     }
                 }
-                PColumn column = newColumn(position++, colDef, pkConstraint, defaultFamilyName, false);
+                PColumn column = newColumn(position++, colDef, pkConstraint, defaultFamilyName, false, columnQualifierTracker);
                 if (SchemaUtil.isPKColumn(column)) {
                     // TODO: remove this constraint?
                     if (pkColumnsIterator.hasNext() && !column.getName().getString().equals(pkColumnsIterator.next().getFirst().getColumnName())) {
@@ -2753,6 +2769,7 @@ public class MetaDataClient {
                 List<PColumn> columns = Lists.newArrayListWithExpectedSize(columnDefs.size());
                 Set<String> colFamiliesForPColumnsToBeAdded = new LinkedHashSet<>();
                 Set<String> families = new LinkedHashSet<>();
+                Map<String, Integer> columnQualifiers = SchemaUtil.getNextColumnQualifiers(table);
                 if (columnDefs.size() > 0 ) {
                     try (PreparedStatement colUpsert = connection.prepareStatement(INSERT_COLUMN_ALTER_TABLE)) {
                         short nextKeySeq = SchemaUtil.getMaxKeySeq(table);
@@ -2773,7 +2790,7 @@ public class MetaDataClient {
                                 throw new SQLExceptionInfo.Builder(SQLExceptionCode.ROWTIMESTAMP_CREATE_ONLY)
                                 .setColumnName(colDef.getColumnDefName().getColumnName()).build().buildException();
                             }
-                            PColumn column = newColumn(position++, colDef, PrimaryKeyConstraint.EMPTY, table.getDefaultFamilyName() == null ? null : table.getDefaultFamilyName().getString(), true);
+                            PColumn column = newColumn(position++, colDef, PrimaryKeyConstraint.EMPTY, table.getDefaultFamilyName() == null ? null : table.getDefaultFamilyName().getString(), true, columnQualifiers);
                             columns.add(column);
                             String pkName = null;
                             Short keySeq = null;
@@ -2811,7 +2828,7 @@ public class MetaDataClient {
                                         ColumnName indexColName = ColumnName.caseSensitiveColumnName(IndexUtil.getIndexColumnName(null, colDef.getColumnDefName().getColumnName()));
                                         Expression expression = new RowKeyColumnExpression(columns.get(i), new RowKeyValueAccessor(pkColumns, ++pkSlotPosition));
                                         ColumnDef indexColDef = FACTORY.columnDef(indexColName, indexColDataType.getSqlTypeName(), colDef.isNull(), colDef.getMaxLength(), colDef.getScale(), true, colDef.getSortOrder(), expression.toString(), colDef.isRowTimestamp());
-                                        PColumn indexColumn = newColumn(indexPosition++, indexColDef, PrimaryKeyConstraint.EMPTY, null, true);
+                                        PColumn indexColumn = newColumn(indexPosition++, indexColDef, PrimaryKeyConstraint.EMPTY, null, true, columnQualifiers);
                                         addColumnMutation(schemaName, index.getTableName().getString(), indexColumn, colUpsert, index.getParentTableName().getString(), index.getPKName() == null ? null : index.getPKName().getString(), ++nextIndexKeySeq, index.getBucketNum() != null);
                                     }
                                 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
index 0f5fa44..b63c97b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
@@ -27,7 +27,7 @@ package org.apache.phoenix.schema;
 public interface PColumn extends PDatum {
 
     /**
-     * @return the name of the column qualifier
+     * @return the name of the column
      */
     PName getName();
 
@@ -60,4 +60,9 @@ public interface PColumn extends PDatum {
     boolean isRowTimestamp();
     
     boolean isDynamic();
+    
+    /**
+     * @return name of the HBase column qualifier
+     */
+    Integer getColumnQualifier();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
index a556f76..5cf1465 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
@@ -40,6 +40,7 @@ public class PColumnImpl implements PColumn {
     private String expressionStr;
     private boolean isRowTimestamp;
     private boolean isDynamic;
+    private Integer columnQualifier;
     
     public PColumnImpl() {
     }
@@ -51,13 +52,13 @@ public class PColumnImpl implements PColumn {
                        Integer scale,
                        boolean nullable,
                        int position,
-                       SortOrder sortOrder, Integer arrSize, byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic) {
-        init(name, familyName, dataType, maxLength, scale, nullable, position, sortOrder, arrSize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic);
+                       SortOrder sortOrder, Integer arrSize, byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic, Integer columnQualifier) {
+        init(name, familyName, dataType, maxLength, scale, nullable, position, sortOrder, arrSize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic, columnQualifier);
     }
 
     public PColumnImpl(PColumn column, int position) {
         this(column.getName(), column.getFamilyName(), column.getDataType(), column.getMaxLength(),
-                column.getScale(), column.isNullable(), position, column.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic());
+                column.getScale(), column.isNullable(), position, column.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic(), column.getColumnQualifier());
     }
 
     private void init(PName name,
@@ -69,7 +70,7 @@ public class PColumnImpl implements PColumn {
             int position,
             SortOrder sortOrder,
             Integer arrSize,
-            byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic) {
+            byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic, Integer columnQualifier) {
     	Preconditions.checkNotNull(sortOrder);
         this.dataType = dataType;
         if (familyName == null) {
@@ -94,6 +95,7 @@ public class PColumnImpl implements PColumn {
         this.expressionStr = expressionStr;
         this.isRowTimestamp = isRowTimestamp;
         this.isDynamic = isDynamic;
+        this.columnQualifier = columnQualifier;
     }
 
     @Override
@@ -205,6 +207,11 @@ public class PColumnImpl implements PColumn {
     public boolean isDynamic() {
         return isDynamic;
     }
+    
+    @Override
+    public Integer getColumnQualifier() {
+        return columnQualifier;
+    }
 
     /**
      * Create a PColumn instance from PBed PColumn instance
@@ -251,8 +258,12 @@ public class PColumnImpl implements PColumn {
         if (column.hasIsDynamic()) {
         	isDynamic = column.getIsDynamic();
         }
+        Integer columnQualifier = null;
+        if (column.hasColumnQualifier()) {
+            columnQualifier = column.getColumnQualifier();
+        }
         return new PColumnImpl(columnName, familyName, dataType, maxLength, scale, nullable, position, sortOrder,
-                arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic);
+                arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic, columnQualifier);
     }
 
     public static PTableProtos.PColumn toProto(PColumn column) {
@@ -283,6 +294,9 @@ public class PColumnImpl implements PColumn {
             builder.setExpression(column.getExpressionStr());
         }
         builder.setIsRowTimestamp(column.isRowTimestamp());
+        if (column.getColumnQualifier() != null) {
+            builder.setColumnQualifier(column.getColumnQualifier());
+        }
         return builder.build();
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
index 67a2714..1bc65be 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
@@ -438,7 +438,7 @@ public class PMetaDataImpl implements PMetaData {
             // Update position of columns that follow removed column
             for (int i = position+1; i < oldColumns.size(); i++) {
                 PColumn oldColumn = oldColumns.get(i);
-                PColumn newColumn = new PColumnImpl(oldColumn.getName(), oldColumn.getFamilyName(), oldColumn.getDataType(), oldColumn.getMaxLength(), oldColumn.getScale(), oldColumn.isNullable(), i-1+positionOffset, oldColumn.getSortOrder(), oldColumn.getArraySize(), oldColumn.getViewConstant(), oldColumn.isViewReferenced(), null, oldColumn.isRowTimestamp(), oldColumn.isDynamic());
+                PColumn newColumn = new PColumnImpl(oldColumn.getName(), oldColumn.getFamilyName(), oldColumn.getDataType(), oldColumn.getMaxLength(), oldColumn.getScale(), oldColumn.isNullable(), i-1+positionOffset, oldColumn.getSortOrder(), oldColumn.getArraySize(), oldColumn.getViewConstant(), oldColumn.isViewReferenced(), null, oldColumn.isRowTimestamp(), oldColumn.isDynamic(), oldColumn.getColumnQualifier());
                 columns.add(newColumn);
             }
             

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
index 734a9ed..23cfd1b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
@@ -38,7 +38,7 @@ public class SaltingUtil {
     public static final String SALTING_COLUMN_NAME = "_SALT";
     public static final String SALTED_ROW_KEY_NAME = "_SALTED_KEY";
     public static final PColumnImpl SALTING_COLUMN = new PColumnImpl(
-            PNameFactory.newName(SALTING_COLUMN_NAME), null, PBinary.INSTANCE, 1, 0, false, 0, SortOrder.getDefault(), 0, null, false, null, false, false);
+            PNameFactory.newName(SALTING_COLUMN_NAME), null, PBinary.INSTANCE, 1, 0, false, 0, SortOrder.getDefault(), 0, null, false, null, false, false, null);
     public static final RowKeySchema VAR_BINARY_SALTED_SCHEMA = new RowKeySchemaBuilder(2)
         .addField(SALTING_COLUMN, false, SortOrder.getDefault())
         .addField(SchemaUtil.VAR_BINARY_DATUM, false, SortOrder.getDefault()).build();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
index dbc65d4..4f2e501 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
@@ -1016,4 +1016,18 @@ public class SchemaUtil {
         return physicalTableName.indexOf(indexPrefix) == 0 ? physicalTableName.substring(indexPrefix.length())
                 : physicalTableName;
     }
+    
+    
+    /**
+     * Return a map of column family -> next column qualifier number to use.
+     */
+    public static Map<String, Integer> getNextColumnQualifiers(PTable table) {
+        Map<String, Integer> map = Maps.newHashMapWithExpectedSize(table.getColumns().size());
+        for (PColumnFamily f : table.getColumnFamilies()) {
+            final int size = f.getColumns().size();
+            int nextColumnQualifier = size == 0 ? 0 : size;
+            map.put(f.getName().getString(), nextColumnQualifier);
+        }
+        return map;
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
index 4660e38..aee3fb5 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
@@ -249,7 +249,7 @@ public class CorrelatePlanTest {
             Expression expr = LiteralExpression.newConstant(row[i]);
             columns.add(new PColumnImpl(PNameFactory.newName(name), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY),
                     expr.getDataType(), expr.getMaxLength(), expr.getScale(), expr.isNullable(),
-                    i, expr.getSortOrder(), null, null, false, name, false, false));
+                    i, expr.getSortOrder(), null, null, false, name, false, false, null));
         }
         try {
             PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
index aba4be4..49dabd0 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
@@ -171,7 +171,7 @@ public class LiteralResultIteratorPlanTest {
             Expression expr = LiteralExpression.newConstant(row[i]);
             columns.add(new PColumnImpl(PNameFactory.newName(name),
                     PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), expr.getDataType(), expr.getMaxLength(),
-                    expr.getScale(), expr.isNullable(), i, expr.getSortOrder(), null, null, false, name, false, false));
+                    expr.getScale(), expr.isNullable(), i, expr.getSortOrder(), null, null, false, name, false, false, null));
         }
         try {
             PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
index 50e2721..fe29e52 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
@@ -117,8 +117,8 @@ public class UnnestArrayPlanTest {
         LiteralExpression dummy = LiteralExpression.newConstant(null, arrayType);
         RowKeyValueAccessor accessor = new RowKeyValueAccessor(Arrays.asList(dummy), 0);
         UnnestArrayPlan plan = new UnnestArrayPlan(subPlan, new RowKeyColumnExpression(dummy, accessor), withOrdinality);
-        PColumn elemColumn = new PColumnImpl(PNameFactory.newName("ELEM"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), baseType, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false);
-        PColumn indexColumn = withOrdinality ? new PColumnImpl(PNameFactory.newName("IDX"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), PInteger.INSTANCE, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false) : null;
+        PColumn elemColumn = new PColumnImpl(PNameFactory.newName("ELEM"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), baseType, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false, null);
+        PColumn indexColumn = withOrdinality ? new PColumnImpl(PNameFactory.newName("IDX"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), PInteger.INSTANCE, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false, null) : null;
         List<PColumn> columns = withOrdinality ? Arrays.asList(elemColumn, indexColumn) : Arrays.asList(elemColumn);
         ProjectedColumnExpression elemExpr = new ProjectedColumnExpression(elemColumn, columns, 0, elemColumn.getName().getString());
         ProjectedColumnExpression indexExpr = withOrdinality ? new ProjectedColumnExpression(indexColumn, columns, 1, indexColumn.getName().getString()) : null;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java b/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
index 7ee579c..e55068d 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
@@ -41,7 +41,7 @@ public class ColumnExpressionTest {
         int maxLen = 30;
         int scale = 5;
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PDecimal.INSTANCE, maxLen, scale,
-                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false);
+                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false, null);
         ColumnExpression colExp = new KeyValueColumnExpression(column);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);
@@ -61,7 +61,7 @@ public class ColumnExpressionTest {
     public void testSerializationWithNullScale() throws Exception {
         int maxLen = 30;
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PBinary.INSTANCE, maxLen, null,
-                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false);
+                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false, null);
         ColumnExpression colExp = new KeyValueColumnExpression(column);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);
@@ -81,7 +81,7 @@ public class ColumnExpressionTest {
     public void testSerializationWithNullMaxLength() throws Exception {
         int scale = 5;
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PVarchar.INSTANCE, null, scale,
-                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false);
+                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false, null);
         ColumnExpression colExp = new KeyValueColumnExpression(column);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);
@@ -100,7 +100,7 @@ public class ColumnExpressionTest {
     @Test
     public void testSerializationWithNullScaleAndMaxLength() throws Exception {
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PDecimal.INSTANCE, null, null, true,
-                20, SortOrder.getDefault(), 0, null, false, null, false, false);
+                20, SortOrder.getDefault(), 0, null, false, null, false, false, null);
         ColumnExpression colExp = new KeyValueColumnExpression(column);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
index f53e871..1ab606a 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
@@ -137,6 +137,10 @@ public class AggregateResultScannerTest extends BaseConnectionlessQueryTest {
 			public boolean isDynamic() {
 				return false;
 			}
+            @Override
+            public Integer getColumnQualifier() {
+                return null;
+            }
         })), null);
         aggregationManager.setAggregators(new ClientAggregators(Collections.<SingleAggregateFunction>singletonList(func), 1));
         ResultIterators iterators = new ResultIterators() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/cd891030/phoenix-protocol/src/main/PTable.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PTable.proto b/phoenix-protocol/src/main/PTable.proto
index c86f6b6..584bfa1 100644
--- a/phoenix-protocol/src/main/PTable.proto
+++ b/phoenix-protocol/src/main/PTable.proto
@@ -49,6 +49,7 @@ message PColumn {
   optional string expression = 12;
   optional bool isRowTimestamp = 13;
   optional bool isDynamic = 14;
+  optional int32 columnQualifier = 15;
 }
 
 message PTableStats {


[12/52] [abbrv] phoenix git commit: PHOENIX-2156 Support drop of column from table with views

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/MetaDataProtos.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/MetaDataProtos.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/MetaDataProtos.java
index dc5726a..ae72382 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/MetaDataProtos.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/MetaDataProtos.java
@@ -198,6 +198,1279 @@ public final class MetaDataProtos {
     // @@protoc_insertion_point(enum_scope:MutationCode)
   }
 
+  public interface SharedTableStateOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // optional bytes tenantId = 1;
+    /**
+     * <code>optional bytes tenantId = 1;</code>
+     */
+    boolean hasTenantId();
+    /**
+     * <code>optional bytes tenantId = 1;</code>
+     */
+    com.google.protobuf.ByteString getTenantId();
+
+    // required bytes schemaName = 2;
+    /**
+     * <code>required bytes schemaName = 2;</code>
+     */
+    boolean hasSchemaName();
+    /**
+     * <code>required bytes schemaName = 2;</code>
+     */
+    com.google.protobuf.ByteString getSchemaName();
+
+    // required bytes tableName = 3;
+    /**
+     * <code>required bytes tableName = 3;</code>
+     */
+    boolean hasTableName();
+    /**
+     * <code>required bytes tableName = 3;</code>
+     */
+    com.google.protobuf.ByteString getTableName();
+
+    // repeated .PColumn columns = 4;
+    /**
+     * <code>repeated .PColumn columns = 4;</code>
+     */
+    java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn> 
+        getColumnsList();
+    /**
+     * <code>repeated .PColumn columns = 4;</code>
+     */
+    org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn getColumns(int index);
+    /**
+     * <code>repeated .PColumn columns = 4;</code>
+     */
+    int getColumnsCount();
+    /**
+     * <code>repeated .PColumn columns = 4;</code>
+     */
+    java.util.List<? extends org.apache.phoenix.coprocessor.generated.PTableProtos.PColumnOrBuilder> 
+        getColumnsOrBuilderList();
+    /**
+     * <code>repeated .PColumn columns = 4;</code>
+     */
+    org.apache.phoenix.coprocessor.generated.PTableProtos.PColumnOrBuilder getColumnsOrBuilder(
+        int index);
+
+    // repeated bytes physicalNames = 5;
+    /**
+     * <code>repeated bytes physicalNames = 5;</code>
+     */
+    java.util.List<com.google.protobuf.ByteString> getPhysicalNamesList();
+    /**
+     * <code>repeated bytes physicalNames = 5;</code>
+     */
+    int getPhysicalNamesCount();
+    /**
+     * <code>repeated bytes physicalNames = 5;</code>
+     */
+    com.google.protobuf.ByteString getPhysicalNames(int index);
+
+    // required int32 viewIndexId = 6;
+    /**
+     * <code>required int32 viewIndexId = 6;</code>
+     */
+    boolean hasViewIndexId();
+    /**
+     * <code>required int32 viewIndexId = 6;</code>
+     */
+    int getViewIndexId();
+  }
+  /**
+   * Protobuf type {@code SharedTableState}
+   */
+  public static final class SharedTableState extends
+      com.google.protobuf.GeneratedMessage
+      implements SharedTableStateOrBuilder {
+    // Use SharedTableState.newBuilder() to construct.
+    private SharedTableState(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private SharedTableState(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final SharedTableState defaultInstance;
+    public static SharedTableState getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public SharedTableState getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private SharedTableState(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              tenantId_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              schemaName_ = input.readBytes();
+              break;
+            }
+            case 26: {
+              bitField0_ |= 0x00000004;
+              tableName_ = input.readBytes();
+              break;
+            }
+            case 34: {
+              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+                columns_ = new java.util.ArrayList<org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn>();
+                mutable_bitField0_ |= 0x00000008;
+              }
+              columns_.add(input.readMessage(org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.PARSER, extensionRegistry));
+              break;
+            }
+            case 42: {
+              if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+                physicalNames_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
+                mutable_bitField0_ |= 0x00000010;
+              }
+              physicalNames_.add(input.readBytes());
+              break;
+            }
+            case 48: {
+              bitField0_ |= 0x00000008;
+              viewIndexId_ = input.readInt32();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+          columns_ = java.util.Collections.unmodifiableList(columns_);
+        }
+        if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+          physicalNames_ = java.util.Collections.unmodifiableList(physicalNames_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_SharedTableState_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_SharedTableState_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.class, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<SharedTableState> PARSER =
+        new com.google.protobuf.AbstractParser<SharedTableState>() {
+      public SharedTableState parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SharedTableState(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SharedTableState> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // optional bytes tenantId = 1;
+    public static final int TENANTID_FIELD_NUMBER = 1;
+    private com.google.protobuf.ByteString tenantId_;
+    /**
+     * <code>optional bytes tenantId = 1;</code>
+     */
+    public boolean hasTenantId() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional bytes tenantId = 1;</code>
+     */
+    public com.google.protobuf.ByteString getTenantId() {
+      return tenantId_;
+    }
+
+    // required bytes schemaName = 2;
+    public static final int SCHEMANAME_FIELD_NUMBER = 2;
+    private com.google.protobuf.ByteString schemaName_;
+    /**
+     * <code>required bytes schemaName = 2;</code>
+     */
+    public boolean hasSchemaName() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required bytes schemaName = 2;</code>
+     */
+    public com.google.protobuf.ByteString getSchemaName() {
+      return schemaName_;
+    }
+
+    // required bytes tableName = 3;
+    public static final int TABLENAME_FIELD_NUMBER = 3;
+    private com.google.protobuf.ByteString tableName_;
+    /**
+     * <code>required bytes tableName = 3;</code>
+     */
+    public boolean hasTableName() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required bytes tableName = 3;</code>
+     */
+    public com.google.protobuf.ByteString getTableName() {
+      return tableName_;
+    }
+
+    // repeated .PColumn columns = 4;
+    public static final int COLUMNS_FIELD_NUMBER = 4;
+    private java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn> columns_;
+    /**
+     * <code>repeated .PColumn columns = 4;</code>
+     */
+    public java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn> getColumnsList() {
+      return columns_;
+    }
+    /**
+     * <code>repeated .PColumn columns = 4;</code>
+     */
+    public java.util.List<? extends org.apache.phoenix.coprocessor.generated.PTableProtos.PColumnOrBuilder> 
+        getColumnsOrBuilderList() {
+      return columns_;
+    }
+    /**
+     * <code>repeated .PColumn columns = 4;</code>
+     */
+    public int getColumnsCount() {
+      return columns_.size();
+    }
+    /**
+     * <code>repeated .PColumn columns = 4;</code>
+     */
+    public org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn getColumns(int index) {
+      return columns_.get(index);
+    }
+    /**
+     * <code>repeated .PColumn columns = 4;</code>
+     */
+    public org.apache.phoenix.coprocessor.generated.PTableProtos.PColumnOrBuilder getColumnsOrBuilder(
+        int index) {
+      return columns_.get(index);
+    }
+
+    // repeated bytes physicalNames = 5;
+    public static final int PHYSICALNAMES_FIELD_NUMBER = 5;
+    private java.util.List<com.google.protobuf.ByteString> physicalNames_;
+    /**
+     * <code>repeated bytes physicalNames = 5;</code>
+     */
+    public java.util.List<com.google.protobuf.ByteString>
+        getPhysicalNamesList() {
+      return physicalNames_;
+    }
+    /**
+     * <code>repeated bytes physicalNames = 5;</code>
+     */
+    public int getPhysicalNamesCount() {
+      return physicalNames_.size();
+    }
+    /**
+     * <code>repeated bytes physicalNames = 5;</code>
+     */
+    public com.google.protobuf.ByteString getPhysicalNames(int index) {
+      return physicalNames_.get(index);
+    }
+
+    // required int32 viewIndexId = 6;
+    public static final int VIEWINDEXID_FIELD_NUMBER = 6;
+    private int viewIndexId_;
+    /**
+     * <code>required int32 viewIndexId = 6;</code>
+     */
+    public boolean hasViewIndexId() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>required int32 viewIndexId = 6;</code>
+     */
+    public int getViewIndexId() {
+      return viewIndexId_;
+    }
+
+    private void initFields() {
+      tenantId_ = com.google.protobuf.ByteString.EMPTY;
+      schemaName_ = com.google.protobuf.ByteString.EMPTY;
+      tableName_ = com.google.protobuf.ByteString.EMPTY;
+      columns_ = java.util.Collections.emptyList();
+      physicalNames_ = java.util.Collections.emptyList();
+      viewIndexId_ = 0;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasSchemaName()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasTableName()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasViewIndexId()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      for (int i = 0; i < getColumnsCount(); i++) {
+        if (!getColumns(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, tenantId_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, schemaName_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeBytes(3, tableName_);
+      }
+      for (int i = 0; i < columns_.size(); i++) {
+        output.writeMessage(4, columns_.get(i));
+      }
+      for (int i = 0; i < physicalNames_.size(); i++) {
+        output.writeBytes(5, physicalNames_.get(i));
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeInt32(6, viewIndexId_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, tenantId_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, schemaName_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(3, tableName_);
+      }
+      for (int i = 0; i < columns_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, columns_.get(i));
+      }
+      {
+        int dataSize = 0;
+        for (int i = 0; i < physicalNames_.size(); i++) {
+          dataSize += com.google.protobuf.CodedOutputStream
+            .computeBytesSizeNoTag(physicalNames_.get(i));
+        }
+        size += dataSize;
+        size += 1 * getPhysicalNamesList().size();
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(6, viewIndexId_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState)) {
+        return super.equals(obj);
+      }
+      org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState other = (org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState) obj;
+
+      boolean result = true;
+      result = result && (hasTenantId() == other.hasTenantId());
+      if (hasTenantId()) {
+        result = result && getTenantId()
+            .equals(other.getTenantId());
+      }
+      result = result && (hasSchemaName() == other.hasSchemaName());
+      if (hasSchemaName()) {
+        result = result && getSchemaName()
+            .equals(other.getSchemaName());
+      }
+      result = result && (hasTableName() == other.hasTableName());
+      if (hasTableName()) {
+        result = result && getTableName()
+            .equals(other.getTableName());
+      }
+      result = result && getColumnsList()
+          .equals(other.getColumnsList());
+      result = result && getPhysicalNamesList()
+          .equals(other.getPhysicalNamesList());
+      result = result && (hasViewIndexId() == other.hasViewIndexId());
+      if (hasViewIndexId()) {
+        result = result && (getViewIndexId()
+            == other.getViewIndexId());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasTenantId()) {
+        hash = (37 * hash) + TENANTID_FIELD_NUMBER;
+        hash = (53 * hash) + getTenantId().hashCode();
+      }
+      if (hasSchemaName()) {
+        hash = (37 * hash) + SCHEMANAME_FIELD_NUMBER;
+        hash = (53 * hash) + getSchemaName().hashCode();
+      }
+      if (hasTableName()) {
+        hash = (37 * hash) + TABLENAME_FIELD_NUMBER;
+        hash = (53 * hash) + getTableName().hashCode();
+      }
+      if (getColumnsCount() > 0) {
+        hash = (37 * hash) + COLUMNS_FIELD_NUMBER;
+        hash = (53 * hash) + getColumnsList().hashCode();
+      }
+      if (getPhysicalNamesCount() > 0) {
+        hash = (37 * hash) + PHYSICALNAMES_FIELD_NUMBER;
+        hash = (53 * hash) + getPhysicalNamesList().hashCode();
+      }
+      if (hasViewIndexId()) {
+        hash = (37 * hash) + VIEWINDEXID_FIELD_NUMBER;
+        hash = (53 * hash) + getViewIndexId();
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code SharedTableState}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_SharedTableState_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_SharedTableState_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.class, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder.class);
+      }
+
+      // Construct using org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getColumnsFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        tenantId_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        schemaName_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        tableName_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        if (columnsBuilder_ == null) {
+          columns_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000008);
+        } else {
+          columnsBuilder_.clear();
+        }
+        physicalNames_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000010);
+        viewIndexId_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000020);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_SharedTableState_descriptor;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState getDefaultInstanceForType() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.getDefaultInstance();
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState build() {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState buildPartial() {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState result = new org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.tenantId_ = tenantId_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.schemaName_ = schemaName_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.tableName_ = tableName_;
+        if (columnsBuilder_ == null) {
+          if (((bitField0_ & 0x00000008) == 0x00000008)) {
+            columns_ = java.util.Collections.unmodifiableList(columns_);
+            bitField0_ = (bitField0_ & ~0x00000008);
+          }
+          result.columns_ = columns_;
+        } else {
+          result.columns_ = columnsBuilder_.build();
+        }
+        if (((bitField0_ & 0x00000010) == 0x00000010)) {
+          physicalNames_ = java.util.Collections.unmodifiableList(physicalNames_);
+          bitField0_ = (bitField0_ & ~0x00000010);
+        }
+        result.physicalNames_ = physicalNames_;
+        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.viewIndexId_ = viewIndexId_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState) {
+          return mergeFrom((org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState other) {
+        if (other == org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.getDefaultInstance()) return this;
+        if (other.hasTenantId()) {
+          setTenantId(other.getTenantId());
+        }
+        if (other.hasSchemaName()) {
+          setSchemaName(other.getSchemaName());
+        }
+        if (other.hasTableName()) {
+          setTableName(other.getTableName());
+        }
+        if (columnsBuilder_ == null) {
+          if (!other.columns_.isEmpty()) {
+            if (columns_.isEmpty()) {
+              columns_ = other.columns_;
+              bitField0_ = (bitField0_ & ~0x00000008);
+            } else {
+              ensureColumnsIsMutable();
+              columns_.addAll(other.columns_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.columns_.isEmpty()) {
+            if (columnsBuilder_.isEmpty()) {
+              columnsBuilder_.dispose();
+              columnsBuilder_ = null;
+              columns_ = other.columns_;
+              bitField0_ = (bitField0_ & ~0x00000008);
+              columnsBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getColumnsFieldBuilder() : null;
+            } else {
+              columnsBuilder_.addAllMessages(other.columns_);
+            }
+          }
+        }
+        if (!other.physicalNames_.isEmpty()) {
+          if (physicalNames_.isEmpty()) {
+            physicalNames_ = other.physicalNames_;
+            bitField0_ = (bitField0_ & ~0x00000010);
+          } else {
+            ensurePhysicalNamesIsMutable();
+            physicalNames_.addAll(other.physicalNames_);
+          }
+          onChanged();
+        }
+        if (other.hasViewIndexId()) {
+          setViewIndexId(other.getViewIndexId());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasSchemaName()) {
+          
+          return false;
+        }
+        if (!hasTableName()) {
+          
+          return false;
+        }
+        if (!hasViewIndexId()) {
+          
+          return false;
+        }
+        for (int i = 0; i < getColumnsCount(); i++) {
+          if (!getColumns(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // optional bytes tenantId = 1;
+      private com.google.protobuf.ByteString tenantId_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>optional bytes tenantId = 1;</code>
+       */
+      public boolean hasTenantId() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>optional bytes tenantId = 1;</code>
+       */
+      public com.google.protobuf.ByteString getTenantId() {
+        return tenantId_;
+      }
+      /**
+       * <code>optional bytes tenantId = 1;</code>
+       */
+      public Builder setTenantId(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        tenantId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bytes tenantId = 1;</code>
+       */
+      public Builder clearTenantId() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        tenantId_ = getDefaultInstance().getTenantId();
+        onChanged();
+        return this;
+      }
+
+      // required bytes schemaName = 2;
+      private com.google.protobuf.ByteString schemaName_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>required bytes schemaName = 2;</code>
+       */
+      public boolean hasSchemaName() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required bytes schemaName = 2;</code>
+       */
+      public com.google.protobuf.ByteString getSchemaName() {
+        return schemaName_;
+      }
+      /**
+       * <code>required bytes schemaName = 2;</code>
+       */
+      public Builder setSchemaName(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        schemaName_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bytes schemaName = 2;</code>
+       */
+      public Builder clearSchemaName() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        schemaName_ = getDefaultInstance().getSchemaName();
+        onChanged();
+        return this;
+      }
+
+      // required bytes tableName = 3;
+      private com.google.protobuf.ByteString tableName_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>required bytes tableName = 3;</code>
+       */
+      public boolean hasTableName() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required bytes tableName = 3;</code>
+       */
+      public com.google.protobuf.ByteString getTableName() {
+        return tableName_;
+      }
+      /**
+       * <code>required bytes tableName = 3;</code>
+       */
+      public Builder setTableName(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        tableName_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bytes tableName = 3;</code>
+       */
+      public Builder clearTableName() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        tableName_ = getDefaultInstance().getTableName();
+        onChanged();
+        return this;
+      }
+
+      // repeated .PColumn columns = 4;
+      private java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn> columns_ =
+        java.util.Collections.emptyList();
+      private void ensureColumnsIsMutable() {
+        if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+          columns_ = new java.util.ArrayList<org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn>(columns_);
+          bitField0_ |= 0x00000008;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.Builder, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumnOrBuilder> columnsBuilder_;
+
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn> getColumnsList() {
+        if (columnsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(columns_);
+        } else {
+          return columnsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public int getColumnsCount() {
+        if (columnsBuilder_ == null) {
+          return columns_.size();
+        } else {
+          return columnsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn getColumns(int index) {
+        if (columnsBuilder_ == null) {
+          return columns_.get(index);
+        } else {
+          return columnsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public Builder setColumns(
+          int index, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn value) {
+        if (columnsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureColumnsIsMutable();
+          columns_.set(index, value);
+          onChanged();
+        } else {
+          columnsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public Builder setColumns(
+          int index, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.Builder builderForValue) {
+        if (columnsBuilder_ == null) {
+          ensureColumnsIsMutable();
+          columns_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          columnsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public Builder addColumns(org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn value) {
+        if (columnsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureColumnsIsMutable();
+          columns_.add(value);
+          onChanged();
+        } else {
+          columnsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public Builder addColumns(
+          int index, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn value) {
+        if (columnsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureColumnsIsMutable();
+          columns_.add(index, value);
+          onChanged();
+        } else {
+          columnsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public Builder addColumns(
+          org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.Builder builderForValue) {
+        if (columnsBuilder_ == null) {
+          ensureColumnsIsMutable();
+          columns_.add(builderForValue.build());
+          onChanged();
+        } else {
+          columnsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public Builder addColumns(
+          int index, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.Builder builderForValue) {
+        if (columnsBuilder_ == null) {
+          ensureColumnsIsMutable();
+          columns_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          columnsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public Builder addAllColumns(
+          java.lang.Iterable<? extends org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn> values) {
+        if (columnsBuilder_ == null) {
+          ensureColumnsIsMutable();
+          super.addAll(values, columns_);
+          onChanged();
+        } else {
+          columnsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public Builder clearColumns() {
+        if (columnsBuilder_ == null) {
+          columns_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000008);
+          onChanged();
+        } else {
+          columnsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public Builder removeColumns(int index) {
+        if (columnsBuilder_ == null) {
+          ensureColumnsIsMutable();
+          columns_.remove(index);
+          onChanged();
+        } else {
+          columnsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.Builder getColumnsBuilder(
+          int index) {
+        return getColumnsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.PColumnOrBuilder getColumnsOrBuilder(
+          int index) {
+        if (columnsBuilder_ == null) {
+          return columns_.get(index);  } else {
+          return columnsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public java.util.List<? extends org.apache.phoenix.coprocessor.generated.PTableProtos.PColumnOrBuilder> 
+           getColumnsOrBuilderList() {
+        if (columnsBuilder_ != null) {
+          return columnsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(columns_);
+        }
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.Builder addColumnsBuilder() {
+        return getColumnsFieldBuilder().addBuilder(
+            org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.Builder addColumnsBuilder(
+          int index) {
+        return getColumnsFieldBuilder().addBuilder(
+            index, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .PColumn columns = 4;</code>
+       */
+      public java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.Builder> 
+           getColumnsBuilderList() {
+        return getColumnsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.Builder, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumnOrBuilder> 
+          getColumnsFieldBuilder() {
+        if (columnsBuilder_ == null) {
+          columnsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn.Builder, org.apache.phoenix.coprocessor.generated.PTableProtos.PColumnOrBuilder>(
+                  columns_,
+                  ((bitField0_ & 0x00000008) == 0x00000008),
+                  getParentForChildren(),
+                  isClean());
+          columns_ = null;
+        }
+        return columnsBuilder_;
+      }
+
+      // repeated bytes physicalNames = 5;
+      private java.util.List<com.google.protobuf.ByteString> physicalNames_ = java.util.Collections.emptyList();
+      private void ensurePhysicalNamesIsMutable() {
+        if (!((bitField0_ & 0x00000010) == 0x00000010)) {
+          physicalNames_ = new java.util.ArrayList<com.google.protobuf.ByteString>(physicalNames_);
+          bitField0_ |= 0x00000010;
+         }
+      }
+      /**
+       * <code>repeated bytes physicalNames = 5;</code>
+       */
+      public java.util.List<com.google.protobuf.ByteString>
+          getPhysicalNamesList() {
+        return java.util.Collections.unmodifiableList(physicalNames_);
+      }
+      /**
+       * <code>repeated bytes physicalNames = 5;</code>
+       */
+      public int getPhysicalNamesCount() {
+        return physicalNames_.size();
+      }
+      /**
+       * <code>repeated bytes physicalNames = 5;</code>
+       */
+      public com.google.protobuf.ByteString getPhysicalNames(int index) {
+        return physicalNames_.get(index);
+      }
+      /**
+       * <code>repeated bytes physicalNames = 5;</code>
+       */
+      public Builder setPhysicalNames(
+          int index, com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensurePhysicalNamesIsMutable();
+        physicalNames_.set(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bytes physicalNames = 5;</code>
+       */
+      public Builder addPhysicalNames(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensurePhysicalNamesIsMutable();
+        physicalNames_.add(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bytes physicalNames = 5;</code>
+       */
+      public Builder addAllPhysicalNames(
+          java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
+        ensurePhysicalNamesIsMutable();
+        super.addAll(values, physicalNames_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bytes physicalNames = 5;</code>
+       */
+      public Builder clearPhysicalNames() {
+        physicalNames_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000010);
+        onChanged();
+        return this;
+      }
+
+      // required int32 viewIndexId = 6;
+      private int viewIndexId_ ;
+      /**
+       * <code>required int32 viewIndexId = 6;</code>
+       */
+      public boolean hasViewIndexId() {
+        return ((bitField0_ & 0x00000020) == 0x00000020);
+      }
+      /**
+       * <code>required int32 viewIndexId = 6;</code>
+       */
+      public int getViewIndexId() {
+        return viewIndexId_;
+      }
+      /**
+       * <code>required int32 viewIndexId = 6;</code>
+       */
+      public Builder setViewIndexId(int value) {
+        bitField0_ |= 0x00000020;
+        viewIndexId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 viewIndexId = 6;</code>
+       */
+      public Builder clearViewIndexId() {
+        bitField0_ = (bitField0_ & ~0x00000020);
+        viewIndexId_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:SharedTableState)
+    }
+
+    static {
+      defaultInstance = new SharedTableState(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:SharedTableState)
+  }
+
   public interface MetaDataResponseOrBuilder
       extends com.google.protobuf.MessageOrBuilder {
 
@@ -303,6 +1576,31 @@ public final class MetaDataProtos {
      */
     org.apache.phoenix.coprocessor.generated.PFunctionProtos.PFunctionOrBuilder getFunctionOrBuilder(
         int index);
+
+    // repeated .SharedTableState sharedTablesToDelete = 9;
+    /**
+     * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+     */
+    java.util.List<org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState> 
+        getSharedTablesToDeleteList();
+    /**
+     * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+     */
+    org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState getSharedTablesToDelete(int index);
+    /**
+     * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+     */
+    int getSharedTablesToDeleteCount();
+    /**
+     * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+     */
+    java.util.List<? extends org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder> 
+        getSharedTablesToDeleteOrBuilderList();
+    /**
+     * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+     */
+    org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder getSharedTablesToDeleteOrBuilder(
+        int index);
   }
   /**
    * Protobuf type {@code MetaDataResponse}
@@ -415,6 +1713,14 @@ public final class MetaDataProtos {
               function_.add(input.readMessage(org.apache.phoenix.coprocessor.generated.PFunctionProtos.PFunction.PARSER, extensionRegistry));
               break;
             }
+            case 74: {
+              if (!((mutable_bitField0_ & 0x00000100) == 0x00000100)) {
+                sharedTablesToDelete_ = new java.util.ArrayList<org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState>();
+                mutable_bitField0_ |= 0x00000100;
+              }
+              sharedTablesToDelete_.add(input.readMessage(org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.PARSER, extensionRegistry));
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -429,6 +1735,9 @@ public final class MetaDataProtos {
         if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
           function_ = java.util.Collections.unmodifiableList(function_);
         }
+        if (((mutable_bitField0_ & 0x00000100) == 0x00000100)) {
+          sharedTablesToDelete_ = java.util.Collections.unmodifiableList(sharedTablesToDelete_);
+        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
@@ -622,6 +1931,42 @@ public final class MetaDataProtos {
       return function_.get(index);
     }
 
+    // repeated .SharedTableState sharedTablesToDelete = 9;
+    public static final int SHAREDTABLESTODELETE_FIELD_NUMBER = 9;
+    private java.util.List<org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState> sharedTablesToDelete_;
+    /**
+     * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+     */
+    public java.util.List<org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState> getSharedTablesToDeleteList() {
+      return sharedTablesToDelete_;
+    }
+    /**
+     * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+     */
+    public java.util.List<? extends org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder> 
+        getSharedTablesToDeleteOrBuilderList() {
+      return sharedTablesToDelete_;
+    }
+    /**
+     * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+     */
+    public int getSharedTablesToDeleteCount() {
+      return sharedTablesToDelete_.size();
+    }
+    /**
+     * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+     */
+    public org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState getSharedTablesToDelete(int index) {
+      return sharedTablesToDelete_.get(index);
+    }
+    /**
+     * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+     */
+    public org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder getSharedTablesToDeleteOrBuilder(
+        int index) {
+      return sharedTablesToDelete_.get(index);
+    }
+
     private void initFields() {
       returnCode_ = org.apache.phoenix.coprocessor.generated.MetaDataProtos.MutationCode.TABLE_ALREADY_EXISTS;
       mutationTime_ = 0L;
@@ -631,6 +1976,7 @@ public final class MetaDataProtos {
       familyName_ = com.google.protobuf.ByteString.EMPTY;
       functionName_ = com.google.protobuf.ByteString.EMPTY;
       function_ = java.util.Collections.emptyList();
+      sharedTablesToDelete_ = java.util.Collections.emptyList();
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -649,6 +1995,12 @@ public final class MetaDataProtos {
           return false;
         }
       }
+      for (int i = 0; i < getSharedTablesToDeleteCount(); i++) {
+        if (!getSharedTablesToDelete(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -680,6 +2032,9 @@ public final class MetaDataProtos {
       for (int i = 0; i < function_.size(); i++) {
         output.writeMessage(8, function_.get(i));
       }
+      for (int i = 0; i < sharedTablesToDelete_.size(); i++) {
+        output.writeMessage(9, sharedTablesToDelete_.get(i));
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -726,6 +2081,10 @@ public final class MetaDataProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(8, function_.get(i));
       }
+      for (int i = 0; i < sharedTablesToDelete_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(9, sharedTablesToDelete_.get(i));
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -783,6 +2142,8 @@ public final class MetaDataProtos {
       }
       result = result && getFunctionList()
           .equals(other.getFunctionList());
+      result = result && getSharedTablesToDeleteList()
+          .equals(other.getSharedTablesToDeleteList());
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -828,6 +2189,10 @@ public final class MetaDataProtos {
         hash = (37 * hash) + FUNCTION_FIELD_NUMBER;
         hash = (53 * hash) + getFunctionList().hashCode();
       }
+      if (getSharedTablesToDeleteCount() > 0) {
+        hash = (37 * hash) + SHAREDTABLESTODELETE_FIELD_NUMBER;
+        hash = (53 * hash) + getSharedTablesToDeleteList().hashCode();
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -931,6 +2296,7 @@ public final class MetaDataProtos {
         if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
           getTableFieldBuilder();
           getFunctionFieldBuilder();
+          getSharedTablesToDeleteFieldBuilder();
         }
       }
       private static Builder create() {
@@ -963,6 +2329,12 @@ public final class MetaDataProtos {
         } else {
           functionBuilder_.clear();
         }
+        if (sharedTablesToDeleteBuilder_ == null) {
+          sharedTablesToDelete_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000100);
+        } else {
+          sharedTablesToDeleteBuilder_.clear();
+        }
         return this;
       }
 
@@ -1033,6 +2405,15 @@ public final class MetaDataProtos {
         } else {
           result.function_ = functionBuilder_.build();
         }
+        if (sharedTablesToDeleteBuilder_ == null) {
+          if (((bitField0_ & 0x00000100) == 0x00000100)) {
+            sharedTablesToDelete_ = java.util.Collections.unmodifiableList(sharedTablesToDelete_);
+            bitField0_ = (bitField0_ & ~0x00000100);
+          }
+          result.sharedTablesToDelete_ = sharedTablesToDelete_;
+        } else {
+          result.sharedTablesToDelete_ = sharedTablesToDeleteBuilder_.build();
+        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -1103,6 +2484,32 @@ public final class MetaDataProtos {
             }
           }
         }
+        if (sharedTablesToDeleteBuilder_ == null) {
+          if (!other.sharedTablesToDelete_.isEmpty()) {
+            if (sharedTablesToDelete_.isEmpty()) {
+              sharedTablesToDelete_ = other.sharedTablesToDelete_;
+              bitField0_ = (bitField0_ & ~0x00000100);
+            } else {
+              ensureSharedTablesToDeleteIsMutable();
+              sharedTablesToDelete_.addAll(other.sharedTablesToDelete_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sharedTablesToDelete_.isEmpty()) {
+            if (sharedTablesToDeleteBuilder_.isEmpty()) {
+              sharedTablesToDeleteBuilder_.dispose();
+              sharedTablesToDeleteBuilder_ = null;
+              sharedTablesToDelete_ = other.sharedTablesToDelete_;
+              bitField0_ = (bitField0_ & ~0x00000100);
+              sharedTablesToDeleteBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getSharedTablesToDeleteFieldBuilder() : null;
+            } else {
+              sharedTablesToDeleteBuilder_.addAllMessages(other.sharedTablesToDelete_);
+            }
+          }
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -1120,6 +2527,12 @@ public final class MetaDataProtos {
             return false;
           }
         }
+        for (int i = 0; i < getSharedTablesToDeleteCount(); i++) {
+          if (!getSharedTablesToDelete(i).isInitialized()) {
+            
+            return false;
+          }
+        }
         return true;
       }
 
@@ -1748,6 +3161,246 @@ public final class MetaDataProtos {
         return functionBuilder_;
       }
 
+      // repeated .SharedTableState sharedTablesToDelete = 9;
+      private java.util.List<org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState> sharedTablesToDelete_ =
+        java.util.Collections.emptyList();
+      private void ensureSharedTablesToDeleteIsMutable() {
+        if (!((bitField0_ & 0x00000100) == 0x00000100)) {
+          sharedTablesToDelete_ = new java.util.ArrayList<org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState>(sharedTablesToDelete_);
+          bitField0_ |= 0x00000100;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder> sharedTablesToDeleteBuilder_;
+
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public java.util.List<org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState> getSharedTablesToDeleteList() {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sharedTablesToDelete_);
+        } else {
+          return sharedTablesToDeleteBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public int getSharedTablesToDeleteCount() {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          return sharedTablesToDelete_.size();
+        } else {
+          return sharedTablesToDeleteBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState getSharedTablesToDelete(int index) {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          return sharedTablesToDelete_.get(index);
+        } else {
+          return sharedTablesToDeleteBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public Builder setSharedTablesToDelete(
+          int index, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState value) {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSharedTablesToDeleteIsMutable();
+          sharedTablesToDelete_.set(index, value);
+          onChanged();
+        } else {
+          sharedTablesToDeleteBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public Builder setSharedTablesToDelete(
+          int index, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder builderForValue) {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          ensureSharedTablesToDeleteIsMutable();
+          sharedTablesToDelete_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sharedTablesToDeleteBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public Builder addSharedTablesToDelete(org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState value) {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSharedTablesToDeleteIsMutable();
+          sharedTablesToDelete_.add(value);
+          onChanged();
+        } else {
+          sharedTablesToDeleteBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public Builder addSharedTablesToDelete(
+          int index, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState value) {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSharedTablesToDeleteIsMutable();
+          sharedTablesToDelete_.add(index, value);
+          onChanged();
+        } else {
+          sharedTablesToDeleteBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public Builder addSharedTablesToDelete(
+          org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder builderForValue) {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          ensureSharedTablesToDeleteIsMutable();
+          sharedTablesToDelete_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sharedTablesToDeleteBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public Builder addSharedTablesToDelete(
+          int index, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder builderForValue) {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          ensureSharedTablesToDeleteIsMutable();
+          sharedTablesToDelete_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sharedTablesToDeleteBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public Builder addAllSharedTablesToDelete(
+          java.lang.Iterable<? extends org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState> values) {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          ensureSharedTablesToDeleteIsMutable();
+          super.addAll(values, sharedTablesToDelete_);
+          onChanged();
+        } else {
+          sharedTablesToDeleteBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public Builder clearSharedTablesToDelete() {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          sharedTablesToDelete_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000100);
+          onChanged();
+        } else {
+          sharedTablesToDeleteBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public Builder removeSharedTablesToDelete(int index) {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          ensureSharedTablesToDeleteIsMutable();
+          sharedTablesToDelete_.remove(index);
+          onChanged();
+        } else {
+          sharedTablesToDeleteBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder getSharedTablesToDeleteBuilder(
+          int index) {
+        return getSharedTablesToDeleteFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder getSharedTablesToDeleteOrBuilder(
+          int index) {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          return sharedTablesToDelete_.get(index);  } else {
+          return sharedTablesToDeleteBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public java.util.List<? extends org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder> 
+           getSharedTablesToDeleteOrBuilderList() {
+        if (sharedTablesToDeleteBuilder_ != null) {
+          return sharedTablesToDeleteBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sharedTablesToDelete_);
+        }
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder addSharedTablesToDeleteBuilder() {
+        return getSharedTablesToDeleteFieldBuilder().addBuilder(
+            org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder addSharedTablesToDeleteBuilder(
+          int index) {
+        return getSharedTablesToDeleteFieldBuilder().addBuilder(
+            index, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .SharedTableState sharedTablesToDelete = 9;</code>
+       */
+      public java.util.List<org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder> 
+           getSharedTablesToDeleteBuilderList() {
+        return getSharedTablesToDeleteFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder> 
+          getSharedTablesToDeleteFieldBuilder() {
+        if (sharedTablesToDeleteBuilder_ == null) {
+          sharedTablesToDeleteBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder, org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder>(
+                  sharedTablesToDelete_,
+                  ((bitField0_ & 0x00000100) == 0x00000100),
+                  getParentForChildren(),
+                  isClean());
+          sharedTablesToDelete_ = null;
+        }
+        return sharedTablesToDeleteBuilder_;
+      }
+
       // @@protoc_insertion_point(builder_scope:MetaDataResponse)
     }
 
@@ -12262,6 +13915,11 @@ public final class MetaDataProtos {
   }
 
   private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_SharedTableState_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_SharedTableState_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
     internal_static_MetaDataResponse_descriptor;
   private static
     com.google.protobuf.GeneratedMessage.FieldAccessorTable
@@ -12351,171 +14009,182 @@ public final class MetaDataProtos {
   static {
     java.lang.String[] descriptorData = {
       "\n\025MetaDataService.proto\032\014PTable.proto\032\017P" +
-      "Function.proto\"\327\001\n\020MetaDataResponse\022!\n\nr" +
-      "eturnCode\030\001 \001(\0162\r.MutationCode\022\024\n\014mutati" +
-      "onTime\030\002 \001(\003\022\026\n\005table\030\003 \001(\0132\007.PTable\022\026\n\016" +
-      "tablesToDelete\030\004 \003(\014\022\022\n\ncolumnName\030\005 \001(\014" +
-      "\022\022\n\nfamilyName\030\006 \001(\014\022\024\n\014functionName\030\007 \001" +
-      "(\014\022\034\n\010function\030\010 \003(\0132\n.PFunction\"\222\001\n\017Get" +
-      "TableRequest\022\020\n\010tenantId\030\001 \002(\014\022\022\n\nschema" +
-      "Name\030\002 \002(\014\022\021\n\ttableName\030\003 \002(\014\022\026\n\016tableTi" +
-      "mestamp\030\004 \002(\003\022\027\n\017clientTimestamp\030\005 \002(\003\022\025",
-      "\n\rclientVersion\030\006 \001(\005\"\212\001\n\023GetFunctionsRe" +
-      "quest\022\020\n\010tenantId\030\001 \002(\014\022\025\n\rfunctionNames" +
-      "\030\002 \003(\014\022\032\n\022functionTimestamps\030\003 \003(\003\022\027\n\017cl" +
-      "ientTimestamp\030\004 \002(\003\022\025\n\rclientVersion\030\005 \001" +
-      "(\005\"K\n\022CreateTableRequest\022\036\n\026tableMetadat" +
-      "aMutations\030\001 \003(\014\022\025\n\rclientVersion\030\002 \001(\005\"" +
-      "r\n\025CreateFunctionRequest\022\036\n\026tableMetadat" +
-      "aMutations\030\001 \003(\014\022\021\n\ttemporary\030\002 \002(\010\022\017\n\007r" +
-      "eplace\030\003 \001(\010\022\025\n\rclientVersion\030\004 \001(\005\"m\n\020D" +
-      "ropTableRequest\022\036\n\026tableMetadataMutation",
-      "s\030\001 \003(\014\022\021\n\ttableType\030\002 \002(\t\022\017\n\007cascade\030\003 " +
-      "\001(\010\022\025\n\rclientVersion\030\004 \001(\005\"I\n\020AddColumnR" +
-      "equest\022\036\n\026tableMetadataMutations\030\001 \003(\014\022\025" +
-      "\n\rclientVersion\030\002 \001(\005\"J\n\021DropColumnReque" +
-      "st\022\036\n\026tableMetadataMutations\030\001 \003(\014\022\025\n\rcl" +
-      "ientVersion\030\002 \001(\005\"^\n\023DropFunctionRequest" +
-      "\022\036\n\026tableMetadataMutations\030\001 \003(\014\022\020\n\010ifEx" +
-      "ists\030\002 \001(\010\022\025\n\rclientVersion\030\003 \001(\005\"P\n\027Upd" +
-      "ateIndexStateRequest\022\036\n\026tableMetadataMut" +
-      "ations\030\001 \003(\014\022\025\n\rclientVersion\030\002 \001(\005\"*\n\021C",
-      "learCacheRequest\022\025\n\rclientVersion\030\001 \001(\005\"" +
-      "*\n\022ClearCacheResponse\022\024\n\014unfreedBytes\030\001 " +
-      "\001(\003\"*\n\021GetVersionRequest\022\025\n\rclientVersio" +
-      "n\030\001 \001(\005\"%\n\022GetVersionResponse\022\017\n\007version" +
-      "\030\001 \002(\003\"\205\001\n\032ClearTableFromCacheRequest\022\020\n" +
-      "\010tenantId\030\001 \002(\014\022\022\n\nschemaName\030\002 \002(\014\022\021\n\tt" +
-      "ableName\030\003 \002(\014\022\027\n\017clientTimestamp\030\004 \002(\003\022" +
-      "\025\n\rclientVersion\030\005 \001(\005\"\035\n\033ClearTableFrom" +
-      "CacheResponse*\365\002\n\014MutationCode\022\030\n\024TABLE_" +
-      "ALREADY_EXISTS\020\000\022\023\n\017TABLE_NOT_FOUND\020\001\022\024\n",
-      "\020COLUMN_NOT_FOUND\020\002\022\031\n\025COLUMN_ALREADY_EX" +
-      "ISTS\020\003\022\035\n\031CONCURRENT_TABLE_MUTATION\020\004\022\027\n" +
-      "\023TABLE_NOT_IN_REGION\020\005\022\025\n\021NEWER_TABLE_FO" +
-      "UND\020\006\022\034\n\030UNALLOWED_TABLE_MUTATION\020\007\022\021\n\rN" +
-      "O_PK_COLUMNS\020\010\022\032\n\026PARENT_TABLE_NOT_FOUND" +
-      "\020\t\022\033\n\027FUNCTION_ALREADY_EXISTS\020\n\022\026\n\022FUNCT" +
-      "ION_NOT_FOUND\020\013\022\030\n\024NEWER_FUNCTION_FOUND\020" +
-      "\014\022\032\n\026FUNCTION_NOT_IN_REGION\020\r2\304\005\n\017MetaDa" +
-      "taService\022/\n\010getTable\022\020.GetTableRequest\032" +
-      "\021.MetaDataResponse\0227\n\014getFunctions\022\024.Get",
-      "FunctionsRequest\032\021.MetaDataResponse\0225\n\013c" +
-      "reateTable\022\023.CreateTableRequest\032\021.MetaDa" +
-      "taResponse\022;\n\016createFunction\022\026.CreateFun" +
-      "ctionRequest\032\021.MetaDataResponse\0221\n\tdropT" +
-      "able\022\021.DropTableRequest\032\021.MetaDataRespon" +
-      "se\0227\n\014dropFunction\022\024.DropFunctionRequest" +
-      "\032\021.MetaDataResponse\0221\n\taddColumn\022\021.AddCo" +
-      "lumnRequest\032\021.MetaDataResponse\0223\n\ndropCo" +
-      "lumn\022\022.DropColumnRequest\032\021.MetaDataRespo" +
-      "nse\022?\n\020updateIndexState\022\030.UpdateIndexSta",
-      "teRequest\032\021.MetaDataResponse\0225\n\nclearCac" +
-      "he\022\022.ClearCacheRequest\032\023.ClearCacheRespo" +
-      "nse\0225\n\ngetVersion\022\022.GetVersionRequest\032\023." +
-      "GetVersionResponse\022P\n\023clearTableFromCach" +
-      "e\022\033.ClearTableFromCacheRequest\032\034.ClearTa" +
-      "bleFromCacheResponseBB\n(org.apache.phoen" +
-      "ix.coprocessor.generatedB\016MetaDataProtos" +
-      "H\001\210\001\001\240\001\001"
+      "Function.proto\"\222\001\n\020SharedTableState\022\020\n\010t" +
+      "enantId\030\001 \001(\014\022\022\n\nschemaName\030\002 \002(\014\022\021\n\ttab" +
+      "leName\030\003 \002(\014\022\031\n\007columns\030\004 \003(\0132\010.PColumn\022" +
+      "\025\n\rphysicalNames\030\005 \003(\014\022\023\n\013viewIndexId\030\006 " +
+      "\002(\005\"\210\002\n\020MetaDataResponse\022!\n\nreturnCode\030\001" +
+      " \001(\0162\r.MutationCode\022\024\n\014mutationTime\030\002 \001(" +
+      "\003\022\026\n\005table\030\003 \001(\0132\007.PTable\022\026\n\016tablesToDel" +
+      "ete\030\004 \003(\014\022\022\n\ncolumnName\030\005 \001(\014\022\022\n\nfamilyN" +
+      "ame\030\006 \001(\014\022\024\n\014functionName\030\007 \001(\014\022\034\n\010funct",
+      "ion\030\010 \003(\0132\n.PFunction\022/\n\024sharedTablesToD" +
+      "elete\030\t \003(\0132\021.SharedTableState\"\222\001\n\017GetTa" +
+      "bleRequest\022\020\n\010tenantId\030\001 \002(\014\022\022\n\nschemaNa" +
+      "me\030\002 \002(\014\022\021\n\ttableName\030\003 \002(\014\022\026\n\016tableTime" +
+      "stamp\030\004 \002(\003\022\027\n\017clientTimestamp\030\005 \002(\003\022\025\n\r" +
+      "clientVersion\030\006 \001(\005\"\212\001\n\023GetFunctionsRequ" +
+      "est\022\020\n\010tenantId\030\001 \002(\014\022\025\n\rfunctionNames\030\002" +
+      " \003(\014\022\032\n\022functionTimestamps\030\003 \003(\003\022\027\n\017clie" +
+      "ntTimestamp\030\004 \002(\003\022\025\n\rclientVersion\030\005 \001(\005" +
+      "\"K\n\022CreateTableRequest\022\036\n\026tableMetadataM",
+      "utations\030\001 \003(\014\022\025\n\rclientVersion\030\002 \001(\005\"r\n" +
+      "\025CreateFunctionRequest\022\036\n\026tableMetadataM" +
+      "utations\030\001 \003(\014\022\021\n\ttemporary\030\002 \002(\010\022\017\n\007rep" +
+      "lace\030\003 \001(\010\022\025\n\rclientVersion\030\004 \001(\005\"m\n\020Dro" +
+      "pTableRequest\022\036\n\026tableMetadataMutations\030" +
+      "\001 \003(\014\022\021\n\ttableType\030\002 \002(\t\022\017\n\007cascade\030\003 \001(" +
+      "\010\022\025\n\rclientVersion\030\004 \001(\005\"I\n\020AddColumnReq" +
+      "uest\022\036\n\026tableMetadataMutations\030\001 \003(\014\022\025\n\r" +
+      "clientVersion\030\002 \001(\005\"J\n\021DropColumnRequest" +
+      "\022\036\n\026tableMetadataMutations\030\001 \003(\014\022\025\n\rclie",
+      "ntVersion\030\002 \001(\005\"^\n\023DropFunctionRequest\022\036" +
+      "\n\026tableMetadataMutations\030\001 \003(\014\022\020\n\010ifExis" +
+      "ts\030\002 \001(\010\022\025\n\rclientVersion\030\003 \001(\005\"P\n\027Updat" +
+      "eIndexStateRequest\022\036\n\026tableMetadataMutat" +
+      "ions\030\001 \003(\014\022\025\n\rclientVersion\030\002 \001(\005\"*\n\021Cle" +
+      "arCacheRequest\022\025\n\rclientVersion\030\001 \001(\005\"*\n" +
+      "\022ClearCacheResponse\022\024\n\014unfreedBytes\030\001 \001(" +
+      "\003\"*\n\021GetVersionRequest\022\025\n\rclientVersion\030" +
+      "\001 \001(\005\"%\n\022GetVersionResponse\022\017\n\007version\030\001" +
+      " \002(\003\"\205\001\n\032ClearTableFromCacheRequest\022\020\n\010t",
+      "enantId\030\001 \002(\014\022\022\n\nschemaName\030\002 \002(\014\022\021\n\ttab" +
+      "leName\030\003 \002(\014\022\027\n\017clientTimestamp\030\004 \002(\003\022\025\n" +
+      "\rclientVersion\030\005 \001(\005\"\035\n\033ClearTableFromCa" +
+      "cheResponse*\365\002\n\014MutationCode\022\030\n\024TABLE_AL" +
+      "READY_EXISTS\020\000\022\023\n\017TABLE_NOT_FOUND\020\001\022\024\n\020C" +
+      "OLUMN_NOT_FOUND\020\002\022\031\n\025COLUMN_ALREADY_EXIS" +
+      "TS\020\003\022\035\n\031CONCURRENT_TABLE_MUTATION\020\004\022\027\n\023T" +
+      "ABLE_NOT_IN_REGION\020\005\022\025\n\021NEWER_TABLE_FOUN" +
+      "D\020\006\022\034\n\030UNALLOWED_TABLE_MUTATION\020\007\022\021\n\rNO_" +
+      "PK_COLUMNS\020\010\022\032\n\026PARENT_TABLE_NOT_FOUND\020\t",
+      "\022\033\n\027FUNCTION_ALREADY_EXISTS\020\n\022\026\n\022FUNCTIO" +
+      "N_NOT_FOUND\020\013\022\030\n\024NEWER_FUNCTION_FOUND\020\014\022" +
+      "\032\n\026FUNCTION_NOT_IN_REGION\020\r2\304\005\n\017MetaData" +
+      "Service\022/\n\010getTable\022\020.GetTableRequest\032\021." +
+      "MetaDataResponse\0227\n\014getFunctions\022\024.GetFu" +
+      "nctionsRequest\032\021.MetaDataResponse\0225\n\013cre" +
+      "ateTable\022\023.CreateTableRequest\032\021.MetaData" +
+      "Response\022;\n\016createFunction\022\026.CreateFunct" +
+      "ionRequest\032\021.MetaDataResponse\0221\n\tdropTab" +
+      "le\022\021.DropTableRequest\032\021.MetaDataResponse",
+      "\0227\n\014dropFunction\022\024.DropFunctionRequest\032\021" +
+      ".MetaDataResponse\0221\n\taddColumn\022\021.AddColu" +
+      "mnRequest\032\021.MetaDataResponse\0223\n\ndropColu" +
+      "mn\022\022.DropColumnRequest\032\021.MetaDataRespons" +
+      "e\022?\n\020updateIndexState\022\030.UpdateIndexState" +
+      "Request\032\021.MetaDataResponse\0225\n\nclearCache" +
+      "\022\022.ClearCacheRequest\032\023.ClearCacheRespons" +
+      "e\0225\n\ngetVersion\022\022.GetVersionRequest\032\023.Ge" +
+      "tVersionResponse\022P\n\023clearTableFromCache\022" +
+      "\033.ClearTableFromCacheRequest\032\034.ClearTabl",
+      "eFromCacheResponseBB\n(org.apache.phoenix" +
+      ".coprocessor.generatedB\016MetaDataProtosH\001" +
+      "\210\001\001\240\001\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
         public com.google.protobuf.ExtensionRegistry assignDescriptors(
             com.google.protobuf.Descriptors.FileDescriptor root) {
           descriptor = root;
-          internal_static_MetaDataResponse_descriptor =
+          internal_static_SharedTableState_descriptor =
             getDescriptor().getMessageTypes().get(0);
+          internal_static_SharedTableState_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_SharedTableState_descriptor,
+              new java.lang.String[] { "TenantId", "SchemaName", "TableName", "Columns", "PhysicalNames", "ViewIndexId", });
+          internal_static_MetaDataResponse_descriptor =
+            getDescriptor().getMessageTypes().get(1);
           internal_static_MetaDataResponse_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_MetaDataResponse_descriptor,
-              new java.lang.String[] { "ReturnCode", "MutationTime", "Table", "TablesToDelete", "ColumnName", "FamilyName", "FunctionName", "Function", });
+              new java.lang.String[] { "ReturnCode", "MutationTime", "Table", "TablesToDelete", "ColumnName", "FamilyName", "FunctionName", "Function", "SharedTablesToDelete", });
           internal_static_GetTableRequest_descriptor =
-            getDescriptor().getMessageTypes().get(1);
+            getDescriptor().getMessageTypes().get(2);
           internal_static_GetTableRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_GetTableRequest_descriptor,
               new java.lang.String[] { "TenantId", "SchemaName", "TableName", "TableTimestamp", "ClientTimestamp", "ClientVersion", });
           internal_static_GetFunctionsRequest_descriptor =
-            getDescriptor().getMessageTypes().get(2);
+            getDescriptor().getMessageTypes().get(3);
           internal_static_GetFunctionsRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_GetFunctionsRequest_descriptor,
               new java.lang.String[] { "TenantId", "FunctionNames", "FunctionTimestamps", "ClientTimestamp", "ClientVersion", });
           internal_static_CreateTableRequest_descriptor =
-            getDescriptor().getMessageTypes().get(3);
+            getDescriptor().getMessageTypes().get(4);
           internal_static_CreateTableRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_CreateTableRequest_descriptor,
               new java.lang.String[] { "TableMetadataMutations", "ClientVersion", });
           internal_static_CreateFunctionRequest_descriptor =
-            getDescriptor().getMessageTypes().get(4);
+            getDescriptor().getMessageTypes().get(5);
           internal_static_CreateFunctionRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_CreateFunctionRequest_descriptor,
               new java.lang.String[] { "TableMetadataMutations", "Temporary", "Replace", "ClientVersion", });
           internal_static_DropTableRequest_descriptor =
-            getDescriptor().getMessageTypes().get(5);
+            getDescriptor().getMessageTypes().get(6);
           internal_static_DropTableRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_DropTableRequest_descriptor,
               new java.lang.String[] { "TableMetadataMutations", "TableType", "Cascade", "ClientVersion", });
           internal_static_AddColumnRequest_descriptor =
-            getDescriptor().getMessageTypes().get(6);
+            getDescriptor().getMessageTypes().get(7);
           internal_static_AddColumnRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_AddColumnRequest_descriptor,
               new java.lang.String[] { "TableMetadataMutations", "ClientVersion", });
           internal_static_DropColumnRequest_descriptor =
-            getDescriptor().getMessageTypes().get(7);
+            getDescriptor().getMessageTypes().get(8);
           internal_static_DropColumnRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_DropColumnRequest_descriptor,
               new java.lang.String[] { "TableMetadataMutations", "ClientVersion", });
           internal_static_DropFunctionRequest_descriptor =
-            getDescriptor().getMessageTypes().get(8);
+            getDescriptor().getMessageTypes().get(9);
           internal_static_DropFunctionRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_DropFunctionRequest_descriptor,
               new java.lang.String[] { "TableMetadataMutations", "IfExists", "ClientVersion", });
           internal_static_UpdateIndexStateRequest_descriptor =
-            getDescriptor().getMessageTypes().get(9);
+            getDescriptor().getMessageTypes().get(10);
           internal_static_UpdateIndexStateRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_UpdateIndexStateRequest_descriptor,
               new java.lang.String[] { "TableMetadataMutations", "ClientVersion", });
           internal_static_ClearCacheRequest_descriptor =
-            getDescriptor().getMessageTypes().get(10);
+            getDescriptor().getMessageTypes().get(11);
           internal_static_ClearCacheRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_ClearCacheRequest_descriptor,
               new java.lang.String[] { "ClientVersion", });
           internal_static_ClearCacheResponse_descriptor =
-            getDescriptor().getMessageTypes().get(11);
+            getDescriptor().getMessageTypes().get(12);
           internal_static_ClearCacheResponse_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_ClearCacheResponse_descriptor,
               new java.lang.String[] { "UnfreedBytes", });
           internal_static_GetVersionRequest_descriptor =
-            getDescriptor().getMessageTypes().get(12);
+            getDescriptor().getMessageTypes().get(13);
           internal_static_GetVersionRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_GetVersionRequest_descriptor,
               new java.lang.String[] { "ClientVersion", });
           internal_static_GetVersionResponse_descriptor =
-            getDescriptor().getMessageTypes().get(13);
+            getDescriptor().getMessageTypes().get(14);
           internal_static_GetVersionResponse_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_GetVersionResponse_descriptor,
               new java.lang.String[] { "Version", });
           internal_static_ClearTableFromCacheRequest_descriptor =
-            getDescriptor().getMessageTypes().get(14);
+            getDescriptor().getMessageTypes().get(15);
           internal_static_ClearTableFromCacheRequest_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_ClearTableFromCacheRequest_descriptor,
               new java.lang.String[] { "TenantId", "SchemaName", "TableName", "ClientTimestamp", "ClientVersion", });
           internal_static_ClearTableFromCacheResponse_descriptor =
-            getDescriptor().getMessageTypes().get(15);
+            getDescriptor().getMessageTypes().get(16);
           internal_static_ClearTableFromCacheResponse_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_ClearTableFromCacheResponse_descriptor,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index 7548078..457a5df 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -109,6 +109,8 @@ import org.apache.phoenix.util.SQLCloseables;
 import org.cloudera.htrace.Sampler;
 import org.cloudera.htrace.TraceScope;
 
+import co.cask.tephra.TransactionContext;
+
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Objects;
 import com.google.common.base.Strings;
@@ -116,8 +118,6 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.collect.Lists;
 
-import co.cask.tephra.TransactionContext;
-
 
 /**
  * 


[38/52] [abbrv] phoenix git commit: Provide right column qualifiers for arrays

Posted by sa...@apache.org.
Provide right column qualifiers for arrays


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

Branch: refs/heads/encodecolumns
Commit: d89c5cb119df5b769f6e6f9931dcab229c6dedc6
Parents: 13a900f
Author: Samarth <sa...@salesforce.com>
Authored: Thu Mar 24 15:53:39 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:31 2016 -0700

----------------------------------------------------------------------
 .../apache/phoenix/compile/ProjectionCompiler.java  |  4 ++--
 .../coprocessor/BaseScannerRegionObserver.java      | 16 +---------------
 .../java/org/apache/phoenix/schema/PColumn.java     |  2 +-
 .../java/org/apache/phoenix/util/IndexUtil.java     |  5 ++---
 .../java/org/apache/phoenix/util/SchemaUtil.java    |  4 ++++
 5 files changed, 10 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/d89c5cb1/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
index e07b350..b9bfff3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
@@ -702,8 +702,8 @@ public class ProjectionCompiler {
                      public Void visit(ProjectedColumnExpression expression) {
                          if (expression.getDataType().isArrayType()) {
                              indexProjectedColumns.add(expression);
-                             //TODO: samarth confirm this change is to have encodedColumnNames as false. 
-                             KeyValueColumnExpression keyValueColumnExpression = new KeyValueColumnExpression(expression.getColumn(), false);
+                             PColumn col = expression.getColumn();
+                             KeyValueColumnExpression keyValueColumnExpression = new KeyValueColumnExpression(col, SchemaUtil.hasEncodedColumnName(col));
                              indexKVs.add(keyValueColumnExpression);
                              copyOfChildren.set(0, keyValueColumnExpression);
                              Integer count = arrayExpressionCounts.get(expression);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d89c5cb1/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
index d66c7ae..9814a7d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
@@ -395,24 +395,10 @@ abstract public class BaseScannerRegionObserver extends BaseRegionObserver {
                 // Using KeyValueSchema to set and retrieve the value
                 // collect the first kv to get the row
                 Cell rowKv = result.get(0);
-                for (KeyValueColumnExpression kvExp : arrayKVRefs) {
-                    if (kvExp.evaluate(tuple, ptr)) {
-                        for (int idx = tuple.size() - 1; idx >= 0; idx--) {
-                            Cell kv = tuple.getValue(idx);
-                            if (Bytes.equals(kvExp.getColumnFamily(), 0, kvExp.getColumnFamily().length,
-                                    kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength())
-                                && Bytes.equals(kvExp.getColumnQualifier(), 0, kvExp.getColumnQualifier().length,
-                                        kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength())) {
-                                // remove the kv that has the full array values.
-                                result.remove(idx);
-                                break;
-                            }
-                        }
-                    }
-                }
                 byte[] value = kvSchema.toBytes(tuple, arrayFuncRefs,
                         kvSchemaBitSet, ptr);
                 // Add a dummy kv with the exact value of the array index
+                // TODO: samarth how does this dummy column qualifier play with encoded column names
                 result.add(new KeyValue(rowKv.getRowArray(), rowKv.getRowOffset(), rowKv.getRowLength(),
                         QueryConstants.ARRAY_VALUE_COLUMN_FAMILY, 0, QueryConstants.ARRAY_VALUE_COLUMN_FAMILY.length,
                         QueryConstants.ARRAY_VALUE_COLUMN_QUALIFIER, 0,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d89c5cb1/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
index 3ffb845..8f61d6d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
@@ -64,7 +64,7 @@ public interface PColumn extends PDatum {
     /**
      * @return name of the HBase column qualifier
      * TODO: samarth I think we should should change this to return byte[] array.
-     * Then we won't have to worry about calling SchemaUtil... everywhere. I think.
+     * Then we won't have to worry about calling SchemaUtil... everywhere 
      */
     Integer getColumnQualifier();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d89c5cb1/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
index bdc546f..15fc605 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
@@ -25,6 +25,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import co.cask.tephra.TxConstants;
+
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.KeyValue;
@@ -67,7 +69,6 @@ import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.parse.ParseNode;
 import org.apache.phoenix.parse.SQLParser;
 import org.apache.phoenix.parse.SelectStatement;
-import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
 import org.apache.phoenix.schema.ColumnNotFoundException;
 import org.apache.phoenix.schema.ColumnRef;
@@ -87,8 +88,6 @@ import org.apache.phoenix.schema.types.PVarchar;
 
 import com.google.common.collect.Lists;
 
-import co.cask.tephra.TxConstants;
-
 public class IndexUtil {
     public static final String INDEX_COLUMN_NAME_SEP = ":";
     public static final byte[] INDEX_COLUMN_NAME_SEP_BYTES = Bytes.toBytes(INDEX_COLUMN_NAME_SEP);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d89c5cb1/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
index 2202277..d7d7d8b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
@@ -1068,4 +1068,8 @@ public class SchemaUtil {
                         QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
     }
     
+    public static boolean hasEncodedColumnName(PColumn column){
+        return !SchemaUtil.isPKColumn(column) && column.getColumnQualifier() != null;
+    }
+    
 }


[15/52] [abbrv] phoenix git commit: PHOENIX-2156 Support drop of column from table with views

Posted by sa...@apache.org.
PHOENIX-2156 Support drop of column from table with views


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

Branch: refs/heads/encodecolumns
Commit: fccbe56a1dfb555a2a9e75a89f763b7746ed986f
Parents: ecc5ff2
Author: Thomas D'Silva <td...@salesforce.com>
Authored: Tue Mar 22 20:18:41 2016 -0700
Committer: Thomas D'Silva <td...@salesforce.com>
Committed: Mon Apr 11 12:47:30 2016 -0700

----------------------------------------------------------------------
 .../end2end/AlterMultiTenantTableWithViews.java |  701 +++++++
 .../apache/phoenix/end2end/AlterTableIT.java    |   29 +-
 .../phoenix/end2end/AlterTableWithViewsIT.java  |  866 ++-------
 .../end2end/TenantSpecificTablesDDLIT.java      |    5 +-
 .../phoenix/end2end/index/DropMetadataIT.java   |  315 +++
 .../phoenix/end2end/index/DropViewIT.java       |  105 -
 .../coprocessor/MetaDataEndpointImpl.java       |  447 +++--
 .../phoenix/coprocessor/MetaDataProtocol.java   |  106 +
 .../coprocessor/generated/MetaDataProtos.java   | 1837 +++++++++++++++++-
 .../apache/phoenix/jdbc/PhoenixConnection.java  |    4 +-
 .../apache/phoenix/schema/MetaDataClient.java   |   70 +-
 .../org/apache/phoenix/schema/PTableImpl.java   |   18 +
 phoenix-protocol/src/main/MetaDataService.proto |   10 +
 13 files changed, 3515 insertions(+), 998 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterMultiTenantTableWithViews.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterMultiTenantTableWithViews.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterMultiTenantTableWithViews.java
new file mode 100644
index 0000000..2cdfe4a
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterMultiTenantTableWithViews.java
@@ -0,0 +1,701 @@
+/*
+ * 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.phoenix.end2end;
+
+import static org.apache.phoenix.query.QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT;
+import static org.apache.phoenix.query.QueryConstants.DIVERGED_VIEW_BASE_COLUMN_COUNT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.schema.ColumnNotFoundException;
+import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableKey;
+import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.util.IndexUtil;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.SchemaUtil;
+import org.junit.Test;
+
+import com.google.common.base.Objects;
+
+public class AlterMultiTenantTableWithViews extends BaseHBaseManagedTimeIT {
+
+    private Connection getTenantConnection(String tenantId) throws Exception {
+        Properties tenantProps = new Properties();
+        tenantProps.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
+        return DriverManager.getConnection(getUrl(), tenantProps);
+    }
+    
+    private static long getTableSequenceNumber(PhoenixConnection conn, String tableName) throws SQLException {
+        PTable table = conn.getTable(new PTableKey(conn.getTenantId(), SchemaUtil.normalizeIdentifier(tableName)));
+        return table.getSequenceNumber();
+    }
+    
+    private static short getMaxKeySequenceNumber(PhoenixConnection conn, String tableName) throws SQLException {
+        PTable table = conn.getTable(new PTableKey(conn.getTenantId(), SchemaUtil.normalizeIdentifier(tableName)));
+        return SchemaUtil.getMaxKeySeq(table);
+    }
+    
+    private static void verifyNewColumns(ResultSet rs, String ... values) throws SQLException {
+        assertTrue(rs.next());
+        int i = 1;
+        for (String value : values) {
+            assertEquals(value, rs.getString(i++));
+        }
+        assertFalse(rs.next());
+        assertEquals(values.length, i - 1);
+    }
+    
+    @Test
+    public void testAddDropColumnToBaseTablePropagatesToEntireViewHierarchy() throws Exception {
+        String baseTable = "testViewHierarchy";
+        String view1 = "view1";
+        String view2 = "view2";
+        String view3 = "view3";
+        String view4 = "view4";
+        /*                                     baseTable
+                                 /                  |               \ 
+                         view1(tenant1)    view3(tenant2)          view4(global)
+                          /
+                        view2(tenant1)  
+        */
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
+            conn.createStatement().execute(baseTableDDL);
+            
+            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
+                String view1DDL = "CREATE VIEW " + view1 + " AS SELECT * FROM " + baseTable;
+                tenant1Conn.createStatement().execute(view1DDL);
+                
+                String view2DDL = "CREATE VIEW " + view2 + " AS SELECT * FROM " + view1;
+                tenant1Conn.createStatement().execute(view2DDL);
+            }
+            
+            try (Connection tenant2Conn = getTenantConnection("tenant2")) {
+                String view3DDL = "CREATE VIEW " + view3 + " AS SELECT * FROM " + baseTable;
+                tenant2Conn.createStatement().execute(view3DDL);
+            }
+            
+            String view4DDL = "CREATE VIEW " + view4 + " AS SELECT * FROM " + baseTable;
+            conn.createStatement().execute(view4DDL);
+            
+            String alterBaseTable = "ALTER TABLE " + baseTable + " ADD V3 VARCHAR";
+            conn.createStatement().execute(alterBaseTable);
+            
+            // verify that the column is visible to view4
+            conn.createStatement().execute("SELECT V3 FROM " + view4);
+            
+            // verify that the column is visible to view1 and view2
+            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
+                tenant1Conn.createStatement().execute("SELECT V3 from " + view1);
+                tenant1Conn.createStatement().execute("SELECT V3 from " + view2);
+            }
+            
+            // verify that the column is visible to view3
+            try (Connection tenant2Conn = getTenantConnection("tenant2")) {
+                tenant2Conn.createStatement().execute("SELECT V3 from " + view3);
+            }
+
+            alterBaseTable = "ALTER TABLE " + baseTable + " DROP COLUMN V1";
+            conn.createStatement().execute(alterBaseTable);
+
+            // verify that the column is not visible to view4
+            try {
+                conn.createStatement().execute("SELECT V1 FROM " + view4);
+                fail();
+            } catch (ColumnNotFoundException e) {
+            }
+            // verify that the column is not visible to view1 and view2
+            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
+                try {
+                    tenant1Conn.createStatement().execute("SELECT V1 from " + view1);
+                    fail();
+                } catch (ColumnNotFoundException e) {
+                }
+                try {
+                    tenant1Conn.createStatement().execute("SELECT V1 from " + view2);
+                    fail();
+                } catch (ColumnNotFoundException e) {
+                }
+            }
+
+            // verify that the column is not visible to view3
+            try (Connection tenant2Conn = getTenantConnection("tenant2")) {
+                try {
+                    tenant2Conn.createStatement().execute("SELECT V1 from " + view3);
+                    fail();
+                } catch (ColumnNotFoundException e) {
+                }
+            }
+        }
+           
+    }
+    
+    @Test
+    public void testChangingPKOfBaseTableChangesPKForAllViews() throws Exception {
+        String baseTable = "testChangePKOfBaseTable";
+        String view1 = "view1";
+        String view2 = "view2";
+        String view3 = "view3";
+        String view4 = "view4";
+        /*                                     baseTable
+                                 /                  |               \ 
+                         view1(tenant1)    view3(tenant2)          view4(global)
+                          /
+                        view2(tenant1)  
+         */
+        Connection tenant1Conn = null, tenant2Conn = null;
+        try (Connection globalConn = DriverManager.getConnection(getUrl())) {
+            String baseTableDDL = "CREATE TABLE "
+                    + baseTable
+                    + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
+            globalConn.createStatement().execute(baseTableDDL);
+
+            tenant1Conn = getTenantConnection("tenant1");
+            String view1DDL = "CREATE VIEW " + view1 + " AS SELECT * FROM " + baseTable;
+            tenant1Conn.createStatement().execute(view1DDL);
+
+            String view2DDL = "CREATE VIEW " + view2 + " AS SELECT * FROM " + view1;
+            tenant1Conn.createStatement().execute(view2DDL);
+
+            tenant2Conn = getTenantConnection("tenant2");
+            String view3DDL = "CREATE VIEW " + view3 + " AS SELECT * FROM " + baseTable;
+            tenant2Conn.createStatement().execute(view3DDL);
+
+            String view4DDL = "CREATE VIEW " + view4 + " AS SELECT * FROM " + baseTable;
+            globalConn.createStatement().execute(view4DDL);
+
+            String alterBaseTable = "ALTER TABLE " + baseTable + " ADD NEW_PK varchar primary key ";
+            globalConn.createStatement().execute(alterBaseTable);
+            
+            // verify that the new column new_pk is now part of the primary key for the entire hierarchy
+            
+            globalConn.createStatement().execute("SELECT * FROM " + baseTable);
+            assertTrue(checkColumnPartOfPk(globalConn.unwrap(PhoenixConnection.class), "NEW_PK", baseTable));
+            
+            tenant1Conn.createStatement().execute("SELECT * FROM " + view1);
+            assertTrue(checkColumnPartOfPk(tenant1Conn.unwrap(PhoenixConnection.class), "NEW_PK", view1));
+            
+            tenant1Conn.createStatement().execute("SELECT * FROM " + view2);
+            assertTrue(checkColumnPartOfPk(tenant1Conn.unwrap(PhoenixConnection.class), "NEW_PK", view2));
+            
+            tenant2Conn.createStatement().execute("SELECT * FROM " + view3);
+            assertTrue(checkColumnPartOfPk(tenant2Conn.unwrap(PhoenixConnection.class), "NEW_PK", view3));
+            
+            globalConn.createStatement().execute("SELECT * FROM " + view4);
+            assertTrue(checkColumnPartOfPk(globalConn.unwrap(PhoenixConnection.class), "NEW_PK", view4));
+
+        } finally {
+            if (tenant1Conn != null) {
+                try {
+                    tenant1Conn.close();
+                } catch (Throwable ignore) {}
+            }
+            if (tenant2Conn != null) {
+                try {
+                    tenant2Conn.close();
+                } catch (Throwable ignore) {}
+            }
+        }
+
+    }
+    
+    private boolean checkColumnPartOfPk(PhoenixConnection conn, String columnName, String tableName) throws SQLException {
+        String normalizedTableName = SchemaUtil.normalizeIdentifier(tableName);
+        PTable table = conn.getTable(new PTableKey(conn.getTenantId(), normalizedTableName));
+        List<PColumn> pkCols = table.getPKColumns();
+        String normalizedColumnName = SchemaUtil.normalizeIdentifier(columnName);
+        for (PColumn pkCol : pkCols) {
+            if (pkCol.getName().getString().equals(normalizedColumnName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    private int getIndexOfPkColumn(PhoenixConnection conn, String columnName, String tableName) throws SQLException {
+        String normalizedTableName = SchemaUtil.normalizeIdentifier(tableName);
+        PTable table = conn.getTable(new PTableKey(conn.getTenantId(), normalizedTableName));
+        List<PColumn> pkCols = table.getPKColumns();
+        String normalizedColumnName = SchemaUtil.normalizeIdentifier(columnName);
+        int i = 0;
+        for (PColumn pkCol : pkCols) {
+            if (pkCol.getName().getString().equals(normalizedColumnName)) {
+                return i;
+            }
+            i++;
+        }
+        return -1;
+    }
+    
+    @Test
+    public void testAddPKColumnToBaseTableWhoseViewsHaveIndices() throws Exception {
+        String baseTable = "testAddPKColumnToBaseTableWhoseViewsHaveIndices";
+        String view1 = "view1";
+        String view2 = "view2";
+        String view3 = "view3";
+        String tenant1 = "tenant1";
+        String tenant2 = "tenant2";
+        String view2Index = view2 + "_idx";
+        String view3Index = view3 + "_idx";
+        /*                          baseTable(mutli-tenant)
+                                 /                           \                
+                         view1(tenant1)                  view3(tenant2, index) 
+                          /
+                        view2(tenant1, index)  
+         */
+        try (Connection globalConn = DriverManager.getConnection(getUrl())) {
+            // make sure that the tables are empty, but reachable
+            globalConn
+            .createStatement()
+            .execute(
+                    "CREATE TABLE "
+                            + baseTable
+                            + " (TENANT_ID VARCHAR NOT NULL, K1 varchar not null, V1 VARCHAR, V2 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, K1)) MULTI_TENANT = true ");
+
+        }
+        try (Connection viewConn = getTenantConnection(tenant1)) {
+            // create tenant specific view for tenant1 - view1
+            viewConn.createStatement().execute("CREATE VIEW " + view1 + " AS SELECT * FROM " + baseTable);
+            PhoenixConnection phxConn = viewConn.unwrap(PhoenixConnection.class);
+            assertEquals(0, getTableSequenceNumber(phxConn, view1));
+            assertEquals(2, getMaxKeySequenceNumber(phxConn, view1));
+
+            // create a view - view2 on view - view1
+            viewConn.createStatement().execute("CREATE VIEW " + view2 + " AS SELECT * FROM " + view1);
+            assertEquals(0, getTableSequenceNumber(phxConn, view2));
+            assertEquals(2, getMaxKeySequenceNumber(phxConn, view2));
+
+
+            // create an index on view2
+            viewConn.createStatement().execute("CREATE INDEX " + view2Index + " ON " + view2 + " (v1) include (v2)");
+            assertEquals(0, getTableSequenceNumber(phxConn, view2Index));
+            assertEquals(4, getMaxKeySequenceNumber(phxConn, view2Index));
+        }
+        try (Connection viewConn = getTenantConnection(tenant2)) {
+            // create tenant specific view for tenant2 - view3
+            viewConn.createStatement().execute("CREATE VIEW " + view3 + " AS SELECT * FROM " + baseTable);
+            PhoenixConnection phxConn = viewConn.unwrap(PhoenixConnection.class);
+            assertEquals(0, getTableSequenceNumber(phxConn, view3));
+            assertEquals(2, getMaxKeySequenceNumber(phxConn, view3));
+
+
+            // create an index on view3
+            viewConn.createStatement().execute("CREATE INDEX " + view3Index + " ON " + view3 + " (v1) include (v2)");
+            assertEquals(0, getTableSequenceNumber(phxConn, view3Index));
+            assertEquals(4, getMaxKeySequenceNumber(phxConn, view3Index));
+
+
+        }
+
+        // alter the base table by adding 1 non-pk and 2 pk columns
+        try (Connection globalConn = DriverManager.getConnection(getUrl())) {
+            globalConn.createStatement().execute("ALTER TABLE " + baseTable + " ADD v3 VARCHAR, k2 VARCHAR PRIMARY KEY, k3 VARCHAR PRIMARY KEY");
+            assertEquals(4, getMaxKeySequenceNumber(globalConn.unwrap(PhoenixConnection.class), baseTable));
+
+            // Upsert records in the base table
+            String upsert = "UPSERT INTO " + baseTable + " (TENANT_ID, K1, K2, K3, V1, V2, V3) VALUES (?, ?, ?, ?, ?, ?, ?)";
+            PreparedStatement stmt = globalConn.prepareStatement(upsert);
+            stmt.setString(1, tenant1);
+            stmt.setString(2, "K1");
+            stmt.setString(3, "K2");
+            stmt.setString(4, "K3");
+            stmt.setString(5, "V1");
+            stmt.setString(6, "V2");
+            stmt.setString(7, "V3");
+            stmt.executeUpdate();
+            stmt.setString(1, tenant2);
+            stmt.setString(2, "K11");
+            stmt.setString(3, "K22");
+            stmt.setString(4, "K33");
+            stmt.setString(5, "V11");
+            stmt.setString(6, "V22");
+            stmt.setString(7, "V33");
+            stmt.executeUpdate();
+            globalConn.commit();
+        }
+
+        // Verify now that the sequence number of data table, indexes and views have changed.
+        // Also verify that the newly added pk columns show up as pk columns of data table, indexes and views.
+        try (Connection viewConn = getTenantConnection(tenant1)) {
+
+            ResultSet rs = viewConn.createStatement().executeQuery("SELECT K2, K3, V3 FROM " + view1);
+            PhoenixConnection phxConn = viewConn.unwrap(PhoenixConnection.class);
+            assertEquals(2, getIndexOfPkColumn(phxConn, "k2", view1));
+            assertEquals(3, getIndexOfPkColumn(phxConn, "k3", view1));
+            assertEquals(1, getTableSequenceNumber(phxConn, view1));
+            assertEquals(4, getMaxKeySequenceNumber(phxConn, view1));
+            verifyNewColumns(rs, "K2", "K3", "V3");
+
+
+            rs = viewConn.createStatement().executeQuery("SELECT K2, K3, V3 FROM " + view2);
+            assertEquals(2, getIndexOfPkColumn(phxConn, "k2", view2));
+            assertEquals(3, getIndexOfPkColumn(phxConn, "k3", view2));
+            assertEquals(1, getTableSequenceNumber(phxConn, view2));
+            assertEquals(4, getMaxKeySequenceNumber(phxConn, view2));
+            verifyNewColumns(rs, "K2", "K3", "V3");
+
+            assertEquals(4, getIndexOfPkColumn(phxConn, IndexUtil.getIndexColumnName(null, "k2"), view2Index));
+            assertEquals(5, getIndexOfPkColumn(phxConn, IndexUtil.getIndexColumnName(null, "k3"), view2Index));
+            assertEquals(1, getTableSequenceNumber(phxConn, view2Index));
+            assertEquals(6, getMaxKeySequenceNumber(phxConn, view2Index));
+        }
+        try (Connection viewConn = getTenantConnection(tenant2)) {
+            ResultSet rs = viewConn.createStatement().executeQuery("SELECT K2, K3, V3 FROM " + view3);
+            PhoenixConnection phxConn = viewConn.unwrap(PhoenixConnection.class);
+            assertEquals(2, getIndexOfPkColumn(phxConn, "k2", view3));
+            assertEquals(3, getIndexOfPkColumn(phxConn, "k3", view3));
+            assertEquals(1, getTableSequenceNumber(phxConn, view3));
+            verifyNewColumns(rs, "K22", "K33", "V33");
+
+            assertEquals(4, getIndexOfPkColumn(phxConn, IndexUtil.getIndexColumnName(null, "k2"), view3Index));
+            assertEquals(5, getIndexOfPkColumn(phxConn, IndexUtil.getIndexColumnName(null, "k3"), view3Index));
+            assertEquals(1, getTableSequenceNumber(phxConn, view3Index));
+            assertEquals(6, getMaxKeySequenceNumber(phxConn, view3Index));
+        }
+        // Verify that the index is actually being used when using newly added pk col
+        try (Connection viewConn = getTenantConnection(tenant1)) {
+            String upsert = "UPSERT INTO " + view2 + " (K1, K2, K3, V1, V2, V3) VALUES ('key1', 'key2', 'key3', 'value1', 'value2', 'value3')";
+            viewConn.createStatement().executeUpdate(upsert);
+            viewConn.commit();
+            Statement stmt = viewConn.createStatement();
+            String sql = "SELECT V2 FROM " + view2 + " WHERE V1 = 'value1' AND K3 = 'key3'";
+            QueryPlan plan = stmt.unwrap(PhoenixStatement.class).optimizeQuery(sql);
+            assertTrue(plan.getTableRef().getTable().getName().getString().equals(SchemaUtil.normalizeIdentifier(view2Index)));
+            ResultSet rs = viewConn.createStatement().executeQuery(sql);
+            verifyNewColumns(rs, "value2");
+        }
+
+    }
+    
+    @Test
+    public void testAddingPkAndKeyValueColumnsToBaseTableWithDivergedView() throws Exception {
+        String baseTable = "testAlteringPkOfBaseTableWithDivergedView".toUpperCase();
+        String view1 = "view1".toUpperCase();
+        String divergedView = "divergedView".toUpperCase();
+        String divergedViewIndex = divergedView + "_IDX";
+        /*                                     baseTable
+                                 /                  |                
+                         view1(tenant1)         divergedView(tenant2)    
+                            
+        */
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
+            conn.createStatement().execute(baseTableDDL);
+            
+            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
+                String view1DDL = "CREATE VIEW " + view1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
+                tenant1Conn.createStatement().execute(view1DDL);
+            }
+            
+            try (Connection tenant2Conn = getTenantConnection("tenant2")) {
+                String divergedViewDDL = "CREATE VIEW " + divergedView + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
+                tenant2Conn.createStatement().execute(divergedViewDDL);
+                // Drop column V2 from the view to have it diverge from the base table
+                tenant2Conn.createStatement().execute("ALTER VIEW " + divergedView + " DROP COLUMN V2");
+                
+                // create an index on the diverged view
+                String indexDDL = "CREATE INDEX " + divergedViewIndex + " ON " + divergedView + " (V1) include (V3)";
+                tenant2Conn.createStatement().execute(indexDDL);
+            }
+            
+            String alterBaseTable = "ALTER TABLE " + baseTable + " ADD KV VARCHAR, PK2 VARCHAR PRIMARY KEY";
+            conn.createStatement().execute(alterBaseTable);
+            
+            
+            // verify that the both columns were added to view1
+            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
+                tenant1Conn.createStatement().execute("SELECT KV from " + view1);
+                tenant1Conn.createStatement().execute("SELECT PK2 from " + view1);
+            }
+            
+            // verify that only the primary key column PK2 was added to diverged view
+            try (Connection tenant2Conn = getTenantConnection("tenant2")) {
+                tenant2Conn.createStatement().execute("SELECT PK2 from " + divergedView);
+                try {
+                    tenant2Conn.createStatement().execute("SELECT KV FROM " + divergedView);
+                } catch (SQLException e) {
+                    assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
+                }
+            }
+            
+            // Upsert records in diverged view. Verify that the PK column was added to the index on it.
+            String upsert = "UPSERT INTO " + divergedView + " (PK1, PK2, V1, V3) VALUES ('PK1', 'PK2', 'V1', 'V3')";
+            try (Connection viewConn = getTenantConnection("tenant2")) {
+                viewConn.createStatement().executeUpdate(upsert);
+                viewConn.commit();
+                Statement stmt = viewConn.createStatement();
+                String sql = "SELECT V3 FROM " + divergedView + " WHERE V1 = 'V1' AND PK2 = 'PK2'";
+                QueryPlan plan = stmt.unwrap(PhoenixStatement.class).optimizeQuery(sql);
+                assertTrue(plan.getTableRef().getTable().getName().getString().equals(SchemaUtil.normalizeIdentifier(divergedViewIndex)));
+                ResultSet rs = viewConn.createStatement().executeQuery(sql);
+                verifyNewColumns(rs, "V3");
+            }
+            
+            // For non-diverged view, base table columns will be added at the same position as base table
+            assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 1, 9, 7, "TENANT_ID", "PK1", "V1", "V2", "V3", "KV", "PK2", "VIEW_COL1", "VIEW_COL2");
+            // For a diverged view, only base table's pk column will be added and that too at the end.
+            assertTableDefinition(conn, divergedView, PTableType.VIEW, baseTable, 2, 7, DIVERGED_VIEW_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V3", "VIEW_COL1", "VIEW_COL2", "PK2");
+            
+            // Add existing column VIEW_COL2 to the base table
+            alterBaseTable = "ALTER TABLE " + baseTable + " ADD VIEW_COL2 CHAR(256)";
+            conn.createStatement().execute(alterBaseTable);
+            
+            // For the non-diverged view, adding the column VIEW_COL2 will end up changing its ordinal position in the view.
+            assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 2, 9, 8, "TENANT_ID", "PK1", "V1", "V2", "V3", "KV", "PK2", "VIEW_COL2", "VIEW_COL1");
+            // For the diverged view, adding the column VIEW_COL2 will not change its ordinal position in the view. It also won't change the base column count or the sequence number
+            assertTableDefinition(conn, divergedView, PTableType.VIEW, baseTable, 2, 7, DIVERGED_VIEW_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V3", "VIEW_COL1", "VIEW_COL2", "PK2");
+        }
+    }
+    
+    @Test
+    public void testAddColumnsToSaltedBaseTableWithViews() throws Exception {
+        String baseTable = "testAddColumnsToSaltedBaseTableWithViews".toUpperCase();
+        String view1 = "view1".toUpperCase();
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
+            conn.createStatement().execute(baseTableDDL);
+
+            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
+                String view1DDL = "CREATE VIEW " + view1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
+                tenant1Conn.createStatement().execute(view1DDL);
+            }
+
+            assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 0, 5, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V2", "V3");
+            assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 0, 7, 5, "TENANT_ID", "PK1", "V1", "V2", "V3", "VIEW_COL1", "VIEW_COL2");
+
+            String alterBaseTable = "ALTER TABLE " + baseTable + " ADD KV VARCHAR, PK2 VARCHAR PRIMARY KEY";
+            conn.createStatement().execute(alterBaseTable);
+
+            assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 1, 7, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V2", "V3", "KV", "PK2");
+            assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 1, 9, 7, "TENANT_ID", "PK1", "V1", "V2", "V3", "KV", "PK2", "VIEW_COL1", "VIEW_COL2");
+
+            // verify that the both columns were added to view1
+            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
+                tenant1Conn.createStatement().execute("SELECT KV from " + view1);
+                tenant1Conn.createStatement().execute("SELECT PK2 from " + view1);
+            }
+        }
+    }
+    
+    @Test
+    public void testDropColumnsFromSaltedBaseTableWithViews() throws Exception {
+        String baseTable = "testDropColumnsFromSaltedBaseTableWithViews".toUpperCase();
+        String view1 = "view1".toUpperCase();
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
+            conn.createStatement().execute(baseTableDDL);
+
+            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
+                String view1DDL = "CREATE VIEW " + view1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
+                tenant1Conn.createStatement().execute(view1DDL);
+            }
+
+            assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 0, 5, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V2", "V3");
+            assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 0, 7, 5, "TENANT_ID", "PK1", "V1", "V2", "V3", "VIEW_COL1", "VIEW_COL2");
+
+            String alterBaseTable = "ALTER TABLE " + baseTable + " DROP COLUMN V2";
+            conn.createStatement().execute(alterBaseTable);
+
+            assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 1, 4, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V3");
+            assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 1, 6, 4, "TENANT_ID", "PK1", "V1", "V3", "VIEW_COL1", "VIEW_COL2");
+
+            // verify that the dropped columns aren't visible
+            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
+                try {
+                    tenant1Conn.createStatement().execute("SELECT KV from " + view1);
+                    fail();
+                } catch (SQLException e) {
+                    assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
+                }
+                try {
+                    tenant1Conn.createStatement().execute("SELECT PK2 from " + view1);
+                    fail();
+                } catch (SQLException e) {
+                    assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
+                }
+            }
+        }
+    }
+    
+    @Test
+    public void testAlteringViewConditionallyModifiesHTableMetadata() throws Exception {
+        String baseTable = "testAlteringViewConditionallyModifiesBaseTable".toUpperCase();
+        String view1 = "view1".toUpperCase();
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
+            conn.createStatement().execute(baseTableDDL);
+            HTableDescriptor tableDesc1 = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin().getTableDescriptor(Bytes.toBytes(baseTable)); 
+            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
+                String view1DDL = "CREATE VIEW " + view1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
+                tenant1Conn.createStatement().execute(view1DDL);
+                // This should not modify the base table
+                String alterView = "ALTER VIEW " + view1 + " ADD NEWCOL1 VARCHAR";
+                tenant1Conn.createStatement().execute(alterView);
+                HTableDescriptor tableDesc2 = tenant1Conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin().getTableDescriptor(Bytes.toBytes(baseTable));
+                assertEquals(tableDesc1, tableDesc2);
+                
+                // Add a new column family that doesn't already exist in the base table
+                alterView = "ALTER VIEW " + view1 + " ADD CF.NEWCOL2 VARCHAR";
+                tenant1Conn.createStatement().execute(alterView);
+                
+                // Verify that the column family now shows up in the base table descriptor
+                tableDesc2 = tenant1Conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin().getTableDescriptor(Bytes.toBytes(baseTable));
+                assertFalse(tableDesc2.equals(tableDesc1));
+                assertNotNull(tableDesc2.getFamily(Bytes.toBytes("CF")));
+                
+                // Add a column with an existing column family. This shouldn't modify the base table.
+                alterView = "ALTER VIEW " + view1 + " ADD CF.NEWCOL3 VARCHAR";
+                tenant1Conn.createStatement().execute(alterView);
+                HTableDescriptor tableDesc3 = tenant1Conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin().getTableDescriptor(Bytes.toBytes(baseTable));
+                assertTrue(tableDesc3.equals(tableDesc2));
+                assertNotNull(tableDesc3.getFamily(Bytes.toBytes("CF")));
+            }
+        }
+    }
+    
+    @Test
+    public void testCacheInvalidatedAfterAddingColumnToBaseTableWithViews() throws Exception {
+        String baseTable = "testCacheInvalidatedAfterAddingColumnToBaseTableWithViews";
+        String viewName = baseTable + "_view";
+        String tenantId = "tenantId";
+        try (Connection globalConn = DriverManager.getConnection(getUrl())) {
+            String tableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true" ;
+            globalConn.createStatement().execute(tableDDL);
+            Properties tenantProps = new Properties();
+            tenantProps.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
+            // create a tenant specific view
+            try (Connection tenantConn =  DriverManager.getConnection(getUrl(), tenantProps)) {
+                String viewDDL = "CREATE VIEW " + viewName + " AS SELECT * FROM " + baseTable;
+                tenantConn.createStatement().execute(viewDDL);
+                
+                // Add a column to the base table using global connection
+                globalConn.createStatement().execute("ALTER TABLE " + baseTable + " ADD NEW_COL VARCHAR");
+
+                // Check now whether the tenant connection can see the column that was added
+                tenantConn.createStatement().execute("SELECT NEW_COL FROM " + viewName);
+                tenantConn.createStatement().execute("SELECT NEW_COL FROM " + baseTable);
+            }
+        }
+    }
+    
+    @Test
+    public void testCacheInvalidatedAfterDroppingColumnFromBaseTableWithViews() throws Exception {
+        String baseTable = "testCacheInvalidatedAfterDroppingColumnFromBaseTableWithViews";
+        String viewName = baseTable + "_view";
+        String tenantId = "tenantId";
+        try (Connection globalConn = DriverManager.getConnection(getUrl())) {
+            String tableDDL =
+                    "CREATE TABLE "
+                            + baseTable
+                            + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true" ;
+            globalConn.createStatement().execute(tableDDL);
+            Properties tenantProps = new Properties();
+            tenantProps.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
+            // create a tenant specific view
+            try (Connection tenantConn =  DriverManager.getConnection(getUrl(), tenantProps)) {
+                String viewDDL = "CREATE VIEW " + viewName + " AS SELECT * FROM " + baseTable;
+                tenantConn.createStatement().execute(viewDDL);
+    
+                // Add a column to the base table using global connection
+                globalConn.createStatement()
+                        .execute("ALTER TABLE " + baseTable + " DROP COLUMN V1");
+    
+                // Check now whether the tenant connection can see the column that was dropped
+                try {
+                    tenantConn.createStatement().execute("SELECT V1 FROM " + viewName);
+                    fail();
+                } catch (ColumnNotFoundException e) {
+                }
+                try {
+                    tenantConn.createStatement().execute("SELECT V1 FROM " + baseTable);
+                    fail();
+                } catch (ColumnNotFoundException e) {
+                }
+            }
+        }
+    }
+
+    public static void assertTableDefinition(Connection conn, String tableName, PTableType tableType, String parentTableName, int sequenceNumber, int columnCount, int baseColumnCount, String... columnName) throws Exception {
+        PreparedStatement p = conn.prepareStatement("SELECT * FROM SYSTEM.CATALOG WHERE TABLE_NAME=? AND TABLE_TYPE=?");
+        p.setString(1, tableName);
+        p.setString(2, tableType.getSerializedValue());
+        ResultSet rs = p.executeQuery();
+        assertTrue(rs.next());
+        assertEquals(AlterTableWithViewsIT.getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in BaseColumnCount"), baseColumnCount, rs.getInt("BASE_COLUMN_COUNT"));
+        assertEquals(AlterTableWithViewsIT.getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in columnCount"), columnCount, rs.getInt("COLUMN_COUNT"));
+        assertEquals(AlterTableWithViewsIT.getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in sequenceNumber"), sequenceNumber, rs.getInt("TABLE_SEQ_NUM"));
+        rs.close();
+    
+        ResultSet parentTableColumnsRs = null; 
+        if (parentTableName != null) {
+            parentTableColumnsRs = conn.getMetaData().getColumns(null, null, parentTableName, null);
+            parentTableColumnsRs.next();
+        }
+        
+        ResultSet viewColumnsRs = conn.getMetaData().getColumns(null, null, tableName, null);
+        for (int i = 0; i < columnName.length; i++) {
+            if (columnName[i] != null) {
+                assertTrue(viewColumnsRs.next());
+                assertEquals(AlterTableWithViewsIT.getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in columnName: i=" + i), columnName[i], viewColumnsRs.getString(PhoenixDatabaseMetaData.COLUMN_NAME));
+                int viewColOrdinalPos = viewColumnsRs.getInt(PhoenixDatabaseMetaData.ORDINAL_POSITION);
+                assertEquals(AlterTableWithViewsIT.getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in ordinalPosition: i=" + i), i+1, viewColOrdinalPos);
+                // validate that all the columns in the base table are present in the view   
+                if (parentTableColumnsRs != null && !parentTableColumnsRs.isAfterLast()) {
+                    ResultSetMetaData parentTableColumnsMetadata = parentTableColumnsRs.getMetaData();
+                    assertEquals(parentTableColumnsMetadata.getColumnCount(), viewColumnsRs.getMetaData().getColumnCount());
+                    int parentTableColOrdinalRs = parentTableColumnsRs.getInt(PhoenixDatabaseMetaData.ORDINAL_POSITION);
+                    assertEquals(AlterTableWithViewsIT.getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in ordinalPosition of view and base table for i=" + i), parentTableColOrdinalRs, viewColOrdinalPos);
+                    for (int columnIndex = 1; columnIndex < parentTableColumnsMetadata.getColumnCount(); columnIndex++) {
+                        String viewColumnValue = viewColumnsRs.getString(columnIndex);
+                        String parentTableColumnValue = parentTableColumnsRs.getString(columnIndex);
+                        if (!Objects.equal(viewColumnValue, parentTableColumnValue)) {
+                            if (parentTableColumnsMetadata.getColumnName(columnIndex).equals(PhoenixDatabaseMetaData.TABLE_NAME)) {
+                                assertEquals(parentTableName, parentTableColumnValue);
+                                assertEquals(tableName, viewColumnValue);
+                            } 
+                        }
+                    }
+                    parentTableColumnsRs.next();
+                }
+            }
+        }
+        assertFalse(AlterTableWithViewsIT.getSystemCatalogEntriesForTable(conn, tableName, ""), viewColumnsRs.next());
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index 122ec16..e09dcea 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -36,7 +36,6 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.Collections;
-import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
@@ -44,8 +43,10 @@ import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.KeepDeletedCells;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
-import org.apache.hadoop.hbase.client.HTableInterface;
-import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
 import org.apache.phoenix.exception.SQLExceptionCode;
@@ -55,8 +56,6 @@ import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.TableNotFoundException;
-import org.apache.phoenix.schema.types.PInteger;
-import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.PropertiesUtil;
@@ -65,8 +64,6 @@ import org.apache.phoenix.util.SchemaUtil;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import com.google.common.collect.Lists;
-
 /**
  *
  * A lot of tests in this class test HBase level properties. As a result,
@@ -358,6 +355,13 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
         assertIndexExists(conn,true);
 
         // verify data table rows
+        Scan scan = new Scan();
+        HTable table = (HTable) conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes(DATA_TABLE_FULL_NAME));
+        ResultScanner results = table.getScanner(scan);
+        for (Result res : results) {
+        	assertNull("Column value was not deleted",res.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, Bytes.toBytes("V2")));
+        }
+        results.close();
         rs = conn.createStatement().executeQuery(dataTableQuery);
         assertTrue(rs.next());
         assertEquals("a",rs.getString(1));
@@ -366,6 +370,13 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
         assertFalse(rs.next());
         
         // verify index table rows
+        scan = new Scan();
+        table = (HTable) conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes(INDEX_TABLE_FULL_NAME));
+        results = table.getScanner(scan);
+        for (Result res : results) {
+        	assertNull("Column value was not deleted",res.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, Bytes.toBytes("0:V2")));
+        }
+        results.close();
         rs = conn.createStatement().executeQuery(indexTableQuery);
         assertTrue(rs.next());
         assertEquals("x",rs.getString(1));
@@ -2204,6 +2215,6 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
 			}
 		}
 	}
-    
+	
 }
- 
\ No newline at end of file
+ 


[25/52] [abbrv] phoenix git commit: PHOENIX-1311 HBase namespaces surfaced in phoenix

Posted by sa...@apache.org.
PHOENIX-1311 HBase namespaces surfaced in phoenix


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

Branch: refs/heads/encodecolumns
Commit: 7e432be79ff3f05143ef3bd86ac278c132d0ec15
Parents: 366e7a7
Author: Ankit Singhal <an...@gmail.com>
Authored: Thu Apr 14 16:09:55 2016 +0530
Committer: Ankit Singhal <an...@gmail.com>
Committed: Thu Apr 14 16:09:55 2016 +0530

----------------------------------------------------------------------
 .../apache/phoenix/end2end/CreateSchemaIT.java  |   83 +
 .../apache/phoenix/end2end/CreateTableIT.java   |   70 +-
 .../apache/phoenix/end2end/DropSchemaIT.java    |  110 +
 .../end2end/NamespaceSchemaMappingIT.java       |  117 +
 .../phoenix/end2end/PhoenixRuntimeIT.java       |    2 +-
 .../end2end/QueryDatabaseMetaDataIT.java        |   12 +-
 .../org/apache/phoenix/end2end/UpgradeIT.java   |   87 +
 .../org/apache/phoenix/end2end/UseSchemaIT.java |  134 +
 .../java/org/apache/phoenix/end2end/ViewIT.java |   31 +-
 .../phoenix/end2end/index/LocalIndexIT.java     |  450 +-
 .../end2end/index/MutableIndexFailureIT.java    |   48 +-
 .../phoenix/end2end/index/ViewIndexIT.java      |   57 +-
 .../org/apache/phoenix/tx/TxCheckpointIT.java   |    5 +-
 phoenix-core/src/main/antlr3/PhoenixSQL.g       |   22 +
 .../ipc/controller/MetadataRpcController.java   |   12 +-
 .../apache/phoenix/compile/ColumnResolver.java  |   10 +
 .../phoenix/compile/CreateSchemaCompiler.java   |   65 +
 .../apache/phoenix/compile/FromCompiler.java    |  166 +-
 .../apache/phoenix/compile/JoinCompiler.java    |   11 +-
 .../apache/phoenix/compile/PostDDLCompiler.java |   24 +-
 .../compile/TupleProjectionCompiler.java        |   24 +-
 .../apache/phoenix/compile/UnionCompiler.java   |   11 +-
 .../coprocessor/MetaDataEndpointImpl.java       |  361 +-
 .../phoenix/coprocessor/MetaDataProtocol.java   |   28 +-
 .../coprocessor/generated/MetaDataProtos.java   | 4211 +++++++++++++++---
 .../coprocessor/generated/PSchemaProtos.java    |  666 +++
 .../coprocessor/generated/PTableProtos.java     |  104 +-
 .../phoenix/exception/SQLExceptionCode.java     |   21 +-
 .../hbase/index/master/IndexMasterObserver.java |    8 +-
 .../write/ParallelWriterIndexCommitter.java     |    2 +-
 .../TrackingParallelWriterIndexCommitter.java   |    2 +-
 .../index/PhoenixIndexFailurePolicy.java        |    8 +-
 .../phoenix/iterate/ChunkedResultIterator.java  |    6 +-
 .../phoenix/iterate/ParallelIterators.java      |    2 +-
 .../apache/phoenix/iterate/SerialIterators.java |    2 +-
 .../apache/phoenix/jdbc/PhoenixConnection.java  |   55 +-
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java   |    8 +-
 .../apache/phoenix/jdbc/PhoenixStatement.java   |   88 +-
 .../phoenix/mapreduce/AbstractBulkLoadTool.java |   15 +-
 .../phoenix/mapreduce/CsvBulkImportUtil.java    |    7 +
 .../mapreduce/MultiHfileOutputFormat.java       |    4 +-
 .../phoenix/mapreduce/index/IndexTool.java      |   15 +-
 .../phoenix/parse/CreateSchemaStatement.java    |   25 +
 .../phoenix/parse/DropSchemaStatement.java      |   38 +
 .../java/org/apache/phoenix/parse/PSchema.java  |   86 +
 .../apache/phoenix/parse/ParseNodeFactory.java  |   12 +
 .../phoenix/parse/UseSchemaStatement.java       |   19 +
 .../apache/phoenix/protobuf/ProtobufUtil.java   |   16 +-
 .../phoenix/query/ConnectionQueryServices.java  |   14 +-
 .../query/ConnectionQueryServicesImpl.java      |  378 +-
 .../query/ConnectionlessQueryServicesImpl.java  |   43 +-
 .../query/DelegateConnectionQueryServices.java  |   43 +-
 .../apache/phoenix/query/MetaDataMutated.java   |    5 +-
 .../apache/phoenix/query/QueryConstants.java    |    7 +
 .../org/apache/phoenix/query/QueryServices.java |    5 +
 .../phoenix/query/QueryServicesOptions.java     |   11 +-
 .../apache/phoenix/schema/DelegateTable.java    |    5 +
 .../apache/phoenix/schema/MetaDataClient.java   |  204 +-
 .../NewerSchemaAlreadyExistsException.java      |   26 +
 .../org/apache/phoenix/schema/PMetaData.java    |    2 +
 .../apache/phoenix/schema/PMetaDataImpl.java    |   51 +-
 .../java/org/apache/phoenix/schema/PTable.java  |    6 +
 .../org/apache/phoenix/schema/PTableImpl.java   |   58 +-
 .../org/apache/phoenix/schema/PTableKey.java    |    2 +
 .../schema/SchemaAlreadyExistsException.java    |   53 +
 .../phoenix/schema/SchemaNotFoundException.java |   52 +
 .../stats/StatisticsCollectorFactory.java       |    5 +
 .../phoenix/schema/stats/StatisticsWriter.java  |    6 +-
 .../java/org/apache/phoenix/util/IndexUtil.java |    2 +-
 .../java/org/apache/phoenix/util/JDBCUtil.java  |    5 +
 .../org/apache/phoenix/util/MetaDataUtil.java   |  106 +-
 .../org/apache/phoenix/util/PhoenixRuntime.java |   79 +-
 .../org/apache/phoenix/util/SchemaUtil.java     |  141 +-
 .../org/apache/phoenix/util/UpgradeUtil.java    |  177 +
 .../phoenix/execute/CorrelatePlanTest.java      |    2 +-
 .../execute/LiteralResultIteratorPlanTest.java  |    2 +-
 .../java/org/apache/phoenix/query/BaseTest.java |   23 +-
 .../query/ParallelIteratorsSplitTest.java       |   11 +
 .../org/apache/phoenix/util/JDBCUtilTest.java   |    8 +
 phoenix-protocol/src/main/MetaDataService.proto |   39 +-
 phoenix-protocol/src/main/PSchema.proto         |   30 +
 phoenix-protocol/src/main/PTable.proto          |    1 +
 82 files changed, 7673 insertions(+), 1289 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateSchemaIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateSchemaIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateSchemaIT.java
new file mode 100644
index 0000000..4cf9eb4
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateSchemaIT.java
@@ -0,0 +1,83 @@
+/*
+ * 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.phoenix.end2end;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.NewerSchemaAlreadyExistsException;
+import org.apache.phoenix.schema.SchemaAlreadyExistsException;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.SchemaUtil;
+import org.junit.Test;
+
+public class CreateSchemaIT extends BaseClientManagedTimeIT {
+
+    @Test
+    public void testCreateSchema() throws Exception {
+        long ts = nextTimestamp();
+        Properties props = new Properties();
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
+        String ddl = "CREATE SCHEMA TEST_SCHEMA";
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);
+                HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();) {
+            conn.createStatement().execute(ddl);
+            assertNotNull(admin.getNamespaceDescriptor("TEST_SCHEMA"));
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 10));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute(ddl);
+            fail();
+        } catch (SchemaAlreadyExistsException e) {
+            // expected
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts - 20));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+            conn.createStatement().execute(ddl);
+            fail();
+        } catch (NewerSchemaAlreadyExistsException e) {
+            // expected
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 100));
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        try {
+            conn.createStatement().execute("CREATE SCHEMA " + SchemaUtil.SCHEMA_FOR_DEFAULT_NAMESPACE);
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.SCHEMA_NOT_ALLOWED.getErrorCode(), e.getErrorCode());
+        }
+        try {
+            conn.createStatement().execute("CREATE SCHEMA " + SchemaUtil.HBASE_NAMESPACE);
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.SCHEMA_NOT_ALLOWED.getErrorCode(), e.getErrorCode());
+        }
+        conn.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
index b0370e8..af25373 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
@@ -19,6 +19,8 @@ package org.apache.phoenix.end2end;
 
 import static org.apache.hadoop.hbase.HColumnDescriptor.DEFAULT_REPLICATION_SCOPE;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -35,9 +37,12 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.query.KeyRange;
+import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.NewerTableAlreadyExistsException;
+import org.apache.phoenix.schema.SchemaNotFoundException;
 import org.apache.phoenix.schema.TableAlreadyExistsException;
 import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.SchemaUtil;
 import org.junit.Test;
 
 
@@ -65,10 +70,12 @@ public class CreateTableIT extends BaseClientManagedTimeIT {
     @Test
     public void testCreateTable() throws Exception {
         long ts = nextTimestamp();
+        String schemaName = "TEST";
+        String tableName = schemaName + ".M_INTERFACE_JOB";
         Properties props = new Properties();
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        String ddl = "CREATE TABLE m_interface_job(                data.addtime VARCHAR ,\n" + 
+        
+        String ddl = "CREATE TABLE " + tableName + "(                data.addtime VARCHAR ,\n" + 
                 "                data.dir VARCHAR ,\n" + 
                 "                data.end_time VARCHAR ,\n" + 
                 "                data.file VARCHAR ,\n" + 
@@ -93,18 +100,41 @@ public class CreateTableIT extends BaseClientManagedTimeIT {
                 "                data.type VARCHAR ,\n" + 
                 "                id INTEGER not null primary key desc\n" + 
                 "                ) ";
-        conn.createStatement().execute(ddl);
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute(ddl);
+        }
+        HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), props).getAdmin();
+        assertNotNull(admin.getTableDescriptor(Bytes.toBytes(tableName)));
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 10));
-        conn = DriverManager.getConnection(getUrl(), props);
-        try {
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
             conn.createStatement().execute(ddl);
             fail();
         } catch (TableAlreadyExistsException e) {
             // expected
         }
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 20));
-        conn = DriverManager.getConnection(getUrl(), props);
-        conn.createStatement().execute("DROP TABLE m_interface_job");
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute("DROP TABLE " + tableName);
+        }
+
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 30));
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.TRUE.toString());
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute("CREATE SCHEMA " + schemaName);
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 40));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute(ddl);
+            assertNotEquals(null,
+                    admin.getTableDescriptor(SchemaUtil.getPhysicalTableName(tableName.getBytes(), true).getName()));
+        } finally {
+            admin.close();
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 50));
+        props.setProperty(QueryServices.DROP_METADATA_ATTRIB, Boolean.TRUE.toString());
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute("DROP TABLE " + tableName);
+        }
     }
 
     @Test
@@ -435,4 +465,30 @@ public class CreateTableIT extends BaseClientManagedTimeIT {
         }
         connAt20.close();
     }
+
+    @Test
+    public void testCreateTableWithoutSchema() throws Exception {
+        String createSchemaDDL = "CREATE SCHEMA T_SCHEMA";
+        String createTableDDL = "CREATE TABLE T_SCHEMA.TEST(pk INTEGER PRIMARY KEY)";
+        String dropTableDDL = "DROP TABLE T_SCHEMA.TEST";
+        Properties props = new Properties();
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+            try {
+                conn.createStatement().execute(createTableDDL);
+                fail();
+            } catch (SchemaNotFoundException snfe) {
+                //expected
+            }
+            conn.createStatement().execute(createSchemaDDL);
+            conn.createStatement().execute(createTableDDL);
+            conn.createStatement().execute(dropTableDDL);
+        }
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(false));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute(createTableDDL);
+        } catch (SchemaNotFoundException e) {
+            fail();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropSchemaIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropSchemaIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropSchemaIT.java
new file mode 100644
index 0000000..665c0a8
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropSchemaIT.java
@@ -0,0 +1,110 @@
+/*
+ * 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.phoenix.end2end;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.NamespaceNotFoundException;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.SchemaNotFoundException;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.Test;
+
+public class DropSchemaIT extends BaseClientManagedTimeIT {
+
+    @Test
+    public void testDropSchema() throws Exception {
+        long ts = nextTimestamp();
+        String schema = "TEST_SCHEMA";
+        String tableName = "TEST";
+        Properties props = new Properties();
+        String ddl = "DROP SCHEMA " + schema;
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute("CREATE SCHEMA " + schema);
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 10));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute("CREATE TABLE " + schema + "." + tableName + "(id INTEGER PRIMARY KEY)");
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 15));
+        HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+
+            try {
+                conn.createStatement().execute(ddl);
+                fail();
+            } catch (SQLException e) {
+                e.printStackTrace();
+                assertEquals(e.getErrorCode(), SQLExceptionCode.CANNOT_MUTATE_SCHEMA.getErrorCode());
+            }
+            assertNotNull(admin.getNamespaceDescriptor(schema));
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts - 20));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute(ddl);
+            fail();
+        } catch (SchemaNotFoundException e) {
+            // expected
+        }
+        assertNotNull(admin.getNamespaceDescriptor(schema));
+
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 40));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute("DROP TABLE " + schema + "." + tableName);
+            //Dropping table manually because Drop_meta_attrib is not working
+            admin.disableTable(TableName.valueOf(schema, tableName));
+            admin.deleteTable(TableName.valueOf(schema, tableName));
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 50));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute(ddl);
+            try {
+                admin.getNamespaceDescriptor(schema);
+                fail();
+            } catch (NamespaceNotFoundException ne) {
+                // expected
+            }
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 60));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            conn.createStatement().execute("DROP SCHEMA IF EXISTS " + schema);
+        }
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 70));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
+            admin.createNamespace(NamespaceDescriptor.create(schema).build());
+            conn.createStatement().execute("DROP SCHEMA IF EXISTS " + schema);
+            assertNotNull(admin.getNamespaceDescriptor(schema));
+        }
+        admin.close();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/NamespaceSchemaMappingIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/NamespaceSchemaMappingIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/NamespaceSchemaMappingIT.java
new file mode 100644
index 0000000..43b62dd
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/NamespaceSchemaMappingIT.java
@@ -0,0 +1,117 @@
+/*
+ * 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.phoenix.end2end;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.types.PBoolean;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.Test;
+/*
+ * since 4.8
+ */
+public class NamespaceSchemaMappingIT extends BaseHBaseManagedTimeIT {
+    /**
+     * Tests that when: There is a table created with older version of phoenix and a table created with newer version
+     * having {@code QueryServices#IS_NAMESPACE_MAPPING_ENABLED} true, then there is only a flag
+     * {@code PhoenixDatabaseMetaData#IS_NAMESPACE_MAPPED} differentiates that whether schema of the table is mapped to
+     * namespace or not
+     */
+    @Test
+    @SuppressWarnings("deprecation")
+    public void testBackWardCompatibility() throws Exception {
+
+        String namespace = "TEST_SCHEMA";
+        String schemaName = namespace;
+        String tableName = "TEST";
+
+        String phoenixFullTableName = schemaName + "." + tableName;
+        String hbaseFullTableName = schemaName + ":" + tableName;
+        HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+        admin.createNamespace(NamespaceDescriptor.create(namespace).build());
+        HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(namespace, tableName));
+        desc.addFamily(new HColumnDescriptor(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES));
+        admin.createTable(desc);
+        desc = new HTableDescriptor(TableName.valueOf(phoenixFullTableName));
+        desc.addFamily(new HColumnDescriptor(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES));
+        admin.createTable(desc);
+
+        Put put = new Put(PVarchar.INSTANCE.toBytes(phoenixFullTableName));
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES,
+                QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+        HTable phoenixSchematable = new HTable(admin.getConfiguration(), phoenixFullTableName);
+        phoenixSchematable.put(put);
+        phoenixSchematable.close();
+        put = new Put(PVarchar.INSTANCE.toBytes(hbaseFullTableName));
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES,
+                QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+        phoenixSchematable.close();
+        HTable namespaceMappedtable = new HTable(admin.getConfiguration(), hbaseFullTableName);
+        namespaceMappedtable.put(put);
+        namespaceMappedtable.close();
+        Properties props = new Properties();
+        props.setProperty(QueryServices.DROP_METADATA_ATTRIB, Boolean.TRUE.toString());
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        String ddl = "create table " + phoenixFullTableName + "(tableName varchar primary key)";
+        conn.createStatement().execute(ddl);
+        String query = "select tableName from " + phoenixFullTableName;
+
+        ResultSet rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals(phoenixFullTableName, rs.getString(1));
+
+        HTable metatable = new HTable(admin.getConfiguration(),
+                SchemaUtil.getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES,
+                        (conn.unwrap(PhoenixConnection.class).getQueryServices().getProps())));
+        Put p = new Put(SchemaUtil.getTableKey(null, schemaName, tableName));
+        p.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, PhoenixDatabaseMetaData.IS_NAMESPACE_MAPPED_BYTES,
+                PBoolean.INSTANCE.toBytes(true));
+        metatable.put(p);
+        metatable.close();
+
+        PhoenixConnection phxConn = (conn.unwrap(PhoenixConnection.class));
+        phxConn.getQueryServices().clearCache();
+        rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals(hbaseFullTableName, rs.getString(1));
+        admin.disableTable(phoenixFullTableName);
+        admin.deleteTable(phoenixFullTableName);
+        conn.createStatement().execute("DROP TABLE " + phoenixFullTableName);
+        admin.close();
+        conn.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java
index 3cab7fa..3ba43e9 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PhoenixRuntimeIT.java
@@ -143,5 +143,5 @@ public class PhoenixRuntimeIT extends BaseHBaseManagedTimeIT {
         assertTenantIds(e7, htable7, new FirstKeyOnlyFilter(), new String[] {"t1", "t2"} );
         
     }
-
+    
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
index ba83e6a..f62bf0f 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
@@ -174,12 +174,10 @@ public class QueryDatabaseMetaDataIT extends BaseClientManagedTimeIT {
 
     @Test
     public void testSchemaMetadataScan() throws SQLException {
-        long ts = nextTimestamp();
-        ensureTableCreated(getUrl(), CUSTOM_ENTITY_DATA_FULL_NAME, null, ts);
-        ensureTableCreated(getUrl(), PTSDB_NAME, null, ts);
         Properties props = new Properties();
-        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 5));
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
         Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.createStatement().execute("CREATE SCHEMA " + CUSTOM_ENTITY_DATA_SCHEMA_NAME);
         DatabaseMetaData dbmd = conn.getMetaData();
         ResultSet rs;
         rs = dbmd.getSchemas(null, CUSTOM_ENTITY_DATA_SCHEMA_NAME);
@@ -190,14 +188,8 @@ public class QueryDatabaseMetaDataIT extends BaseClientManagedTimeIT {
 
         rs = dbmd.getSchemas(null, null);
         assertTrue(rs.next());
-        assertEquals(rs.getString("TABLE_SCHEM"),null);
-        assertEquals(rs.getString("TABLE_CATALOG"),null);
-        assertTrue(rs.next());
         assertEquals(rs.getString("TABLE_SCHEM"),CUSTOM_ENTITY_DATA_SCHEMA_NAME);
         assertEquals(rs.getString("TABLE_CATALOG"),null);
-        assertTrue(rs.next());
-        assertEquals(rs.getString("TABLE_SCHEM"),PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA);
-        assertEquals(rs.getString("TABLE_CATALOG"),null);
         assertFalse(rs.next());
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
index 094816c..1c86039 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
@@ -26,20 +26,26 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import java.io.IOException;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Properties;
+import java.util.Set;
 
 import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.client.RowMutations;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.MetaDataUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.UpgradeUtil;
@@ -111,6 +117,86 @@ public class UpgradeIT extends BaseHBaseManagedTimeIT {
         testViewUpgrade(true, TENANT_ID, "SAMESCHEMA", "TABLEWITHVIEW5", "SAMESCHEMA", "VIEW5",
             ColumnDiff.LESS);
     }
+
+    @Test
+    public void testMapTableToNamespaceDuringUpgrade()
+            throws SQLException, IOException, IllegalArgumentException, InterruptedException {
+        String[] strings = new String[] { "a", "b", "c", "d" };
+
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            String schemaName = "TEST";
+            String phoenixFullTableName = schemaName + ".S_NEW";
+            String indexName = "IDX";
+            String localIndexName = "LIDX";
+            String[] tableNames = new String[] { phoenixFullTableName, schemaName + "." + indexName,
+                    schemaName + "." + localIndexName, "diff.v", "test.v" };
+            conn.createStatement().execute("CREATE TABLE " + phoenixFullTableName
+                    + "(k VARCHAR PRIMARY KEY, v INTEGER, f INTEGER, g INTEGER NULL, h INTEGER NULL)");
+            PreparedStatement upsertStmt = conn
+                    .prepareStatement("UPSERT INTO " + phoenixFullTableName + " VALUES(?, ?, 0, 0, 0)");
+            int i = 1;
+            for (String str : strings) {
+                upsertStmt.setString(1, str);
+                upsertStmt.setInt(2, i++);
+                upsertStmt.execute();
+            }
+            conn.commit();
+            // creating local index
+            conn.createStatement()
+                    .execute("create local index " + localIndexName + " on " + phoenixFullTableName + "(K)");
+            // creating global index
+            conn.createStatement().execute("create index " + indexName + " on " + phoenixFullTableName + "(k)");
+            // creating view in schema 'diff'
+            conn.createStatement().execute("CREATE VIEW diff.v (col VARCHAR) AS SELECT * FROM " + phoenixFullTableName);
+            // creating view in schema 'test'
+            conn.createStatement().execute("CREATE VIEW test.v (col VARCHAR) AS SELECT * FROM " + phoenixFullTableName);
+            // Creating index on views
+            conn.createStatement().execute("create index v_idx on diff.v(col)");
+            conn.createStatement().execute("create index v_idx on test.v(col)");
+
+            // validate data
+            for (String tableName : tableNames) {
+                ResultSet rs = conn.createStatement().executeQuery("select * from " + tableName);
+                for (String str : strings) {
+                    assertTrue(rs.next());
+                    assertEquals(str, rs.getString(1));
+                }
+            }
+
+            HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
+            assertTrue(admin.tableExists(phoenixFullTableName));
+            assertTrue(admin.tableExists(MetaDataUtil.getLocalIndexPhysicalName(Bytes.toBytes(phoenixFullTableName))));
+            assertTrue(admin.tableExists(schemaName + QueryConstants.NAME_SEPARATOR + indexName));
+            assertTrue(admin.tableExists(MetaDataUtil.getViewIndexPhysicalName(Bytes.toBytes(phoenixFullTableName))));
+            Properties props = new Properties();
+            props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
+            admin.close();
+            PhoenixConnection phxConn = DriverManager.getConnection(getUrl(), props).unwrap(PhoenixConnection.class);
+            UpgradeUtil.upgradeTable(phxConn, phoenixFullTableName);
+            Set<String> viewNames = MetaDataUtil.getViewNames(phxConn, phoenixFullTableName);
+            for (String viewName : viewNames) {
+                UpgradeUtil.upgradeTable(phxConn, viewName);
+            }
+            admin = phxConn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
+            String hbaseTableName = SchemaUtil.getPhysicalTableName(Bytes.toBytes(phoenixFullTableName), true)
+                    .getNameAsString();
+            assertTrue(admin.tableExists(hbaseTableName));
+            assertTrue(admin.tableExists(MetaDataUtil.getLocalIndexPhysicalName(Bytes.toBytes(hbaseTableName))));
+            assertTrue(admin.tableExists(schemaName + QueryConstants.NAMESPACE_SEPARATOR + indexName));
+            assertTrue(admin.tableExists(MetaDataUtil.getViewIndexPhysicalName(Bytes.toBytes(hbaseTableName))));
+            i = 0;
+            // validate data
+            for (String tableName : tableNames) {
+                ResultSet rs = phxConn.createStatement().executeQuery("select * from " + tableName);
+                for (String str : strings) {
+                    assertTrue(rs.next());
+                    assertEquals(str, rs.getString(1));
+                }
+            }
+            phxConn.close();
+            admin.close();
+        }
+    }
     
     @Test
     public void testSettingBaseColumnCountForMultipleViewsOnTable() throws Exception {
@@ -329,4 +415,5 @@ public class UpgradeIT extends BaseHBaseManagedTimeIT {
         }
         return DriverManager.getConnection(getUrl());
     }
+    
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/UseSchemaIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UseSchemaIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UseSchemaIT.java
new file mode 100644
index 0000000..793d165
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UseSchemaIT.java
@@ -0,0 +1,134 @@
+/*
+ * 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.phoenix.end2end;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.Test;
+
+public class UseSchemaIT extends BaseHBaseManagedTimeIT {
+
+    @Test
+    public void testUseSchema() throws Exception {
+        Properties props = new Properties();
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        String ddl = "CREATE SCHEMA IF NOT EXISTS TEST_SCHEMA";
+        conn.createStatement().execute(ddl);
+        ddl = "create table test_schema.test(id varchar primary key)";
+        conn.createStatement().execute(ddl);
+        conn.createStatement().execute("use test_schema");
+        String query = "select count(*) from test";
+        ResultSet rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals(0, rs.getInt(1));
+        try {
+            conn.createStatement().execute("use test");
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.SCHEMA_NOT_FOUND.getErrorCode(), e.getErrorCode());
+        }
+        conn.createStatement().execute("use default");
+        ddl = "create table IF NOT EXISTS test(schema_name varchar primary key)";
+        conn.createStatement().execute(ddl);
+        conn.createStatement().executeUpdate("upsert into test values('"+SchemaUtil.SCHEMA_FOR_DEFAULT_NAMESPACE+"')");
+        conn.commit();
+        rs = conn.createStatement().executeQuery("select schema_name from test");
+        assertTrue(rs.next());
+        assertEquals(SchemaUtil.SCHEMA_FOR_DEFAULT_NAMESPACE, rs.getString(1));
+        conn.close();
+    }
+
+    @Test
+    public void testSchemaInJdbcUrl() throws Exception {
+        Properties props = new Properties();
+        String schema = "TEST_SCHEMA";
+        props.setProperty(QueryServices.SCHEMA_ATTRIB, schema);
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(true);
+        String ddl = "CREATE SCHEMA IF NOT EXISTS " + schema;
+        conn.createStatement().execute(ddl);
+        ddl = "create table IF NOT EXISTS " + schema + ".test(schema_name varchar primary key)";
+        conn.createStatement().execute(ddl);
+        conn.createStatement().executeUpdate("upsert into " + schema + ".test values('" + schema + "')");
+        String query = "select schema_name from test";
+        ResultSet rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals(schema, rs.getString(1));
+
+        schema = "test";
+        ddl = "CREATE SCHEMA " + schema;
+        conn.createStatement().execute(ddl);
+        conn.createStatement().execute("use " + schema);
+        ddl = "create table test(schema_name varchar primary key)";
+        conn.createStatement().execute(ddl);
+        conn.createStatement().executeUpdate("upsert into test values('" + schema + "')");
+        rs = conn.createStatement().executeQuery("select schema_name from test");
+        assertTrue(rs.next());
+        assertEquals(schema, rs.getString(1));
+        conn.close();
+    }
+
+    @Test
+    public void testMappedView() throws Exception {
+        Properties props = new Properties();
+        String schema = "TEST_SCHEMA_V";
+        String tableName = "TEST";
+        String fullTablename = schema + QueryConstants.NAME_SEPARATOR + tableName;
+        props.setProperty(QueryServices.SCHEMA_ATTRIB, schema);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+        admin.createNamespace(NamespaceDescriptor.create(schema).build());
+        HTableDescriptor desc = new HTableDescriptor(fullTablename);
+        desc.addFamily(new HColumnDescriptor(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES));
+        admin.createTable(desc);
+        Put put = new Put(PVarchar.INSTANCE.toBytes(fullTablename));
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES,
+                QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+        HTable phoenixSchematable = new HTable(admin.getConfiguration(), fullTablename);
+        phoenixSchematable.put(put);
+        phoenixSchematable.close();
+        conn.createStatement().execute("CREATE VIEW " + tableName + " (tablename VARCHAR PRIMARY KEY)");
+        ResultSet rs = conn.createStatement().executeQuery("select tablename from " + tableName);
+        assertTrue(rs.next());
+        assertEquals(fullTablename, rs.getString(1));
+        admin.close();
+        conn.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
index 146fb1f..c87d82d 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ViewIT.java
@@ -34,18 +34,24 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.List;
+import java.util.Properties;
 
+import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.query.KeyRange;
+import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.ColumnAlreadyExistsException;
 import org.apache.phoenix.schema.ReadOnlyTableException;
 import org.apache.phoenix.schema.TableNotFoundException;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.SchemaUtil;
 import org.junit.Test;
 
 
+
 public class ViewIT extends BaseViewIT {
 	
     public ViewIT(boolean transactional) {
@@ -325,16 +331,37 @@ public class ViewIT extends BaseViewIT {
         assertEquals(5, count);
     }
 
+    
+    @Test
+    public void testViewAndTableInDifferentSchemasWithNamespaceMappingEnabled() throws Exception {
+        testViewAndTableInDifferentSchemas(true);
+    }
+
     @Test
     public void testViewAndTableInDifferentSchemas() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        String fullTableName = "s1.t"+tableSuffix;
+        testViewAndTableInDifferentSchemas(false);
+
+    }
+
+    public void testViewAndTableInDifferentSchemas(boolean isNamespaceMapped) throws Exception {
+        Properties props = new Properties();
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
+        Connection conn = DriverManager.getConnection(getUrl(),props);
+        String fullTableName = "s1.t" + tableSuffix + (isNamespaceMapped ? "_N" : "");
+        if (isNamespaceMapped) {
+            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS s1");
+        }
 		String ddl = "CREATE TABLE " + fullTableName + " (k INTEGER NOT NULL PRIMARY KEY, v1 DATE)" + tableDDLOptions;
+        HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
         conn.createStatement().execute(ddl);
+        assertTrue(admin.tableExists(SchemaUtil.getPhysicalTableName(SchemaUtil.normalizeIdentifier(fullTableName),
+                conn.unwrap(PhoenixConnection.class).getQueryServices().getProps())));
         ddl = "CREATE VIEW s2.v1 (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
         conn.createStatement().execute(ddl);
         ddl = "CREATE VIEW v2 (v2 VARCHAR) AS SELECT * FROM " + fullTableName + " WHERE k > 5";
         conn.createStatement().execute(ddl);
+        conn.createStatement().executeQuery("SELECT * FROM s2.v1");
+        conn.createStatement().executeQuery("SELECT * FROM v2");
         ddl = "DROP VIEW v1";
         try {
             conn.createStatement().execute(ddl);


[45/52] [abbrv] phoenix git commit: Replace empty key value with unit tests passing

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index f4300fd..c5a56ab 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -17,6 +17,7 @@
  */
 package org.apache.phoenix.schema;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static org.apache.phoenix.hbase.index.util.KeyValueBuilder.addQuietly;
 import static org.apache.phoenix.hbase.index.util.KeyValueBuilder.deleteQuietly;
 import static org.apache.phoenix.schema.SaltingUtil.SALTING_COLUMN;
@@ -31,6 +32,8 @@ import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
+import co.cask.tephra.TxConstants;
+
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.client.Delete;
@@ -59,6 +62,7 @@ import org.apache.phoenix.schema.types.PChar;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PDouble;
 import org.apache.phoenix.schema.types.PFloat;
+import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PVarchar;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.SchemaUtil;
@@ -108,7 +112,8 @@ public class PTableImpl implements PTable {
     private List<PColumnFamily> families;
     private Map<byte[], PColumnFamily> familyByBytes;
     private Map<String, PColumnFamily> familyByString;
-    private ListMultimap<String,PColumn> columnsByName;
+    private ListMultimap<String, PColumn> columnsByName;
+    private ListMultimap<Integer, PColumn> kvColumnsByColumnQualifiers;
     private PName pkName;
     private Integer bucketNum;
     private RowKeySchema rowKeySchema;
@@ -139,6 +144,7 @@ public class PTableImpl implements PTable {
     private int rowTimestampColPos;
     private long updateCacheFrequency;
     private boolean isNamespaceMapped;
+    private StorageScheme storageScheme;
 
     public PTableImpl() {
         this.indexes = Collections.emptyList();
@@ -170,7 +176,7 @@ public class PTableImpl implements PTable {
     }
     
     public PTableImpl(PName tenantId, PName schemaName, PName tableName, long timestamp, List<PColumnFamily> families, 
-            List<PColumn> columns, List<PName> physicalNames, Short viewIndexId, boolean multiTenant, boolean isNamespaceMpped) throws SQLException { // For indexes stored in shared physical tables
+            List<PColumn> columns, List<PName> physicalNames, Short viewIndexId, boolean multiTenant, boolean isNamespaceMpped, StorageScheme storageScheme) throws SQLException { // For indexes stored in shared physical tables
         this.pkColumns = this.allColumns = Collections.emptyList();
         this.rowKeySchema = RowKeySchema.EMPTY_SCHEMA;
         this.indexes = Collections.emptyList();
@@ -184,7 +190,7 @@ public class PTableImpl implements PTable {
         init(tenantId, this.schemaName, this.tableName, PTableType.INDEX, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
             PTableStats.EMPTY_STATS, this.schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
             null, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
-            isTransactional, updateCacheFrequency, indexDisableTimestamp,isNamespaceMpped);
+            isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMpped, storageScheme);
     }
 
     public PTableImpl(long timeStamp) { // For delete marker
@@ -227,7 +233,7 @@ public class PTableImpl implements PTable {
                 table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table), parentSchemaName, table.getParentTableName(),
                 indexes, table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), viewStatement,
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
+                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
     }
 
     public static PTableImpl makePTable(PTable table, List<PColumn> columns) throws SQLException {
@@ -236,7 +242,7 @@ public class PTableImpl implements PTable {
                 table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
+                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns) throws SQLException {
@@ -245,7 +251,7 @@ public class PTableImpl implements PTable {
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(),
                 table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows) throws SQLException {
@@ -254,7 +260,7 @@ public class PTableImpl implements PTable {
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
-                table.getIndexType(), table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
+                table.getIndexType(), table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
     }
     
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows, boolean isWalDisabled,
@@ -264,7 +270,7 @@ public class PTableImpl implements PTable {
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 isWalDisabled, isMultitenant, storeNulls, table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), isTransactional, updateCacheFrequency, table.getIndexDisableTimestamp(), isNamespaceMapped);
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), isTransactional, updateCacheFrequency, table.getIndexDisableTimestamp(), isNamespaceMapped, table.getStorageScheme());
     }
     
     public static PTableImpl makePTable(PTable table, PIndexState state) throws SQLException {
@@ -274,7 +280,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
+                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
     }
 
     public static PTableImpl makePTable(PTable table, boolean rowKeyOrderOptimizable) throws SQLException {
@@ -284,7 +290,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), rowKeyOrderOptimizable, table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
+                table.getBaseColumnCount(), rowKeyOrderOptimizable, table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
     }
 
     public static PTableImpl makePTable(PTable table, PTableStats stats) throws SQLException {
@@ -294,7 +300,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), stats,
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
     }
 
     public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
@@ -303,12 +309,12 @@ public class PTableImpl implements PTable {
             boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
             boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
             IndexType indexType, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency,
-            long indexDisableTimestamp, boolean isNamespaceMapped) throws SQLException {
+            long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme) throws SQLException {
         return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns, dataSchemaName,
                 dataTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
                 viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId,
                 indexType, PTableStats.EMPTY_STATS, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, rowKeyOrderOptimizable, isTransactional,
-                updateCacheFrequency,indexDisableTimestamp, isNamespaceMapped);
+                updateCacheFrequency,indexDisableTimestamp, isNamespaceMapped, storageScheme);
     }
 
     public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
@@ -317,12 +323,12 @@ public class PTableImpl implements PTable {
             boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
             boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
             IndexType indexType, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency,
-            @NotNull PTableStats stats, int baseColumnCount, long indexDisableTimestamp, boolean isNamespaceMapped)
+            @NotNull PTableStats stats, int baseColumnCount, long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme)
             throws SQLException {
         return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName,
                 bucketNum, columns, dataSchemaName, dataTableName, indexes, isImmutableRows, physicalNames,
                 defaultFamilyName, viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId,
-                indexType, stats, baseColumnCount, rowKeyOrderOptimizable, isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped);
+                indexType, stats, baseColumnCount, rowKeyOrderOptimizable, isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, storageScheme);
     }
 
     private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state,
@@ -330,11 +336,11 @@ public class PTableImpl implements PTable {
             PName parentSchemaName, PName parentTableName, List<PTable> indexes, boolean isImmutableRows,
             List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL, boolean multiTenant,
             boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType,
-            PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped) throws SQLException {
+            PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme) throws SQLException {
         init(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
                 stats, schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
                 viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
-                isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped);
+                isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, storageScheme);
     }
     
     @Override
@@ -367,7 +373,7 @@ public class PTableImpl implements PTable {
             PName pkName, Integer bucketNum, List<PColumn> columns, PTableStats stats, PName parentSchemaName, PName parentTableName,
             List<PTable> indexes, boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL,
             boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
-            IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped) throws SQLException {
+            IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme) throws SQLException {
         Preconditions.checkNotNull(schemaName);
         Preconditions.checkArgument(tenantId==null || tenantId.getBytes().length > 0); // tenantId should be null or not empty
         int estimatedSize = SizedUtil.OBJECT_SIZE * 2 + 23 * SizedUtil.POINTER_SIZE + 4 * SizedUtil.INT_SIZE + 2 * SizedUtil.LONG_SIZE + 2 * SizedUtil.INT_OBJECT_SIZE +
@@ -402,10 +408,12 @@ public class PTableImpl implements PTable {
         this.rowKeyOrderOptimizable = rowKeyOrderOptimizable;
         this.updateCacheFrequency = updateCacheFrequency;
         this.isNamespaceMapped = isNamespaceMapped;
+        this.storageScheme = storageScheme;
         List<PColumn> pkColumns;
         PColumn[] allColumns;
         
         this.columnsByName = ArrayListMultimap.create(columns.size(), 1);
+        this.kvColumnsByColumnQualifiers = (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES ? ArrayListMultimap.<Integer, PColumn>create(columns.size(), 1) : null);
         int numPKColumns = 0;
         if (bucketNum != null) {
             // Add salt column to allColumns and pkColumns, but don't add to
@@ -432,7 +440,22 @@ public class PTableImpl implements PTable {
                     if (Objects.equal(familyName, dupColumn.getFamilyName())) {
                         count++;
                         if (count > 1) {
-                            throw new ColumnAlreadyExistsException(null, name.getString(), columnName);
+                            throw new ColumnAlreadyExistsException(schemaName.getString(), name.getString(), columnName);
+                        }
+                    }
+                }
+            }
+            Integer cq = column.getColumnQualifier();
+            //TODO: samarth understand the implication of this.
+            if (kvColumnsByColumnQualifiers != null && cq != null) {
+                if (kvColumnsByColumnQualifiers.put(cq, column)) {
+                    int count = 0;
+                    for (PColumn dupColumn : kvColumnsByColumnQualifiers.get(cq)) {
+                        if (Objects.equal(familyName, dupColumn.getFamilyName())) {
+                            count++;
+                            if (count > 1) {
+                                throw new ColumnAlreadyExistsException(schemaName.getString(), name.getString(), columnName);
+                            }
                         }
                     }
                 }
@@ -497,7 +520,7 @@ public class PTableImpl implements PTable {
                 .orderedBy(Bytes.BYTES_COMPARATOR);
         for (int i = 0; i < families.length; i++) {
             Map.Entry<PName,List<PColumn>> entry = iterator.next();
-            PColumnFamily family = new PColumnFamilyImpl(entry.getKey(), entry.getValue());
+            PColumnFamily family = new PColumnFamilyImpl(entry.getKey(), entry.getValue(), storageScheme == StorageScheme.ENCODED_COLUMN_NAMES);
             families[i] = family;
             familyByString.put(family.getName().getString(), family);
             familyByBytes.put(family.getName().getBytes(), family);
@@ -683,7 +706,7 @@ public class PTableImpl implements PTable {
     }
 
     @Override
-    public PColumn getColumn(String name) throws ColumnNotFoundException, AmbiguousColumnException {
+    public PColumn getPColumnForColumnName(String name) throws ColumnNotFoundException, AmbiguousColumnException {
         List<PColumn> columns = columnsByName.get(name);
         int size = columns.size();
         if (size == 0) {
@@ -702,6 +725,35 @@ public class PTableImpl implements PTable {
         }
         return columns.get(0);
     }
+    
+    @Override
+    public PColumn getPColumnForColumnQualifier(byte[] cq) throws ColumnNotFoundException, AmbiguousColumnException {
+        if (SchemaUtil.usesEncodedColumnNames(this)) {
+            String columnName = (String)PVarchar.INSTANCE.toObject(cq);
+            return getPColumnForColumnName(columnName);
+        } else {
+            Integer qualifier = (Integer)PInteger.INSTANCE.toObject(cq);
+            List<PColumn> columns = kvColumnsByColumnQualifiers.get(qualifier);
+            int size = columns.size();
+            if (size == 0) {
+                //TODO: samarth should we have a column qualifier not found exception?
+                throw new ColumnNotFoundException(Bytes.toString(cq));
+            }
+            if (size > 1) {
+                for (PColumn column : columns) {
+                    if (column.getFamilyName() == null || QueryConstants.DEFAULT_COLUMN_FAMILY.equals(column.getFamilyName().getString())) {
+                        // Allow ambiguity with PK column or column in the default column family,
+                        // since a PK column cannot be prefixed and a user would not know how to
+                        // prefix a column in the default column family.
+                        return column;
+                    }
+                }
+                //TODO: samarth should we have a column qualifier not found exception?
+                throw new AmbiguousColumnException(columns.get(0).getName().getString());
+            }
+            return columns.get(0);
+        }
+    }
 
     /**
      *
@@ -794,7 +846,8 @@ public class PTableImpl implements PTable {
         public void setValue(PColumn column, byte[] byteValue) {
             deleteRow = null;
             byte[] family = column.getFamilyName().getBytes();
-            byte[] qualifier = column.getName().getBytes();
+            byte[] qualifier = getColumnQualifier(column);
+            ImmutableBytesPtr qualifierPtr = getColumnQualifierPtr(column);
             PDataType type = column.getDataType();
             // Check null, since some types have no byte representation for null
             boolean isNull = type.isNull(byteValue);
@@ -804,7 +857,7 @@ public class PTableImpl implements PTable {
                 }
                 removeIfPresent(setValues, family, qualifier);
                 deleteQuietly(unsetValues, kvBuilder, kvBuilder.buildDeleteColumns(keyPtr, column
-                            .getFamilyName().getBytesPtr(), column.getName().getBytesPtr(), ts));
+                            .getFamilyName().getBytesPtr(), qualifierPtr, ts));
             } else {
                 ImmutableBytesWritable ptr = new ImmutableBytesWritable(byteValue == null ?
                         HConstants.EMPTY_BYTE_ARRAY : byteValue);
@@ -818,7 +871,7 @@ public class PTableImpl implements PTable {
             	}
                 removeIfPresent(unsetValues, family, qualifier);
                 addQuietly(setValues, kvBuilder, kvBuilder.buildPut(keyPtr,
-                        column.getFamilyName().getBytesPtr(), column.getName().getBytesPtr(),
+                        column.getFamilyName().getBytesPtr(), qualifierPtr,
                         ts, ptr));
             }
         }
@@ -847,6 +900,26 @@ public class PTableImpl implements PTable {
                 deleteRow.setDurability(Durability.SKIP_WAL);
             }
         }
+        
+        private byte[] getColumnQualifier(PColumn column) {
+            //return column.getName().getBytes();
+            checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
+            boolean tableUsesEncodedColumnNames = SchemaUtil.usesEncodedColumnNames(PTableImpl.this);
+            if (!tableUsesEncodedColumnNames) {
+                return column.getName().getBytes();
+            }
+            return PInteger.INSTANCE.toBytes(column.getColumnQualifier());
+        }
+        
+        private ImmutableBytesPtr getColumnQualifierPtr(PColumn column) {
+//            return column.getName().getBytesPtr();
+            checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
+            boolean tableUsesEncodedColumnNames = SchemaUtil.usesEncodedColumnNames(PTableImpl.this);
+            if (!tableUsesEncodedColumnNames) {
+                return column.getName().getBytesPtr();
+            }
+            return new ImmutableBytesPtr(PInteger.INSTANCE.toBytes(column.getColumnQualifier()));
+        }
     }
 
     @Override
@@ -1104,14 +1177,17 @@ public class PTableImpl implements PTable {
       if (table.hasIsNamespaceMapped()) {
           isNamespaceMapped = table.getIsNamespaceMapped();
       }
-      
+      StorageScheme storageScheme = null;
+      if (table.hasStorageScheme()) {
+          storageScheme = StorageScheme.fromSerializedValue(table.getStorageScheme().toByteArray()[0]);
+      }
       try {
         PTableImpl result = new PTableImpl();
         result.init(tenantId, schemaName, tableName, tableType, indexState, timeStamp, sequenceNumber, pkName,
             (bucketNum == NO_SALTING) ? null : bucketNum, columns, stats, schemaName,dataTableName, indexes,
             isImmutableRows, physicalNames, defaultFamilyName, viewStatement, disableWAL,
             multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
-            isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped);
+            isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, storageScheme);
         return result;
       } catch (SQLException e) {
         throw new RuntimeException(e); // Impossible
@@ -1203,6 +1279,9 @@ public class PTableImpl implements PTable {
       builder.setUpdateCacheFrequency(table.getUpdateCacheFrequency());
       builder.setIndexDisableTimestamp(table.getIndexDisableTimestamp());
       builder.setIsNamespaceMapped(table.isNamespaceMapped());
+      if (table.getStorageScheme() != null) {
+          builder.setStorageScheme(ByteStringer.wrap(new byte[]{table.getStorageScheme().getSerializedValue()}));
+      }
       return builder.build();
     }
 
@@ -1245,4 +1324,9 @@ public class PTableImpl implements PTable {
     public boolean isNamespaceMapped() {
         return isNamespaceMapped;
     }
+    
+    @Override
+    public StorageScheme getStorageScheme() {
+        return storageScheme;
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/ProjectedColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/ProjectedColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/ProjectedColumn.java
index 19dd1c1..9336938 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/ProjectedColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/ProjectedColumn.java
@@ -39,6 +39,7 @@ public class ProjectedColumn extends DelegateColumn {
         return name;
     }
     
+    @Override
     public PName getFamilyName() {
         return familyName;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
index 734a9ed..23cfd1b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
@@ -38,7 +38,7 @@ public class SaltingUtil {
     public static final String SALTING_COLUMN_NAME = "_SALT";
     public static final String SALTED_ROW_KEY_NAME = "_SALTED_KEY";
     public static final PColumnImpl SALTING_COLUMN = new PColumnImpl(
-            PNameFactory.newName(SALTING_COLUMN_NAME), null, PBinary.INSTANCE, 1, 0, false, 0, SortOrder.getDefault(), 0, null, false, null, false, false);
+            PNameFactory.newName(SALTING_COLUMN_NAME), null, PBinary.INSTANCE, 1, 0, false, 0, SortOrder.getDefault(), 0, null, false, null, false, false, null);
     public static final RowKeySchema VAR_BINARY_SALTED_SCHEMA = new RowKeySchemaBuilder(2)
         .addField(SALTING_COLUMN, false, SortOrder.getDefault())
         .addField(SchemaUtil.VAR_BINARY_DATUM, false, SortOrder.getDefault()).build();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
index 2f56a93..9947e0c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
@@ -176,7 +176,7 @@ public class IndexUtil {
             throw new IllegalArgumentException("Could not find column family \"" +  indexColumnName.substring(0, pos) + "\" in index column name of \"" + indexColumnName + "\"", e);
         }
         try {
-            return family.getColumn(indexColumnName.substring(pos+1));
+            return family.getPColumnForColumnName(indexColumnName.substring(pos+1));
         } catch (ColumnNotFoundException e) {
             throw new IllegalArgumentException("Could not find column \"" +  indexColumnName.substring(pos+1) + "\" in index column name of \"" + indexColumnName + "\"", e);
         }
@@ -203,10 +203,11 @@ public class IndexUtil {
 
     private static boolean isEmptyKeyValue(PTable table, ColumnReference ref) {
         byte[] emptyKeyValueCF = SchemaUtil.getEmptyColumnFamily(table);
+        byte[] emptyKeyValueQualifier = SchemaUtil.getEmptyKeyValueInfo(table).getFirst();
         return (Bytes.compareTo(emptyKeyValueCF, 0, emptyKeyValueCF.length, ref.getFamilyWritable()
                 .get(), ref.getFamilyWritable().getOffset(), ref.getFamilyWritable().getLength()) == 0 && Bytes
-                .compareTo(QueryConstants.EMPTY_COLUMN_BYTES, 0,
-                    QueryConstants.EMPTY_COLUMN_BYTES.length, ref.getQualifierWritable().get(), ref
+                .compareTo(emptyKeyValueQualifier, 0,
+                        emptyKeyValueQualifier.length, ref.getQualifierWritable().get(), ref
                             .getQualifierWritable().getOffset(), ref.getQualifierWritable()
                             .getLength()) == 0);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
index f83317e..b5f5d5f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
@@ -481,9 +481,9 @@ public class PhoenixRuntime {
             String familyName = tokens[0];
             String familyColumn = tokens[1];
             PColumnFamily family = table.getColumnFamily(familyName);
-            pColumn = family.getColumn(familyColumn);
+            pColumn = family.getPColumnForColumnName(familyColumn);
         } else {
-            pColumn = table.getColumn(columnName);
+            pColumn = table.getPColumnForColumnName(columnName);
         }
         return getColumnInfo(pColumn);
     }
@@ -996,9 +996,9 @@ public class PhoenixRuntime {
         PColumn pColumn = null;
         if (familyName != null) {
             PColumnFamily family = table.getColumnFamily(familyName);
-            pColumn = family.getColumn(columnName);
+            pColumn = family.getPColumnForColumnName(columnName);
         } else {
-            pColumn = table.getColumn(columnName);
+            pColumn = table.getPColumnForColumnName(columnName);
         }
         return pColumn;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
index 7e93263..2202277 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
@@ -46,6 +46,7 @@ import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.exception.SQLExceptionInfo;
 import org.apache.phoenix.expression.Expression;
@@ -67,6 +68,7 @@ import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.PTable.StorageScheme;
 import org.apache.phoenix.schema.RowKeySchema;
 import org.apache.phoenix.schema.RowKeySchema.RowKeySchemaBuilder;
 import org.apache.phoenix.schema.SaltingUtil;
@@ -74,6 +76,7 @@ import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableProperty;
 import org.apache.phoenix.schema.ValueSchema.Field;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PVarbinary;
 import org.apache.phoenix.schema.types.PVarchar;
 
@@ -154,8 +157,9 @@ public class SchemaUtil {
     			rowSize += KeyValue.getKeyValueDataStructureSize(keyLength, column.getFamilyName().getBytes().length, column.getName().getBytes().length, valueLength);
     		}
     	}
+    	byte[] emptyKeyValueKV = SchemaUtil.getEmptyKeyValueInfo(table).getFirst();
     	// Empty key value
-    	rowSize += KeyValue.getKeyValueDataStructureSize(keyLength, getEmptyColumnFamily(table).length, QueryConstants.EMPTY_COLUMN_BYTES.length, 0);
+    	rowSize += KeyValue.getKeyValueDataStructureSize(keyLength, getEmptyColumnFamily(table).length, emptyKeyValueKV.length, 0);
     	return rowSize;
     }
     
@@ -390,7 +394,7 @@ public class SchemaUtil {
                 }
             } else {
                 try {
-                    return table.getColumnFamily(familyName.getString()).getColumn(column.getName().getString()).getName().getString();
+                    return table.getColumnFamily(familyName.getString()).getPColumnForColumnName(column.getName().getString()).getName().getString();
                 } catch (ColumnFamilyNotFoundException e) {
                     continue; // Shouldn't happen
                 } catch (ColumnNotFoundException e) {
@@ -587,7 +591,7 @@ public class SchemaUtil {
     
     public static boolean columnExists(PTable table, String columnName) {
         try {
-            table.getColumn(columnName);
+            table.getPColumnForColumnName(columnName);
             return true;
         } catch (ColumnNotFoundException e) {
             return false;
@@ -1015,6 +1019,53 @@ public class SchemaUtil {
     private static String getStrippedName(String physicalTableName, String indexPrefix) {
         return physicalTableName.indexOf(indexPrefix) == 0 ? physicalTableName.substring(indexPrefix.length())
                 : physicalTableName;
+    }      
+    
+    /**
+     * Return a map of column family -> next column qualifier number to use.
+     */
+    public static Map<String, Integer> getNextColumnQualifiers(PTable table) {
+        Map<String, Integer> map = Maps.newHashMapWithExpectedSize(table.getColumns().size());
+        for (PColumnFamily f : table.getColumnFamilies()) {
+            final int size = f.getColumns().size();
+            // column qualifiers start with 1.
+            map.put(f.getName().getString(), size + 1);
+        }
+        return map;
+    }
+    
+    public static boolean usesEncodedColumnNames(PTable table) {
+        return table.getStorageScheme() != null && table.getStorageScheme() == StorageScheme.ENCODED_COLUMN_NAMES;
+    }
+    
+    public static byte[] getColumnQualifier(PColumn column, PTable table) {
+      checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
+      return usesEncodedColumnNames(table) ? PInteger.INSTANCE.toBytes(column.getColumnQualifier()) : column.getName().getBytes();
+    }
+    
+    public static byte[] getColumnQualifier(PColumn column, boolean encodedColumnName) {
+        checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
+        return encodedColumnName ? PInteger.INSTANCE.toBytes(column.getColumnQualifier()) : column.getName().getBytes(); 
+    }
+    
+    /**
+     * @return pair of byte arrays. The first part of the pair is the empty key value's column qualifier, and the second
+     *         part is the value to use for it.
+     */
+    public static Pair<byte[], byte[]> getEmptyKeyValueInfo(PTable table) {
+        return usesEncodedColumnNames(table) ? new Pair<>(QueryConstants.ENCODED_EMPTY_COLUMN_BYTES,
+                QueryConstants.ENCODED_EMPTY_COLUMN_VALUE_BYTES) : new Pair<>(QueryConstants.EMPTY_COLUMN_BYTES,
+                QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+    }
+    
+    /**
+     * @return pair of byte arrays. The first part of the pair is the empty key value's column qualifier, and the second
+     *         part is the value to use for it.
+     */
+    public static Pair<byte[], byte[]> getEmptyKeyValueInfo(boolean usesEncodedColumnNames) {
+        return usesEncodedColumnNames ? new Pair<>(QueryConstants.ENCODED_EMPTY_COLUMN_BYTES,
+                QueryConstants.ENCODED_EMPTY_COLUMN_VALUE_BYTES) : new Pair<>(QueryConstants.EMPTY_COLUMN_BYTES,
+                        QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
     }
     
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/compile/HavingCompilerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/HavingCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/HavingCompilerTest.java
index 1c7477d..ae2bd14 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/HavingCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/HavingCompilerTest.java
@@ -156,7 +156,7 @@ public class HavingCompilerTest extends BaseConnectionlessQueryTest {
         String query = "select count(1) from atable group by a_string having count(1) >= 1 or a_string = 'foo'";
         List<Object> binds = Collections.emptyList();
         Expressions expressions = compileStatement(query,binds);
-        PColumn aCol = ATABLE.getColumn("A_STRING");
+        PColumn aCol = ATABLE.getPColumnForColumnName("A_STRING");
         Expression h = or(
                 constantComparison(CompareOp.GREATER_OR_EQUAL, new CountAggregateFunction(),1L),
                 constantComparison(CompareOp.EQUAL, 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
index 4b756fa..8bc73ae 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
@@ -163,7 +163,7 @@ public class QueryCompilerTest extends BaseConnectionlessQueryTest {
             String query = "CREATE TABLE t1 (k integer not null primary key, a.k decimal, b.k decimal)";
             conn.createStatement().execute(query);
             PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
-            PColumn c = pconn.getTable(new PTableKey(pconn.getTenantId(), "T1")).getColumn("K");
+            PColumn c = pconn.getTable(new PTableKey(pconn.getTenantId(), "T1")).getPColumnForColumnName("K");
             assertTrue(SchemaUtil.isPKColumn(c));
         } finally {
             conn.close();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
index 2f1a369..d7d7d02 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
@@ -67,8 +67,10 @@ import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.ColumnRef;
 import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.RowKeyValueAccessor;
 import org.apache.phoenix.schema.SaltingUtil;
+import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.types.PChar;
 import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.schema.types.PVarchar;
@@ -118,9 +120,9 @@ public class WhereCompilerTest extends BaseConnectionlessQueryTest {
         QueryPlan plan = pstmt.optimizeQuery();
         Scan scan = plan.getContext().getScan();
         Filter filter = scan.getFilter();
-        ColumnExpression idExpression = new ColumnRef(plan.getTableRef(), plan.getTableRef().getTable().getColumn("ID").getPosition()).newColumnExpression();
+        ColumnExpression idExpression = new ColumnRef(plan.getTableRef(), plan.getTableRef().getTable().getPColumnForColumnName("ID").getPosition()).newColumnExpression();
         Expression id = new RowKeyColumnExpression(idExpression,new RowKeyValueAccessor(plan.getTableRef().getTable().getPKColumns(),0));
-        Expression company = new KeyValueColumnExpression(plan.getTableRef().getTable().getColumn("COMPANY"));
+        Expression company = new KeyValueColumnExpression(plan.getTableRef().getTable().getPColumnForColumnName("COMPANY"), true);
         // FilterList has no equals implementation
         assertTrue(filter instanceof FilterList);
         FilterList filterList = (FilterList)filter;
@@ -148,11 +150,11 @@ public class WhereCompilerTest extends BaseConnectionlessQueryTest {
         QueryPlan plan = pstmt.optimizeQuery();
         Scan scan = plan.getContext().getScan();
         Filter filter = scan.getFilter();
-        PColumn column = plan.getTableRef().getTable().getColumn("COMPANY");
+        PColumn column = plan.getTableRef().getTable().getPColumnForColumnName("COMPANY");
         assertEquals(
                 singleKVFilter(constantComparison(
                     CompareOp.EQUAL,
-                    new KeyValueColumnExpression(column),
+                    new KeyValueColumnExpression(column, true),
                     "c3")),
                 filter);
     }
@@ -939,16 +941,18 @@ public class WhereCompilerTest extends BaseConnectionlessQueryTest {
         QueryPlan plan = pstmt.optimizeQuery();
         Scan scan = plan.getContext().getScan();
         Filter filter = scan.getFilter();
-
+        PTable table = plan.getTableRef().getTable();
+        ColumnExpression aInteger = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("A_INTEGER").getPosition()).newColumnExpression();
+        ColumnExpression aString = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("A_STRING").getPosition()).newColumnExpression();
         assertEquals(
             multiKVFilter(and(
                 constantComparison(
                     CompareOp.EQUAL,
-                    A_INTEGER,
+                    aInteger,
                     0),
                 constantComparison(
                     CompareOp.EQUAL,
-                    A_STRING,
+                    aString,
                     "foo"))),
             filter);
         
@@ -971,16 +975,18 @@ public class WhereCompilerTest extends BaseConnectionlessQueryTest {
         QueryPlan plan = pstmt.optimizeQuery();
         Scan scan = plan.getContext().getScan();
         Filter filter = scan.getFilter();
-
+        PTable table = plan.getTableRef().getTable();
+        ColumnExpression aInteger = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("A_INTEGER").getPosition()).newColumnExpression();
+        ColumnExpression aString = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("A_STRING").getPosition()).newColumnExpression();
         assertEquals(
             multiKVFilter(and(
                 constantComparison(
                     CompareOp.EQUAL,
-                    A_INTEGER,
+                    aInteger,
                     0),
                 constantComparison(
                     CompareOp.EQUAL,
-                    A_STRING,
+                    aString,
                     "foo"))),
             filter);
         

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
index 4660e38..36193e9 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
@@ -249,14 +249,14 @@ public class CorrelatePlanTest {
             Expression expr = LiteralExpression.newConstant(row[i]);
             columns.add(new PColumnImpl(PNameFactory.newName(name), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY),
                     expr.getDataType(), expr.getMaxLength(), expr.getScale(), expr.isNullable(),
-                    i, expr.getSortOrder(), null, null, false, name, false, false));
+                    i, expr.getSortOrder(), null, null, false, name, false, false, null));
         }
         try {
             PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME,
                     PTableType.SUBQUERY, null, MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM,
                     null, null, columns, null, null, Collections.<PTable>emptyList(),
                     false, Collections.<PName>emptyList(), null, null, false, false, false, null,
-                    null, null, true, false, 0, 0L, Boolean.FALSE);
+                    null, null, true, false, 0, 0L, Boolean.FALSE, null);
             TableRef sourceTable = new TableRef(pTable);
             List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> newArrayList();
             for (PColumn column : sourceTable.getTable().getColumns()) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
index aba4be4..ca4d80b 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
@@ -171,13 +171,13 @@ public class LiteralResultIteratorPlanTest {
             Expression expr = LiteralExpression.newConstant(row[i]);
             columns.add(new PColumnImpl(PNameFactory.newName(name),
                     PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), expr.getDataType(), expr.getMaxLength(),
-                    expr.getScale(), expr.isNullable(), i, expr.getSortOrder(), null, null, false, name, false, false));
+                    expr.getScale(), expr.isNullable(), i, expr.getSortOrder(), null, null, false, name, false, false, null));
         }
         try {
             PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,
                     MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM, null, null, columns, null, null,
                     Collections.<PTable> emptyList(), false, Collections.<PName> emptyList(), null, null, false, false,
-                    false, null, null, null, true, false, 0, 0L, false);
+                    false, null, null, null, true, false, 0, 0L, false, null);
             TableRef sourceTable = new TableRef(pTable);
             List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> newArrayList();
             for (PColumn column : sourceTable.getTable().getColumns()) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
index 50e2721..fe29e52 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
@@ -117,8 +117,8 @@ public class UnnestArrayPlanTest {
         LiteralExpression dummy = LiteralExpression.newConstant(null, arrayType);
         RowKeyValueAccessor accessor = new RowKeyValueAccessor(Arrays.asList(dummy), 0);
         UnnestArrayPlan plan = new UnnestArrayPlan(subPlan, new RowKeyColumnExpression(dummy, accessor), withOrdinality);
-        PColumn elemColumn = new PColumnImpl(PNameFactory.newName("ELEM"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), baseType, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false);
-        PColumn indexColumn = withOrdinality ? new PColumnImpl(PNameFactory.newName("IDX"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), PInteger.INSTANCE, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false) : null;
+        PColumn elemColumn = new PColumnImpl(PNameFactory.newName("ELEM"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), baseType, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false, null);
+        PColumn indexColumn = withOrdinality ? new PColumnImpl(PNameFactory.newName("IDX"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), PInteger.INSTANCE, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false, null) : null;
         List<PColumn> columns = withOrdinality ? Arrays.asList(elemColumn, indexColumn) : Arrays.asList(elemColumn);
         ProjectedColumnExpression elemExpr = new ProjectedColumnExpression(elemColumn, columns, 0, elemColumn.getName().getString());
         ProjectedColumnExpression indexExpr = withOrdinality ? new ProjectedColumnExpression(indexColumn, columns, 1, indexColumn.getName().getString()) : null;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java b/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
index 7ee579c..98c2495 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
@@ -41,8 +41,8 @@ public class ColumnExpressionTest {
         int maxLen = 30;
         int scale = 5;
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PDecimal.INSTANCE, maxLen, scale,
-                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false);
-        ColumnExpression colExp = new KeyValueColumnExpression(column);
+                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false, 0);
+        ColumnExpression colExp = new KeyValueColumnExpression(column, true);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);
         colExp.write(dOut);
@@ -61,8 +61,8 @@ public class ColumnExpressionTest {
     public void testSerializationWithNullScale() throws Exception {
         int maxLen = 30;
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PBinary.INSTANCE, maxLen, null,
-                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false);
-        ColumnExpression colExp = new KeyValueColumnExpression(column);
+                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false, 0);
+        ColumnExpression colExp = new KeyValueColumnExpression(column, true);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);
         colExp.write(dOut);
@@ -81,8 +81,8 @@ public class ColumnExpressionTest {
     public void testSerializationWithNullMaxLength() throws Exception {
         int scale = 5;
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PVarchar.INSTANCE, null, scale,
-                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false);
-        ColumnExpression colExp = new KeyValueColumnExpression(column);
+                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false, 0);
+        ColumnExpression colExp = new KeyValueColumnExpression(column, true);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);
         colExp.write(dOut);
@@ -100,8 +100,8 @@ public class ColumnExpressionTest {
     @Test
     public void testSerializationWithNullScaleAndMaxLength() throws Exception {
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PDecimal.INSTANCE, null, null, true,
-                20, SortOrder.getDefault(), 0, null, false, null, false, false);
-        ColumnExpression colExp = new KeyValueColumnExpression(column);
+                20, SortOrder.getDefault(), 0, null, false, null, false, false, 0);
+        ColumnExpression colExp = new KeyValueColumnExpression(column, true);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);
         colExp.write(dOut);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/index/IndexMaintainerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/index/IndexMaintainerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/index/IndexMaintainerTest.java
index 435f0fe..e7e03d6 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/index/IndexMaintainerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/index/IndexMaintainerTest.java
@@ -135,8 +135,7 @@ public class IndexMaintainerTest  extends BaseConnectionlessQueryTest {
             }
             ValueGetter valueGetter = newValueGetter(row, valueMap);
             
-            List<Mutation> indexMutations =
-                    IndexTestUtil.generateIndexData(index, table, dataMutation, ptr, builder);
+            List<Mutation> indexMutations = IndexTestUtil.generateIndexData(index, table, dataMutation, ptr, builder);
             assertEquals(1,indexMutations.size());
             assertTrue(indexMutations.get(0) instanceof Put);
             Mutation indexMutation = indexMutations.get(0);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
index f53e871..cb9c640 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
@@ -137,7 +137,11 @@ public class AggregateResultScannerTest extends BaseConnectionlessQueryTest {
 			public boolean isDynamic() {
 				return false;
 			}
-        })), null);
+            @Override
+            public Integer getColumnQualifier() {
+                return null;
+            }
+        }, false)), null);
         aggregationManager.setAggregators(new ClientAggregators(Collections.<SingleAggregateFunction>singletonList(func), 1));
         ResultIterators iterators = new ResultIterators() {
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/query/BaseConnectionlessQueryTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseConnectionlessQueryTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseConnectionlessQueryTest.java
index 452ea4d..0844d9b 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseConnectionlessQueryTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseConnectionlessQueryTest.java
@@ -125,15 +125,15 @@ public class BaseConnectionlessQueryTest extends BaseTest {
         try {
             PTable table = conn.getTable(new PTableKey(null, ATABLE_NAME));
             ATABLE = table;
-            ORGANIZATION_ID = new ColumnRef(new TableRef(table), table.getColumn("ORGANIZATION_ID").getPosition()).newColumnExpression();
-            ENTITY_ID = new ColumnRef(new TableRef(table), table.getColumn("ENTITY_ID").getPosition()).newColumnExpression();
-            A_INTEGER = new ColumnRef(new TableRef(table), table.getColumn("A_INTEGER").getPosition()).newColumnExpression();
-            A_STRING = new ColumnRef(new TableRef(table), table.getColumn("A_STRING").getPosition()).newColumnExpression();
-            B_STRING = new ColumnRef(new TableRef(table), table.getColumn("B_STRING").getPosition()).newColumnExpression();
-            A_DATE = new ColumnRef(new TableRef(table), table.getColumn("A_DATE").getPosition()).newColumnExpression();
-            A_TIME = new ColumnRef(new TableRef(table), table.getColumn("A_TIME").getPosition()).newColumnExpression();
-            A_TIMESTAMP = new ColumnRef(new TableRef(table), table.getColumn("A_TIMESTAMP").getPosition()).newColumnExpression();
-            X_DECIMAL = new ColumnRef(new TableRef(table), table.getColumn("X_DECIMAL").getPosition()).newColumnExpression();
+            ORGANIZATION_ID = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("ORGANIZATION_ID").getPosition()).newColumnExpression();
+            ENTITY_ID = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("ENTITY_ID").getPosition()).newColumnExpression();
+            A_INTEGER = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("A_INTEGER").getPosition()).newColumnExpression();
+            A_STRING = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("A_STRING").getPosition()).newColumnExpression();
+            B_STRING = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("B_STRING").getPosition()).newColumnExpression();
+            A_DATE = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("A_DATE").getPosition()).newColumnExpression();
+            A_TIME = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("A_TIME").getPosition()).newColumnExpression();
+            A_TIMESTAMP = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("A_TIMESTAMP").getPosition()).newColumnExpression();
+            X_DECIMAL = new ColumnRef(new TableRef(table), table.getPColumnForColumnName("X_DECIMAL").getPosition()).newColumnExpression();
         } finally {
             conn.close();
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
index 3396cf8..a86cc8d 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
@@ -142,15 +142,14 @@ public class ConnectionlessTest {
         assertTrue(iterator.hasNext());
         kv = iterator.next();
         assertArrayEquals(expectedRowKey1, kv.getRow());        
-        assertEquals(name1, PVarchar.INSTANCE.toObject(kv.getValue()));
-        assertTrue(iterator.hasNext());
+        assertEquals(QueryConstants.EMPTY_COLUMN_VALUE, PVarchar.INSTANCE.toObject(kv.getValue()));
         kv = iterator.next();
         assertArrayEquals(expectedRowKey1, kv.getRow());        
-        assertEquals(now, PDate.INSTANCE.toObject(kv.getValue()));
+        assertEquals(name1, PVarchar.INSTANCE.toObject(kv.getValue()));
         assertTrue(iterator.hasNext());
         kv = iterator.next();
         assertArrayEquals(expectedRowKey1, kv.getRow());        
-        assertEquals(QueryConstants.EMPTY_COLUMN_VALUE, PVarchar.INSTANCE.toObject(kv.getValue()));
+        assertEquals(now, PDate.INSTANCE.toObject(kv.getValue()));
     }
 
     @SuppressWarnings("deprecation")
@@ -159,15 +158,15 @@ public class ConnectionlessTest {
         assertTrue(iterator.hasNext());
         kv = iterator.next();
         assertArrayEquals(expectedRowKey2, kv.getRow());        
-        assertEquals(name2, PVarchar.INSTANCE.toObject(kv.getValue()));
-        assertTrue(iterator.hasNext());
+        assertEquals(QueryConstants.EMPTY_COLUMN_VALUE, PVarchar.INSTANCE.toObject(kv.getValue()));
         kv = iterator.next();
         assertArrayEquals(expectedRowKey2, kv.getRow());        
-        assertEquals(now, PDate.INSTANCE.toObject(kv.getValue()));
+        assertEquals(name2, PVarchar.INSTANCE.toObject(kv.getValue()));
         assertTrue(iterator.hasNext());
         kv = iterator.next();
         assertArrayEquals(expectedRowKey2, kv.getRow());        
-        assertEquals(QueryConstants.EMPTY_COLUMN_VALUE, PVarchar.INSTANCE.toObject(kv.getValue()));
+        assertEquals(now, PDate.INSTANCE.toObject(kv.getValue()));
+        assertFalse(iterator.hasNext());
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java b/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
index c73c160..77417b5 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
@@ -257,11 +257,11 @@ public class TestUtil {
     }
 
     public static Expression constantComparison(CompareOp op, PColumn c, Object o) {
-        return  new ComparisonExpression(Arrays.<Expression>asList(new KeyValueColumnExpression(c), LiteralExpression.newConstant(o)), op);
+        return  new ComparisonExpression(Arrays.<Expression>asList(new KeyValueColumnExpression(c, true), LiteralExpression.newConstant(o)), op);
     }
 
     public static Expression kvColumn(PColumn c) {
-        return new KeyValueColumnExpression(c);
+        return new KeyValueColumnExpression(c, true);
     }
 
     public static Expression pkColumn(PColumn c, List<PColumn> columns) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-protocol/src/main/PTable.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PTable.proto b/phoenix-protocol/src/main/PTable.proto
index c86f6b6..ec0c616 100644
--- a/phoenix-protocol/src/main/PTable.proto
+++ b/phoenix-protocol/src/main/PTable.proto
@@ -49,6 +49,7 @@ message PColumn {
   optional string expression = 12;
   optional bool isRowTimestamp = 13;
   optional bool isDynamic = 14;
+  optional int32 columnQualifier = 15;
 }
 
 message PTableStats {
@@ -91,4 +92,5 @@ message PTable {
   optional int64 updateCacheFrequency = 28;
   optional int64 indexDisableTimestamp = 29;
   optional bool isNamespaceMapped = 30;
+  optional bytes storageScheme = 31;
 }


[22/52] [abbrv] phoenix git commit: PHOENIX-1311 HBase namespaces surfaced in phoenix

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/MetaDataProtos.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/MetaDataProtos.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/MetaDataProtos.java
index ae72382..62e300a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/MetaDataProtos.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/MetaDataProtos.java
@@ -69,6 +69,30 @@ public final class MetaDataProtos {
      * <code>FUNCTION_NOT_IN_REGION = 13;</code>
      */
     FUNCTION_NOT_IN_REGION(13, 13),
+    /**
+     * <code>SCHEMA_ALREADY_EXISTS = 14;</code>
+     */
+    SCHEMA_ALREADY_EXISTS(14, 14),
+    /**
+     * <code>NEWER_SCHEMA_FOUND = 15;</code>
+     */
+    NEWER_SCHEMA_FOUND(15, 15),
+    /**
+     * <code>SCHEMA_NOT_FOUND = 16;</code>
+     */
+    SCHEMA_NOT_FOUND(16, 16),
+    /**
+     * <code>SCHEMA_NOT_IN_REGION = 17;</code>
+     */
+    SCHEMA_NOT_IN_REGION(17, 17),
+    /**
+     * <code>TABLES_EXIST_ON_SCHEMA = 18;</code>
+     */
+    TABLES_EXIST_ON_SCHEMA(18, 18),
+    /**
+     * <code>UNALLOWED_SCHEMA_MUTATION = 19;</code>
+     */
+    UNALLOWED_SCHEMA_MUTATION(19, 19),
     ;
 
     /**
@@ -127,6 +151,30 @@ public final class MetaDataProtos {
      * <code>FUNCTION_NOT_IN_REGION = 13;</code>
      */
     public static final int FUNCTION_NOT_IN_REGION_VALUE = 13;
+    /**
+     * <code>SCHEMA_ALREADY_EXISTS = 14;</code>
+     */
+    public static final int SCHEMA_ALREADY_EXISTS_VALUE = 14;
+    /**
+     * <code>NEWER_SCHEMA_FOUND = 15;</code>
+     */
+    public static final int NEWER_SCHEMA_FOUND_VALUE = 15;
+    /**
+     * <code>SCHEMA_NOT_FOUND = 16;</code>
+     */
+    public static final int SCHEMA_NOT_FOUND_VALUE = 16;
+    /**
+     * <code>SCHEMA_NOT_IN_REGION = 17;</code>
+     */
+    public static final int SCHEMA_NOT_IN_REGION_VALUE = 17;
+    /**
+     * <code>TABLES_EXIST_ON_SCHEMA = 18;</code>
+     */
+    public static final int TABLES_EXIST_ON_SCHEMA_VALUE = 18;
+    /**
+     * <code>UNALLOWED_SCHEMA_MUTATION = 19;</code>
+     */
+    public static final int UNALLOWED_SCHEMA_MUTATION_VALUE = 19;
 
 
     public final int getNumber() { return value; }
@@ -147,6 +195,12 @@ public final class MetaDataProtos {
         case 11: return FUNCTION_NOT_FOUND;
         case 12: return NEWER_FUNCTION_FOUND;
         case 13: return FUNCTION_NOT_IN_REGION;
+        case 14: return SCHEMA_ALREADY_EXISTS;
+        case 15: return NEWER_SCHEMA_FOUND;
+        case 16: return SCHEMA_NOT_FOUND;
+        case 17: return SCHEMA_NOT_IN_REGION;
+        case 18: return TABLES_EXIST_ON_SCHEMA;
+        case 19: return UNALLOWED_SCHEMA_MUTATION;
         default: return null;
       }
     }
@@ -1601,6 +1655,20 @@ public final class MetaDataProtos {
      */
     org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableStateOrBuilder getSharedTablesToDeleteOrBuilder(
         int index);
+
+    // optional .PSchema schema = 10;
+    /**
+     * <code>optional .PSchema schema = 10;</code>
+     */
+    boolean hasSchema();
+    /**
+     * <code>optional .PSchema schema = 10;</code>
+     */
+    org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema getSchema();
+    /**
+     * <code>optional .PSchema schema = 10;</code>
+     */
+    org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchemaOrBuilder getSchemaOrBuilder();
   }
   /**
    * Protobuf type {@code MetaDataResponse}
@@ -1721,6 +1789,19 @@ public final class MetaDataProtos {
               sharedTablesToDelete_.add(input.readMessage(org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.PARSER, extensionRegistry));
               break;
             }
+            case 82: {
+              org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000040) == 0x00000040)) {
+                subBuilder = schema_.toBuilder();
+              }
+              schema_ = input.readMessage(org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(schema_);
+                schema_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000040;
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -1967,6 +2048,28 @@ public final class MetaDataProtos {
       return sharedTablesToDelete_.get(index);
     }
 
+    // optional .PSchema schema = 10;
+    public static final int SCHEMA_FIELD_NUMBER = 10;
+    private org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema schema_;
+    /**
+     * <code>optional .PSchema schema = 10;</code>
+     */
+    public boolean hasSchema() {
+      return ((bitField0_ & 0x00000040) == 0x00000040);
+    }
+    /**
+     * <code>optional .PSchema schema = 10;</code>
+     */
+    public org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema getSchema() {
+      return schema_;
+    }
+    /**
+     * <code>optional .PSchema schema = 10;</code>
+     */
+    public org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchemaOrBuilder getSchemaOrBuilder() {
+      return schema_;
+    }
+
     private void initFields() {
       returnCode_ = org.apache.phoenix.coprocessor.generated.MetaDataProtos.MutationCode.TABLE_ALREADY_EXISTS;
       mutationTime_ = 0L;
@@ -1977,6 +2080,7 @@ public final class MetaDataProtos {
       functionName_ = com.google.protobuf.ByteString.EMPTY;
       function_ = java.util.Collections.emptyList();
       sharedTablesToDelete_ = java.util.Collections.emptyList();
+      schema_ = org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.getDefaultInstance();
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -2001,6 +2105,12 @@ public final class MetaDataProtos {
           return false;
         }
       }
+      if (hasSchema()) {
+        if (!getSchema().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -2035,6 +2145,9 @@ public final class MetaDataProtos {
       for (int i = 0; i < sharedTablesToDelete_.size(); i++) {
         output.writeMessage(9, sharedTablesToDelete_.get(i));
       }
+      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        output.writeMessage(10, schema_);
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -2085,6 +2198,10 @@ public final class MetaDataProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(9, sharedTablesToDelete_.get(i));
       }
+      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(10, schema_);
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -2144,6 +2261,11 @@ public final class MetaDataProtos {
           .equals(other.getFunctionList());
       result = result && getSharedTablesToDeleteList()
           .equals(other.getSharedTablesToDeleteList());
+      result = result && (hasSchema() == other.hasSchema());
+      if (hasSchema()) {
+        result = result && getSchema()
+            .equals(other.getSchema());
+      }
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -2193,6 +2315,10 @@ public final class MetaDataProtos {
         hash = (37 * hash) + SHAREDTABLESTODELETE_FIELD_NUMBER;
         hash = (53 * hash) + getSharedTablesToDeleteList().hashCode();
       }
+      if (hasSchema()) {
+        hash = (37 * hash) + SCHEMA_FIELD_NUMBER;
+        hash = (53 * hash) + getSchema().hashCode();
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -2297,6 +2423,7 @@ public final class MetaDataProtos {
           getTableFieldBuilder();
           getFunctionFieldBuilder();
           getSharedTablesToDeleteFieldBuilder();
+          getSchemaFieldBuilder();
         }
       }
       private static Builder create() {
@@ -2335,6 +2462,12 @@ public final class MetaDataProtos {
         } else {
           sharedTablesToDeleteBuilder_.clear();
         }
+        if (schemaBuilder_ == null) {
+          schema_ = org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.getDefaultInstance();
+        } else {
+          schemaBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000200);
         return this;
       }
 
@@ -2414,6 +2547,14 @@ public final class MetaDataProtos {
         } else {
           result.sharedTablesToDelete_ = sharedTablesToDeleteBuilder_.build();
         }
+        if (((from_bitField0_ & 0x00000200) == 0x00000200)) {
+          to_bitField0_ |= 0x00000040;
+        }
+        if (schemaBuilder_ == null) {
+          result.schema_ = schema_;
+        } else {
+          result.schema_ = schemaBuilder_.build();
+        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -2510,6 +2651,9 @@ public final class MetaDataProtos {
             }
           }
         }
+        if (other.hasSchema()) {
+          mergeSchema(other.getSchema());
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -2533,6 +2677,12 @@ public final class MetaDataProtos {
             return false;
           }
         }
+        if (hasSchema()) {
+          if (!getSchema().isInitialized()) {
+            
+            return false;
+          }
+        }
         return true;
       }
 
@@ -3401,6 +3551,123 @@ public final class MetaDataProtos {
         return sharedTablesToDeleteBuilder_;
       }
 
+      // optional .PSchema schema = 10;
+      private org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema schema_ = org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema, org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.Builder, org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchemaOrBuilder> schemaBuilder_;
+      /**
+       * <code>optional .PSchema schema = 10;</code>
+       */
+      public boolean hasSchema() {
+        return ((bitField0_ & 0x00000200) == 0x00000200);
+      }
+      /**
+       * <code>optional .PSchema schema = 10;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema getSchema() {
+        if (schemaBuilder_ == null) {
+          return schema_;
+        } else {
+          return schemaBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .PSchema schema = 10;</code>
+       */
+      public Builder setSchema(org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema value) {
+        if (schemaBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          schema_ = value;
+          onChanged();
+        } else {
+          schemaBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000200;
+        return this;
+      }
+      /**
+       * <code>optional .PSchema schema = 10;</code>
+       */
+      public Builder setSchema(
+          org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.Builder builderForValue) {
+        if (schemaBuilder_ == null) {
+          schema_ = builderForValue.build();
+          onChanged();
+        } else {
+          schemaBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000200;
+        return this;
+      }
+      /**
+       * <code>optional .PSchema schema = 10;</code>
+       */
+      public Builder mergeSchema(org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema value) {
+        if (schemaBuilder_ == null) {
+          if (((bitField0_ & 0x00000200) == 0x00000200) &&
+              schema_ != org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.getDefaultInstance()) {
+            schema_ =
+              org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.newBuilder(schema_).mergeFrom(value).buildPartial();
+          } else {
+            schema_ = value;
+          }
+          onChanged();
+        } else {
+          schemaBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000200;
+        return this;
+      }
+      /**
+       * <code>optional .PSchema schema = 10;</code>
+       */
+      public Builder clearSchema() {
+        if (schemaBuilder_ == null) {
+          schema_ = org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.getDefaultInstance();
+          onChanged();
+        } else {
+          schemaBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000200);
+        return this;
+      }
+      /**
+       * <code>optional .PSchema schema = 10;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.Builder getSchemaBuilder() {
+        bitField0_ |= 0x00000200;
+        onChanged();
+        return getSchemaFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .PSchema schema = 10;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchemaOrBuilder getSchemaOrBuilder() {
+        if (schemaBuilder_ != null) {
+          return schemaBuilder_.getMessageOrBuilder();
+        } else {
+          return schema_;
+        }
+      }
+      /**
+       * <code>optional .PSchema schema = 10;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema, org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.Builder, org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchemaOrBuilder> 
+          getSchemaFieldBuilder() {
+        if (schemaBuilder_ == null) {
+          schemaBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema, org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchema.Builder, org.apache.phoenix.coprocessor.generated.PSchemaProtos.PSchemaOrBuilder>(
+                  schema_,
+                  getParentForChildren(),
+                  isClean());
+          schema_ = null;
+        }
+        return schemaBuilder_;
+      }
+
       // @@protoc_insertion_point(builder_scope:MetaDataResponse)
     }
 
@@ -5297,56 +5564,63 @@ public final class MetaDataProtos {
     // @@protoc_insertion_point(class_scope:GetFunctionsRequest)
   }
 
-  public interface CreateTableRequestOrBuilder
+  public interface GetSchemaRequestOrBuilder
       extends com.google.protobuf.MessageOrBuilder {
 
-    // repeated bytes tableMetadataMutations = 1;
+    // required string schemaName = 1;
     /**
-     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     * <code>required string schemaName = 1;</code>
      */
-    java.util.List<com.google.protobuf.ByteString> getTableMetadataMutationsList();
+    boolean hasSchemaName();
     /**
-     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     * <code>required string schemaName = 1;</code>
      */
-    int getTableMetadataMutationsCount();
+    java.lang.String getSchemaName();
     /**
-     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     * <code>required string schemaName = 1;</code>
      */
-    com.google.protobuf.ByteString getTableMetadataMutations(int index);
+    com.google.protobuf.ByteString
+        getSchemaNameBytes();
 
-    // optional int32 clientVersion = 2;
+    // required int64 clientTimestamp = 2;
     /**
-     * <code>optional int32 clientVersion = 2;</code>
+     * <code>required int64 clientTimestamp = 2;</code>
+     */
+    boolean hasClientTimestamp();
+    /**
+     * <code>required int64 clientTimestamp = 2;</code>
+     */
+    long getClientTimestamp();
+
+    // required int32 clientVersion = 3;
+    /**
+     * <code>required int32 clientVersion = 3;</code>
      */
     boolean hasClientVersion();
     /**
-     * <code>optional int32 clientVersion = 2;</code>
+     * <code>required int32 clientVersion = 3;</code>
      */
     int getClientVersion();
   }
   /**
-   * Protobuf type {@code CreateTableRequest}
-   *
-   * <pre>
-   * each byte array represents a MutationProto instance
-   * </pre>
+   * Protobuf type {@code GetSchemaRequest}
    */
-  public static final class CreateTableRequest extends
+  public static final class GetSchemaRequest extends
       com.google.protobuf.GeneratedMessage
-      implements CreateTableRequestOrBuilder {
-    // Use CreateTableRequest.newBuilder() to construct.
-    private CreateTableRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      implements GetSchemaRequestOrBuilder {
+    // Use GetSchemaRequest.newBuilder() to construct.
+    private GetSchemaRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
       super(builder);
       this.unknownFields = builder.getUnknownFields();
     }
-    private CreateTableRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+    private GetSchemaRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
 
-    private static final CreateTableRequest defaultInstance;
-    public static CreateTableRequest getDefaultInstance() {
+    private static final GetSchemaRequest defaultInstance;
+    public static GetSchemaRequest getDefaultInstance() {
       return defaultInstance;
     }
 
-    public CreateTableRequest getDefaultInstanceForType() {
+    public GetSchemaRequest getDefaultInstanceForType() {
       return defaultInstance;
     }
 
@@ -5356,7 +5630,7 @@ public final class MetaDataProtos {
         getUnknownFields() {
       return this.unknownFields;
     }
-    private CreateTableRequest(
+    private GetSchemaRequest(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -5380,15 +5654,17 @@ public final class MetaDataProtos {
               break;
             }
             case 10: {
-              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-                tableMetadataMutations_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
-                mutable_bitField0_ |= 0x00000001;
-              }
-              tableMetadataMutations_.add(input.readBytes());
+              bitField0_ |= 0x00000001;
+              schemaName_ = input.readBytes();
               break;
             }
             case 16: {
-              bitField0_ |= 0x00000001;
+              bitField0_ |= 0x00000002;
+              clientTimestamp_ = input.readInt64();
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000004;
               clientVersion_ = input.readInt32();
               break;
             }
@@ -5400,82 +5676,116 @@ public final class MetaDataProtos {
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e.getMessage()).setUnfinishedMessage(this);
       } finally {
-        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
-          tableMetadataMutations_ = java.util.Collections.unmodifiableList(tableMetadataMutations_);
-        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateTableRequest_descriptor;
+      return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_GetSchemaRequest_descriptor;
     }
 
     protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateTableRequest_fieldAccessorTable
+      return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_GetSchemaRequest_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest.class, org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest.Builder.class);
+              org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest.class, org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<CreateTableRequest> PARSER =
-        new com.google.protobuf.AbstractParser<CreateTableRequest>() {
-      public CreateTableRequest parsePartialFrom(
+    public static com.google.protobuf.Parser<GetSchemaRequest> PARSER =
+        new com.google.protobuf.AbstractParser<GetSchemaRequest>() {
+      public GetSchemaRequest parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new CreateTableRequest(input, extensionRegistry);
+        return new GetSchemaRequest(input, extensionRegistry);
       }
     };
 
     @java.lang.Override
-    public com.google.protobuf.Parser<CreateTableRequest> getParserForType() {
+    public com.google.protobuf.Parser<GetSchemaRequest> getParserForType() {
       return PARSER;
     }
 
     private int bitField0_;
-    // repeated bytes tableMetadataMutations = 1;
-    public static final int TABLEMETADATAMUTATIONS_FIELD_NUMBER = 1;
-    private java.util.List<com.google.protobuf.ByteString> tableMetadataMutations_;
+    // required string schemaName = 1;
+    public static final int SCHEMANAME_FIELD_NUMBER = 1;
+    private java.lang.Object schemaName_;
     /**
-     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     * <code>required string schemaName = 1;</code>
      */
-    public java.util.List<com.google.protobuf.ByteString>
-        getTableMetadataMutationsList() {
-      return tableMetadataMutations_;
+    public boolean hasSchemaName() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
     }
     /**
-     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     * <code>required string schemaName = 1;</code>
      */
-    public int getTableMetadataMutationsCount() {
-      return tableMetadataMutations_.size();
+    public java.lang.String getSchemaName() {
+      java.lang.Object ref = schemaName_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          schemaName_ = s;
+        }
+        return s;
+      }
     }
     /**
-     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     * <code>required string schemaName = 1;</code>
      */
-    public com.google.protobuf.ByteString getTableMetadataMutations(int index) {
-      return tableMetadataMutations_.get(index);
+    public com.google.protobuf.ByteString
+        getSchemaNameBytes() {
+      java.lang.Object ref = schemaName_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        schemaName_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
     }
 
-    // optional int32 clientVersion = 2;
-    public static final int CLIENTVERSION_FIELD_NUMBER = 2;
+    // required int64 clientTimestamp = 2;
+    public static final int CLIENTTIMESTAMP_FIELD_NUMBER = 2;
+    private long clientTimestamp_;
+    /**
+     * <code>required int64 clientTimestamp = 2;</code>
+     */
+    public boolean hasClientTimestamp() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required int64 clientTimestamp = 2;</code>
+     */
+    public long getClientTimestamp() {
+      return clientTimestamp_;
+    }
+
+    // required int32 clientVersion = 3;
+    public static final int CLIENTVERSION_FIELD_NUMBER = 3;
     private int clientVersion_;
     /**
-     * <code>optional int32 clientVersion = 2;</code>
+     * <code>required int32 clientVersion = 3;</code>
      */
     public boolean hasClientVersion() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return ((bitField0_ & 0x00000004) == 0x00000004);
     }
     /**
-     * <code>optional int32 clientVersion = 2;</code>
+     * <code>required int32 clientVersion = 3;</code>
      */
     public int getClientVersion() {
       return clientVersion_;
     }
 
     private void initFields() {
-      tableMetadataMutations_ = java.util.Collections.emptyList();
+      schemaName_ = "";
+      clientTimestamp_ = 0L;
       clientVersion_ = 0;
     }
     private byte memoizedIsInitialized = -1;
@@ -5483,6 +5793,18 @@ public final class MetaDataProtos {
       byte isInitialized = memoizedIsInitialized;
       if (isInitialized != -1) return isInitialized == 1;
 
+      if (!hasSchemaName()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasClientTimestamp()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasClientVersion()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -5490,15 +5812,2128 @@ public final class MetaDataProtos {
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
       getSerializedSize();
-      for (int i = 0; i < tableMetadataMutations_.size(); i++) {
-        output.writeBytes(1, tableMetadataMutations_.get(i));
-      }
       if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        output.writeInt32(2, clientVersion_);
+        output.writeBytes(1, getSchemaNameBytes());
       }
-      getUnknownFields().writeTo(output);
-    }
-
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeInt64(2, clientTimestamp_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeInt32(3, clientVersion_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getSchemaNameBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(2, clientTimestamp_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(3, clientVersion_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest)) {
+        return super.equals(obj);
+      }
+      org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest other = (org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest) obj;
+
+      boolean result = true;
+      result = result && (hasSchemaName() == other.hasSchemaName());
+      if (hasSchemaName()) {
+        result = result && getSchemaName()
+            .equals(other.getSchemaName());
+      }
+      result = result && (hasClientTimestamp() == other.hasClientTimestamp());
+      if (hasClientTimestamp()) {
+        result = result && (getClientTimestamp()
+            == other.getClientTimestamp());
+      }
+      result = result && (hasClientVersion() == other.hasClientVersion());
+      if (hasClientVersion()) {
+        result = result && (getClientVersion()
+            == other.getClientVersion());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasSchemaName()) {
+        hash = (37 * hash) + SCHEMANAME_FIELD_NUMBER;
+        hash = (53 * hash) + getSchemaName().hashCode();
+      }
+      if (hasClientTimestamp()) {
+        hash = (37 * hash) + CLIENTTIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + hashLong(getClientTimestamp());
+      }
+      if (hasClientVersion()) {
+        hash = (37 * hash) + CLIENTVERSION_FIELD_NUMBER;
+        hash = (53 * hash) + getClientVersion();
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code GetSchemaRequest}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequestOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_GetSchemaRequest_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_GetSchemaRequest_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest.class, org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest.Builder.class);
+      }
+
+      // Construct using org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        schemaName_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        clientTimestamp_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        clientVersion_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_GetSchemaRequest_descriptor;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest getDefaultInstanceForType() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest.getDefaultInstance();
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest build() {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest buildPartial() {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest result = new org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.schemaName_ = schemaName_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.clientTimestamp_ = clientTimestamp_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.clientVersion_ = clientVersion_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest) {
+          return mergeFrom((org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest other) {
+        if (other == org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest.getDefaultInstance()) return this;
+        if (other.hasSchemaName()) {
+          bitField0_ |= 0x00000001;
+          schemaName_ = other.schemaName_;
+          onChanged();
+        }
+        if (other.hasClientTimestamp()) {
+          setClientTimestamp(other.getClientTimestamp());
+        }
+        if (other.hasClientVersion()) {
+          setClientVersion(other.getClientVersion());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasSchemaName()) {
+          
+          return false;
+        }
+        if (!hasClientTimestamp()) {
+          
+          return false;
+        }
+        if (!hasClientVersion()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string schemaName = 1;
+      private java.lang.Object schemaName_ = "";
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public boolean hasSchemaName() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public java.lang.String getSchemaName() {
+        java.lang.Object ref = schemaName_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          schemaName_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getSchemaNameBytes() {
+        java.lang.Object ref = schemaName_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          schemaName_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public Builder setSchemaName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        schemaName_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public Builder clearSchemaName() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        schemaName_ = getDefaultInstance().getSchemaName();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string schemaName = 1;</code>
+       */
+      public Builder setSchemaNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        schemaName_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required int64 clientTimestamp = 2;
+      private long clientTimestamp_ ;
+      /**
+       * <code>required int64 clientTimestamp = 2;</code>
+       */
+      public boolean hasClientTimestamp() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required int64 clientTimestamp = 2;</code>
+       */
+      public long getClientTimestamp() {
+        return clientTimestamp_;
+      }
+      /**
+       * <code>required int64 clientTimestamp = 2;</code>
+       */
+      public Builder setClientTimestamp(long value) {
+        bitField0_ |= 0x00000002;
+        clientTimestamp_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int64 clientTimestamp = 2;</code>
+       */
+      public Builder clearClientTimestamp() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        clientTimestamp_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // required int32 clientVersion = 3;
+      private int clientVersion_ ;
+      /**
+       * <code>required int32 clientVersion = 3;</code>
+       */
+      public boolean hasClientVersion() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required int32 clientVersion = 3;</code>
+       */
+      public int getClientVersion() {
+        return clientVersion_;
+      }
+      /**
+       * <code>required int32 clientVersion = 3;</code>
+       */
+      public Builder setClientVersion(int value) {
+        bitField0_ |= 0x00000004;
+        clientVersion_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 clientVersion = 3;</code>
+       */
+      public Builder clearClientVersion() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        clientVersion_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:GetSchemaRequest)
+    }
+
+    static {
+      defaultInstance = new GetSchemaRequest(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:GetSchemaRequest)
+  }
+
+  public interface CreateTableRequestOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated bytes tableMetadataMutations = 1;
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    java.util.List<com.google.protobuf.ByteString> getTableMetadataMutationsList();
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    int getTableMetadataMutationsCount();
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    com.google.protobuf.ByteString getTableMetadataMutations(int index);
+
+    // optional int32 clientVersion = 2;
+    /**
+     * <code>optional int32 clientVersion = 2;</code>
+     */
+    boolean hasClientVersion();
+    /**
+     * <code>optional int32 clientVersion = 2;</code>
+     */
+    int getClientVersion();
+  }
+  /**
+   * Protobuf type {@code CreateTableRequest}
+   *
+   * <pre>
+   * each byte array represents a MutationProto instance
+   * </pre>
+   */
+  public static final class CreateTableRequest extends
+      com.google.protobuf.GeneratedMessage
+      implements CreateTableRequestOrBuilder {
+    // Use CreateTableRequest.newBuilder() to construct.
+    private CreateTableRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CreateTableRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CreateTableRequest defaultInstance;
+    public static CreateTableRequest getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CreateTableRequest getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CreateTableRequest(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                tableMetadataMutations_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              tableMetadataMutations_.add(input.readBytes());
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000001;
+              clientVersion_ = input.readInt32();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          tableMetadataMutations_ = java.util.Collections.unmodifiableList(tableMetadataMutations_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateTableRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateTableRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest.class, org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CreateTableRequest> PARSER =
+        new com.google.protobuf.AbstractParser<CreateTableRequest>() {
+      public CreateTableRequest parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CreateTableRequest(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CreateTableRequest> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // repeated bytes tableMetadataMutations = 1;
+    public static final int TABLEMETADATAMUTATIONS_FIELD_NUMBER = 1;
+    private java.util.List<com.google.protobuf.ByteString> tableMetadataMutations_;
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    public java.util.List<com.google.protobuf.ByteString>
+        getTableMetadataMutationsList() {
+      return tableMetadataMutations_;
+    }
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    public int getTableMetadataMutationsCount() {
+      return tableMetadataMutations_.size();
+    }
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    public com.google.protobuf.ByteString getTableMetadataMutations(int index) {
+      return tableMetadataMutations_.get(index);
+    }
+
+    // optional int32 clientVersion = 2;
+    public static final int CLIENTVERSION_FIELD_NUMBER = 2;
+    private int clientVersion_;
+    /**
+     * <code>optional int32 clientVersion = 2;</code>
+     */
+    public boolean hasClientVersion() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional int32 clientVersion = 2;</code>
+     */
+    public int getClientVersion() {
+      return clientVersion_;
+    }
+
+    private void initFields() {
+      tableMetadataMutations_ = java.util.Collections.emptyList();
+      clientVersion_ = 0;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < tableMetadataMutations_.size(); i++) {
+        output.writeBytes(1, tableMetadataMutations_.get(i));
+      }
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt32(2, clientVersion_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      {
+        int dataSize = 0;
+        for (int i = 0; i < tableMetadataMutations_.size(); i++) {
+          dataSize += com.google.protobuf.CodedOutputStream
+            .computeBytesSizeNoTag(tableMetadataMutations_.get(i));
+        }
+        size += dataSize;
+        size += 1 * getTableMetadataMutationsList().size();
+      }
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(2, clientVersion_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest)) {
+        return super.equals(obj);
+      }
+      org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest other = (org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest) obj;
+
+      boolean result = true;
+      result = result && getTableMetadataMutationsList()
+          .equals(other.getTableMetadataMutationsList());
+      result = result && (hasClientVersion() == other.hasClientVersion());
+      if (hasClientVersion()) {
+        result = result && (getClientVersion()
+            == other.getClientVersion());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (getTableMetadataMutationsCount() > 0) {
+        hash = (37 * hash) + TABLEMETADATAMUTATIONS_FIELD_NUMBER;
+        hash = (53 * hash) + getTableMetadataMutationsList().hashCode();
+      }
+      if (hasClientVersion()) {
+        hash = (37 * hash) + CLIENTVERSION_FIELD_NUMBER;
+        hash = (53 * hash) + getClientVersion();
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code CreateTableRequest}
+     *
+     * <pre>
+     * each byte array represents a MutationProto instance
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequestOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateTableRequest_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateTableRequest_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest.class, org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest.Builder.class);
+      }
+
+      // Construct using org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        tableMetadataMutations_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        clientVersion_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateTableRequest_descriptor;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest getDefaultInstanceForType() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest.getDefaultInstance();
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest build() {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest buildPartial() {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest result = new org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          tableMetadataMutations_ = java.util.Collections.unmodifiableList(tableMetadataMutations_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.tableMetadataMutations_ = tableMetadataMutations_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.clientVersion_ = clientVersion_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest) {
+          return mergeFrom((org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest other) {
+        if (other == org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest.getDefaultInstance()) return this;
+        if (!other.tableMetadataMutations_.isEmpty()) {
+          if (tableMetadataMutations_.isEmpty()) {
+            tableMetadataMutations_ = other.tableMetadataMutations_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureTableMetadataMutationsIsMutable();
+            tableMetadataMutations_.addAll(other.tableMetadataMutations_);
+          }
+          onChanged();
+        }
+        if (other.hasClientVersion()) {
+          setClientVersion(other.getClientVersion());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated bytes tableMetadataMutations = 1;
+      private java.util.List<com.google.protobuf.ByteString> tableMetadataMutations_ = java.util.Collections.emptyList();
+      private void ensureTableMetadataMutationsIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          tableMetadataMutations_ = new java.util.ArrayList<com.google.protobuf.ByteString>(tableMetadataMutations_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+      /**
+       * <code>repeated bytes tableMetadataMutations = 1;</code>
+       */
+      public java.util.List<com.google.protobuf.ByteString>
+          getTableMetadataMutationsList() {
+        return java.util.Collections.unmodifiableList(tableMetadataMutations_);
+      }
+      /**
+       * <code>repeated bytes tableMetadataMutations = 1;</code>
+       */
+      public int getTableMetadataMutationsCount() {
+        return tableMetadataMutations_.size();
+      }
+      /**
+       * <code>repeated bytes tableMetadataMutations = 1;</code>
+       */
+      public com.google.protobuf.ByteString getTableMetadataMutations(int index) {
+        return tableMetadataMutations_.get(index);
+      }
+      /**
+       * <code>repeated bytes tableMetadataMutations = 1;</code>
+       */
+      public Builder setTableMetadataMutations(
+          int index, com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureTableMetadataMutationsIsMutable();
+        tableMetadataMutations_.set(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bytes tableMetadataMutations = 1;</code>
+       */
+      public Builder addTableMetadataMutations(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureTableMetadataMutationsIsMutable();
+        tableMetadataMutations_.add(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bytes tableMetadataMutations = 1;</code>
+       */
+      public Builder addAllTableMetadataMutations(
+          java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
+        ensureTableMetadataMutationsIsMutable();
+        super.addAll(values, tableMetadataMutations_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bytes tableMetadataMutations = 1;</code>
+       */
+      public Builder clearTableMetadataMutations() {
+        tableMetadataMutations_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+        return this;
+      }
+
+      // optional int32 clientVersion = 2;
+      private int clientVersion_ ;
+      /**
+       * <code>optional int32 clientVersion = 2;</code>
+       */
+      public boolean hasClientVersion() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional int32 clientVersion = 2;</code>
+       */
+      public int getClientVersion() {
+        return clientVersion_;
+      }
+      /**
+       * <code>optional int32 clientVersion = 2;</code>
+       */
+      public Builder setClientVersion(int value) {
+        bitField0_ |= 0x00000002;
+        clientVersion_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int32 clientVersion = 2;</code>
+       */
+      public Builder clearClientVersion() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        clientVersion_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:CreateTableRequest)
+    }
+
+    static {
+      defaultInstance = new CreateTableRequest(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:CreateTableRequest)
+  }
+
+  public interface CreateFunctionRequestOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated bytes tableMetadataMutations = 1;
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    java.util.List<com.google.protobuf.ByteString> getTableMetadataMutationsList();
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    int getTableMetadataMutationsCount();
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    com.google.protobuf.ByteString getTableMetadataMutations(int index);
+
+    // required bool temporary = 2;
+    /**
+     * <code>required bool temporary = 2;</code>
+     */
+    boolean hasTemporary();
+    /**
+     * <code>required bool temporary = 2;</code>
+     */
+    boolean getTemporary();
+
+    // optional bool replace = 3;
+    /**
+     * <code>optional bool replace = 3;</code>
+     */
+    boolean hasReplace();
+    /**
+     * <code>optional bool replace = 3;</code>
+     */
+    boolean getReplace();
+
+    // optional int32 clientVersion = 4;
+    /**
+     * <code>optional int32 clientVersion = 4;</code>
+     */
+    boolean hasClientVersion();
+    /**
+     * <code>optional int32 clientVersion = 4;</code>
+     */
+    int getClientVersion();
+  }
+  /**
+   * Protobuf type {@code CreateFunctionRequest}
+   *
+   * <pre>
+   * each byte array represents a MutationProto instance
+   * </pre>
+   */
+  public static final class CreateFunctionRequest extends
+      com.google.protobuf.GeneratedMessage
+      implements CreateFunctionRequestOrBuilder {
+    // Use CreateFunctionRequest.newBuilder() to construct.
+    private CreateFunctionRequest(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private CreateFunctionRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final CreateFunctionRequest defaultInstance;
+    public static CreateFunctionRequest getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public CreateFunctionRequest getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private CreateFunctionRequest(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                tableMetadataMutations_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              tableMetadataMutations_.add(input.readBytes());
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000001;
+              temporary_ = input.readBool();
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000002;
+              replace_ = input.readBool();
+              break;
+            }
+            case 32: {
+              bitField0_ |= 0x00000004;
+              clientVersion_ = input.readInt32();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          tableMetadataMutations_ = java.util.Collections.unmodifiableList(tableMetadataMutations_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateFunctionRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateFunctionRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest.class, org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<CreateFunctionRequest> PARSER =
+        new com.google.protobuf.AbstractParser<CreateFunctionRequest>() {
+      public CreateFunctionRequest parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new CreateFunctionRequest(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<CreateFunctionRequest> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // repeated bytes tableMetadataMutations = 1;
+    public static final int TABLEMETADATAMUTATIONS_FIELD_NUMBER = 1;
+    private java.util.List<com.google.protobuf.ByteString> tableMetadataMutations_;
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    public java.util.List<com.google.protobuf.ByteString>
+        getTableMetadataMutationsList() {
+      return tableMetadataMutations_;
+    }
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    public int getTableMetadataMutationsCount() {
+      return tableMetadataMutations_.size();
+    }
+    /**
+     * <code>repeated bytes tableMetadataMutations = 1;</code>
+     */
+    public com.google.protobuf.ByteString getTableMetadataMutations(int index) {
+      return tableMetadataMutations_.get(index);
+    }
+
+    // required bool temporary = 2;
+    public static final int TEMPORARY_FIELD_NUMBER = 2;
+    private boolean temporary_;
+    /**
+     * <code>required bool temporary = 2;</code>
+     */
+    public boolean hasTemporary() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required bool temporary = 2;</code>
+     */
+    public boolean getTemporary() {
+      return temporary_;
+    }
+
+    // optional bool replace = 3;
+    public static final int REPLACE_FIELD_NUMBER = 3;
+    private boolean replace_;
+    /**
+     * <code>optional bool replace = 3;</code>
+     */
+    public boolean hasReplace() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional bool replace = 3;</code>
+     */
+    public boolean getReplace() {
+      return replace_;
+    }
+
+    // optional int32 clientVersion = 4;
+    public static final int CLIENTVERSION_FIELD_NUMBER = 4;
+    private int clientVersion_;
+    /**
+     * <code>optional int32 clientVersion = 4;</code>
+     */
+    public boolean hasClientVersion() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional int32 clientVersion = 4;</code>
+     */
+    public int getClientVersion() {
+      return clientVersion_;
+    }
+
+    private void initFields() {
+      tableMetadataMutations_ = java.util.Collections.emptyList();
+      temporary_ = false;
+      replace_ = false;
+      clientVersion_ = 0;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasTemporary()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < tableMetadataMutations_.size(); i++) {
+        output.writeBytes(1, tableMetadataMutations_.get(i));
+      }
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBool(2, temporary_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBool(3, replace_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeInt32(4, clientVersion_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      {
+        int dataSize = 0;
+        for (int i = 0; i < tableMetadataMutations_.size(); i++) {
+          dataSize += com.google.protobuf.CodedOutputStream
+            .computeBytesSizeNoTag(tableMetadataMutations_.get(i));
+        }
+        size += dataSize;
+        size += 1 * getTableMetadataMutationsList().size();
+      }
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(2, temporary_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(3, replace_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(4, clientVersion_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest)) {
+        return super.equals(obj);
+      }
+      org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest other = (org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest) obj;
+
+      boolean result = true;
+      result = result && getTableMetadataMutationsList()
+          .equals(other.getTableMetadataMutationsList());
+      result = result && (hasTemporary() == other.hasTemporary());
+      if (hasTemporary()) {
+        result = result && (getTemporary()
+            == other.getTemporary());
+      }
+      result = result && (hasReplace() == other.hasReplace());
+      if (hasReplace()) {
+        result = result && (getReplace()
+            == other.getReplace());
+      }
+      result = result && (hasClientVersion() == other.hasClientVersion());
+      if (hasClientVersion()) {
+        result = result && (getClientVersion()
+            == other.getClientVersion());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (getTableMetadataMutationsCount() > 0) {
+        hash = (37 * hash) + TABLEMETADATAMUTATIONS_FIELD_NUMBER;
+        hash = (53 * hash) + getTableMetadataMutationsList().hashCode();
+      }
+      if (hasTemporary()) {
+        hash = (37 * hash) + TEMPORARY_FIELD_NUMBER;
+        hash = (53 * hash) + hashBoolean(getTemporary());
+      }
+      if (hasReplace()) {
+        hash = (37 * hash) + REPLACE_FIELD_NUMBER;
+        hash = (53 * hash) + hashBoolean(getReplace());
+      }
+      if (hasClientVersion()) {
+        hash = (37 * hash) + CLIENTVERSION_FIELD_NUMBER;
+        hash = (53 * hash) + getClientVersion();
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code CreateFunctionRequest}
+     *
+     * <pre>
+     * each byte array represents a MutationProto instance
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequestOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateFunctionRequest_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateFunctionRequest_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest.class, org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest.Builder.class);
+      }
+
+      // Construct using org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        tableMetadataMutations_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        temporary_ = false;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        replace_ = false;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        clientVersion_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.internal_static_CreateFunctionRequest_descriptor;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest getDefaultInstanceForType() {
+        return org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest.getDefaultInstance();
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest build() {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest buildPartial() {
+        org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest result = new org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          tableMetadataMutations_ = java.util.Collections.unmodifiableList(tableMetadataMutations_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.tableMetadataMutations_ = tableMetadataMutations_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.temporary_ = temporary_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.replace_ = replace_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.clientVersion_ = clientVersion_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest) {
+          return mergeFrom((org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest other) {
+        if (other == org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest.getDefaultInstance()) return this;
+        if (!other.tableMetadataMutations_.isEmpty()) {
+          if (tableMetadataMutations_.isEmpty()) {
+            tableMetadataMutations_ = other.tableMetadataMutations_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+  

<TRUNCATED>

[03/52] [abbrv] phoenix git commit: PHOENIX-2722 support mysql offset clause

Posted by sa...@apache.org.
PHOENIX-2722 support mysql offset clause


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

Branch: refs/heads/encodecolumns
Commit: f65d0481d00e2fa70b03d97345377cb26d7fcb22
Parents: 4c588f4
Author: Ankit Singhal <an...@gmail.com>
Authored: Fri Apr 8 16:06:50 2016 +0530
Committer: Ankit Singhal <an...@gmail.com>
Committed: Fri Apr 8 16:06:50 2016 +0530

----------------------------------------------------------------------
 .../apache/phoenix/end2end/AutoCommitIT.java    |  14 +-
 .../apache/phoenix/end2end/CreateTableIT.java   |   2 +-
 .../apache/phoenix/end2end/DerivedTableIT.java  | 144 ++++++++++++-
 .../org/apache/phoenix/end2end/HashJoinIT.java  | 161 ++++++++++++++
 .../phoenix/end2end/QueryWithOffsetIT.java      | 211 +++++++++++++++++++
 .../org/apache/phoenix/end2end/ReadOnlyIT.java  |  12 +-
 .../apache/phoenix/end2end/SortMergeJoinIT.java |  44 ++++
 phoenix-core/src/main/antlr3/PhoenixSQL.g       |  16 +-
 .../apache/phoenix/compile/DeleteCompiler.java  |  13 +-
 .../apache/phoenix/compile/JoinCompiler.java    |  10 +-
 .../phoenix/compile/ListJarsQueryPlan.java      |   5 +
 .../apache/phoenix/compile/OffsetCompiler.java  | 114 ++++++++++
 .../apache/phoenix/compile/OrderByCompiler.java |   3 +-
 .../apache/phoenix/compile/PostDDLCompiler.java |   3 +-
 .../apache/phoenix/compile/QueryCompiler.java   |  52 +++--
 .../org/apache/phoenix/compile/QueryPlan.java   |   2 +
 .../phoenix/compile/StatementNormalizer.java    |   2 +-
 .../phoenix/compile/SubqueryRewriter.java       |  10 +-
 .../phoenix/compile/SubselectRewriter.java      |  15 +-
 .../apache/phoenix/compile/TraceQueryPlan.java  |   5 +
 .../apache/phoenix/compile/UpsertCompiler.java  |   2 +-
 .../coprocessor/BaseScannerRegionObserver.java  |   1 +
 .../phoenix/coprocessor/ScanRegionObserver.java |  95 ++++++++-
 .../apache/phoenix/execute/AggregatePlan.java   |  43 ++--
 .../apache/phoenix/execute/BaseQueryPlan.java   |   9 +-
 .../phoenix/execute/ClientAggregatePlan.java    |  19 +-
 .../phoenix/execute/ClientProcessingPlan.java   |  10 +-
 .../apache/phoenix/execute/ClientScanPlan.java  |  38 ++--
 .../phoenix/execute/DegenerateQueryPlan.java    |   2 +-
 .../phoenix/execute/DelegateQueryPlan.java      |   4 +
 .../execute/LiteralResultIterationPlan.java     |  13 +-
 .../org/apache/phoenix/execute/ScanPlan.java    |  58 +++--
 .../phoenix/execute/SortMergeJoinPlan.java      |   5 +
 .../org/apache/phoenix/execute/UnionPlan.java   |  15 +-
 .../phoenix/iterate/BaseResultIterators.java    |  14 +-
 .../apache/phoenix/iterate/ExplainTable.java    |  16 +-
 .../phoenix/iterate/LimitingResultIterator.java |   2 +-
 .../iterate/MergeSortTopNResultIterator.java    |  21 +-
 .../phoenix/iterate/OffsetResultIterator.java   |  62 ++++++
 .../OrderedAggregatingResultIterator.java       |   6 +-
 .../phoenix/iterate/OrderedResultIterator.java  |  58 +++--
 .../phoenix/iterate/ParallelIterators.java      |   4 +-
 .../apache/phoenix/iterate/SerialIterators.java |  19 +-
 .../phoenix/iterate/TableResultIterator.java    |  22 +-
 .../apache/phoenix/jdbc/PhoenixStatement.java   |  18 +-
 .../org/apache/phoenix/join/HashJoinInfo.java   |   2 +-
 .../apache/phoenix/optimize/QueryOptimizer.java |   2 +-
 .../apache/phoenix/parse/DeleteStatement.java   |   6 +
 .../phoenix/parse/FilterableStatement.java      |   1 +
 .../org/apache/phoenix/parse/OffsetNode.java    |  67 ++++++
 .../apache/phoenix/parse/ParseNodeFactory.java  |  55 +++--
 .../apache/phoenix/parse/ParseNodeRewriter.java |   2 +-
 .../apache/phoenix/parse/SelectStatement.java   |  35 ++-
 .../apache/phoenix/query/QueryConstants.java    |   6 +
 .../java/org/apache/phoenix/util/QueryUtil.java |  30 ++-
 .../java/org/apache/phoenix/util/ScanUtil.java  |   4 +
 .../phoenix/execute/CorrelatePlanTest.java      |  39 +++-
 .../execute/LiteralResultIteratorPlanTest.java  | 192 +++++++++++++++++
 .../phoenix/execute/UnnestArrayPlanTest.java    |   3 +-
 .../query/ParallelIteratorsSplitTest.java       |   5 +
 60 files changed, 1621 insertions(+), 222 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoCommitIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoCommitIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoCommitIT.java
index aa92c5e..469f2de 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoCommitIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AutoCommitIT.java
@@ -42,21 +42,21 @@ public class AutoCommitIT extends BaseHBaseManagedTimeIT {
         conn.setAutoCommit(true);
         
         String ddl = "CREATE TABLE test_table " +
-                "  (row varchar not null, col1 integer" +
-                "  CONSTRAINT pk PRIMARY KEY (row))\n";
+                "  (r varchar not null, col1 integer" +
+                "  CONSTRAINT pk PRIMARY KEY (r))\n";
         createTestTable(getUrl(), ddl);
         
-        String query = "UPSERT INTO test_table(row, col1) VALUES('row1', 1)";
+        String query = "UPSERT INTO test_table(r, col1) VALUES('row1', 1)";
         PreparedStatement statement = conn.prepareStatement(query);
         statement.executeUpdate();
         conn.commit();
         
         conn.setAutoCommit(false);
-        query = "UPSERT INTO test_table(row, col1) VALUES('row1', 2)";
+        query = "UPSERT INTO test_table(r, col1) VALUES('row1', 2)";
         statement = conn.prepareStatement(query);
         statement.executeUpdate();
         
-        query = "DELETE FROM test_table WHERE row='row1'";
+        query = "DELETE FROM test_table WHERE r='row1'";
         statement = conn.prepareStatement(query);
         statement.executeUpdate();
         conn.commit();
@@ -66,11 +66,11 @@ public class AutoCommitIT extends BaseHBaseManagedTimeIT {
         ResultSet rs = statement.executeQuery();
         assertFalse(rs.next());
 
-        query = "DELETE FROM test_table WHERE row='row1'";
+        query = "DELETE FROM test_table WHERE r='row1'";
         statement = conn.prepareStatement(query);
         statement.executeUpdate();
 
-        query = "UPSERT INTO test_table(row, col1) VALUES('row1', 3)";
+        query = "UPSERT INTO test_table(r, col1) VALUES('row1', 3)";
         statement = conn.prepareStatement(query);
         statement.executeUpdate();
         conn.commit();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
index 5ffc354..b0370e8 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
@@ -74,7 +74,7 @@ public class CreateTableIT extends BaseClientManagedTimeIT {
                 "                data.file VARCHAR ,\n" + 
                 "                data.fk_log VARCHAR ,\n" + 
                 "                data.host VARCHAR ,\n" + 
-                "                data.row VARCHAR ,\n" + 
+                "                data.r VARCHAR ,\n" + 
                 "                data.size VARCHAR ,\n" + 
                 "                data.start_time VARCHAR ,\n" + 
                 "                data.stat_date DATE ,\n" + 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
index 1a772c8..9b37f9e 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DerivedTableIT.java
@@ -232,6 +232,46 @@ public class DerivedTableIT extends BaseClientManagedTimeIT {
             assertEquals(9,rs.getInt(1));
 
             assertFalse(rs.next());
+
+            // Inner limit < outer query offset
+            query = "SELECT t.eid, t.x + 9 FROM (SELECT entity_id eid, b_string b, a_byte + 1 x FROM aTable LIMIT 1 OFFSET 1 ) AS t WHERE t.b = '"
+                    + C_VALUE + "' OFFSET 2";
+            statement = conn.prepareStatement(query);
+            rs = statement.executeQuery();
+            assertFalse(rs.next());
+
+            // (where) offset
+            query = "SELECT t.eid, t.x + 9 FROM (SELECT entity_id eid, b_string b, a_byte + 1 x FROM aTable WHERE a_byte + 1 < 9 ) AS t OFFSET 2";
+            statement = conn.prepareStatement(query);
+            rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(ROW3, rs.getString(1));
+            assertEquals(13, rs.getInt(2));
+            assertTrue(rs.next());
+            assertEquals(ROW4, rs.getString(1));
+            assertEquals(14, rs.getInt(2));
+            assertTrue(rs.next());
+            assertEquals(ROW5, rs.getString(1));
+            assertEquals(15, rs.getInt(2));
+            assertTrue(rs.next());
+            assertEquals(ROW6, rs.getString(1));
+            assertEquals(16, rs.getInt(2));
+            assertTrue(rs.next());
+            assertEquals(ROW7, rs.getString(1));
+            assertEquals(17, rs.getInt(2));
+
+            // (offset) where
+            query = "SELECT t.eid, t.x + 9 FROM (SELECT entity_id eid, b_string b, a_byte + 1 x FROM aTable OFFSET 4) AS t WHERE t.b = '"
+                    + C_VALUE + "'";
+            statement = conn.prepareStatement(query);
+            rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(ROW5, rs.getString(1));
+            assertEquals(15, rs.getInt(2));
+            assertTrue(rs.next());
+            assertEquals(ROW8, rs.getString(1));
+            assertEquals(18, rs.getInt(2));
+
         } finally {
             conn.close();
         }
@@ -349,6 +389,17 @@ public class DerivedTableIT extends BaseClientManagedTimeIT {
             assertEquals(1,rs.getInt(2));
 
             assertFalse(rs.next());
+
+            // (groupby) groupby orderby offset
+            query = "SELECT t.c, count(*) FROM (SELECT count(*) c FROM aTable GROUP BY a_string) AS t GROUP BY t.c ORDER BY count(*) DESC OFFSET 1";
+            statement = conn.prepareStatement(query);
+            rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(1, rs.getInt(1));
+            assertEquals(1, rs.getInt(2));
+
+            assertFalse(rs.next());
+
         } finally {
             conn.close();
         }
@@ -544,7 +595,98 @@ public class DerivedTableIT extends BaseClientManagedTimeIT {
             conn.close();
         }
     }
-    
+
+    @Test
+    public void testDerivedTableWithOffset() throws Exception {
+        long ts = nextTimestamp();
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 1));
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        try {
+            // (LIMIT OFFSET )
+            String query = "SELECT t.eid FROM (SELECT entity_id eid FROM aTable LIMIT 2 OFFSET 1) AS t";
+            PreparedStatement statement = conn.prepareStatement(query);
+            ResultSet rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(ROW2, rs.getString(1));
+            assertTrue(rs.next());
+            assertEquals(ROW3, rs.getString(1));
+
+            assertFalse(rs.next());
+
+            // (OFFSET) limit
+            query = "SELECT t.eid FROM (SELECT entity_id eid FROM aTable OFFSET 1) AS t LIMIT 2";
+            statement = conn.prepareStatement(query);
+            rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(ROW2, rs.getString(1));
+            assertTrue(rs.next());
+            assertEquals(ROW3, rs.getString(1));
+
+            assertFalse(rs.next());
+
+            // (limit OFFSET) limit OFFSET
+            query = "SELECT t.eid FROM (SELECT entity_id eid FROM aTable LIMIT 2 OFFSET 1) AS t LIMIT 4 OFFSET 1";
+            statement = conn.prepareStatement(query);
+            rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(ROW3, rs.getString(1));
+            assertFalse(rs.next());
+
+            // (limit OFFSET) limit 2
+            query = "SELECT t.eid FROM (SELECT entity_id eid FROM aTable LIMIT 4 OFFSET 1) AS t LIMIT 2";
+            statement = conn.prepareStatement(query);
+            rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(ROW2, rs.getString(1));
+            assertTrue(rs.next());
+            assertEquals(ROW3, rs.getString(1));
+
+            assertFalse(rs.next());
+
+            // (limit ? OFFSET ?) limit ? OFFSET ?
+            query = "SELECT t.eid FROM (SELECT entity_id eid FROM aTable LIMIT ? OFFSET ?) AS t LIMIT ? OFFSET ?";
+            statement = conn.prepareStatement(query);
+            statement.setInt(1, 4);
+            statement.setInt(2, 2);
+            statement.setInt(3, 2);
+            statement.setInt(4, 2);
+            rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(ROW5, rs.getString(1));
+            assertTrue(rs.next());
+            assertEquals(ROW6, rs.getString(1));
+            assertFalse(rs.next());
+
+            // (groupby orderby OFFSET)
+            query = "SELECT a, s FROM (SELECT a_string a, sum(a_byte) s FROM aTable GROUP BY a_string ORDER BY sum(a_byte) OFFSET 1)";
+            statement = conn.prepareStatement(query);
+            rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(A_VALUE, rs.getString(1));
+            assertEquals(10, rs.getInt(2));
+            assertTrue(rs.next());
+            assertEquals(B_VALUE, rs.getString(1));
+            assertEquals(26, rs.getInt(2));
+
+            assertFalse(rs.next());
+
+            // (union OFFSET) groupby 
+            query = "SELECT a_string, count(*) FROM (SELECT a_string FROM aTable where a_byte < 4 union all SELECT a_string FROM aTable where a_byte > 8 OFFSET 1) group by a_string";
+            statement = conn.prepareStatement(query);
+            rs = statement.executeQuery();
+            assertTrue (rs.next());
+            assertEquals(A_VALUE,rs.getString(1));
+            assertEquals(2,rs.getInt(2));
+            assertTrue (rs.next());
+            assertEquals(C_VALUE,rs.getString(1));
+            assertEquals(1,rs.getInt(2));
+            assertFalse(rs.next());
+        } finally {
+            conn.close();
+        }
+    }
+
     @Test
     public void testDerivedTableWithDistinct() throws Exception {
         long ts = nextTimestamp();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
index 00655cf..3e2356f 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
@@ -441,6 +441,38 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
                 "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
                 "    DYNAMIC SERVER FILTER BY \"I.item_id\" IN (\"O.item_id\")\n" +
                 "    JOIN-SCANNER 4 ROW LIMIT",
+                /*
+                 * testJoinWithOffset()
+                 *     SELECT order_id, i.name, s.name, s.address, quantity 
+                 *     FROM joinSupplierTable s 
+                 *     LEFT JOIN joinItemTable i ON i.supplier_id = s.supplier_id 
+                 *     LEFT JOIN joinOrderTable o ON o.item_id = i.item_id LIMIT 1 OFFSET 2
+                 */
+                "CLIENT SERIAL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
+                "    SERVER OFFSET 2\n" +
+                "    SERVER 3 ROW LIMIT\n" +
+                "CLIENT 1 ROW LIMIT\n" +
+                "    PARALLEL LEFT-JOIN TABLE 0\n" +
+                "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
+                "    PARALLEL LEFT-JOIN TABLE 1(DELAYED EVALUATION)\n" +
+                "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
+                "    JOIN-SCANNER 3 ROW LIMIT",
+                /*
+                 * testJoinWithOffset()
+                 *     SELECT order_id, i.name, s.name, s.address, quantity 
+                 *     FROM joinSupplierTable s 
+                 *     JOIN joinItemTable i ON i.supplier_id = s.supplier_id 
+                 *     JOIN joinOrderTable o ON o.item_id = i.item_id LIMIT 1 OFFSET 2
+                 */
+                "CLIENT SERIAL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
+                "    SERVER OFFSET 2\n" +
+                "CLIENT 1 ROW LIMIT\n" +
+                "    PARALLEL INNER-JOIN TABLE 0\n" +
+                "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
+                "    PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)\n" +
+                "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
+                "    DYNAMIC SERVER FILTER BY \"S.supplier_id\" IN (\"I.supplier_id\")\n" +
+                "    JOIN-SCANNER 3 ROW LIMIT",
                 }});
         testCases.add(new String[][] {
                 {
@@ -770,6 +802,38 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
                 "    PARALLEL INNER-JOIN TABLE 0\n" +
                 "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_SCHEMA + ".OrderTable\n" +
                 "    JOIN-SCANNER 4 ROW LIMIT",
+                /*
+                 * testJoinWithLimit()
+                 *     SELECT order_id, i.name, s.name, s.address, quantity 
+                 *     FROM joinSupplierTable s 
+                 *     LEFT JOIN joinItemTable i ON i.supplier_id = s.supplier_id 
+                 *     LEFT JOIN joinOrderTable o ON o.item_id = i.item_id LIMIT 1 OFFSET 2
+                 */
+                "CLIENT SERIAL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
+                "    SERVER OFFSET 2\n" +
+                "    SERVER 3 ROW LIMIT\n" +
+                "CLIENT 1 ROW LIMIT\n" +
+                "    PARALLEL LEFT-JOIN TABLE 0\n" +
+                "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_SCHEMA + ".idx_item\n" +
+                "    PARALLEL LEFT-JOIN TABLE 1(DELAYED EVALUATION)\n" +
+                "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
+                "    JOIN-SCANNER 3 ROW LIMIT",
+                /*
+                 * testJoinWithLimit()
+                 *     SELECT order_id, i.name, s.name, s.address, quantity 
+                 *     FROM joinSupplierTable s 
+                 *     JOIN joinItemTable i ON i.supplier_id = s.supplier_id 
+                 *     JOIN joinOrderTable o ON o.item_id = i.item_id LIMIT 1 OFFSET 2
+                 */
+                "CLIENT SERIAL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
+                "    SERVER OFFSET 2\n" +
+                "CLIENT 1 ROW LIMIT\n" +
+                "    PARALLEL INNER-JOIN TABLE 0\n" +
+                "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_SCHEMA + ".idx_item\n" +
+                "    PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)\n" +
+                "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
+                "    DYNAMIC SERVER FILTER BY \"S.supplier_id\" IN (\"I.0:supplier_id\")\n" +
+                "    JOIN-SCANNER 3 ROW LIMIT",
                 }});
         testCases.add(new String[][] {
                 {
@@ -1124,6 +1188,40 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
                 "        CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
                 "    DYNAMIC SERVER FILTER BY \"I.:item_id\" IN (\"O.item_id\")\n" +
                 "    JOIN-SCANNER 4 ROW LIMIT",
+                /*
+                 * testJoinWithOffset()
+                 *     SELECT order_id, i.name, s.name, s.address, quantity 
+                 *     FROM joinSupplierTable s 
+                 *     LEFT JOIN joinItemTable i ON i.supplier_id = s.supplier_id 
+                 *     LEFT JOIN joinOrderTable o ON o.item_id = i.item_id LIMIT 1 OFFSET 2
+                 */
+                "CLIENT SERIAL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
+                "    SERVER OFFSET 2\n" +
+                "    SERVER 3 ROW LIMIT\n" +
+                "CLIENT 1 ROW LIMIT\n" +
+                "    PARALLEL LEFT-JOIN TABLE 0\n" +
+                "        CLIENT PARALLEL 1-WAY RANGE SCAN OVER "+ MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+JOIN_ITEM_TABLE_DISPLAY_NAME + " [-32768]\n" +
+                "        CLIENT MERGE SORT\n" +      
+                "    PARALLEL LEFT-JOIN TABLE 1(DELAYED EVALUATION)\n" +
+                "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
+                "    JOIN-SCANNER 3 ROW LIMIT",
+                /*
+                 * testJoinWithOffset()
+                 *     SELECT order_id, i.name, s.name, s.address, quantity 
+                 *     FROM joinSupplierTable s 
+                 *     JOIN joinItemTable i ON i.supplier_id = s.supplier_id 
+                 *     JOIN joinOrderTable o ON o.item_id = i.item_id LIMIT 1 OFFSET 2
+                 */
+                "CLIENT SERIAL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
+                "    SERVER OFFSET 2\n" +
+                "CLIENT 1 ROW LIMIT\n" +
+                "    PARALLEL INNER-JOIN TABLE 0\n" +
+                "        CLIENT PARALLEL 1-WAY RANGE SCAN OVER "+ MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+JOIN_ITEM_TABLE_DISPLAY_NAME + " [-32768]\n" +
+                "        CLIENT MERGE SORT\n" +
+                "    PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)\n" +
+                "        CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
+                "    DYNAMIC SERVER FILTER BY \"S.supplier_id\" IN (\"I.0:supplier_id\")\n" +
+                "    JOIN-SCANNER 3 ROW LIMIT",
                 }});
         return testCases;
     }
@@ -2920,6 +3018,26 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
             assertEquals(rs.getString(4), "S5");
 
             assertFalse(rs.next());
+
+            query = "SELECT item.\"item_id\", item.name, supp.\"supplier_id\", supp.name FROM "
+                    + JOIN_ITEM_TABLE_FULL_NAME
+                    + " item INNER JOIN (SELECT reverse(loc_id), \"supplier_id\", name FROM "
+                    + JOIN_SUPPLIER_TABLE_FULL_NAME
+                    + " ORDER BY \"supplier_id\"  OFFSET 2) AS supp ON item.\"supplier_id\" = supp.\"supplier_id\" AND (supp.name != 'S1')";
+            statement = conn.prepareStatement(query);
+            rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "0000000005");
+            assertEquals(rs.getString(2), "T5");
+            assertEquals(rs.getString(3), "0000000005");
+            assertEquals(rs.getString(4), "S5");
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "0000000006");
+            assertEquals(rs.getString(2), "T6");
+            assertEquals(rs.getString(3), "0000000006");
+            assertEquals(rs.getString(4), "S6");
+            assertFalse(rs.next());
+
         } finally {
             conn.close();
         }
@@ -3234,6 +3352,49 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
     }
 
     @Test
+    public void testJoinWithOffset() throws Exception {
+        String query1 = "SELECT \"order_id\", i.name, s.name, s.address, quantity FROM " + JOIN_SUPPLIER_TABLE_FULL_NAME
+                + " s LEFT JOIN " + JOIN_ITEM_TABLE_FULL_NAME + " i ON i.\"supplier_id\" = s.\"supplier_id\" LEFT JOIN "
+                + JOIN_ORDER_TABLE_FULL_NAME + " o ON o.\"item_id\" = i.\"item_id\" LIMIT 1 OFFSET 2 ";
+        String query2 = "SELECT \"order_id\", i.name, s.name, s.address, quantity FROM " + JOIN_SUPPLIER_TABLE_FULL_NAME
+                + " s JOIN " + JOIN_ITEM_TABLE_FULL_NAME + " i ON i.\"supplier_id\" = s.\"supplier_id\" JOIN "
+                + JOIN_ORDER_TABLE_FULL_NAME + " o ON o.\"item_id\" = i.\"item_id\" LIMIT 1 OFFSET 2 ";
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        try {
+            PreparedStatement statement = conn.prepareStatement(query1);
+            ResultSet rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "000000000000005");
+            assertEquals(rs.getString(2), "T3");
+            assertEquals(rs.getString(3), "S2");
+            assertEquals(rs.getString(4), "202 YYY Street");
+            assertEquals(rs.getInt(5), 5000);
+
+            assertFalse(rs.next());
+
+            rs = conn.createStatement().executeQuery("EXPLAIN " + query1);
+            assertEquals(plans[22], QueryUtil.getExplainPlan(rs));
+
+            statement = conn.prepareStatement(query2);
+            rs = statement.executeQuery();
+
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "000000000000005");
+            assertEquals(rs.getString(2), "T3");
+            assertEquals(rs.getString(3), "S2");
+            assertEquals(rs.getString(4), "202 YYY Street");
+            assertEquals(rs.getInt(5), 5000);
+            assertFalse(rs.next());
+
+            rs = conn.createStatement().executeQuery("EXPLAIN " + query2);
+            assertEquals(plans[23], QueryUtil.getExplainPlan(rs));
+        } finally {
+            conn.close();
+        }
+    }
+
+    @Test
     public void testNonEquiJoin() throws Exception {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithOffsetIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithOffsetIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithOffsetIT.java
new file mode 100644
index 0000000..c609581
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithOffsetIT.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * 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 maynot 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 applicablelaw 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.phoenix.end2end;
+
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import com.google.common.collect.Maps;
+
+@RunWith(Parameterized.class)
+public class QueryWithOffsetIT extends BaseOwnClusterHBaseManagedTimeIT {
+    
+    private String tableName;
+    private final String[] strings = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
+            "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
+    private final String ddl;
+
+    public QueryWithOffsetIT(String preSplit) {
+        this.tableName = tableName + "_" + preSplit.charAt(2);
+        this.ddl = "CREATE TABLE " + tableName + " (t_id VARCHAR NOT NULL,\n" + "k1 INTEGER NOT NULL,\n"
+                + "k2 INTEGER NOT NULL,\n" + "C3.k3 INTEGER,\n" + "C2.v1 VARCHAR,\n"
+                + "CONSTRAINT pk PRIMARY KEY (t_id, k1, k2)) " + preSplit;
+    }
+
+    @BeforeClass
+    public static void doSetup() throws Exception {
+        Map<String, String> props = Maps.newHashMapWithExpectedSize(1);
+        props.put(QueryServices.FORCE_ROW_KEY_ORDER_ATTRIB, Boolean.toString(true));
+        // Must update config before starting server
+        setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+    }
+
+    @Parameters(name="preSplit = {0}")
+    public static Collection<String> data() {
+        return Arrays.asList(new String[] { " SPLIT ON ('e','i','o')", " SALT_BUCKETS=10" });
+    }
+
+    @Test
+    public void testLimitOffset() throws SQLException {
+        Connection conn;
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        conn = DriverManager.getConnection(getUrl(), props);
+        createTestTable(getUrl(), ddl);
+        initTableValues(conn);
+        int limit = 10;
+        int offset = 10;
+        updateStatistics(conn);
+        ResultSet rs;
+        rs = conn.createStatement()
+                .executeQuery("SELECT t_id from " + tableName + " order by t_id limit " + limit + " offset " + offset);
+        int i = 0;
+        while (i++ < limit) {
+            assertTrue(rs.next());
+            assertEquals(strings[offset + i - 1], rs.getString(1));
+        }
+
+        limit = 35;
+        rs = conn.createStatement().executeQuery("SELECT t_id from " + tableName + " union all SELECT t_id from "
+                + tableName + " offset " + offset + " FETCH FIRST " + limit + " rows only");
+        i = 0;
+        while (i++ < strings.length - offset) {
+            assertTrue(rs.next());
+            assertEquals(strings[offset + i - 1], rs.getString(1));
+        }
+        i = 0;
+        while (i++ < limit - strings.length - offset) {
+            assertTrue(rs.next());
+            assertEquals(strings[i - 1], rs.getString(1));
+        }
+        conn.close();
+    }
+
+    @Test
+    public void testOffsetSerialQueryExecutedOnServer() throws SQLException {
+        Connection conn;
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        conn = DriverManager.getConnection(getUrl(), props);
+        int offset = 10;
+        createTestTable(getUrl(), ddl);
+        initTableValues(conn);
+        updateStatistics(conn);
+        String query = "SELECT t_id from " + tableName + " offset " + offset;
+        ResultSet rs = conn.createStatement().executeQuery("EXPLAIN " + query);
+        rs.next();
+        rs.next();
+        rs.next();
+        assertEquals("    SERVER OFFSET " + offset, rs.getString(1));
+        rs = conn.createStatement().executeQuery(query);
+        int i = 0;
+        while (i++ < strings.length - offset) {
+            assertTrue(rs.next());
+            assertEquals(strings[offset + i - 1], rs.getString(1));
+        }
+        conn.close();
+    }
+
+    @Test
+    public void testOffsetWithoutLimit() throws SQLException {
+        Connection conn;
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        conn = DriverManager.getConnection(getUrl(), props);
+        int offset = 10;
+        createTestTable(getUrl(), ddl);
+        initTableValues(conn);
+        updateStatistics(conn);
+        ResultSet rs;
+        rs = conn.createStatement()
+                .executeQuery("SELECT t_id from " + tableName + " order by t_id offset " + offset + " row");
+        int i = 0;
+        while (i++ < strings.length - offset) {
+            assertTrue(rs.next());
+            assertEquals(strings[offset + i - 1], rs.getString(1));
+        }
+
+        rs = conn.createStatement().executeQuery(
+                "SELECT k3, count(*) from " + tableName + " group by k3 order by k3 desc offset " + offset + " row");
+
+        i = 0;
+        while (i++ < strings.length - offset) {
+            assertTrue(rs.next());
+            assertEquals(strings.length - offset - i + 2, rs.getInt(1));
+        }
+
+        rs = conn.createStatement().executeQuery("SELECT t_id from " + tableName + " union all SELECT t_id from "
+                + tableName + " offset " + offset + " rows");
+        i = 0;
+        while (i++ < strings.length - offset) {
+            assertTrue(rs.next());
+            assertEquals(strings[offset + i - 1], rs.getString(1));
+        }
+        i = 0;
+        while (i++ < strings.length) {
+            assertTrue(rs.next());
+            assertEquals(strings[i - 1], rs.getString(1));
+        }
+        conn.close();
+    }
+
+    private void initTableValues(Connection conn) throws SQLException {
+        for (int i = 0; i < 26; i++) {
+            conn.createStatement().execute("UPSERT INTO " + tableName + " values('" + strings[i] + "'," + i + ","
+                    + (i + 1) + "," + (i + 2) + ",'" + strings[25 - i] + "')");
+        }
+        conn.commit();
+    }
+
+    private void updateStatistics(Connection conn) throws SQLException {
+        String query = "UPDATE STATISTICS " + tableName + " SET \"" + QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB
+                + "\"=" + Long.toString(500);
+        conn.createStatement().execute(query);
+    }
+
+    @Test
+    public void testMetaDataWithOffset() throws SQLException {
+        Connection conn;
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        conn = DriverManager.getConnection(getUrl(), props);
+        createTestTable(getUrl(), ddl);
+        initTableValues(conn);
+        updateStatistics(conn);
+        PreparedStatement stmt = conn.prepareStatement("SELECT * from " + tableName + " offset ?");
+        ParameterMetaData pmd = stmt.getParameterMetaData();
+        assertEquals(1, pmd.getParameterCount());
+        assertEquals(Types.INTEGER, pmd.getParameterType(1));
+        stmt.setInt(1, 10);
+        ResultSet rs = stmt.executeQuery();
+        ResultSetMetaData md = rs.getMetaData();
+        assertEquals(5, md.getColumnCount());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReadOnlyIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReadOnlyIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReadOnlyIT.java
index fbebe08..bcc4ee8 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReadOnlyIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReadOnlyIT.java
@@ -40,11 +40,11 @@ public class ReadOnlyIT extends BaseHBaseManagedTimeIT {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);
         String ddl = "CREATE TABLE test_table " +
-                        "  (row varchar not null, col1 integer" +
-                        "  CONSTRAINT pk PRIMARY KEY (row))\n"; 
+                        "  (r varchar not null, col1 integer" +
+                        "  CONSTRAINT pk PRIMARY KEY (r))\n"; 
         createTestTable(getUrl(), ddl);
 
-        String query = "UPSERT INTO test_table(row, col1) VALUES('row1', 777)";
+        String query = "UPSERT INTO test_table(r, col1) VALUES('row1', 777)";
         PreparedStatement statement = conn.prepareStatement(query);
         statement.executeUpdate();
         conn.commit();
@@ -53,8 +53,8 @@ public class ReadOnlyIT extends BaseHBaseManagedTimeIT {
 		conn.setReadOnly(true);
                 assertTrue(conn.isReadOnly());
 		ddl = "CREATE TABLE test_table2 " +
-				"  (row varchar not null, col1 integer" +
-				"  CONSTRAINT pk PRIMARY KEY (row))\n";
+				"  (r varchar not null, col1 integer" +
+				"  CONSTRAINT pk PRIMARY KEY (r))\n";
 		statement = conn.prepareStatement(ddl);
         	statement.executeUpdate();
         	conn.commit();
@@ -64,7 +64,7 @@ public class ReadOnlyIT extends BaseHBaseManagedTimeIT {
         }
 	  
 	try {  
-                query = "UPSERT INTO test_table(row, col1) VALUES('row1', 888)";
+                query = "UPSERT INTO test_table(r, col1) VALUES('row1', 888)";
                 statement = conn.prepareStatement(query);
                 statement.executeUpdate();
                 conn.commit();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinIT.java
index f19b886..43afd0d 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinIT.java
@@ -2383,6 +2383,50 @@ public class SortMergeJoinIT extends BaseHBaseManagedTimeIT {
     }
 
     @Test
+    public void testJoinWithOffset() throws Exception {
+        String query1 = "SELECT /*+ USE_SORT_MERGE_JOIN*/ \"order_id\", i.name, s.name, s.address, quantity FROM "
+                + JOIN_SUPPLIER_TABLE_FULL_NAME + " s LEFT JOIN " + JOIN_ITEM_TABLE_FULL_NAME
+                + " i ON i.\"supplier_id\" = s.\"supplier_id\" LEFT JOIN " + JOIN_ORDER_TABLE_FULL_NAME
+                + " o ON o.\"item_id\" = i.\"item_id\" LIMIT 2 OFFSET 1";
+        String query2 = "SELECT /*+ USE_SORT_MERGE_JOIN*/ \"order_id\", i.name, s.name, s.address, quantity FROM "
+                + JOIN_SUPPLIER_TABLE_FULL_NAME + " s JOIN " + JOIN_ITEM_TABLE_FULL_NAME
+                + " i ON i.\"supplier_id\" = s.\"supplier_id\" JOIN " + JOIN_ORDER_TABLE_FULL_NAME
+                + " o ON o.\"item_id\" = i.\"item_id\" LIMIT 1 OFFSET 2";
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        try {
+            PreparedStatement statement = conn.prepareStatement(query1);
+            ResultSet rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertNull(rs.getString(1));
+            assertNull(rs.getString(2));
+            assertEquals(rs.getString(3), "S4");
+            assertEquals(rs.getString(4), "404 YYY Street");
+            assertEquals(rs.getInt(5), 0);
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "000000000000001");
+            assertEquals(rs.getString(2), "T1");
+            assertEquals(rs.getString(3), "S1");
+            assertEquals(rs.getString(4), "101 YYY Street");
+            assertEquals(rs.getInt(5), 1000);
+            assertFalse(rs.next());
+
+            statement = conn.prepareStatement(query2);
+            rs = statement.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(rs.getString(1), "000000000000005");
+            assertEquals(rs.getString(2), "T3");
+            assertEquals(rs.getString(3), "S2");
+            assertEquals(rs.getString(4), "202 YYY Street");
+            assertEquals(rs.getInt(5), 5000);
+
+            assertFalse(rs.next());
+        } finally {
+            conn.close();
+        }
+    }
+
+    @Test
     public void testNonEquiJoin() throws Exception {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/antlr3/PhoenixSQL.g
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/antlr3/PhoenixSQL.g b/phoenix-core/src/main/antlr3/PhoenixSQL.g
index 834a410..a042090 100644
--- a/phoenix-core/src/main/antlr3/PhoenixSQL.g
+++ b/phoenix-core/src/main/antlr3/PhoenixSQL.g
@@ -125,6 +125,11 @@ tokens
     LIST = 'list';
     JARS='jars';
     ROW_TIMESTAMP='row_timestamp';
+    OFFSET ='offset';
+    FETCH = 'fetch';
+    ROW = 'row';
+    ROWS = 'rows';
+    ONLY = 'only';
 }
 
 
@@ -650,7 +655,7 @@ single_select returns [SelectStatement ret]
         (WHERE where=expression)?
         (GROUP BY group=group_by)?
         (HAVING having=expression)?
-        { ParseContext context = contextStack.peek(); $ret = factory.select(from, h, d!=null, sel, where, group, having, null, null, getBindCount(), context.isAggregate(), context.hasSequences(), null, new HashMap<String,UDFParseNode>(udfParseNodes)); }
+        { ParseContext context = contextStack.peek(); $ret = factory.select(from, h, d!=null, sel, where, group, having, null, null,null, getBindCount(), context.isAggregate(), context.hasSequences(), null, new HashMap<String,UDFParseNode>(udfParseNodes)); }
     ;
 finally{ contextStack.pop(); }
 
@@ -665,7 +670,9 @@ select_node returns [SelectStatement ret]
     :   u=unioned_selects
         (ORDER BY order=order_by)?
         (LIMIT l=limit)?
-        { ParseContext context = contextStack.peek(); $ret = factory.select(u, order, l, getBindCount(), context.isAggregate()); }
+        (OFFSET o=offset (ROW | ROWS)?)?
+        (FETCH (FIRST | NEXT) (l=limit)? (ROW | ROWS) ONLY)?
+        { ParseContext context = contextStack.peek(); $ret = factory.select(u, order, l, o, getBindCount(), context.isAggregate()); }
     ;
 finally{ contextStack.pop(); }
 
@@ -697,6 +704,11 @@ limit returns [LimitNode ret]
     | l=int_or_long_literal { $ret = factory.limit(l); }
     ;
     
+offset returns [OffsetNode ret]
+	: b=bind_expression { $ret = factory.offset(b); }
+    | l=int_or_long_literal { $ret = factory.offset(l); }
+    ;
+
 sampling_rate returns [LiteralParseNode ret]
     : l=literal { $ret = l; }
     ;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java
index 24a2add..2a97686 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java
@@ -352,12 +352,10 @@ public class DeleteCompiler {
                     PColumn column = table.getPKColumns().get(i);
                     aliasedNodes.add(FACTORY.aliasedNode(null, FACTORY.column(null, '"' + column.getName().getString() + '"', null)));
                 }
-                select = FACTORY.select(
-                        delete.getTable(), 
-                        hint, false, aliasedNodes, delete.getWhere(), 
-                        Collections.<ParseNode>emptyList(), null, 
-                        delete.getOrderBy(), delete.getLimit(),
-                        delete.getBindCount(), false, false, Collections.<SelectStatement>emptyList(), delete.getUdfParseNodes());
+                select = FACTORY.select(delete.getTable(), hint, false, aliasedNodes, delete.getWhere(),
+                        Collections.<ParseNode> emptyList(), null, delete.getOrderBy(), delete.getLimit(), null,
+                        delete.getBindCount(), false, false, Collections.<SelectStatement> emptyList(),
+                        delete.getUdfParseNodes());
                 select = StatementNormalizer.normalize(select, resolverToBe);
                 SelectStatement transformedSelect = SubqueryRewriter.transform(select, resolverToBe, connection);
                 if (transformedSelect != select) {
@@ -514,7 +512,8 @@ public class DeleteCompiler {
                     projectorToBe = new RowProjector(projectorToBe,true);
                 }
                 final RowProjector projector = projectorToBe;
-                final QueryPlan aggPlan = new AggregatePlan(context, select, tableRef, projector, null, OrderBy.EMPTY_ORDER_BY, null, GroupBy.EMPTY_GROUP_BY, null);
+                final QueryPlan aggPlan = new AggregatePlan(context, select, tableRef, projector, null, null,
+                        OrderBy.EMPTY_ORDER_BY, null, GroupBy.EMPTY_GROUP_BY, null);
                 mutationPlans.add(new MutationPlan() {
                     @Override
                     public ParameterMetaData getParameterMetaData() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
index 5d03f57..e6c5970 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
@@ -689,7 +689,9 @@ public class JoinCompiler {
             if (isSubselect())
                 return SubselectRewriter.applyOrderBy(SubselectRewriter.applyPostFilters(subselect, preFilters, tableNode.getAlias()), orderBy, tableNode.getAlias());
 
-            return NODE_FACTORY.select(tableNode, select.getHint(), false, selectNodes, getPreFiltersCombined(), null, null, orderBy, null, 0, false, select.hasSequence(), Collections.<SelectStatement>emptyList(), select.getUdfParseNodes());
+            return NODE_FACTORY.select(tableNode, select.getHint(), false, selectNodes, getPreFiltersCombined(), null,
+                    null, orderBy, null, null, 0, false, select.hasSequence(),
+                    Collections.<SelectStatement> emptyList(), select.getUdfParseNodes());
         }
 
         public boolean hasFilters() {
@@ -1071,7 +1073,8 @@ public class JoinCompiler {
                 && !select.isAggregate()
                 && !select.isDistinct()
                 && !(select.getFrom() instanceof DerivedTableNode)
-                && select.getLimit() == null;
+                && select.getLimit() == null
+                && select.getOffset() == null;
     }
 
     private static ParseNode combine(List<ParseNode> nodes) {
@@ -1268,7 +1271,8 @@ public class JoinCompiler {
         String tableAlias = tableRef.getTableAlias();
         TableNode from = NODE_FACTORY.namedTable(tableAlias == null ? null : '"' + tableAlias + '"', tName, dynamicCols);
 
-        return NODE_FACTORY.select(from, hintNode, false, selectList, where, groupBy, null, orderBy, null, 0, groupBy != null, hasSequence, Collections.<SelectStatement>emptyList(), udfParseNodes);
+        return NODE_FACTORY.select(from, hintNode, false, selectList, where, groupBy, null, orderBy, null, null, 0,
+                groupBy != null, hasSequence, Collections.<SelectStatement> emptyList(), udfParseNodes);
     }
 
     public static PTable joinProjectedTables(PTable left, PTable right, JoinType type) throws SQLException {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
index 7f3277a..1047334 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
@@ -194,6 +194,11 @@ public class ListJarsQueryPlan implements QueryPlan {
     }
 
     @Override
+    public Integer getOffset() {
+        return null;
+    }
+
+    @Override
     public OrderBy getOrderBy() {
         return OrderBy.EMPTY_ORDER_BY;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/OffsetCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/OffsetCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/OffsetCompiler.java
new file mode 100644
index 0000000..54be50b
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/OffsetCompiler.java
@@ -0,0 +1,114 @@
+/*
+ * 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.phoenix.compile;
+
+import java.sql.SQLException;
+
+import org.apache.phoenix.parse.BindParseNode;
+import org.apache.phoenix.parse.FilterableStatement;
+import org.apache.phoenix.parse.LiteralParseNode;
+import org.apache.phoenix.parse.OffsetNode;
+import org.apache.phoenix.parse.ParseNodeFactory;
+import org.apache.phoenix.parse.TraverseNoParseNodeVisitor;
+import org.apache.phoenix.schema.PDatum;
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PInteger;
+
+public class OffsetCompiler {
+    private static final ParseNodeFactory NODE_FACTORY = new ParseNodeFactory();
+
+    public static final PDatum OFFSET_DATUM = new PDatum() {
+        @Override
+        public boolean isNullable() {
+            return false;
+        }
+
+        @Override
+        public PDataType getDataType() {
+            return PInteger.INSTANCE;
+        }
+
+        @Override
+        public Integer getMaxLength() {
+            return null;
+        }
+
+        @Override
+        public Integer getScale() {
+            return null;
+        }
+
+        @Override
+        public SortOrder getSortOrder() {
+            return SortOrder.getDefault();
+        }
+    };
+
+    private OffsetCompiler() {}
+
+    public static Integer compile(StatementContext context, FilterableStatement statement) throws SQLException {
+        OffsetNode offsetNode = statement.getOffset();
+        if (offsetNode == null) { return null; }
+        OffsetParseNodeVisitor visitor = new OffsetParseNodeVisitor(context);
+        offsetNode.getOffsetParseNode().accept(visitor);
+        return visitor.getOffset();
+    }
+
+    private static class OffsetParseNodeVisitor extends TraverseNoParseNodeVisitor<Void> {
+        private final StatementContext context;
+        private Integer offset;
+
+        public OffsetParseNodeVisitor(StatementContext context) {
+            this.context = context;
+        }
+
+        public Integer getOffset() {
+            return offset;
+        }
+
+        @Override
+        public Void visit(LiteralParseNode node) throws SQLException {
+            Object offsetValue = node.getValue();
+            if (offsetValue != null) {
+                Integer offset = (Integer)OFFSET_DATUM.getDataType().toObject(offsetValue, node.getType());
+                if (offset.intValue() >= 0) {
+                    this.offset = offset;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public Void visit(BindParseNode node) throws SQLException {
+            // This is for static evaluation in SubselectRewriter.
+            if (context == null) return null;
+
+            Object value = context.getBindManager().getBindValue(node);
+            context.getBindManager().addParamMetaData(node, OFFSET_DATUM);
+            // Resolve the bind value, create a LiteralParseNode, and call the
+            // visit method for it.
+            // In this way, we can deal with just having a literal on one side
+            // of the expression.
+            visit(NODE_FACTORY.literal(value, OFFSET_DATUM.getDataType()));
+            return null;
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
index 0ae31f0..91fa5c8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
@@ -82,7 +82,8 @@ public class OrderByCompiler {
      */
     public static OrderBy compile(StatementContext context,
                                   SelectStatement statement,
-                                  GroupBy groupBy, Integer limit, 
+                                  GroupBy groupBy, Integer limit,
+                                  Integer offset,
                                   RowProjector rowProjector,
                                   TupleProjector tupleProjector,
                                   boolean isInRowKeyOrder) throws SQLException {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
index 2659b3f..752e1a5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
@@ -254,7 +254,8 @@ public class PostDDLCompiler {
                             } catch (AmbiguousColumnException e) {
                                 continue;
                             }
-                            QueryPlan plan = new AggregatePlan(context, select, tableRef, projector, null, OrderBy.EMPTY_ORDER_BY, null, GroupBy.EMPTY_GROUP_BY, null);
+                            QueryPlan plan = new AggregatePlan(context, select, tableRef, projector, null, null,
+                                    OrderBy.EMPTY_ORDER_BY, null, GroupBy.EMPTY_GROUP_BY, null);
                             try {
                                 ResultIterator iterator = plan.iterator();
                                 try {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
index 8a86d67..82e2e92 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
@@ -72,6 +72,7 @@ import org.apache.phoenix.schema.PDatum;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.TableNotFoundException;
 import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.ScanUtil;
 
 import com.google.common.collect.Lists;
@@ -168,7 +169,11 @@ public class QueryCompiler {
             SelectStatement subSelect = unionAllSelects.get(i);
             // Push down order-by and limit into sub-selects.
             if (!select.getOrderBy().isEmpty() || select.getLimit() != null) {
-                subSelect = NODE_FACTORY.select(subSelect, select.getOrderBy(), select.getLimit());
+                if (select.getOffset() == null) {
+                    subSelect = NODE_FACTORY.select(subSelect, select.getOrderBy(), select.getLimit(), null);
+                } else {
+                    subSelect = NODE_FACTORY.select(subSelect, select.getOrderBy(), null, null);
+                }
             }
             QueryPlan subPlan = compileSubquery(subSelect, true);
             TupleProjector projector = new TupleProjector(subPlan.getProjector());
@@ -182,8 +187,8 @@ public class QueryCompiler {
         StatementContext context = new StatementContext(statement, resolver, scan, sequenceManager);
 
         QueryPlan plan = compileSingleFlatQuery(context, select, statement.getParameters(), false, false, null, null, false);
-        plan =  new UnionPlan(context, select, tableRef, plan.getProjector(), plan.getLimit(), plan.getOrderBy(), GroupBy.EMPTY_GROUP_BY, 
-                plans, context.getBindManager().getParameterMetaData()); 
+        plan = new UnionPlan(context, select, tableRef, plan.getProjector(), plan.getLimit(), plan.getOffset(),
+                plan.getOrderBy(), GroupBy.EMPTY_GROUP_BY, plans, context.getBindManager().getParameterMetaData());
         return plan;
     }
 
@@ -324,10 +329,13 @@ public class QueryCompiler {
             QueryPlan plan = compileSingleFlatQuery(context, query, binds, asSubquery, !asSubquery && joinTable.isAllLeftJoin(), null, !table.isSubselect() && projectPKColumns ? tupleProjector : null, true);
             Expression postJoinFilterExpression = joinTable.compilePostFilterExpression(context, table);
             Integer limit = null;
+            Integer offset = null;
             if (!query.isAggregate() && !query.isDistinct() && query.getOrderBy().isEmpty()) {
                 limit = plan.getLimit();
+                offset = plan.getOffset();
             }
-            HashJoinInfo joinInfo = new HashJoinInfo(projectedTable, joinIds, joinExpressions, joinTypes, starJoinVector, tables, fieldPositions, postJoinFilterExpression, limit);
+            HashJoinInfo joinInfo = new HashJoinInfo(projectedTable, joinIds, joinExpressions, joinTypes,
+                    starJoinVector, tables, fieldPositions, postJoinFilterExpression, QueryUtil.getOffsetLimit(limit, offset));
             return HashJoinPlan.create(joinTable.getStatement(), plan, joinInfo, hashPlans);
         }
         
@@ -378,10 +386,14 @@ public class QueryCompiler {
             QueryPlan rhsPlan = compileSingleFlatQuery(context, rhs, binds, asSubquery, !asSubquery && type == JoinType.Right, null, !rhsTable.isSubselect() && projectPKColumns ? tupleProjector : null, true);
             Expression postJoinFilterExpression = joinTable.compilePostFilterExpression(context, rhsTable);
             Integer limit = null;
+            Integer offset = null;
             if (!rhs.isAggregate() && !rhs.isDistinct() && rhs.getOrderBy().isEmpty()) {
                 limit = rhsPlan.getLimit();
+                offset = rhsPlan.getOffset();
             }
-            HashJoinInfo joinInfo = new HashJoinInfo(projectedTable, joinIds, new List[] {joinExpressions}, new JoinType[] {type == JoinType.Right ? JoinType.Left : type}, new boolean[] {true}, new PTable[] {lhsTable}, new int[] {fieldPosition}, postJoinFilterExpression, limit);
+            HashJoinInfo joinInfo = new HashJoinInfo(projectedTable, joinIds, new List[] { joinExpressions },
+                    new JoinType[] { type == JoinType.Right ? JoinType.Left : type }, new boolean[] { true },
+                    new PTable[] { lhsTable }, new int[] { fieldPosition }, postJoinFilterExpression,  QueryUtil.getOffsetLimit(limit, offset));
             Pair<Expression, Expression> keyRangeExpressions = new Pair<Expression, Expression>(null, null);
             getKeyExpressionCombinations(keyRangeExpressions, context, joinTable.getStatement(), rhsTableRef, type, joinExpressions, hashExpressions);
             return HashJoinPlan.create(joinTable.getStatement(), rhsPlan, joinInfo, new HashSubPlan[] {new HashSubPlan(0, lhsPlan, hashExpressions, false, keyRangeExpressions.getFirst(), keyRangeExpressions.getSecond())});
@@ -432,7 +444,11 @@ public class QueryCompiler {
         context.setResolver(resolver);
         TableNode from = NODE_FACTORY.namedTable(tableRef.getTableAlias(), NODE_FACTORY.table(tableRef.getTable().getSchemaName().getString(), tableRef.getTable().getTableName().getString()));
         ParseNode where = joinTable.getPostFiltersCombined();
-        SelectStatement select = asSubquery ? NODE_FACTORY.select(from, joinTable.getStatement().getHint(), false, Collections.<AliasedNode> emptyList(), where, null, null, orderBy, null, 0, false, joinTable.getStatement().hasSequence(), Collections.<SelectStatement>emptyList(), joinTable.getStatement().getUdfParseNodes())
+        SelectStatement select = asSubquery
+                ? NODE_FACTORY.select(from, joinTable.getStatement().getHint(), false,
+                        Collections.<AliasedNode> emptyList(), where, null, null, orderBy, null, null, 0, false,
+                        joinTable.getStatement().hasSequence(), Collections.<SelectStatement> emptyList(),
+                        joinTable.getStatement().getUdfParseNodes())
                 : NODE_FACTORY.select(joinTable.getStatement(), from, where);
         
         return compileSingleFlatQuery(context, select, binds, asSubquery, false, innerPlan, null, isInRowKeyOrder);
@@ -529,6 +545,7 @@ public class QueryCompiler {
             viewWhere = new SQLParser(table.getViewStatement()).parseQuery().getWhere();
         }
         Integer limit = LimitCompiler.compile(context, select);
+        Integer offset = OffsetCompiler.compile(context, select);
 
         GroupBy groupBy = GroupByCompiler.compile(context, select, isInRowKeyOrder);
         // Optimize the HAVING clause by finding any group by expressions that can be moved
@@ -547,7 +564,8 @@ public class QueryCompiler {
         groupBy = groupBy.compile(context, innerPlanTupleProjector);
         context.setResolver(resolver); // recover resolver
         RowProjector projector = ProjectionCompiler.compile(context, select, groupBy, asSubquery ? Collections.<PDatum>emptyList() : targetColumns, where);
-        OrderBy orderBy = OrderByCompiler.compile(context, select, groupBy, limit, projector, groupBy == GroupBy.EMPTY_GROUP_BY ? innerPlanTupleProjector : null, isInRowKeyOrder); 
+        OrderBy orderBy = OrderByCompiler.compile(context, select, groupBy, limit, offset, projector,
+                groupBy == GroupBy.EMPTY_GROUP_BY ? innerPlanTupleProjector : null, isInRowKeyOrder);
         // Final step is to build the query plan
         if (!asSubquery) {
             int maxRows = statement.getMaxRows();
@@ -567,11 +585,14 @@ public class QueryCompiler {
         QueryPlan plan = innerPlan;
         if (plan == null) {
             ParallelIteratorFactory parallelIteratorFactory = asSubquery ? null : this.parallelIteratorFactory;
-            plan = select.getFrom() == null ?
-                      new LiteralResultIterationPlan(context, select, tableRef, projector, limit, orderBy, parallelIteratorFactory)
-                    : (select.isAggregate() || select.isDistinct() ? 
-                              new AggregatePlan(context, select, tableRef, projector, limit, orderBy, parallelIteratorFactory, groupBy, having)
-                            : new ScanPlan(context, select, tableRef, projector, limit, orderBy, parallelIteratorFactory, allowPageFilter));
+           plan = select.getFrom() == null
+                   ? new LiteralResultIterationPlan(context, select, tableRef, projector, limit, offset, orderBy,
+                           parallelIteratorFactory)
+                   : (select.isAggregate() || select.isDistinct()
+                           ? new AggregatePlan(context, select, tableRef, projector, limit, offset, orderBy,
+                                   parallelIteratorFactory, groupBy, having)
+                           : new ScanPlan(context, select, tableRef, projector, limit, offset, orderBy,
+                                   parallelIteratorFactory, allowPageFilter));
         }
         if (!subqueries.isEmpty()) {
             int count = subqueries.size();
@@ -588,9 +609,10 @@ public class QueryCompiler {
             if (LiteralExpression.isTrue(where)) {
                 where = null; // we do not pass "true" as filter
             }
-            plan =  select.isAggregate() || select.isDistinct() ?
-                      new ClientAggregatePlan(context, select, tableRef, projector, limit, where, orderBy, groupBy, having, plan)
-                    : new ClientScanPlan(context, select, tableRef, projector, limit, where, orderBy, plan);
+            plan = select.isAggregate() || select.isDistinct()
+                    ? new ClientAggregatePlan(context, select, tableRef, projector, limit, offset, where, orderBy,
+                            groupBy, having, plan)
+                    : new ClientScanPlan(context, select, tableRef, projector, limit, offset, where, orderBy, plan);
 
         }
         

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryPlan.java
index 1c0c469..4dcc134 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryPlan.java
@@ -60,6 +60,8 @@ public interface QueryPlan extends StatementPlan {
     
     Integer getLimit();
 
+    Integer getOffset();
+    
     OrderBy getOrderBy();
 
     GroupBy getGroupBy();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java
index 9b54c86..566afc8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java
@@ -100,7 +100,7 @@ public class StatementNormalizer extends ParseNodeRewriter {
             if (selectNodes != normSelectNodes) {
                 statement = NODE_FACTORY.select(statement.getFrom(), statement.getHint(), statement.isDistinct(),
                         normSelectNodes, statement.getWhere(), statement.getGroupBy(), statement.getHaving(), statement.getOrderBy(),
-                        statement.getLimit(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
+                        statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
             }
         }
         

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/SubqueryRewriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/SubqueryRewriter.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/SubqueryRewriter.java
index 123cb6a..f051aa5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/SubqueryRewriter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/SubqueryRewriter.java
@@ -341,7 +341,10 @@ public class SubqueryRewriter extends ParseNodeRewriter {
                 groupbyNodes.set(i - 1, aliasedNode.getNode());
             }
             SelectStatement derivedTableStmt = NODE_FACTORY.select(subquery, subquery.isDistinct(), derivedTableSelect, where, derivedTableGroupBy, true);
-            subquery = NODE_FACTORY.select(NODE_FACTORY.derivedTable(derivedTableAlias, derivedTableStmt), subquery.getHint(), false, selectNodes, null, groupbyNodes, null, Collections.<OrderByNode> emptyList(), null, subquery.getBindCount(), true, false, Collections.<SelectStatement>emptyList(), subquery.getUdfParseNodes());
+            subquery = NODE_FACTORY.select(NODE_FACTORY.derivedTable(derivedTableAlias, derivedTableStmt),
+                    subquery.getHint(), false, selectNodes, null, groupbyNodes, null,
+                    Collections.<OrderByNode> emptyList(), null, null, subquery.getBindCount(), true, false,
+                    Collections.<SelectStatement> emptyList(), subquery.getUdfParseNodes());
         }
         
         ParseNode onNode = conditionExtractor.getJoinCondition();
@@ -364,7 +367,10 @@ public class SubqueryRewriter extends ParseNodeRewriter {
             return select;
         
         // Wrap as a derived table.
-        return NODE_FACTORY.select(NODE_FACTORY.derivedTable(ParseNodeFactory.createTempAlias(), select), HintNode.EMPTY_HINT_NODE, false, select.getSelect(), null, null, null, null, null, select.getBindCount(), false, false, Collections.<SelectStatement> emptyList(), select.getUdfParseNodes());
+        return NODE_FACTORY.select(NODE_FACTORY.derivedTable(ParseNodeFactory.createTempAlias(), select),
+                HintNode.EMPTY_HINT_NODE, false, select.getSelect(), null, null, null, null, null, null,
+                select.getBindCount(), false, false, Collections.<SelectStatement> emptyList(),
+                select.getUdfParseNodes());
     }
     
     private List<AliasedNode> fixAliasedNodes(List<AliasedNode> nodes, boolean addSelectOne) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/SubselectRewriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/SubselectRewriter.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/SubselectRewriter.java
index 853d772..1def3a7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/SubselectRewriter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/SubselectRewriter.java
@@ -30,6 +30,7 @@ import org.apache.phoenix.parse.ColumnParseNode;
 import org.apache.phoenix.parse.DerivedTableNode;
 import org.apache.phoenix.parse.HintNode;
 import org.apache.phoenix.parse.LimitNode;
+import org.apache.phoenix.parse.OffsetNode;
 import org.apache.phoenix.parse.OrderByNode;
 import org.apache.phoenix.parse.ParseNode;
 import org.apache.phoenix.parse.ParseNodeRewriter;
@@ -110,6 +111,7 @@ public class SubselectRewriter extends ParseNodeRewriter {
         ParseNode havingRewrite = subselect.getHaving();
         List<OrderByNode> orderByRewrite = subselect.getOrderBy();
         LimitNode limitRewrite = subselect.getLimit();
+        OffsetNode offsetRewrite = subselect.getOffset();
         HintNode hintRewrite = subselect.getHint();
         boolean isDistinctRewrite = subselect.isDistinct();
         boolean isAggregateRewrite = subselect.isAggregate();
@@ -187,6 +189,13 @@ public class SubselectRewriter extends ParseNodeRewriter {
             }
         }
         
+        OffsetNode offset = select.getOffset();
+        if (offsetRewrite != null || (limitRewrite != null && offset != null)) {
+            return select;
+        } else {
+            offsetRewrite = offset;
+        }
+        
         LimitNode limit = select.getLimit();
         if (limit != null) {
             if (limitRewrite == null) {
@@ -207,8 +216,10 @@ public class SubselectRewriter extends ParseNodeRewriter {
             hintRewrite = hintRewrite == null ? hint : HintNode.combine(hint, hintRewrite);
         }
         
-        return NODE_FACTORY.select(subselect.getFrom(), hintRewrite, isDistinctRewrite, selectNodesRewrite, whereRewrite, groupByRewrite, 
-            havingRewrite, orderByRewrite, limitRewrite, select.getBindCount(), isAggregateRewrite, select.hasSequence(), select.getSelects(), select.getUdfParseNodes());
+        return NODE_FACTORY.select(subselect.getFrom(), hintRewrite, isDistinctRewrite, selectNodesRewrite,
+                whereRewrite, groupByRewrite, havingRewrite, orderByRewrite, limitRewrite, offsetRewrite,
+                select.getBindCount(), isAggregateRewrite, select.hasSequence(), select.getSelects(),
+                select.getUdfParseNodes());
     }
     
     private SelectStatement applyPostFilters(SelectStatement statement, List<ParseNode> postFilters) throws SQLException {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
index 58cdb64..699643b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
@@ -212,6 +212,11 @@ public class TraceQueryPlan implements QueryPlan {
     }
 
     @Override
+    public Integer getOffset() {
+        return null;
+    }
+
+    @Override
     public OrderBy getOrderBy() {
         return OrderBy.EMPTY_ORDER_BY;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
index 6ec7f70..7c6347f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
@@ -655,7 +655,7 @@ public class UpsertCompiler {
                     scan.setAttribute(BaseScannerRegionObserver.UPSERT_SELECT_EXPRS, UngroupedAggregateRegionObserver.serialize(projectedExpressions));
                     
                     // Ignore order by - it has no impact
-                    final QueryPlan aggPlan = new AggregatePlan(context, select, tableRef, aggProjector, null, OrderBy.EMPTY_ORDER_BY, null, GroupBy.EMPTY_GROUP_BY, null);
+                    final QueryPlan aggPlan = new AggregatePlan(context, select, tableRef, aggProjector, null,null, OrderBy.EMPTY_ORDER_BY, null, GroupBy.EMPTY_GROUP_BY, null);
                     return new MutationPlan() {
                         @Override
                         public ParameterMetaData getParameterMetaData() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
index 9b440ac..96ee543 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
@@ -98,6 +98,7 @@ abstract public class BaseScannerRegionObserver extends BaseRegionObserver {
     public static final String TX_SCN = "_TxScn";
     public static final String SCAN_ACTUAL_START_ROW = "_ScanActualStartRow";
     public static final String IGNORE_NEWER_MUTATIONS = "_IGNORE_NEWER_MUTATIONS";
+    public final static String SCAN_OFFSET = "_RowOffset";
     
     /**
      * Attribute name used to pass custom annotations in Scans and Mutations (later). Custom annotations

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
index 5df5755..3333d9c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
@@ -23,19 +23,20 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.sql.SQLException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
-import co.cask.tephra.Transaction;
-
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.regionserver.HRegion;
 import org.apache.hadoop.hbase.regionserver.RegionScanner;
+import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.WritableUtils;
 import org.apache.phoenix.cache.GlobalCache;
 import org.apache.phoenix.cache.TenantCache;
@@ -47,23 +48,27 @@ import org.apache.phoenix.expression.OrderByExpression;
 import org.apache.phoenix.expression.function.ArrayIndexFunction;
 import org.apache.phoenix.hbase.index.covered.update.ColumnReference;
 import org.apache.phoenix.index.IndexMaintainer;
+import org.apache.phoenix.iterate.OffsetResultIterator;
 import org.apache.phoenix.iterate.OrderedResultIterator;
 import org.apache.phoenix.iterate.RegionScannerResultIterator;
 import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.join.HashJoinInfo;
 import org.apache.phoenix.memory.MemoryManager.MemoryChunk;
+import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.KeyValueSchema;
 import org.apache.phoenix.schema.KeyValueSchema.KeyValueSchemaBuilder;
 import org.apache.phoenix.schema.ValueBitSet;
+import org.apache.phoenix.schema.tuple.ResultTuple;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.ScanUtil;
 import org.apache.phoenix.util.ServerUtil;
-import org.apache.phoenix.util.TransactionUtil;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
+import co.cask.tephra.Transaction;
+
 
 /**
  *
@@ -121,7 +126,8 @@ public class ScanRegionObserver extends BaseScannerRegionObserver {
                 orderByExpressions.add(orderByExpression);
             }
             ResultIterator inner = new RegionScannerResultIterator(s);
-            return new OrderedResultIterator(inner, orderByExpressions, thresholdBytes, limit >= 0 ? limit : null, estimatedRowSize);
+            return new OrderedResultIterator(inner, orderByExpressions, thresholdBytes, limit >= 0 ? limit : null, null,
+                    estimatedRowSize);
         } catch (IOException e) {
             throw new RuntimeException(e);
         } finally {
@@ -183,7 +189,11 @@ public class ScanRegionObserver extends BaseScannerRegionObserver {
             offset = region.getStartKey().length != 0 ? region.getStartKey().length:region.getEndKey().length;
             ScanUtil.setRowKeyOffset(scan, offset);
         }
-
+        byte[] scanOffsetBytes = scan.getAttribute(BaseScannerRegionObserver.SCAN_OFFSET);
+        Integer scanOffset = null;
+        if (scanOffsetBytes != null) {
+            scanOffset = Bytes.toInt(scanOffsetBytes);
+        }
         RegionScanner innerScanner = s;
 
         Set<KeyValueColumnExpression> arrayKVRefs = Sets.newHashSet();
@@ -217,7 +227,11 @@ public class ScanRegionObserver extends BaseScannerRegionObserver {
         if (j != null) {
             innerScanner = new HashJoinRegionScanner(innerScanner, p, j, tenantId, c.getEnvironment());
         }
-
+        if (scanOffset != null) {
+            innerScanner = getOffsetScanner(c, innerScanner,
+                    new OffsetResultIterator(new RegionScannerResultIterator(innerScanner), scanOffset),
+                    scan.getAttribute(QueryConstants.LAST_SCAN) != null);
+        }
         final OrderedResultIterator iterator = deserializeFromScan(scan,innerScanner);
         if (iterator == null) {
             return innerScanner;
@@ -226,6 +240,73 @@ public class ScanRegionObserver extends BaseScannerRegionObserver {
         return getTopNScanner(c, innerScanner, iterator, tenantId);
     }
 
+    private RegionScanner getOffsetScanner(final ObserverContext<RegionCoprocessorEnvironment> c, final RegionScanner s,
+            final OffsetResultIterator iterator, final boolean isLastScan) throws IOException {
+        final Tuple firstTuple;
+        final HRegion region = c.getEnvironment().getRegion();
+        region.startRegionOperation();
+        try {
+            // Once we return from the first call to next, we've run through and
+            // cached
+            // the topN rows, so we no longer need to start/stop a region
+            // operation.
+            Tuple tuple = iterator.next();
+            if (tuple == null && !isLastScan) {
+                List<KeyValue> kvList = new ArrayList<KeyValue>(1);
+                KeyValue kv = new KeyValue(QueryConstants.OFFSET_ROW_KEY_BYTES, QueryConstants.OFFSET_FAMILY,
+                        QueryConstants.OFFSET_COLUMN, Bytes.toBytes(iterator.getUnusedOffset()));
+                kvList.add(kv);
+                Result r = new Result(kvList);
+                firstTuple = new ResultTuple(r);
+            } else {
+                firstTuple = tuple;
+            }
+        } catch (Throwable t) {
+            ServerUtil.throwIOException(region.getRegionInfo().getRegionNameAsString(), t);
+            return null;
+        } finally {
+            region.closeRegionOperation();
+        }
+        return new BaseRegionScanner(s) {
+            private Tuple tuple = firstTuple;
+
+            @Override
+            public boolean isFilterDone() {
+                return tuple == null;
+            }
+
+            @Override
+            public boolean next(List<Cell> results) throws IOException {
+                try {
+                    if (isFilterDone()) { return false; }
+                    for (int i = 0; i < tuple.size(); i++) {
+                        results.add(tuple.getValue(i));
+                    }
+                    tuple = iterator.next();
+                    return !isFilterDone();
+                } catch (Throwable t) {
+                    ServerUtil.throwIOException(region.getRegionInfo().getRegionNameAsString(), t);
+                    return false;
+                }
+            }
+
+            @Override
+            public void close() throws IOException {
+                try {
+                    s.close();
+                } finally {
+                    try {
+                        if (iterator != null) {
+                            iterator.close();
+                        }
+                    } catch (SQLException e) {
+                        ServerUtil.throwIOException(region.getRegionInfo().getRegionNameAsString(), e);
+                    }
+                }
+            }
+        };
+    }
+
     /**
      *  Return region scanner that does TopN.
      *  We only need to call startRegionOperation and closeRegionOperation when


[40/52] [abbrv] phoenix git commit: Store encoded column counters for base tables and make views use them

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 7ddefed..a612e42 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -33,7 +33,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TYPE;
@@ -41,6 +41,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DECIMAL_DIGITS;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_VALUE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER_COUNTER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.FUNCTION_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IMMUTABLE_ROWS;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP;
@@ -123,11 +124,13 @@ import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.client.Mutation;
 import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
+import org.apache.hadoop.hbase.zookeeper.ZKConfig;
 import org.apache.phoenix.compile.ColumnResolver;
 import org.apache.phoenix.compile.FromCompiler;
 import org.apache.phoenix.compile.IndexExpressionCompiler;
@@ -216,6 +219,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Lists;
@@ -285,6 +289,13 @@ public class MetaDataClient {
             LINK_TYPE + "," +
             PARENT_TENANT_ID + " " + PVarchar.INSTANCE.getSqlTypeName() + // Dynamic column for now to prevent schema change
             ") VALUES (?, ?, ?, ?, ?, ?)";
+    private static final String UPDATE_ENCODED_COLUMN_COUNT = 
+            "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
+            TABLE_SCHEM + "," +
+            TABLE_NAME + "," +
+            COLUMN_FAMILY + "," +
+            ENCODED_COLUMN_QUALIFIER_COUNTER + 
+            ") VALUES (?, ?, ?, ?)";
     private static final String INCREMENT_SEQ_NUM =
             "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
             TENANT_ID + "," +
@@ -338,7 +349,7 @@ public class MetaDataClient {
         PK_NAME + "," +  // write this both in the column and table rows for access by metadata APIs
         KEY_SEQ + "," +
         COLUMN_DEF + "," +
-        COLUMN_QUALIFIER + "," +
+        ENCODED_COLUMN_QUALIFIER + "," +
         IS_ROW_TIMESTAMP +
         ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
     private static final String INSERT_COLUMN_ALTER_TABLE =
@@ -361,7 +372,7 @@ public class MetaDataClient {
             PK_NAME + "," +  // write this both in the column and table rows for access by metadata APIs
             KEY_SEQ + "," +
             COLUMN_DEF + ", " +
-            COLUMN_QUALIFIER +
+            ENCODED_COLUMN_QUALIFIER +
             ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
     private static final String UPDATE_COLUMN_POSITION =
         "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\" ( " +
@@ -814,7 +825,7 @@ public class MetaDataClient {
         argUpsert.execute();
     }
 
-    private PColumn newColumn(int position, ColumnDef def, PrimaryKeyConstraint pkConstraint, String defaultColumnFamily, boolean addingToPK, Map<String, Integer> nextColumnQualifiers) throws SQLException {
+    private PColumn newColumn(int position, ColumnDef def, PrimaryKeyConstraint pkConstraint, String defaultColumnFamily, boolean addingToPK, Map<String, Integer> nextEncodedColumnQualifiers) throws SQLException {
         try {
             ColumnName columnDefName = def.getColumnDefName();
             SortOrder sortOrder = def.getSortOrder();
@@ -863,13 +874,13 @@ public class MetaDataClient {
                 isNull = false;
             }
             Integer columnQualifier = null;
-            if (!isPK && nextColumnQualifiers != null) {
-                columnQualifier = nextColumnQualifiers.get(familyName.getString());
+            if (!isPK && nextEncodedColumnQualifiers != null) {
+                columnQualifier = nextEncodedColumnQualifiers.get(familyName.getString());
                 if (columnQualifier == null) {
                     // We use columnQualifier 0 for the special empty key value.
                     columnQualifier = 1;
                 }
-                nextColumnQualifiers.put(familyName.toString(), columnQualifier + 1);
+                nextEncodedColumnQualifiers.put(familyName.toString(), columnQualifier + 1);
             }
             PColumn column = new PColumnImpl(PNameFactory.newName(columnName), familyName, def.getDataType(),
                     def.getMaxLength(), def.getScale(), isNull, position, sortOrder, def.getArraySize(), null, false, def.getExpression(), isRowTimestamp, false, columnQualifier);
@@ -1867,7 +1878,7 @@ public class MetaDataClient {
                 columns = newArrayListWithExpectedSize(colDefs.size());
                 pkColumns = newLinkedHashSetWithExpectedSize(colDefs.size() + 1); // in case salted
             }
-
+            
             // Don't add link for mapped view, as it just points back to itself and causes the drop to
             // fail because it looks like there's always a view associated with it.
             if (!physicalNames.isEmpty()) {
@@ -1908,33 +1919,74 @@ public class MetaDataClient {
             int pkPositionOffset = pkColumns.size();
             int position = positionOffset;
             
-            StorageScheme storageScheme = null;
-            Map<String, Integer> nextColumnQualifiers = null; // this would be null for tables created for columns with storage scheme != ENCODED_COLUMN_NAMES
+            StorageScheme storageScheme = StorageScheme.NON_ENCODED_COLUMN_NAMES;
+            Map<String, Integer> nextCQCounters = null;
+            Map<String, Integer> updatedPhysicalTableCQCounters = null;
+            PTable viewPhysicalTable = null;
+            //TODO: samarth what about local indexes.
             if (SchemaUtil.isSystemTable(Bytes.toBytes(SchemaUtil.getTableName(schemaName, tableName)))) {
                 // System tables have hard-coded column qualifiers. So we can't use column encoding for them.
                 storageScheme = StorageScheme.NON_ENCODED_COLUMN_NAMES;
-            } else if (parent != null && tableType == PTableType.VIEW) {
-                // We can't control what column qualifiers are used in HTable mapped to Phoenix views. So
-                // we are not able to encode column names.
-                if (viewType != null && viewType == MAPPED) {
+            } else if (tableType == PTableType.VIEW) {
+                /*
+                 * We can't control what column qualifiers are used in HTable mapped to Phoenix views. So we are not
+                 * able to encode column names.
+                 */  
+                if (viewType == MAPPED) {
                     storageScheme = StorageScheme.NON_ENCODED_COLUMN_NAMES;
                 } else {
-                    // for regular phoenix views, use the storage scheme of the parent since they all share the parent's
-                    // HTable.
-                    storageScheme = parent.getStorageScheme();
+                    /*
+                     * For regular phoenix views, use the storage scheme of the physical table since they all share the
+                     * the same HTable. Views always use the base table's column qualifier counters for doling out
+                     * encoded column qualifiers.
+                     */
+                    viewPhysicalTable = connection.getTable(new PTableKey(null, physicalNames.get(0).getString()));
+                    storageScheme = viewPhysicalTable.getStorageScheme();
                     if (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES) {
-                        nextColumnQualifiers  = SchemaUtil.getNextEncodedColumnQualifiers(parent);
+                        nextCQCounters  = viewPhysicalTable.getEncodedCQCounters();
+                        updatedPhysicalTableCQCounters = Maps.newHashMapWithExpectedSize(colDefs.size());
                     }
                 }
             } else {
-                // New indexes on existing tables can have encoded column names. But unfortunately, due to 
-                // backward compatibility reasons, we aren't able to change IndexMaintainer and the state
-                // that is serialized in it. Because of this we are forced to have the indexes inherit the
-                // storage scheme of the parent data tables. Otherwise, we always attempt to create tables 
-                // with encoded column names.
-                storageScheme = parent != null ? parent.getStorageScheme() : StorageScheme.ENCODED_COLUMN_NAMES;
+                /*
+                 * New indexes on existing tables can have encoded column names. But unfortunately, due to backward
+                 * compatibility reasons, we aren't able to change IndexMaintainer and the state that is serialized in
+                 * it. Because of this we are forced to have the indexes inherit the storage scheme of the parent data
+                 * tables. Otherwise, we always attempt to create tables with encoded column names. 
+                 * 
+                 * Also of note is the case with shared indexes i.e. local indexes and view indexes. In these cases, 
+                 * column qualifiers for covered columns don't have to be unique because rows of the logical indexes are 
+                 * partitioned by the virtue of indexId present in the row key. As such, different shared indexes can use
+                 * potentially overlapping column qualifiers.
+                 * 
+                 * If the hbase table already exists, then possibly encoded or non-encoded column qualifiers already exist. 
+                 * In this case we pursue ahead with non-encoded column qualifier scheme. If the phoenix table already exists 
+                 * then we rely on the PTable, with appropriate storage scheme, returned in the MetadataMutationResult to be updated 
+                 * in the client cache. If it doesn't then the non-encoded column qualifier scheme works because we cannot control 
+                 * the column qualifiers that were used when populating the hbase table.
+                 */
+                byte[] tableNameBytes = SchemaUtil.getTableNameAsBytes(schemaName, tableName);
+                boolean hbaseTableAlreadyExists = true;
+                try (HBaseAdmin admin = connection.getQueryServices().getAdmin()) {
+                    try {
+                        admin.getTableDescriptor(tableNameBytes);
+                    } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
+                        hbaseTableAlreadyExists = false;
+                    }
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                } catch (UnsupportedOperationException e) {
+                    //FIXME: samarth I am not sure about this.
+                }
+                if (parent != null) {
+                    storageScheme = parent.getStorageScheme();
+                } else if (hbaseTableAlreadyExists) {
+                    storageScheme = StorageScheme.NON_ENCODED_COLUMN_NAMES;
+                } else {
+                    storageScheme = StorageScheme.ENCODED_COLUMN_NAMES;
+                }
                 if (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES) {
-                    nextColumnQualifiers  = Maps.newHashMapWithExpectedSize(colDefs.size() - pkColumns.size());
+                    nextCQCounters  = Maps.newHashMapWithExpectedSize(colDefs.size() - pkColumns.size());
                 }
             }
             
@@ -1956,7 +2008,11 @@ public class MetaDataClient {
                                 .setColumnName(colDef.getColumnDefName().getColumnName()).build().buildException();
                     }
                 }
-                PColumn column = newColumn(position++, colDef, pkConstraint, defaultFamilyName, false, nextColumnQualifiers);
+                PColumn column = newColumn(position++, colDef, pkConstraint, defaultFamilyName, false, nextCQCounters);
+                String cf = column.getFamilyName() != null ? column.getFamilyName().getString() : null;
+                if (updatedPhysicalTableCQCounters != null && cf != null && EncodedColumnsUtil.hasEncodedColumnName(column)) {
+                    updatedPhysicalTableCQCounters.put(cf, nextCQCounters.get(cf));
+                }
                 if (SchemaUtil.isPKColumn(column)) {
                     // TODO: remove this constraint?
                     if (pkColumnsIterator.hasNext() && !column.getName().getString().equals(pkColumnsIterator.next().getFirst().getColumnName())) {
@@ -1988,9 +2044,45 @@ public class MetaDataClient {
                         .build().buildException();
                 }
                 if (column.getFamilyName() != null) {
-                    familyNames.put(column.getFamilyName().getString(),column.getFamilyName());
+                    familyNames.put(cf,column.getFamilyName());
                 }
             }
+            
+            if (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES) {
+                // Store the encoded column counter for each column family for phoenix entities that have their own hbase
+                // tables i.e. base tables and indexes.
+                Map<String, Integer> mapToUse = tableType == VIEW ? updatedPhysicalTableCQCounters : nextCQCounters;
+                if (tableType != VIEW && nextCQCounters.isEmpty()) {
+                    // Case when a table or index has only pk columns.
+                    nextCQCounters.put(defaultFamilyName == null ? QueryConstants.DEFAULT_COLUMN_FAMILY : defaultFamilyName, 1);
+                }
+                if (mapToUse != null) {
+                    PreparedStatement linkStatement = connection.prepareStatement(UPDATE_ENCODED_COLUMN_COUNT);
+                    String schemaNameToUse = tableType == VIEW ? viewPhysicalTable.getSchemaName().getString() : schemaName;
+                    String tableNameToUse = tableType == VIEW ? viewPhysicalTable.getTableName().getString() : tableName;
+                    for (Entry<String, Integer> entry : mapToUse.entrySet()) {
+                        String familyName = entry.getKey();
+                        Integer nextQualifier = entry.getValue();
+                        linkStatement.setString(1, schemaNameToUse);
+                        linkStatement.setString(2, tableNameToUse);
+                        linkStatement.setString(3, familyName);
+                        linkStatement.setInt(4, nextQualifier);
+                        linkStatement.execute();
+                    }
+
+                    // When a view adds its own columns, then we need to increase the sequence number of the base table
+                    // too since we want clients to get the latest PTable of the base table.
+                    if (tableType == VIEW && updatedPhysicalTableCQCounters != null && !updatedPhysicalTableCQCounters.isEmpty()) {
+                        PreparedStatement incrementStatement = connection.prepareStatement(INCREMENT_SEQ_NUM);
+                        incrementStatement.setString(1, null);
+                        incrementStatement.setString(2, viewPhysicalTable.getSchemaName().getString());
+                        incrementStatement.setString(3, viewPhysicalTable.getTableName().getString());
+                        incrementStatement.setLong(4, viewPhysicalTable.getSequenceNumber() + 1);
+                        incrementStatement.execute();
+                    }
+                }
+            }
+            
             // We need a PK definition for a TABLE or mapped VIEW
             if (!isPK && pkColumnsNames.isEmpty() && tableType != PTableType.VIEW && viewType != ViewType.MAPPED) {
                 throw new SQLExceptionInfo.Builder(SQLExceptionCode.PRIMARY_KEY_MISSING)
@@ -2074,7 +2166,7 @@ public class MetaDataClient {
                         Collections.<PTable>emptyList(), isImmutableRows,
                         Collections.<PName>emptyList(), defaultFamilyName == null ? null :
                                 PNameFactory.newName(defaultFamilyName), null,
-                        Boolean.TRUE.equals(disableWAL), false, false, null, indexId, indexType, true, false, 0, 0L, isNamespaceMapped, StorageScheme.NON_ENCODED_COLUMN_NAMES);
+                        Boolean.TRUE.equals(disableWAL), false, false, null, indexId, indexType, true, false, 0, 0L, isNamespaceMapped, StorageScheme.NON_ENCODED_COLUMN_NAMES, ImmutableMap.<String, Integer>of());
                 connection.addTable(table, MetaDataProtocol.MIN_TABLE_TIMESTAMP);
             } else if (tableType == PTableType.INDEX && indexId == null) {
                 if (tableProps.get(HTableDescriptor.MAX_FILESIZE) == null) {
@@ -2240,13 +2332,14 @@ public class MetaDataClient {
                 throw new ConcurrentTableMutationException(schemaName, tableName);
             default:
                 PName newSchemaName = PNameFactory.newName(schemaName);
+                // Views always rely on the parent table's map to dole out encoded column qualifiers.
+                Map<String, Integer> qualifierMapToBe = tableType == PTableType.VIEW ? ImmutableMap.<String, Integer>of() : nextCQCounters;
                 PTable table =  PTableImpl.makePTable(
                         tenantId, newSchemaName, PNameFactory.newName(tableName), tableType, indexState, timestamp!=null ? timestamp : result.getMutationTime(),
                         PTable.INITIAL_SEQ_NUM, pkName == null ? null : PNameFactory.newName(pkName), saltBucketNum, columns,
                         dataTableName == null ? null : newSchemaName, dataTableName == null ? null : PNameFactory.newName(dataTableName), Collections.<PTable>emptyList(), isImmutableRows,
                         physicalNames, defaultFamilyName == null ? null : PNameFactory.newName(defaultFamilyName), viewStatement, Boolean.TRUE.equals(disableWAL), multiTenant, storeNulls, viewType,
-                        indexId, indexType, rowKeyOrderOptimizable, transactional, updateCacheFrequency, 0L, isNamespaceMapped, storageScheme);
-                        
+                        indexId, indexType, rowKeyOrderOptimizable, transactional, updateCacheFrequency, 0L, isNamespaceMapped, storageScheme, qualifierMapToBe);
                 result = new MetaDataMutationResult(code, result.getMutationTime(), table, true);
                 addTableToCache(result);
                 return table;
@@ -2805,8 +2898,16 @@ public class MetaDataClient {
                 List<PColumn> columns = Lists.newArrayListWithExpectedSize(columnDefs.size());
                 Set<String> colFamiliesForPColumnsToBeAdded = new LinkedHashSet<>();
                 Set<String> families = new LinkedHashSet<>();
-                Map<String, Integer> nextColumnQualifiers = SchemaUtil.getNextEncodedColumnQualifiers(table);
+                PTableType tableType = table.getType();
+                PTable tableForCQCounters = null;
+                Map<String, Integer> cqCountersToUse = null;
+                Map<String, Integer> cfWithUpdatedCQCounters = null; 
                 if (columnDefs.size() > 0 ) {
+                    //FIXME: samarth change this to fetch table from server if client cache doesn't have it. What about local indexes?
+                    //TODO: samarth should these be guarded by storage scheme check. Better to have the map always available. immutable empty for views and non encoded.
+                    tableForCQCounters = tableType == PTableType.VIEW ? connection.getTable(new PTableKey(null, table.getPhysicalName().getString())) : table;
+                     cqCountersToUse = tableForCQCounters.getEncodedCQCounters();
+                    cfWithUpdatedCQCounters = cqCountersToUse != null ? Maps.<String, Integer>newHashMapWithExpectedSize(columnDefs.size()) : null; 
                     try (PreparedStatement colUpsert = connection.prepareStatement(INSERT_COLUMN_ALTER_TABLE)) {
                         short nextKeySeq = SchemaUtil.getMaxKeySeq(table);
                         for( ColumnDef colDef : columnDefs) {
@@ -2826,11 +2927,15 @@ public class MetaDataClient {
                                 throw new SQLExceptionInfo.Builder(SQLExceptionCode.ROWTIMESTAMP_CREATE_ONLY)
                                 .setColumnName(colDef.getColumnDefName().getColumnName()).build().buildException();
                             }
-                            PColumn column = newColumn(position++, colDef, PrimaryKeyConstraint.EMPTY, table.getDefaultFamilyName() == null ? null : table.getDefaultFamilyName().getString(), true, nextColumnQualifiers);
+                            PColumn column = newColumn(position++, colDef, PrimaryKeyConstraint.EMPTY, table.getDefaultFamilyName() == null ? null : table.getDefaultFamilyName().getString(), true, cqCountersToUse);
+                            String cf = column.getFamilyName() != null ? column.getFamilyName().getString() : null;
+                            if (cfWithUpdatedCQCounters != null && cf != null && EncodedColumnsUtil.hasEncodedColumnName(column)) {
+                                cfWithUpdatedCQCounters.put(cf, cqCountersToUse.get(cf));
+                            }
                             columns.add(column);
                             String pkName = null;
                             Short keySeq = null;
-
+                            
                             // TODO: support setting properties on other families?
                             if (column.getFamilyName() == null) {
                                 ++numPkColumnsAdded;
@@ -2842,7 +2947,7 @@ public class MetaDataClient {
                             colFamiliesForPColumnsToBeAdded.add(column.getFamilyName() == null ? null : column.getFamilyName().getString());
                             addColumnMutation(schemaName, tableName, column, colUpsert, null, pkName, keySeq, table.getBucketNum() != null);
                         }
-
+                        
                         // Add any new PK columns to end of index PK
                         if (numPkColumnsAdded>0) {
                             // create PK column list that includes the newly created columns
@@ -2864,7 +2969,7 @@ public class MetaDataClient {
                                         ColumnName indexColName = ColumnName.caseSensitiveColumnName(IndexUtil.getIndexColumnName(null, colDef.getColumnDefName().getColumnName()));
                                         Expression expression = new RowKeyColumnExpression(columns.get(i), new RowKeyValueAccessor(pkColumns, ++pkSlotPosition));
                                         ColumnDef indexColDef = FACTORY.columnDef(indexColName, indexColDataType.getSqlTypeName(), colDef.isNull(), colDef.getMaxLength(), colDef.getScale(), true, colDef.getSortOrder(), expression.toString(), colDef.isRowTimestamp());
-                                        PColumn indexColumn = newColumn(indexPosition++, indexColDef, PrimaryKeyConstraint.EMPTY, null, true, nextColumnQualifiers);
+                                        PColumn indexColumn = newColumn(indexPosition++, indexColDef, PrimaryKeyConstraint.EMPTY, null, true, cqCountersToUse);
                                         addColumnMutation(schemaName, index.getTableName().getString(), indexColumn, colUpsert, index.getParentTableName().getString(), index.getPKName() == null ? null : index.getPKName().getString(), ++nextIndexKeySeq, index.getBucketNum() != null);
                                     }
                                 }
@@ -2900,6 +3005,7 @@ public class MetaDataClient {
                     tableMetaData.addAll(connection.getMutationState().toMutations(timeStamp).next().getSecond());
                     connection.rollback();
                 }
+                
                 long seqNum = table.getSequenceNumber();
                 if (changingPhoenixTableProperty || columnDefs.size() > 0) { 
                     seqNum = incrementTableSeqNum(table, statement.getTableType(), columnDefs.size(), isTransactional, updateCacheFrequency, isImmutableRows, disableWAL, multiTenant, storeNulls);
@@ -2911,6 +3017,31 @@ public class MetaDataClient {
                 Collections.reverse(tableMetaData);
                 // Add column metadata afterwards, maintaining the order so columns have more predictable ordinal position
                 tableMetaData.addAll(columnMetaData);
+                //TODO: samarth I am not sure this is going to work on server side. But for now lets add these mutations here.
+                if (cfWithUpdatedCQCounters != null && !cfWithUpdatedCQCounters.isEmpty()) {
+                    PreparedStatement linkStatement = connection.prepareStatement(UPDATE_ENCODED_COLUMN_COUNT);
+                    for (Entry<String, Integer> entry : cfWithUpdatedCQCounters.entrySet()) {
+                        String familyName = entry.getKey();
+                        Integer nextQualifier = entry.getValue();
+                        linkStatement.setString(1, tableForCQCounters.getSchemaName().getString());
+                        linkStatement.setString(2, tableForCQCounters.getTableName().getString());
+                        linkStatement.setString(3, familyName);
+                        linkStatement.setInt(4, nextQualifier);
+                        linkStatement.execute();
+                    }
+                    // When a view adds its own columns, then we need to increase the sequence number of the base table
+                    // too since we want clients to get the latest PTable of the base table.
+                    if (tableType == VIEW) {
+                        PreparedStatement incrementStatement = connection.prepareStatement(INCREMENT_SEQ_NUM);
+                        incrementStatement.setString(1, null); //TODO: samarth verify that tenant id should be null here
+                        incrementStatement.setString(2, tableForCQCounters.getSchemaName().getString());
+                        incrementStatement.setString(3, tableForCQCounters.getTableName().getString());
+                        incrementStatement.setLong(4, tableForCQCounters.getSequenceNumber() + 1);
+                        incrementStatement.execute();
+                    }
+                    tableMetaData.addAll(connection.getMutationState().toMutations(timeStamp).next().getSecond());
+                    connection.rollback();
+                }
 
                 byte[] family = families.size() > 0 ? families.iterator().next().getBytes() : null;
 
@@ -3232,7 +3363,7 @@ public class MetaDataClient {
                                         sharedTableState.getSchemaName(), sharedTableState.getTableName(), ts,
                                         table.getColumnFamilies(), sharedTableState.getColumns(),
                                         sharedTableState.getPhysicalNames(), sharedTableState.getViewIndexId(),
-                                        table.isMultiTenant(), table.isNamespaceMapped(), table.getStorageScheme());
+                                        table.isMultiTenant(), table.isNamespaceMapped(), table.getStorageScheme(), table.getEncodedCQCounters());
                                 TableRef indexTableRef = new TableRef(viewIndexTable);
                                 PName indexTableTenantId = sharedTableState.getTenantId();
                                 if (indexTableTenantId==null) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
index e32477e..e42000e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
@@ -18,6 +18,7 @@
 package org.apache.phoenix.schema;
 
 import java.util.List;
+import java.util.Map;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.Bytes;
@@ -130,7 +131,7 @@ public interface PTable extends PMetaDataEntity {
          * Link from a view to its parent table
          */
         PARENT_TABLE((byte)3);
-
+        
         private final byte[] byteValue;
         private final byte serializedValue;
 
@@ -384,4 +385,5 @@ public interface PTable extends PMetaDataEntity {
     long getUpdateCacheFrequency();
     boolean isNamespaceMapped();
     StorageScheme getStorageScheme();
+    Map<String, Integer> getEncodedCQCounters();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index 577d1c5..e7b8c78 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -28,6 +28,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
@@ -46,6 +47,7 @@ import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.coprocessor.generated.PGuidePostsProtos;
 import org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts;
 import org.apache.phoenix.coprocessor.generated.PTableProtos;
+import org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter;
 import org.apache.phoenix.exception.DataExceedsCapacityException;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
@@ -146,6 +148,7 @@ public class PTableImpl implements PTable {
     private long updateCacheFrequency;
     private boolean isNamespaceMapped;
     private StorageScheme storageScheme;
+    private Map<String, Integer> encodedCQCounters;
 
     public PTableImpl() {
         this.indexes = Collections.emptyList();
@@ -177,7 +180,7 @@ public class PTableImpl implements PTable {
     }
     
     public PTableImpl(PName tenantId, PName schemaName, PName tableName, long timestamp, List<PColumnFamily> families, 
-            List<PColumn> columns, List<PName> physicalNames, Short viewIndexId, boolean multiTenant, boolean isNamespaceMpped, StorageScheme storageScheme) throws SQLException { // For indexes stored in shared physical tables
+            List<PColumn> columns, List<PName> physicalNames, Short viewIndexId, boolean multiTenant, boolean isNamespaceMpped, StorageScheme storageScheme, Map<String, Integer> encodedColumnQualifierCounters) throws SQLException { // For indexes stored in shared physical tables
         this.pkColumns = this.allColumns = Collections.emptyList();
         this.rowKeySchema = RowKeySchema.EMPTY_SCHEMA;
         this.indexes = Collections.emptyList();
@@ -191,7 +194,7 @@ public class PTableImpl implements PTable {
         init(tenantId, this.schemaName, this.tableName, PTableType.INDEX, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
             PTableStats.EMPTY_STATS, this.schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
             null, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
-            isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMpped, storageScheme);
+            isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMpped, storageScheme, encodedColumnQualifierCounters);
     }
 
     public PTableImpl(long timeStamp) { // For delete marker
@@ -234,7 +237,7 @@ public class PTableImpl implements PTable {
                 table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table), parentSchemaName, table.getParentTableName(),
                 indexes, table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), viewStatement,
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
+                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme(), table.getEncodedCQCounters());
     }
 
     public static PTableImpl makePTable(PTable table, List<PColumn> columns) throws SQLException {
@@ -243,7 +246,7 @@ public class PTableImpl implements PTable {
                 table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
+                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme(), table.getEncodedCQCounters());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns) throws SQLException {
@@ -252,7 +255,7 @@ public class PTableImpl implements PTable {
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(),
                 table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme(), table.getEncodedCQCounters());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows) throws SQLException {
@@ -261,7 +264,7 @@ public class PTableImpl implements PTable {
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
-                table.getIndexType(), table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
+                table.getIndexType(), table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme(), table.getEncodedCQCounters());
     }
     
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows, boolean isWalDisabled,
@@ -271,7 +274,7 @@ public class PTableImpl implements PTable {
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 isWalDisabled, isMultitenant, storeNulls, table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), isTransactional, updateCacheFrequency, table.getIndexDisableTimestamp(), isNamespaceMapped, table.getStorageScheme());
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), isTransactional, updateCacheFrequency, table.getIndexDisableTimestamp(), isNamespaceMapped, table.getStorageScheme(), table.getEncodedCQCounters());
     }
     
     public static PTableImpl makePTable(PTable table, PIndexState state) throws SQLException {
@@ -281,7 +284,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
+                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme(), table.getEncodedCQCounters());
     }
 
     public static PTableImpl makePTable(PTable table, boolean rowKeyOrderOptimizable) throws SQLException {
@@ -291,7 +294,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), rowKeyOrderOptimizable, table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
+                table.getBaseColumnCount(), rowKeyOrderOptimizable, table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme(), table.getEncodedCQCounters());
     }
 
     public static PTableImpl makePTable(PTable table, PTableStats stats) throws SQLException {
@@ -301,7 +304,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), stats,
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme(), table.getEncodedCQCounters());
     }
 
     public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
@@ -310,12 +313,12 @@ public class PTableImpl implements PTable {
             boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
             boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
             IndexType indexType, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency,
-            long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme) throws SQLException {
+            long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme, Map<String, Integer> encodedColumnQualifierCounters) throws SQLException {
         return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns, dataSchemaName,
                 dataTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
                 viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId,
                 indexType, PTableStats.EMPTY_STATS, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, rowKeyOrderOptimizable, isTransactional,
-                updateCacheFrequency,indexDisableTimestamp, isNamespaceMapped, storageScheme);
+                updateCacheFrequency,indexDisableTimestamp, isNamespaceMapped, storageScheme, encodedColumnQualifierCounters);
     }
 
     public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
@@ -324,12 +327,12 @@ public class PTableImpl implements PTable {
             boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
             boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
             IndexType indexType, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency,
-            @NotNull PTableStats stats, int baseColumnCount, long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme)
+            @NotNull PTableStats stats, int baseColumnCount, long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme, Map<String, Integer> encodedColumnQualifierCounters)
             throws SQLException {
         return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName,
                 bucketNum, columns, dataSchemaName, dataTableName, indexes, isImmutableRows, physicalNames,
                 defaultFamilyName, viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId,
-                indexType, stats, baseColumnCount, rowKeyOrderOptimizable, isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, storageScheme);
+                indexType, stats, baseColumnCount, rowKeyOrderOptimizable, isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, storageScheme, encodedColumnQualifierCounters);
     }
 
     private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state,
@@ -337,11 +340,11 @@ public class PTableImpl implements PTable {
             PName parentSchemaName, PName parentTableName, List<PTable> indexes, boolean isImmutableRows,
             List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL, boolean multiTenant,
             boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType,
-            PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme) throws SQLException {
+            PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme, Map<String, Integer> encodedColumnQualifierCounters) throws SQLException {
         init(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
                 stats, schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
                 viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
-                isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, storageScheme);
+                isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, storageScheme, encodedColumnQualifierCounters);
     }
     
     @Override
@@ -374,7 +377,7 @@ public class PTableImpl implements PTable {
             PName pkName, Integer bucketNum, List<PColumn> columns, PTableStats stats, PName parentSchemaName, PName parentTableName,
             List<PTable> indexes, boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL,
             boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
-            IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme) throws SQLException {
+            IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped, StorageScheme storageScheme, Map<String, Integer> encodedColumnQualifierCounters) throws SQLException {
         Preconditions.checkNotNull(schemaName);
         Preconditions.checkArgument(tenantId==null || tenantId.getBytes().length > 0); // tenantId should be null or not empty
         int estimatedSize = SizedUtil.OBJECT_SIZE * 2 + 23 * SizedUtil.POINTER_SIZE + 4 * SizedUtil.INT_SIZE + 2 * SizedUtil.LONG_SIZE + 2 * SizedUtil.INT_OBJECT_SIZE +
@@ -547,9 +550,9 @@ public class PTableImpl implements PTable {
         for (PName name : this.physicalNames) {
             estimatedSize += name.getEstimatedSize();
         }
-
         this.estimatedSize = estimatedSize;
         this.baseColumnCount = baseColumnCount;
+        this.encodedCQCounters = encodedColumnQualifierCounters;
     }
 
     @Override
@@ -1065,7 +1068,8 @@ public class PTableImpl implements PTable {
     public IndexType getIndexType() {
         return indexType;
     }
-
+    
+    //FIXME: samarth change the proto here
     /**
      * Construct a PTable instance from ProtoBuffered PTable instance
      * @param table
@@ -1169,13 +1173,22 @@ public class PTableImpl implements PTable {
       if (table.hasStorageScheme()) {
           storageScheme = StorageScheme.fromSerializedValue(table.getStorageScheme().toByteArray()[0]);
       }
+      int numCounters = table.getEncodedColumnQualifierCountersCount();
+      Map<String, Integer> encodedColumnQualifierCounters = null;
+      if (numCounters > 0) {
+          encodedColumnQualifierCounters = Maps.newHashMapWithExpectedSize(numCounters);
+          for (int i = 0; i < numCounters; i++) {
+              PTableProtos.EncodedColumnQualifierCounter c = table.getEncodedColumnQualifierCounters(i);
+              encodedColumnQualifierCounters.put(c.getFamilyName(), c.getCounter());
+          }
+      }
       try {
         PTableImpl result = new PTableImpl();
         result.init(tenantId, schemaName, tableName, tableType, indexState, timeStamp, sequenceNumber, pkName,
             (bucketNum == NO_SALTING) ? null : bucketNum, columns, stats, schemaName,dataTableName, indexes,
             isImmutableRows, physicalNames, defaultFamilyName, viewStatement, disableWAL,
             multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
-            isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, storageScheme);
+            isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped, storageScheme, encodedColumnQualifierCounters);
         return result;
       } catch (SQLException e) {
         throw new RuntimeException(e); // Impossible
@@ -1270,6 +1283,15 @@ public class PTableImpl implements PTable {
       if (table.getStorageScheme() != null) {
           builder.setStorageScheme(ByteStringer.wrap(new byte[]{table.getStorageScheme().getSerializedValue()}));
       }
+      Map<String, Integer> encodedColumnQualifierCounters = table.getEncodedCQCounters();
+      if (encodedColumnQualifierCounters != null) {
+          for (Entry<String, Integer> entry : encodedColumnQualifierCounters.entrySet()) {
+              EncodedColumnQualifierCounter.Builder b = EncodedColumnQualifierCounter.newBuilder();
+              b.setFamilyName(entry.getKey());
+              b.setCounter(entry.getValue());
+              builder.addEncodedColumnQualifierCounters(b.build());
+          }
+      }
       return builder.build();
     }
 
@@ -1317,4 +1339,9 @@ public class PTableImpl implements PTable {
     public StorageScheme getStorageScheme() {
         return storageScheme;
     }
+    
+    @Override
+    public Map<String, Integer> getEncodedCQCounters() {
+        return encodedCQCounters;
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
index 216cf34..de6551a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
@@ -1024,23 +1024,29 @@ public class SchemaUtil {
     /**
      * Return a map of column family -> next column qualifier number to use.
      */
-    public static Map<String, Integer> getNextEncodedColumnQualifiers(PTable table) {
-        if (EncodedColumnsUtil.usesEncodedColumnNames(table)) {
-            Map<String, Integer> map = Maps.newHashMapWithExpectedSize(table.getColumns().size());
-            int max = 0; 
-            for (PColumnFamily f : table.getColumnFamilies()) {
-                for (PColumn column : f.getColumns()) {
-                    if (column.getEncodedColumnQualifier() > max) {
-                        max = column.getEncodedColumnQualifier();
-                    }
-                }
-                // column qualifiers start with 1.
-                map.put(f.getName().getString(), max + 1);
-            }
-            return map;
-        }
-        return null;
-    }
+//    public static Map<String, Integer> getNextEncodedColumnQualifiers(PTable table) {
+//        if (EncodedColumnsUtil.usesEncodedColumnNames(table)) {
+//            Map<String, Integer> map = Maps.newHashMapWithExpectedSize(table.getColumns().size());
+//            int max = 0; 
+//            for (PColumnFamily f : table.getColumnFamilies()) {
+//                for (PColumn column : f.getColumns()) {
+//                    if (column.getEncodedColumnQualifier() > max) {
+//                        max = column.getEncodedColumnQualifier();
+//                    }
+//                }
+//                // column qualifiers start with 1.
+//                map.put(f.getName().getString(), max + 1);
+//            }
+//            // When a table has only primary key columns table.getColumnFamilies() will be empty.
+//            // In that case, populate the map with the next column qualifier (1) for the default column
+//            // family of the table.
+//            if (map.isEmpty()) {
+//                map.put(SchemaUtil.getEmptyColumnFamilyAsString(table), 1);
+//            }
+//            return map;
+//        }
+//        return null;
+//    }
     
     public static boolean usesEncodedColumnNames(PTable table) {
         return table.getStorageScheme() != null && table.getStorageScheme() == StorageScheme.ENCODED_COLUMN_NAMES;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
index d7d7d02..7b0a905 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
@@ -122,7 +122,7 @@ public class WhereCompilerTest extends BaseConnectionlessQueryTest {
         Filter filter = scan.getFilter();
         ColumnExpression idExpression = new ColumnRef(plan.getTableRef(), plan.getTableRef().getTable().getPColumnForColumnName("ID").getPosition()).newColumnExpression();
         Expression id = new RowKeyColumnExpression(idExpression,new RowKeyValueAccessor(plan.getTableRef().getTable().getPKColumns(),0));
-        Expression company = new KeyValueColumnExpression(plan.getTableRef().getTable().getPColumnForColumnName("COMPANY"), true);
+        Expression company = new KeyValueColumnExpression(plan.getTableRef().getTable().getPColumnForColumnName("COMPANY"), false);
         // FilterList has no equals implementation
         assertTrue(filter instanceof FilterList);
         FilterList filterList = (FilterList)filter;
@@ -154,7 +154,7 @@ public class WhereCompilerTest extends BaseConnectionlessQueryTest {
         assertEquals(
                 singleKVFilter(constantComparison(
                     CompareOp.EQUAL,
-                    new KeyValueColumnExpression(column, true),
+                    new KeyValueColumnExpression(column, false),
                     "c3")),
                 filter);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
index 36193e9..944dda0 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
@@ -256,7 +256,7 @@ public class CorrelatePlanTest {
                     PTableType.SUBQUERY, null, MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM,
                     null, null, columns, null, null, Collections.<PTable>emptyList(),
                     false, Collections.<PName>emptyList(), null, null, false, false, false, null,
-                    null, null, true, false, 0, 0L, Boolean.FALSE, null);
+                    null, null, true, false, 0, 0L, Boolean.FALSE, null, null);
             TableRef sourceTable = new TableRef(pTable);
             List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> newArrayList();
             for (PColumn column : sourceTable.getTable().getColumns()) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
index ca4d80b..90b75a6 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
@@ -177,7 +177,7 @@ public class LiteralResultIteratorPlanTest {
             PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,
                     MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM, null, null, columns, null, null,
                     Collections.<PTable> emptyList(), false, Collections.<PName> emptyList(), null, null, false, false,
-                    false, null, null, null, true, false, 0, 0L, false, null);
+                    false, null, null, null, true, false, 0, 0L, false, null, null);
             TableRef sourceTable = new TableRef(pTable);
             List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> newArrayList();
             for (PColumn column : sourceTable.getTable().getColumns()) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
index a86cc8d..089c5f1 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java
@@ -136,37 +136,36 @@ public class ConnectionlessTest {
         conn.rollback(); // to clear the list of mutations for the next
     }
     
-    @SuppressWarnings("deprecation")
     private static void assertRow1(Iterator<KeyValue> iterator, byte[] expectedRowKey1) {
         KeyValue kv;
         assertTrue(iterator.hasNext());
         kv = iterator.next();
         assertArrayEquals(expectedRowKey1, kv.getRow());        
-        assertEquals(QueryConstants.EMPTY_COLUMN_VALUE, PVarchar.INSTANCE.toObject(kv.getValue()));
-        kv = iterator.next();
-        assertArrayEquals(expectedRowKey1, kv.getRow());        
         assertEquals(name1, PVarchar.INSTANCE.toObject(kv.getValue()));
         assertTrue(iterator.hasNext());
         kv = iterator.next();
         assertArrayEquals(expectedRowKey1, kv.getRow());        
         assertEquals(now, PDate.INSTANCE.toObject(kv.getValue()));
+        assertTrue(iterator.hasNext());
+        kv = iterator.next();
+        assertArrayEquals(expectedRowKey1, kv.getRow());        
+        assertEquals(QueryConstants.EMPTY_COLUMN_VALUE, PVarchar.INSTANCE.toObject(kv.getValue()));
     }
 
-    @SuppressWarnings("deprecation")
     private static void assertRow2(Iterator<KeyValue> iterator, byte[] expectedRowKey2) {
         KeyValue kv;
         assertTrue(iterator.hasNext());
         kv = iterator.next();
         assertArrayEquals(expectedRowKey2, kv.getRow());        
-        assertEquals(QueryConstants.EMPTY_COLUMN_VALUE, PVarchar.INSTANCE.toObject(kv.getValue()));
-        kv = iterator.next();
-        assertArrayEquals(expectedRowKey2, kv.getRow());        
         assertEquals(name2, PVarchar.INSTANCE.toObject(kv.getValue()));
         assertTrue(iterator.hasNext());
         kv = iterator.next();
         assertArrayEquals(expectedRowKey2, kv.getRow());        
         assertEquals(now, PDate.INSTANCE.toObject(kv.getValue()));
-        assertFalse(iterator.hasNext());
+        assertTrue(iterator.hasNext());
+        kv = iterator.next();
+        assertArrayEquals(expectedRowKey2, kv.getRow());        
+        assertEquals(QueryConstants.EMPTY_COLUMN_VALUE, PVarchar.INSTANCE.toObject(kv.getValue()));
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-protocol/src/main/PTable.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PTable.proto b/phoenix-protocol/src/main/PTable.proto
index ec0c616..6f30a91 100644
--- a/phoenix-protocol/src/main/PTable.proto
+++ b/phoenix-protocol/src/main/PTable.proto
@@ -93,4 +93,10 @@ message PTable {
   optional int64 indexDisableTimestamp = 29;
   optional bool isNamespaceMapped = 30;
   optional bytes storageScheme = 31;
+  repeated EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;
+}
+
+message EncodedColumnQualifierCounter {
+  required string familyName = 1;
+  required int32 counter = 2; 
 }


[46/52] [abbrv] phoenix git commit: Replace empty key value with unit tests passing

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java b/phoenix-core/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java
index b8b0350..4767090 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java
@@ -40,7 +40,7 @@ import org.apache.hadoop.hbase.util.Writables;
 import org.apache.hadoop.io.Writable;
 import org.apache.hadoop.io.WritableUtils;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
-import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.util.SchemaUtil;
 
 /**
  * When selecting specific columns in a SELECT query, this filter passes only selected columns
@@ -53,6 +53,8 @@ public class ColumnProjectionFilter extends FilterBase implements Writable {
     private byte[] emptyCFName;
     private Map<ImmutableBytesPtr, NavigableSet<ImmutableBytesPtr>> columnsTracker;
     private Set<byte[]> conditionOnlyCfs;
+    private boolean usesEncodedColumnNames;
+    private byte[] emptyKVQualifier;
 
     public ColumnProjectionFilter() {
 
@@ -60,10 +62,12 @@ public class ColumnProjectionFilter extends FilterBase implements Writable {
 
     public ColumnProjectionFilter(byte[] emptyCFName,
             Map<ImmutableBytesPtr, NavigableSet<ImmutableBytesPtr>> columnsTracker,
-            Set<byte[]> conditionOnlyCfs) {
+            Set<byte[]> conditionOnlyCfs, boolean usesEncodedColumnNames) {
         this.emptyCFName = emptyCFName;
         this.columnsTracker = columnsTracker;
         this.conditionOnlyCfs = conditionOnlyCfs;
+        this.usesEncodedColumnNames = usesEncodedColumnNames;
+        this.emptyKVQualifier = SchemaUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst();
     }
 
     @Override
@@ -87,6 +91,9 @@ public class ColumnProjectionFilter extends FilterBase implements Writable {
             familyMapSize--;
         }
         int conditionOnlyCfsSize = WritableUtils.readVInt(input);
+        usesEncodedColumnNames = conditionOnlyCfsSize > 0;
+        emptyKVQualifier = SchemaUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst();
+        conditionOnlyCfsSize = Math.abs(conditionOnlyCfsSize) - 1; // restore to the actual value.
         this.conditionOnlyCfs = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
         while (conditionOnlyCfsSize > 0) {
             this.conditionOnlyCfs.add(WritableUtils.readCompressedByteArray(input));
@@ -110,12 +117,13 @@ public class ColumnProjectionFilter extends FilterBase implements Writable {
                 }
             }
         }
-        // Write conditionOnlyCfs
-        WritableUtils.writeVInt(output, this.conditionOnlyCfs.size());
+        // Encode usesEncodedColumnNames in conditionOnlyCfs size.
+        WritableUtils.writeVInt(output, (this.conditionOnlyCfs.size() + 1) * (usesEncodedColumnNames ? 1 : -1));
         for (byte[] f : this.conditionOnlyCfs) {
             WritableUtils.writeCompressedByteArray(output, f);
         }
-    }
+    
+}
 
     @Override
     public byte[] toByteArray() throws IOException {
@@ -153,9 +161,9 @@ public class ColumnProjectionFilter extends FilterBase implements Writable {
         // make sure we're not holding to any of the byte[]'s
         ptr.set(HConstants.EMPTY_BYTE_ARRAY);
         if (kvs.isEmpty()) {
-            kvs.add(new KeyValue(firstKV.getRowArray(), firstKV.getRowOffset(),firstKV.getRowLength(), this.emptyCFName,
-                    0, this.emptyCFName.length, QueryConstants.EMPTY_COLUMN_BYTES, 0,
-                    QueryConstants.EMPTY_COLUMN_BYTES.length, HConstants.LATEST_TIMESTAMP, Type.Maximum, null, 0, 0));
+            kvs.add(new KeyValue(firstKV.getRowArray(), firstKV.getRowOffset(), firstKV.getRowLength(),
+                    this.emptyCFName, 0, this.emptyCFName.length, emptyKVQualifier, 0,
+                    emptyKVQualifier.length, HConstants.LATEST_TIMESTAMP, Type.Maximum, null, 0, 0));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java b/phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
index 569faa5..8d03797 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
@@ -184,7 +184,7 @@ public abstract class MultiKeyValueComparisonFilter extends BooleanExpressionFil
         ExpressionVisitor<Void> visitor = new StatelessTraverseAllExpressionVisitor<Void>() {
             @Override
             public Void visit(KeyValueColumnExpression expression) {
-                inputTuple.addColumn(expression.getColumnFamily(), expression.getColumnName());
+                inputTuple.addColumn(expression.getColumnFamily(), expression.getColumnQualifier());
                 return null;
             }
         };

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java b/phoenix-core/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java
index eaf8d35..07f7072 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java
@@ -58,7 +58,7 @@ public abstract class SingleKeyValueComparisonFilter extends BooleanExpressionFi
             @Override
             public Void visit(KeyValueColumnExpression expression) {
                 cf = expression.getColumnFamily();
-                cq = expression.getColumnName();
+                cq = expression.getColumnQualifier();
                 return null;
             }
         };

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
index 57616cb..9dfc5d3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
@@ -299,6 +299,8 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
     private int maxTrailingNulls;
     private ColumnReference dataEmptyKeyValueRef;
     private boolean rowKeyOrderOptimizable;
+    private boolean usesEncodedColumnNames;
+    private ImmutableBytesPtr emptyKeyValueQualifierPtr;
     
     private IndexMaintainer(RowKeySchema dataRowKeySchema, boolean isDataTableSalted) {
         this.dataRowKeySchema = dataRowKeySchema;
@@ -312,14 +314,19 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
         this.isMultiTenant = dataTable.isMultiTenant();
         this.viewIndexId = index.getViewIndexId() == null ? null : MetaDataUtil.getViewIndexIdDataType().toBytes(index.getViewIndexId());
         this.isLocalIndex = index.getIndexType() == IndexType.LOCAL;
-
+        /* 
+         * There is nothing to prevent new indexes on existing tables to have encoded column names.
+         * Except, due to backward compatibility reasons, we aren't able to change IndexMaintainer and the state
+         * that is serialized in it. Because of this we are forced to have the indexes inherit the
+         * storage scheme of the parent data tables. 
+         */
+        this.usesEncodedColumnNames = SchemaUtil.usesEncodedColumnNames(index);
         byte[] indexTableName = index.getPhysicalName().getBytes();
         // Use this for the nDataSaltBuckets as we need this for local indexes
         // TODO: persist nDataSaltBuckets separately, but maintain b/w compat.
         Integer nIndexSaltBuckets = isLocalIndex ? dataTable.getBucketNum() : index.getBucketNum();
         boolean indexWALDisabled = index.isWALDisabled();
         int indexPosOffset = (index.getBucketNum() == null ? 0 : 1) + (this.isMultiTenant ? 1 : 0) + (this.viewIndexId == null ? 0 : 1);
-//        int indexPosOffset = !isLocalIndex && nIndexSaltBuckets > 0 ? 1 : 0;
         int nIndexColumns = index.getColumns().size() - indexPosOffset;
         int nIndexPKColumns = index.getPKColumns().size() - indexPosOffset;
         // number of expressions that are indexed that are not present in the row key of the data table
@@ -330,7 +337,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
             String dataFamilyName = IndexUtil.getDataColumnFamilyName(indexColumnName);
             String dataColumnName = IndexUtil.getDataColumnName(indexColumnName);
             try {
-                PColumn dataColumn = dataFamilyName.equals("") ? dataTable.getColumn(dataColumnName) : dataTable.getColumnFamily(dataFamilyName).getColumn(dataColumnName);
+                PColumn dataColumn = dataFamilyName.equals("") ? dataTable.getPColumnForColumnName(dataColumnName) : dataTable.getColumnFamily(dataFamilyName).getPColumnForColumnName(dataColumnName);
                 if (SchemaUtil.isPKColumn(dataColumn)) 
                     continue;
             } catch (ColumnNotFoundException e) {
@@ -404,7 +411,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
                 throw new RuntimeException(e); // Impossible
             }
             if ( expressionIndexCompiler.getColumnRef()!=null ) {
-            	// get the column of the data table that corresponds to this index column
+            	// get the column of the data column that corresponds to this index column
 	            PColumn column = IndexUtil.getDataColumn(dataTable, indexColumn.getName().getString());
 	            boolean isPKColumn = SchemaUtil.isPKColumn(column);
 	            if (isPKColumn) {
@@ -429,7 +436,8 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
             PColumnFamily family = index.getColumnFamilies().get(i);
             for (PColumn indexColumn : family.getColumns()) {
                 PColumn column = IndexUtil.getDataColumn(dataTable, indexColumn.getName().getString());
-                this.coveredColumns.add(new ColumnReference(column.getFamilyName().getBytes(), column.getName().getBytes()));
+                byte[] cq = SchemaUtil.getColumnQualifier(column, index);
+                this.coveredColumns.add(new ColumnReference(column.getFamilyName().getBytes(), cq));
             }
         }
         this.estimatedIndexRowKeyBytes = estimateIndexRowKeyByteSize(indexColByteSize);
@@ -750,7 +758,6 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
             // same for all rows in this index)
             if (!viewConstantColumnBitSet.get(i)) {
                 int pos = rowKeyMetaData.getIndexPkPosition(i-dataPosOffset);
-                Field dataField = dataRowKeySchema.getField(i);
                 indexFields[pos] = 
                         dataRowKeySchema.getField(i);
             } 
@@ -844,9 +851,9 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
             put = new Put(indexRowKey);
             // add the keyvalue for the empty row
             put.add(kvBuilder.buildPut(new ImmutableBytesPtr(indexRowKey),
-                this.getEmptyKeyValueFamily(), QueryConstants.EMPTY_COLUMN_BYTES_PTR, ts,
+                this.getEmptyKeyValueFamily(), emptyKeyValueQualifierPtr, ts,
                 // set the value to the empty column name
-                QueryConstants.EMPTY_COLUMN_BYTES_PTR));
+                emptyKeyValueQualifierPtr));
             put.setDurability(!indexWALDisabled ? Durability.USE_DEFAULT : Durability.SKIP_WAL);
         }
         int i = 0;
@@ -1059,6 +1066,8 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
         
         if (isNewClient) {
             int numIndexedExpressions = WritableUtils.readVInt(input);
+            usesEncodedColumnNames = numIndexedExpressions > 0;
+            numIndexedExpressions = Math.abs(numIndexedExpressions) - 1;
             indexedExpressions = Lists.newArrayListWithExpectedSize(numIndexedExpressions);        
             for (int i = 0; i < numIndexedExpressions; i++) {
             	Expression expression = ExpressionType.values()[WritableUtils.readVInt(input)].newInstance();
@@ -1148,7 +1157,9 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
         WritableUtils.writeVInt(output,-emptyKeyValueCFPtr.getLength());
         output.write(emptyKeyValueCFPtr.get(),emptyKeyValueCFPtr.getOffset(), emptyKeyValueCFPtr.getLength());
         
-        WritableUtils.writeVInt(output, indexedExpressions.size());
+        // Hack to encode usesEncodedColumnNames in indexedExpressions size.
+        int indexedExpressionsSize = (indexedExpressions.size() + 1) * (usesEncodedColumnNames ? 1 : -1);
+        WritableUtils.writeVInt(output, indexedExpressionsSize);
         for (Expression expression : indexedExpressions) {
         	WritableUtils.writeVInt(output, ExpressionType.valueOf(expression).ordinal());
         	expression.write(output);
@@ -1205,10 +1216,9 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
      * Init calculated state reading/creating
      */
     private void initCachedState() {
-        dataEmptyKeyValueRef =
-                new ColumnReference(emptyKeyValueCFPtr.copyBytesIfNecessary(),
-                        QueryConstants.EMPTY_COLUMN_BYTES);
-
+        dataEmptyKeyValueRef = new ColumnReference(emptyKeyValueCFPtr.copyBytesIfNecessary(), SchemaUtil
+                .getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst());
+        emptyKeyValueQualifierPtr = new ImmutableBytesPtr(SchemaUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst());
         indexQualifiers = Lists.newArrayListWithExpectedSize(this.coveredColumns.size());
         for (ColumnReference ref : coveredColumns) {
             indexQualifiers.add(new ImmutableBytesPtr(IndexUtil.getIndexColumnName(
@@ -1222,7 +1232,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
         	KeyValueExpressionVisitor visitor = new KeyValueExpressionVisitor() {
                 @Override
                 public Void visit(KeyValueColumnExpression expression) {
-                	if (indexedColumns.add(new ColumnReference(expression.getColumnFamily(), expression.getColumnName()))) {
+                	if (indexedColumns.add(new ColumnReference(expression.getColumnFamily(), expression.getColumnQualifier()))) {
                 		indexedColumnTypes.add(expression.getDataType());
                 	}
                     return null;
@@ -1487,4 +1497,8 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
             return udfParseNodes;
         }
     }
+    
+    public byte[] getEmptyKeyValueQualifier() {
+        return emptyKeyValueQualifierPtr.copyBytes();
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
index 32dc632..6ee981a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
@@ -221,10 +221,15 @@ public class PhoenixTransactionalIndexer extends BaseRegionObserver {
                 Scan scan = new Scan();
                 // Project all mutable columns
                 for (ColumnReference ref : mutableColumns) {
+                    //TODO: samarth confirm this is ok
                     scan.addColumn(ref.getFamily(), ref.getQualifier());
                 }
+                // Indexes inherit the storage scheme of the data table which means all the indexes have the same
+                // storage scheme and empty key value qualifier.
+                byte[] emptyKeyValueQualifier = indexMaintainers.get(0).getEmptyKeyValueQualifier();
+                
                 // Project empty key value column
-                scan.addColumn(indexMaintainers.get(0).getDataEmptyKeyValueCF(), QueryConstants.EMPTY_COLUMN_BYTES);
+                scan.addColumn(indexMaintainers.get(0).getDataEmptyKeyValueCF(), emptyKeyValueQualifier);
                 ScanRanges scanRanges = ScanRanges.create(SchemaUtil.VAR_BINARY_SCHEMA, Collections.singletonList(keys), ScanUtil.SINGLE_COLUMN_SLOT_SPAN, KeyRange.EVERYTHING_RANGE, null, true, -1);
                 scanRanges.initializeScan(scan);
                 TableName tableName = env.getRegion().getRegionInfo().getTable();
@@ -262,7 +267,8 @@ public class PhoenixTransactionalIndexer extends BaseRegionObserver {
             Collection<Pair<Mutation, byte[]>> indexUpdates) throws IOException {
         if (scanner != null) {
             Result result;
-            ColumnReference emptyColRef = new ColumnReference(indexMetaData.getIndexMaintainers().get(0).getDataEmptyKeyValueCF(), QueryConstants.EMPTY_COLUMN_BYTES);
+            ColumnReference emptyColRef = new ColumnReference(indexMetaData.getIndexMaintainers().get(0)
+                    .getDataEmptyKeyValueCF(), indexMetaData.getIndexMaintainers().get(0).getEmptyKeyValueQualifier());
             // Process existing data table rows by removing the old index row and adding the new index row
             while ((result = scanner.next()) != null) {
                 Mutation m = mutations.remove(new ImmutableBytesPtr(result.getRow()));
@@ -290,7 +296,7 @@ public class PhoenixTransactionalIndexer extends BaseRegionObserver {
             // to generate point delete markers for all index rows that were added. We don't have Tephra
             // manage index rows in change sets because we don't want to be hit with the additional
             // memory hit and do not need to do conflict detection on index rows.
-            ColumnReference emptyColRef = new ColumnReference(indexMetaData.getIndexMaintainers().get(0).getDataEmptyKeyValueCF(), QueryConstants.EMPTY_COLUMN_BYTES);
+            ColumnReference emptyColRef = new ColumnReference(indexMetaData.getIndexMaintainers().get(0).getDataEmptyKeyValueCF(), indexMetaData.getIndexMaintainers().get(0).getEmptyKeyValueQualifier());
             while ((result = scanner.next()) != null) {
                 Mutation m = mutations.remove(new ImmutableBytesPtr(result.getRow()));
                 // Sort by timestamp, type, cf, cq so we can process in time batches from oldest to newest

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
index 043bd30..e743dc7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
@@ -205,7 +205,7 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
                             // Project empty key value unless the column family containing it has
                             // been projected in its entirety.
                             if (!familyMap.containsKey(ecf) || familyMap.get(ecf) != null) {
-                                scan.addColumn(ecf, QueryConstants.EMPTY_COLUMN_BYTES);
+                                scan.addColumn(ecf, SchemaUtil.getEmptyKeyValueInfo(table).getFirst());
                             }
                         }
                     }
@@ -302,6 +302,7 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
                         if (whereCol.getSecond() == null) {
                             scan.addFamily(family);                            
                         } else {
+                            //TODO: samarth confirm this
                             scan.addColumn(family, whereCol.getSecond());
                         }
                     }
@@ -326,7 +327,7 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
             // the ExplicitColumnTracker not to be used, though.
             if (!statement.isAggregate() && filteredColumnNotInProjection) {
                 ScanUtil.andFilterAtEnd(scan, new ColumnProjectionFilter(SchemaUtil.getEmptyColumnFamily(table),
-                        columnsTracker, conditionOnlyCfs));
+                        columnsTracker, conditionOnlyCfs, SchemaUtil.usesEncodedColumnNames(table)));
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index d98ebe3..f253cc9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -205,6 +205,8 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
     public static final byte[] BASE_COLUMN_COUNT_BYTES = Bytes.toBytes(BASE_COLUMN_COUNT);
     public static final String IS_ROW_TIMESTAMP = "IS_ROW_TIMESTAMP";
     public static final byte[] IS_ROW_TIMESTAMP_BYTES = Bytes.toBytes(IS_ROW_TIMESTAMP);
+    public static final String COLUMN_QUALIFIER = "COLUMN_QUALIFIER";
+    public static final byte[] COLUMN_QUALIFIER_BYTES = Bytes.toBytes(COLUMN_QUALIFIER);
 
     public static final String TABLE_FAMILY = QueryConstants.DEFAULT_COLUMN_FAMILY;
     public static final byte[] TABLE_FAMILY_BYTES = QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES;
@@ -293,6 +295,8 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
     public static final byte[] UPDATE_CACHE_FREQUENCY_BYTES = Bytes.toBytes(UPDATE_CACHE_FREQUENCY);
 
     public static final String ASYNC_CREATED_DATE = "ASYNC_CREATED_DATE";
+    public static final String STORAGE_SCHEME = "STORAGE_SCHEME";
+    public static final byte[] STORAGE_SCHEME_BYTES = Bytes.toBytes(STORAGE_SCHEME);
 
     private final PhoenixConnection connection;
     private final ResultSet emptyResultSet;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java
index 0525de9..57e1e93 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java
@@ -281,7 +281,7 @@ public abstract class AbstractBulkLoadTool extends Configured implements Tool {
         final String tableNamesAsJson = TargetTableRefFunctions.NAMES_TO_JSON.apply(tablesToBeLoaded);
         final String logicalNamesAsJson = TargetTableRefFunctions.LOGICAL_NAMES_TO_JSON.apply(tablesToBeLoaded);
 
-        job.getConfiguration().set(FormatToBytesWritableMapper.TABLE_NAMES_CONFKEY,tableNamesAsJson);
+        job.getConfiguration().set(FormatToBytesWritableMapper.PHYSICAL_TABLE_NAMES_CONFKEY,tableNamesAsJson);
         job.getConfiguration().set(FormatToBytesWritableMapper.LOGICAL_NAMES_CONFKEY,logicalNamesAsJson);
 
         // give subclasses their hook

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java
index 1211b83..0a28f38 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.TreeMap;
+
 import javax.annotation.Nullable;
 
 import org.apache.hadoop.conf.Configuration;
@@ -44,12 +45,12 @@ import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.mapreduce.bulkload.TableRowkeyPair;
 import org.apache.phoenix.mapreduce.bulkload.TargetTableRefFunctions;
 import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
-import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.util.ColumnInfo;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.UpsertExecutor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -86,7 +87,7 @@ public abstract class FormatToBytesWritableMapper<RECORD> extends Mapper<LongWri
     public static final String IGNORE_INVALID_ROW_CONFKEY = "phoenix.mapreduce.import.ignoreinvalidrow";
 
     /** Configuration key for the table names */
-    public static final String TABLE_NAMES_CONFKEY = "phoenix.mapreduce.import.tablenames";
+    public static final String PHYSICAL_TABLE_NAMES_CONFKEY = "phoenix.mapreduce.import.tablenames";
 
     /** Configuration key for the table logical names */
     public static final String LOGICAL_NAMES_CONFKEY = "phoenix.mapreduce.import.logicalnames";
@@ -101,8 +102,9 @@ public abstract class FormatToBytesWritableMapper<RECORD> extends Mapper<LongWri
     protected PhoenixConnection conn;
     protected UpsertExecutor<RECORD, ?> upsertExecutor;
     protected ImportPreUpsertKeyValueProcessor preUpdateProcessor;
-    protected List<String> tableNames;
-    protected List<String> logicalNames;
+    //TODO: merge physicalTableNames and logicalNames into some associative data structure since they are 1:1.
+    protected List<String> physicalTableNames;
+    protected List<Pair<String, byte[]>> logicalTables; // List of pairs of a table's logical name and the empty key value's qualifier used for it.
     protected MapperUpsertListener<RECORD> upsertListener;
 
     /*
@@ -130,11 +132,14 @@ public abstract class FormatToBytesWritableMapper<RECORD> extends Mapper<LongWri
             // that auto-commit is not turned on
             conn.setAutoCommit(false);
 
-            final String tableNamesConf = conf.get(TABLE_NAMES_CONFKEY);
+            final String tableNamesConf = conf.get(PHYSICAL_TABLE_NAMES_CONFKEY);
             final String logicalNamesConf = conf.get(LOGICAL_NAMES_CONFKEY);
-            tableNames = TargetTableRefFunctions.NAMES_FROM_JSON.apply(tableNamesConf);
-            logicalNames = TargetTableRefFunctions.NAMES_FROM_JSON.apply(logicalNamesConf);
-
+            physicalTableNames = TargetTableRefFunctions.NAMES_FROM_JSON.apply(tableNamesConf);
+            List<String> logicalTableNames = TargetTableRefFunctions.NAMES_FROM_JSON.apply(logicalNamesConf);
+            for (String logicalTableName : logicalTableNames) {
+                PTable table = PhoenixRuntime.getTable(conn, logicalTableName);
+                logicalTables.add(new Pair<>(logicalTableName, SchemaUtil.getEmptyKeyValueInfo(table).getFirst()));
+            }
             columnIndexes = initColumnIndexes();
         } catch (SQLException | ClassNotFoundException e) {
             throw new RuntimeException(e);
@@ -146,7 +151,6 @@ public abstract class FormatToBytesWritableMapper<RECORD> extends Mapper<LongWri
         preUpdateProcessor = PhoenixConfigurationUtil.loadPreUpsertProcessor(conf);
     }
 
-    @SuppressWarnings("deprecation")
     @Override
     protected void map(LongWritable key, Text value, Context context) throws IOException,
             InterruptedException {
@@ -176,8 +180,8 @@ public abstract class FormatToBytesWritableMapper<RECORD> extends Mapper<LongWri
                 keyValueList = preUpdateProcessor.preUpsert(kvPair.getFirst(), keyValueList);
                 byte[] first = kvPair.getFirst();
                 // Create a list of KV for each table
-                for (int i = 0; i < tableNames.size(); i++) {
-                    if (Bytes.compareTo(Bytes.toBytes(tableNames.get(i)), first) == 0) {
+                for (int i = 0; i < physicalTableNames.size(); i++) {
+                    if (Bytes.compareTo(Bytes.toBytes(physicalTableNames.get(i)), first) == 0) {
                         if (!map.containsKey(i)) {
                             map.put(i, new ArrayList<KeyValue>());
                         }
@@ -204,8 +208,8 @@ public abstract class FormatToBytesWritableMapper<RECORD> extends Mapper<LongWri
     private List<Map<byte[], Map<byte[], Integer>>> initColumnIndexes() throws SQLException {
         List<Map<byte[], Map<byte[], Integer>>> tableMap = new ArrayList<>();
         int tableIndex;
-        for (tableIndex = 0; tableIndex < tableNames.size(); tableIndex++) {
-            PTable table = PhoenixRuntime.getTable(conn, logicalNames.get(tableIndex));
+        for (tableIndex = 0; tableIndex < physicalTableNames.size(); tableIndex++) {
+            PTable table = PhoenixRuntime.getTable(conn, logicalTables.get(tableIndex).getFirst());
             Map<byte[], Map<byte[], Integer>> columnMap = new TreeMap<>(Bytes.BYTES_COMPARATOR);
             List<PColumn> cls = table.getColumns();
             for (int i = 0; i < cls.size(); i++) {
@@ -250,7 +254,7 @@ public abstract class FormatToBytesWritableMapper<RECORD> extends Mapper<LongWri
      * Collect all column values for the same rowKey
      *
      * @param context    Current mapper context
-     * @param tableIndex Table index in tableNames list
+     * @param tableIndex Table index in tableNames or logicalTables list
      * @param lkv        List of KV values that will be combined in a single ImmutableBytesWritable
      * @throws IOException
      * @throws InterruptedException
@@ -261,12 +265,14 @@ public abstract class FormatToBytesWritableMapper<RECORD> extends Mapper<LongWri
         ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
         DataOutputStream outputStream = new DataOutputStream(bos);
         ImmutableBytesWritable outputKey = new ImmutableBytesWritable();
+        String tableName = physicalTableNames.get(tableIndex);
+        Pair<String, byte[]> logicalTable = logicalTables.get(tableIndex);
         if (!lkv.isEmpty()) {
             // All Key Values for the same row are supposed to be the same, so init rowKey only once
             Cell first = lkv.get(0);
             outputKey.set(first.getRowArray(), first.getRowOffset(), first.getRowLength());
             for (KeyValue cell : lkv) {
-                if (isEmptyCell(cell)) {
+                if (isEmptyCell(cell, logicalTable.getSecond())) {
                     continue;
                 }
                 int i = findIndex(tableIndex, cell);
@@ -281,13 +287,13 @@ public abstract class FormatToBytesWritableMapper<RECORD> extends Mapper<LongWri
         }
         ImmutableBytesWritable aggregatedArray = new ImmutableBytesWritable(bos.toByteArray());
         outputStream.close();
-        context.write(new TableRowkeyPair(tableNames.get(tableIndex), outputKey), aggregatedArray);
+        context.write(new TableRowkeyPair(tableName, outputKey), aggregatedArray);
     }
 
-    protected boolean isEmptyCell(KeyValue cell) {
+    protected boolean isEmptyCell(KeyValue cell, byte[] emptyKVQualifier) {
         if (Bytes.compareTo(cell.getQualifierArray(), cell.getQualifierOffset(),
-                cell.getQualifierLength(), QueryConstants.EMPTY_COLUMN_BYTES, 0,
-                QueryConstants.EMPTY_COLUMN_BYTES.length) != 0)
+                cell.getQualifierLength(), emptyKVQualifier, 0,
+                emptyKVQualifier.length) != 0)
             return false;
         else
             return true;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
index e906431..04fe959 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
@@ -80,7 +80,7 @@ public class FormatToKeyValueReducer
         try {
             PhoenixConnection conn = (PhoenixConnection) QueryUtil.getConnection(clientInfos, conf);
             builder = conn.getKeyValueBuilder();
-            final String tableNamesConf = conf.get(FormatToBytesWritableMapper.TABLE_NAMES_CONFKEY);
+            final String tableNamesConf = conf.get(FormatToBytesWritableMapper.PHYSICAL_TABLE_NAMES_CONFKEY);
             final String logicalNamesConf = conf.get(FormatToBytesWritableMapper.LOGICAL_NAMES_CONFKEY);
             tableNames = TargetTableRefFunctions.NAMES_FROM_JSON.apply(tableNamesConf);
             logicalNames = TargetTableRefFunctions.NAMES_FROM_JSON.apply(logicalNamesConf);
@@ -98,16 +98,16 @@ public class FormatToKeyValueReducer
             PTable table = PhoenixRuntime.getTable(conn, tableName);
             emptyFamilyName.add(SchemaUtil.getEmptyColumnFamilyPtr(table));
             List<PColumn> cls = table.getColumns();
-            List<Pair<byte[], byte[]>> list = new ArrayList(cls.size());
+            List<Pair<byte[], byte[]>> list = new ArrayList<>(cls.size());
             for (int i = 0; i < cls.size(); i++) {
                 PColumn c = cls.get(i);
-                if (c.getFamilyName() == null) {
+                if (SchemaUtil.isPKColumn(c)) {
                     list.add(null); // Skip PK column
                     continue;
                 }
                 byte[] family = c.getFamilyName().getBytes();
-                byte[] name = c.getName().getBytes();
-                list.add(new Pair(family, name));
+                byte[] name = SchemaUtil.getColumnQualifier(c, table);
+                list.add(new Pair<>(family, name));
             }
             columnIndexes.add(list);
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index dec11af..d0c7769 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -575,6 +575,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         }
     }
     
+    @Override
     public PMetaData updateResolvedTimestamp(PTable table, long resolvedTime) throws SQLException {
     	synchronized (latestMetaDataLock) {
             throwConnectionClosedIfNullMetaData();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
index 36aa8cd..f8f6672 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
@@ -29,6 +29,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CURRENT_VALUE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CYCLE_FLAG;
@@ -83,6 +84,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SOURCE_DATA_TYPE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SQL_DATA_TYPE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SQL_DATETIME_SUB;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.START_WITH;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORAGE_SCHEME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORE_NULLS;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE;
@@ -116,6 +118,7 @@ import org.apache.phoenix.schema.MetaDataSplitPolicy;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.util.ByteUtil;
 
 
@@ -183,11 +186,18 @@ public interface QueryConstants {
     public static final byte[] EMPTY_COLUMN_BYTES = Bytes.toBytes(EMPTY_COLUMN_NAME);
     public static final ImmutableBytesPtr EMPTY_COLUMN_BYTES_PTR = new ImmutableBytesPtr(
             EMPTY_COLUMN_BYTES);
+    public static final Integer ENCODED_EMPTY_COLUMN_NAME = 0;
+    public static final byte[] ENCODED_EMPTY_COLUMN_BYTES = PInteger.INSTANCE.toBytes(ENCODED_EMPTY_COLUMN_NAME);
+    public static final ImmutableBytesPtr ENCODED_EMPTY_COLUMN_BYTES_PTR = new ImmutableBytesPtr(
+            ENCODED_EMPTY_COLUMN_BYTES);
     public final static String EMPTY_COLUMN_VALUE = "x";
     public final static byte[] EMPTY_COLUMN_VALUE_BYTES = Bytes.toBytes(EMPTY_COLUMN_VALUE);
     public static final ImmutableBytesPtr EMPTY_COLUMN_VALUE_BYTES_PTR = new ImmutableBytesPtr(
             EMPTY_COLUMN_VALUE_BYTES);
-
+    public static final String ENCODED_EMPTY_COLUMN_VALUE = EMPTY_COLUMN_VALUE;
+    public final static byte[] ENCODED_EMPTY_COLUMN_VALUE_BYTES = Bytes.toBytes(EMPTY_COLUMN_VALUE);
+    public static final ImmutableBytesPtr ENCODED_EMPTY_COLUMN_VALUE_BYTES_PTR = new ImmutableBytesPtr(
+            ENCODED_EMPTY_COLUMN_VALUE_BYTES);
     public static final String DEFAULT_COLUMN_FAMILY = "0";
     public static final byte[] DEFAULT_COLUMN_FAMILY_BYTES = Bytes.toBytes(DEFAULT_COLUMN_FAMILY);
     public static final ImmutableBytesPtr DEFAULT_COLUMN_FAMILY_BYTES_PTR = new ImmutableBytesPtr(
@@ -267,6 +277,8 @@ public interface QueryConstants {
             TRANSACTIONAL + " BOOLEAN," +
             UPDATE_CACHE_FREQUENCY + " BIGINT," +
             IS_NAMESPACE_MAPPED + " BOOLEAN," +
+            COLUMN_QUALIFIER + " INTEGER," +
+            STORAGE_SCHEME + " TINYINT, " + 
             "CONSTRAINT " + SYSTEM_TABLE_PK_NAME + " PRIMARY KEY (" + TENANT_ID + ","
             + TABLE_SCHEM + "," + TABLE_NAME + "," + COLUMN_NAME + "," + COLUMN_FAMILY + "))\n" +
             HConstants.VERSIONS + "=" + MetaDataProtocol.DEFAULT_MAX_META_DATA_VERSIONS + ",\n" +

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
index 76f6218..d7c6456 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
@@ -45,7 +45,7 @@ public class ColumnRef {
     }
 
     public ColumnRef(TableRef tableRef, String familyName, String columnName) throws MetaDataEntityNotFoundException {
-        this(tableRef, tableRef.getTable().getColumnFamily(familyName).getColumn(columnName).getPosition());
+        this(tableRef, tableRef.getTable().getColumnFamily(familyName).getPColumnForColumnName(columnName).getPosition());
     }
 
     public ColumnRef(TableRef tableRef, int columnPosition) {
@@ -109,7 +109,7 @@ public class ColumnRef {
         	return new ProjectedColumnExpression(column, table, displayName);
         }
        
-        return new KeyValueColumnExpression(column, displayName);
+        return new KeyValueColumnExpression(column, displayName, SchemaUtil.usesEncodedColumnNames(table));
     }
 
     public ColumnRef cloneAtTimestamp(long timestamp) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
index a60229e..65e362c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
@@ -90,4 +90,9 @@ public class DelegateColumn extends DelegateDatum implements PColumn {
 	public boolean isDynamic() {
 		return getDelegate().isDynamic();
 	}
+
+    @Override
+    public Integer getColumnQualifier() {
+        return getDelegate().getColumnQualifier();
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
index 7b9af43..3fd95b6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
@@ -97,8 +97,8 @@ public class DelegateTable implements PTable {
     }
 
     @Override
-    public PColumn getColumn(String name) throws ColumnNotFoundException, AmbiguousColumnException {
-        return delegate.getColumn(name);
+    public PColumn getPColumnForColumnName(String name) throws ColumnNotFoundException, AmbiguousColumnException {
+        return delegate.getPColumnForColumnName(name);
     }
 
     @Override
@@ -276,4 +276,14 @@ public class DelegateTable implements PTable {
     public boolean isNamespaceMapped() {
         return delegate.isNamespaceMapped();
     }
+    
+    @Override
+    public StorageScheme getStorageScheme() {
+        return delegate.getStorageScheme();
+    }
+
+    @Override
+    public PColumn getPColumnForColumnQualifier(byte[] cq) throws ColumnNotFoundException, AmbiguousColumnException {
+        return delegate.getPColumnForColumnQualifier(cq);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index ac40554..4893a79 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -33,6 +33,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TYPE;
@@ -66,6 +67,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.PK_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.RETURN_TYPE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SALT_BUCKETS;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SORT_ORDER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORAGE_SCHEME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORE_NULLS;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE;
@@ -187,6 +189,7 @@ import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.query.QueryServicesOptions;
 import org.apache.phoenix.schema.PTable.IndexType;
 import org.apache.phoenix.schema.PTable.LinkType;
+import org.apache.phoenix.schema.PTable.StorageScheme;
 import org.apache.phoenix.schema.PTable.ViewType;
 import org.apache.phoenix.schema.stats.PTableStats;
 import org.apache.phoenix.schema.types.PDataType;
@@ -256,8 +259,9 @@ public class MetaDataClient {
             BASE_COLUMN_COUNT + "," +
             TRANSACTIONAL + "," +
             UPDATE_CACHE_FREQUENCY + "," +
-            IS_NAMESPACE_MAPPED +
-            ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)";
+            IS_NAMESPACE_MAPPED + "," +
+            STORAGE_SCHEME + 
+            ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
 
     private static final String CREATE_SCHEMA = "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE
             + "\"( " + TABLE_SCHEM + "," + TABLE_NAME + ") VALUES (?,?)";
@@ -333,8 +337,9 @@ public class MetaDataClient {
         PK_NAME + "," +  // write this both in the column and table rows for access by metadata APIs
         KEY_SEQ + "," +
         COLUMN_DEF + "," +
-        IS_ROW_TIMESTAMP + 
-        ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+        COLUMN_QUALIFIER + "," +
+        IS_ROW_TIMESTAMP +
+        ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
     private static final String INSERT_COLUMN_ALTER_TABLE =
             "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
             TENANT_ID + "," +
@@ -354,8 +359,9 @@ public class MetaDataClient {
             IS_VIEW_REFERENCED + "," +
             PK_NAME + "," +  // write this both in the column and table rows for access by metadata APIs
             KEY_SEQ + "," +
-            COLUMN_DEF +
-            ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+            COLUMN_DEF + ", " +
+            COLUMN_QUALIFIER +
+            ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
     private static final String UPDATE_COLUMN_POSITION =
         "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\" ( " +
         TENANT_ID + "," +
@@ -705,10 +711,10 @@ public class MetaDataClient {
                     byte[] cf= colRef.getFamily();
                     byte[] cq= colRef.getQualifier();
                     if (cf!=null) {
-                        view.getColumnFamily(cf).getColumn(cq);
+                        view.getColumnFamily(cf).getPColumnForColumnQualifier(cq);
                     }
                     else {
-                        view.getColumn( Bytes.toString(cq));
+                        view.getPColumnForColumnQualifier(cq);
                     }
                 } catch (ColumnNotFoundException e) { // Ignore this index and continue with others
                     containsAllReqdCols = false;
@@ -724,7 +730,7 @@ public class MetaDataClient {
                         // but the WHERE clause for the view statement (which is added to the index below)
                         // would fail to compile.
                         String indexColumnName = IndexUtil.getIndexColumnName(col);
-                        index.getColumn(indexColumnName);
+                        index.getPColumnForColumnName(indexColumnName);
                     } catch (ColumnNotFoundException e) { // Ignore this index and continue with others
                         containsAllReqdCols = false;
                         break;
@@ -782,8 +788,13 @@ public class MetaDataClient {
         } else {
             colUpsert.setString(18, column.getExpressionStr());
         }
-        if (colUpsert.getParameterMetaData().getParameterCount() > 18) {
-            colUpsert.setBoolean(19, column.isRowTimestamp());
+        if (column.getColumnQualifier() == null) {
+            colUpsert.setNull(19, Types.INTEGER);
+        } else {
+            colUpsert.setInt(19, column.getColumnQualifier());
+        }
+        if (colUpsert.getParameterMetaData().getParameterCount() > 19) {
+            colUpsert.setBoolean(20, column.isRowTimestamp());
         }
         colUpsert.execute();
     }
@@ -802,7 +813,7 @@ public class MetaDataClient {
         argUpsert.execute();
     }
 
-    private PColumn newColumn(int position, ColumnDef def, PrimaryKeyConstraint pkConstraint, String defaultColumnFamily, boolean addingToPK) throws SQLException {
+    private PColumn newColumn(int position, ColumnDef def, PrimaryKeyConstraint pkConstraint, String defaultColumnFamily, boolean addingToPK, Map<String, Integer> nextColumnQualifiers) throws SQLException {
         try {
             ColumnName columnDefName = def.getColumnDefName();
             SortOrder sortOrder = def.getSortOrder();
@@ -850,15 +861,23 @@ public class MetaDataClient {
                 }
                 isNull = false;
             }
-
+            Integer columnQualifier = null;
+            if (!isPK && nextColumnQualifiers != null) {
+                columnQualifier = nextColumnQualifiers.get(familyName.getString());
+                if (columnQualifier == null) {
+                    // We use columnQualifier 0 for the special empty key value.
+                    columnQualifier = 1;
+                }
+                nextColumnQualifiers.put(familyName.toString(), columnQualifier + 1);
+            }
             PColumn column = new PColumnImpl(PNameFactory.newName(columnName), familyName, def.getDataType(),
-                    def.getMaxLength(), def.getScale(), isNull, position, sortOrder, def.getArraySize(), null, false, def.getExpression(), isRowTimestamp, false);
+                    def.getMaxLength(), def.getScale(), isNull, position, sortOrder, def.getArraySize(), null, false, def.getExpression(), isRowTimestamp, false, columnQualifier);
             return column;
         } catch (IllegalArgumentException e) { // Based on precondition check in constructor
             throw new SQLException(e);
         }
     }
-
+    
     public MutationState createTable(CreateTableStatement statement, byte[][] splits, PTable parent, String viewStatement, ViewType viewType, byte[][] viewColumnConstants, BitSet isViewColumnReferenced) throws SQLException {
         PTable table = createTableInternal(statement, splits, parent, viewStatement, viewType, viewColumnConstants, isViewColumnReferenced, null, null, null);
         if (table == null || table.getType() == PTableType.VIEW || table.isTransactional()) {
@@ -1727,7 +1746,7 @@ public class MetaDataClient {
                 .build().buildException();
             }
             // can't create a transactional table if it has a row timestamp column
-            if (pkConstraint.getNumColumnsWithRowTimestamp()>0 && transactional) {
+            if (pkConstraint.getNumColumnsWithRowTimestamp() > 0 && transactional) {
                 throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_CREATE_TXN_TABLE_WITH_ROW_TIMESTAMP)
                 .setSchemaName(schemaName).setTableName(tableName)
                 .build().buildException();
@@ -1888,6 +1907,39 @@ public class MetaDataClient {
             int pkPositionOffset = pkColumns.size();
             int position = positionOffset;
             
+            StorageScheme storageScheme = null;
+            Map<String, Integer> nextColumnQualifiers = null; // this would be null for tables created before phoenix 4.8.
+            if (SchemaUtil.isSystemTable(Bytes.toBytes(SchemaUtil.getTableName(schemaName, tableName)))) {
+                // System tables have hard-coded column qualifiers. So we can't use column encoding for them.
+                storageScheme = StorageScheme.NON_ENCODED_COLUMN_NAMES;
+            } else if (parent != null && tableType == PTableType.VIEW) {
+                // We can't control what column qualifiers are used in HTable mapped to Phoenix views. So
+                // we are not able to encode column names.
+                if (viewType != null && viewType == MAPPED) {
+                    storageScheme = StorageScheme.NON_ENCODED_COLUMN_NAMES;
+                } else {
+                    // for regular phoenix views, use the storage scheme of the parent since they all share the parent's
+                    // HTable.
+                    storageScheme = parent.getStorageScheme();
+                    if (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES) {
+                        nextColumnQualifiers  = SchemaUtil.getNextColumnQualifiers(parent);
+                    }
+                }
+            } else if (parent != null && tableType == PTableType.INDEX) {
+                // New indexes on existing tables can have encoded column names. But unfortunately, due to 
+                // backward compatibility reasons, we aren't able to change IndexMaintainer and the state
+                // that is serialized in it. Because of this we are forced to have the indexes inherit the
+                // storage scheme of the parent data tables.
+                storageScheme = parent.getStorageScheme();
+                if (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES) {
+                    nextColumnQualifiers  = SchemaUtil.getNextColumnQualifiers(parent);
+                }
+            } else {
+                // we always attempt to create tables with encoded column names.
+                storageScheme = StorageScheme.ENCODED_COLUMN_NAMES;
+                nextColumnQualifiers = Maps.newHashMapWithExpectedSize(colDefs.size() - pkColumns.size());
+            }
+            
             for (ColumnDef colDef : colDefs) {
                 rowTimeStampColumnAlreadyFound = checkAndValidateRowTimestampCol(colDef, pkConstraint, rowTimeStampColumnAlreadyFound, tableType);
                 if (colDef.isPK()) { // i.e. the column is declared as CREATE TABLE COLNAME DATATYPE PRIMARY KEY...
@@ -1906,7 +1958,7 @@ public class MetaDataClient {
                                 .setColumnName(colDef.getColumnDefName().getColumnName()).build().buildException();
                     }
                 }
-                PColumn column = newColumn(position++, colDef, pkConstraint, defaultFamilyName, false);
+                PColumn column = newColumn(position++, colDef, pkConstraint, defaultFamilyName, false, nextColumnQualifiers);
                 if (SchemaUtil.isPKColumn(column)) {
                     // TODO: remove this constraint?
                     if (pkColumnsIterator.hasNext() && !column.getName().getString().equals(pkColumnsIterator.next().getFirst().getColumnName())) {
@@ -2017,13 +2069,14 @@ public class MetaDataClient {
             if (SchemaUtil.isMetaTable(schemaName,tableName)) {
                 // TODO: what about stats for system catalog?
                 PName newSchemaName = PNameFactory.newName(schemaName);
+                // Column names and qualifiers and hardcoded for system tables.
                 PTable table = PTableImpl.makePTable(tenantId,newSchemaName, PNameFactory.newName(tableName), tableType,
                         null, MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM,
                         PNameFactory.newName(QueryConstants.SYSTEM_TABLE_PK_NAME), null, columns, null, null,
                         Collections.<PTable>emptyList(), isImmutableRows,
                         Collections.<PName>emptyList(), defaultFamilyName == null ? null :
                                 PNameFactory.newName(defaultFamilyName), null,
-                        Boolean.TRUE.equals(disableWAL), false, false, null, indexId, indexType, true, false, 0, 0L, isNamespaceMapped);
+                        Boolean.TRUE.equals(disableWAL), false, false, null, indexId, indexType, true, false, 0, 0L, isNamespaceMapped, StorageScheme.NON_ENCODED_COLUMN_NAMES);
                 connection.addTable(table, MetaDataProtocol.MIN_TABLE_TIMESTAMP);
             } else if (tableType == PTableType.INDEX && indexId == null) {
                 if (tableProps.get(HTableDescriptor.MAX_FILESIZE) == null) {
@@ -2083,7 +2136,6 @@ public class MetaDataClient {
                 tableMetaData.addAll(connection.getMutationState().toMutations(timestamp).next().getSecond());
                 connection.rollback();
             }
-
             String dataTableName = parent == null || tableType == PTableType.VIEW ? null : parent.getTableName().getString();
             PIndexState indexState = parent == null || tableType == PTableType.VIEW  ? null : PIndexState.BUILDING;
             PreparedStatement tableUpsert = connection.prepareStatement(CREATE_TABLE);
@@ -2130,6 +2182,7 @@ public class MetaDataClient {
             tableUpsert.setBoolean(21, transactional);
             tableUpsert.setLong(22, updateCacheFrequency);
             tableUpsert.setBoolean(23, isNamespaceMapped);
+            tableUpsert.setByte(24, storageScheme.getSerializedValue()); //TODO: samarth should there be a null check here?
             tableUpsert.execute();
 
             if (asyncCreatedDate != null) {
@@ -2194,7 +2247,8 @@ public class MetaDataClient {
                         PTable.INITIAL_SEQ_NUM, pkName == null ? null : PNameFactory.newName(pkName), saltBucketNum, columns,
                         dataTableName == null ? null : newSchemaName, dataTableName == null ? null : PNameFactory.newName(dataTableName), Collections.<PTable>emptyList(), isImmutableRows,
                         physicalNames, defaultFamilyName == null ? null : PNameFactory.newName(defaultFamilyName), viewStatement, Boolean.TRUE.equals(disableWAL), multiTenant, storeNulls, viewType,
-                        indexId, indexType, rowKeyOrderOptimizable, transactional, updateCacheFrequency, 0L, isNamespaceMapped);
+                        indexId, indexType, rowKeyOrderOptimizable, transactional, updateCacheFrequency, 0L, isNamespaceMapped, storageScheme);
+                        
                 result = new MetaDataMutationResult(code, result.getMutationTime(), table, true);
                 addTableToCache(result);
                 return table;
@@ -2753,6 +2807,7 @@ public class MetaDataClient {
                 List<PColumn> columns = Lists.newArrayListWithExpectedSize(columnDefs.size());
                 Set<String> colFamiliesForPColumnsToBeAdded = new LinkedHashSet<>();
                 Set<String> families = new LinkedHashSet<>();
+                Map<String, Integer> nextColumnQualifiers = SchemaUtil.getNextColumnQualifiers(table);
                 if (columnDefs.size() > 0 ) {
                     try (PreparedStatement colUpsert = connection.prepareStatement(INSERT_COLUMN_ALTER_TABLE)) {
                         short nextKeySeq = SchemaUtil.getMaxKeySeq(table);
@@ -2773,7 +2828,7 @@ public class MetaDataClient {
                                 throw new SQLExceptionInfo.Builder(SQLExceptionCode.ROWTIMESTAMP_CREATE_ONLY)
                                 .setColumnName(colDef.getColumnDefName().getColumnName()).build().buildException();
                             }
-                            PColumn column = newColumn(position++, colDef, PrimaryKeyConstraint.EMPTY, table.getDefaultFamilyName() == null ? null : table.getDefaultFamilyName().getString(), true);
+                            PColumn column = newColumn(position++, colDef, PrimaryKeyConstraint.EMPTY, table.getDefaultFamilyName() == null ? null : table.getDefaultFamilyName().getString(), true, nextColumnQualifiers);
                             columns.add(column);
                             String pkName = null;
                             Short keySeq = null;
@@ -2811,7 +2866,7 @@ public class MetaDataClient {
                                         ColumnName indexColName = ColumnName.caseSensitiveColumnName(IndexUtil.getIndexColumnName(null, colDef.getColumnDefName().getColumnName()));
                                         Expression expression = new RowKeyColumnExpression(columns.get(i), new RowKeyValueAccessor(pkColumns, ++pkSlotPosition));
                                         ColumnDef indexColDef = FACTORY.columnDef(indexColName, indexColDataType.getSqlTypeName(), colDef.isNull(), colDef.getMaxLength(), colDef.getScale(), true, colDef.getSortOrder(), expression.toString(), colDef.isRowTimestamp());
-                                        PColumn indexColumn = newColumn(indexPosition++, indexColDef, PrimaryKeyConstraint.EMPTY, null, true);
+                                        PColumn indexColumn = newColumn(indexPosition++, indexColDef, PrimaryKeyConstraint.EMPTY, null, true, nextColumnQualifiers);
                                         addColumnMutation(schemaName, index.getTableName().getString(), indexColumn, colUpsert, index.getParentTableName().getString(), index.getPKName() == null ? null : index.getPKName().getString(), ++nextIndexKeySeq, index.getBucketNum() != null);
                                     }
                                 }
@@ -3090,7 +3145,7 @@ public class MetaDataClient {
                         } 
                         else if (coveredColumns.contains(columnToDropRef)) {
                             String indexColumnName = IndexUtil.getIndexColumnName(columnToDrop);
-                            PColumn indexColumn = index.getColumn(indexColumnName);
+                            PColumn indexColumn = index.getPColumnForColumnName(indexColumnName);
                             indexColumnsToDrop.add(indexColumn);
                             // add the index column to be dropped so that we actually delete the column values
                             columnsToDrop.add(new ColumnRef(new TableRef(index), indexColumn.getPosition()));
@@ -3180,7 +3235,7 @@ public class MetaDataClient {
                                         sharedTableState.getSchemaName(), sharedTableState.getTableName(), ts,
                                         table.getColumnFamilies(), sharedTableState.getColumns(),
                                         sharedTableState.getPhysicalNames(), sharedTableState.getViewIndexId(),
-                                        table.isMultiTenant(), table.isNamespaceMapped());
+                                        table.isMultiTenant(), table.isNamespaceMapped(), table.getStorageScheme());
                                 TableRef indexTableRef = new TableRef(viewIndexTable);
                                 PName indexTableTenantId = sharedTableState.getTenantId();
                                 if (indexTableTenantId==null) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
index 0f5fa44..b63c97b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
@@ -27,7 +27,7 @@ package org.apache.phoenix.schema;
 public interface PColumn extends PDatum {
 
     /**
-     * @return the name of the column qualifier
+     * @return the name of the column
      */
     PName getName();
 
@@ -60,4 +60,9 @@ public interface PColumn extends PDatum {
     boolean isRowTimestamp();
     
     boolean isDynamic();
+    
+    /**
+     * @return name of the HBase column qualifier
+     */
+    Integer getColumnQualifier();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamily.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamily.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamily.java
index 24da14d..c4c383e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamily.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamily.java
@@ -39,16 +39,22 @@ public interface PColumnFamily {
     Collection<PColumn> getColumns();
     
     /**
-     * @return The PColumn for the specified column qualifier.
+     * @return The PColumn for the specified column name.
      * @throws ColumnNotFoundException if the column cannot be found
      */
-    PColumn getColumn(byte[] qualifier) throws ColumnNotFoundException;
+    PColumn getPColumnForColumnNameBytes(byte[] columnNameBytes) throws ColumnNotFoundException;
     
     /**
-     * @return The PColumn for the specified column qualifier.
+     * @return The PColumn for the specified column name.
      * @throws ColumnNotFoundException if the column cannot be found
      */
-    PColumn getColumn(String name) throws ColumnNotFoundException;
+    PColumn getPColumnForColumnName(String columnName) throws ColumnNotFoundException;
     
     int getEstimatedSize();
+    
+    /**
+     * @return The PColumn for the specified column qualifier.
+     * @throws ColumnNotFoundException if the column cannot be found
+     */
+    PColumn getPColumnForColumnQualifier(byte[] cq) throws ColumnNotFoundException;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
index 2e29656..a3d855b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
@@ -21,6 +21,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.SizedUtil;
 
 import com.google.common.base.Preconditions;
@@ -31,8 +32,9 @@ import com.google.common.collect.ImmutableSortedMap;
 public class PColumnFamilyImpl implements PColumnFamily {
     private final PName name;
     private final List<PColumn> columns;
-    private final Map<String, PColumn> columnByString;
-    private final Map<byte[], PColumn> columnByBytes;
+    private final Map<String, PColumn> columnNamesByStrings;
+    private final Map<byte[], PColumn> columnNamesByBytes;
+    private final Map<byte[], PColumn> columnQualifiersByBytes;
     private final int estimatedSize;
 
     @Override
@@ -40,22 +42,28 @@ public class PColumnFamilyImpl implements PColumnFamily {
         return estimatedSize;
     }
     
-    public PColumnFamilyImpl(PName name, List<PColumn> columns) {
+    public PColumnFamilyImpl(PName name, List<PColumn> columns, boolean useEncodedColumnNames) {
         Preconditions.checkNotNull(name);
         // Include guidePosts also in estimating the size
         long estimatedSize = SizedUtil.OBJECT_SIZE + SizedUtil.POINTER_SIZE * 5 + SizedUtil.INT_SIZE + name.getEstimatedSize() +
                 SizedUtil.sizeOfMap(columns.size()) * 2 + SizedUtil.sizeOfArrayList(columns.size());
         this.name = name;
         this.columns = ImmutableList.copyOf(columns);
-        ImmutableMap.Builder<String, PColumn> columnByStringBuilder = ImmutableMap.builder();
-        ImmutableSortedMap.Builder<byte[], PColumn> columnByBytesBuilder = ImmutableSortedMap.orderedBy(Bytes.BYTES_COMPARATOR);
+        ImmutableMap.Builder<String, PColumn> columnNamesByStringBuilder = ImmutableMap.builder();
+        ImmutableSortedMap.Builder<byte[], PColumn> columnNamesByBytesBuilder = ImmutableSortedMap.orderedBy(Bytes.BYTES_COMPARATOR);
+        ImmutableSortedMap.Builder<byte[], PColumn> columnQualifiersByBytesBuilder = ImmutableSortedMap.orderedBy(Bytes.BYTES_COMPARATOR);
         for (PColumn column : columns) {
             estimatedSize += column.getEstimatedSize();
-            columnByBytesBuilder.put(column.getName().getBytes(), column);
-            columnByStringBuilder.put(column.getName().getString(), column);
+            columnNamesByBytesBuilder.put(column.getName().getBytes(), column);
+            columnNamesByStringBuilder.put(column.getName().getString(), column);
+            // TODO: samarth fix this. projected columns have column family for pk columns which messes up with checks.
+            if (!useEncodedColumnNames || (useEncodedColumnNames && !(column.getColumnQualifier() == null))) {
+                columnQualifiersByBytesBuilder.put(SchemaUtil.getColumnQualifier(column, useEncodedColumnNames), column);
+            }
         }
-        this.columnByBytes = columnByBytesBuilder.build();
-        this.columnByString = columnByStringBuilder.build();
+        this.columnNamesByBytes = columnNamesByBytesBuilder.build();
+        this.columnNamesByStrings = columnNamesByStringBuilder.build();
+        this.columnQualifiersByBytes = useEncodedColumnNames ? columnQualifiersByBytesBuilder.build() : columnNamesByBytes;
         this.estimatedSize = (int)estimatedSize;
     }
     
@@ -70,19 +78,28 @@ public class PColumnFamilyImpl implements PColumnFamily {
     }
 
     @Override
-    public PColumn getColumn(byte[] qualifier) throws ColumnNotFoundException  {
-        PColumn column = columnByBytes.get(qualifier);
+    public PColumn getPColumnForColumnNameBytes(byte[] columnNameBytes) throws ColumnNotFoundException  {
+        PColumn column = columnNamesByBytes.get(columnNameBytes);
         if (column == null) {
-            throw new ColumnNotFoundException(Bytes.toString(qualifier));
+            throw new ColumnNotFoundException(Bytes.toString(columnNameBytes));
         }
         return column;
     }
     
     @Override
-    public PColumn getColumn(String name) throws ColumnNotFoundException  {
-        PColumn column = columnByString.get(name);
+    public PColumn getPColumnForColumnName(String columnName) throws ColumnNotFoundException  {
+        PColumn column = columnNamesByStrings.get(columnName);
         if (column == null) {
-            throw new ColumnNotFoundException(name);
+            throw new ColumnNotFoundException(columnName);
+        }
+        return column;
+    }
+    
+    @Override
+    public PColumn getPColumnForColumnQualifier(byte[] cq) throws ColumnNotFoundException {
+        PColumn column = columnQualifiersByBytes.get(cq);
+        if (column == null) {
+            throw new ColumnNotFoundException(Bytes.toString(cq));
         }
         return column;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
index a556f76..5cf1465 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
@@ -40,6 +40,7 @@ public class PColumnImpl implements PColumn {
     private String expressionStr;
     private boolean isRowTimestamp;
     private boolean isDynamic;
+    private Integer columnQualifier;
     
     public PColumnImpl() {
     }
@@ -51,13 +52,13 @@ public class PColumnImpl implements PColumn {
                        Integer scale,
                        boolean nullable,
                        int position,
-                       SortOrder sortOrder, Integer arrSize, byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic) {
-        init(name, familyName, dataType, maxLength, scale, nullable, position, sortOrder, arrSize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic);
+                       SortOrder sortOrder, Integer arrSize, byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic, Integer columnQualifier) {
+        init(name, familyName, dataType, maxLength, scale, nullable, position, sortOrder, arrSize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic, columnQualifier);
     }
 
     public PColumnImpl(PColumn column, int position) {
         this(column.getName(), column.getFamilyName(), column.getDataType(), column.getMaxLength(),
-                column.getScale(), column.isNullable(), position, column.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic());
+                column.getScale(), column.isNullable(), position, column.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic(), column.getColumnQualifier());
     }
 
     private void init(PName name,
@@ -69,7 +70,7 @@ public class PColumnImpl implements PColumn {
             int position,
             SortOrder sortOrder,
             Integer arrSize,
-            byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic) {
+            byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic, Integer columnQualifier) {
     	Preconditions.checkNotNull(sortOrder);
         this.dataType = dataType;
         if (familyName == null) {
@@ -94,6 +95,7 @@ public class PColumnImpl implements PColumn {
         this.expressionStr = expressionStr;
         this.isRowTimestamp = isRowTimestamp;
         this.isDynamic = isDynamic;
+        this.columnQualifier = columnQualifier;
     }
 
     @Override
@@ -205,6 +207,11 @@ public class PColumnImpl implements PColumn {
     public boolean isDynamic() {
         return isDynamic;
     }
+    
+    @Override
+    public Integer getColumnQualifier() {
+        return columnQualifier;
+    }
 
     /**
      * Create a PColumn instance from PBed PColumn instance
@@ -251,8 +258,12 @@ public class PColumnImpl implements PColumn {
         if (column.hasIsDynamic()) {
         	isDynamic = column.getIsDynamic();
         }
+        Integer columnQualifier = null;
+        if (column.hasColumnQualifier()) {
+            columnQualifier = column.getColumnQualifier();
+        }
         return new PColumnImpl(columnName, familyName, dataType, maxLength, scale, nullable, position, sortOrder,
-                arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic);
+                arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic, columnQualifier);
     }
 
     public static PTableProtos.PColumn toProto(PColumn column) {
@@ -283,6 +294,9 @@ public class PColumnImpl implements PColumn {
             builder.setExpression(column.getExpressionStr());
         }
         builder.setIsRowTimestamp(column.isRowTimestamp());
+        if (column.getColumnQualifier() != null) {
+            builder.setColumnQualifier(column.getColumnQualifier());
+        }
         return builder.build();
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
index 67a2714..4c42d69 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
@@ -423,7 +423,7 @@ public class PMetaDataImpl implements PMetaData {
             if (familyName == null) {
                 column = table.getPKColumn(columnToRemove.getName().getString());
             } else {
-                column = table.getColumnFamily(familyName).getColumn(columnToRemove.getName().getString());
+                column = table.getColumnFamily(familyName).getPColumnForColumnName(columnToRemove.getName().getString());
             }
             int positionOffset = 0;
             int position = column.getPosition();
@@ -438,7 +438,7 @@ public class PMetaDataImpl implements PMetaData {
             // Update position of columns that follow removed column
             for (int i = position+1; i < oldColumns.size(); i++) {
                 PColumn oldColumn = oldColumns.get(i);
-                PColumn newColumn = new PColumnImpl(oldColumn.getName(), oldColumn.getFamilyName(), oldColumn.getDataType(), oldColumn.getMaxLength(), oldColumn.getScale(), oldColumn.isNullable(), i-1+positionOffset, oldColumn.getSortOrder(), oldColumn.getArraySize(), oldColumn.getViewConstant(), oldColumn.isViewReferenced(), null, oldColumn.isRowTimestamp(), oldColumn.isDynamic());
+                PColumn newColumn = new PColumnImpl(oldColumn.getName(), oldColumn.getFamilyName(), oldColumn.getDataType(), oldColumn.getMaxLength(), oldColumn.getScale(), oldColumn.isNullable(), i-1+positionOffset, oldColumn.getSortOrder(), oldColumn.getArraySize(), oldColumn.getViewConstant(), oldColumn.isViewReferenced(), null, oldColumn.isRowTimestamp(), oldColumn.isDynamic(), oldColumn.getColumnQualifier());
                 columns.add(newColumn);
             }
             

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/PName.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PName.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PName.java
index 0e1337c..8df6a95 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PName.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PName.java
@@ -83,6 +83,32 @@ public interface PName {
             return 0;
         }
     };
+    public static PName ENCODED_EMPTY_COLUMN_NAME = new PName() {
+        @Override
+        public String getString() {
+            return String.valueOf(QueryConstants.ENCODED_EMPTY_COLUMN_NAME);
+        }
+
+        @Override
+        public byte[] getBytes() {
+            return QueryConstants.ENCODED_EMPTY_COLUMN_BYTES;
+        }
+        
+        @Override
+        public String toString() {
+            return getString();
+        }
+
+        @Override
+        public ImmutableBytesPtr getBytesPtr() {
+            return QueryConstants.ENCODED_EMPTY_COLUMN_BYTES_PTR;
+        }
+
+        @Override
+        public int getEstimatedSize() {
+            return 0;
+        }
+    };
     /**
      * Get the client-side, normalized name as referenced
      * in a SQL statement.

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
index 84db752..567050c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
@@ -154,6 +154,34 @@ public interface PTable extends PMetaDataEntity {
             return LinkType.values()[serializedValue-1];
         }
     }
+    
+    public enum StorageScheme {
+        ENCODED_COLUMN_NAMES((byte)1),
+        NON_ENCODED_COLUMN_NAMES((byte)2);
+
+        private final byte[] byteValue;
+        private final byte serializedValue;
+
+        StorageScheme(byte serializedValue) {
+            this.serializedValue = serializedValue;
+            this.byteValue = Bytes.toBytes(this.name());
+        }
+
+        public byte[] getBytes() {
+            return byteValue;
+        }
+
+        public byte getSerializedValue() {
+            return this.serializedValue;
+        }
+
+        public static StorageScheme fromSerializedValue(byte serializedValue) {
+            if (serializedValue < 1 || serializedValue > StorageScheme.values().length) {
+                return null;
+            }
+            return StorageScheme.values()[serializedValue-1];
+        }
+    }
 
     long getTimeStamp();
     long getSequenceNumber();
@@ -209,7 +237,17 @@ public interface PTable extends PMetaDataEntity {
      * can be found
      * @throws AmbiguousColumnException if multiple columns are found with the given name
      */
-    PColumn getColumn(String name) throws ColumnNotFoundException, AmbiguousColumnException;
+    //TODO: samarth inspect all the callers of this method.
+    PColumn getPColumnForColumnName(String name) throws ColumnNotFoundException, AmbiguousColumnException;
+    
+    /**
+     * Get the column with the given column qualifier.
+     * @param column qualifier bytes
+     * @return the PColumn with the given column qualifier
+     * @throws ColumnNotFoundException if no column with the given column qualifier can be found
+     * @throws AmbiguousColumnException if multiple columns are found with the given column qualifier
+     */
+    PColumn getPColumnForColumnQualifier(byte[] cq) throws ColumnNotFoundException, AmbiguousColumnException; 
     
     /**
      * Get the PK column with the given name.
@@ -345,6 +383,6 @@ public interface PTable extends PMetaDataEntity {
      */
     int getRowTimestampColPos();
     long getUpdateCacheFrequency();
-
     boolean isNamespaceMapped();
+    StorageScheme getStorageScheme();
 }


[50/52] [abbrv] phoenix git commit: Rebasing with latest and fixing associated test failures

Posted by sa...@apache.org.
Rebasing with latest and fixing associated test failures


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

Branch: refs/heads/encodecolumns
Commit: 390bd393d9734c20b3786c973faf6a048c64ab00
Parents: 2b3acb2
Author: Samarth <sa...@salesforce.com>
Authored: Fri Apr 22 17:51:27 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:32 2016 -0700

----------------------------------------------------------------------
 .../apache/phoenix/end2end/AlterTableIT.java    | 219 ++++++++++++++++++-
 .../phoenix/end2end/AlterTableWithViewsIT.java  | 213 ------------------
 .../apache/phoenix/end2end/CreateTableIT.java   |   5 +
 .../phoenix/end2end/index/DropMetadataIT.java   |  14 +-
 .../coprocessor/MetaDataEndpointImpl.java       |  10 +-
 .../apache/phoenix/jdbc/PhoenixConnection.java  |   8 +-
 .../apache/phoenix/schema/MetaDataClient.java   |  45 ++--
 .../org/apache/phoenix/schema/PTableImpl.java   |   5 +-
 .../org/apache/phoenix/schema/PTableKey.java    |   6 +-
 .../org/apache/phoenix/util/SchemaUtil.java     |  68 +-----
 10 files changed, 277 insertions(+), 316 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/390bd393/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index 6f31955..ca1f8cf 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -18,6 +18,14 @@
 package org.apache.phoenix.end2end;
 
 import static org.apache.hadoop.hbase.HColumnDescriptor.DEFAULT_REPLICATION_SCOPE;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_COUNTER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM;
+import static org.apache.phoenix.query.QueryConstants.DEFAULT_COLUMN_FAMILY;
 import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
 import static org.apache.phoenix.util.TestUtil.closeConnection;
 import static org.apache.phoenix.util.TestUtil.closeStatement;
@@ -44,7 +52,6 @@ import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.KeepDeletedCells;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.client.HTable;
-import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.ResultScanner;
 import org.apache.hadoop.hbase.client.Scan;
@@ -54,10 +61,10 @@ import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.TableNotFoundException;
-import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.PropertiesUtil;
@@ -2218,5 +2225,213 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
 		}
 	}
 	
+	@Test
+    public void testClientAndServerMetadataForEncodedColumns() throws Exception {
+        String schemaName = "XYZ";
+        String baseTableName = "testClientAndServerMetadataForEncodedColumns".toUpperCase();
+        String viewName = "VIEW1";
+        String fullTableName = schemaName + "." + baseTableName;
+        String fullViewName = schemaName + "." + viewName;
+        for (int i = 0; i < 2; i++) {
+            try (Connection conn = DriverManager.getConnection(getUrl())) {
+                PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
+                conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + fullTableName + " ("
+                        + " ID char(1) NOT NULL,"
+                        + " COL1 integer NOT NULL,"
+                        + " COL2 bigint NOT NULL,"
+                        + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
+                        + " )");
+                PTable baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+                long initBaseTableSeqNumber = baseTable.getSequenceNumber(); 
+
+                // assert that the client side cache is updated.
+                Map<String, Integer> cqCounters = baseTable.getEncodedCQCounters();
+                assertEquals(1, cqCounters.size());
+                int counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+                assertEquals(1, counter);
+
+                // assert that the server side metadata is updated correctly.
+                assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 1);
+                assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber);
+
+                // now create a view and validate client and server side metadata
+                String viewDDL = "CREATE VIEW " + fullViewName + " ( VIEW_COL1 INTEGER, A.VIEW_COL2 VARCHAR ) AS SELECT * FROM " + fullTableName;
+                conn.createStatement().execute(viewDDL);
+                baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+                PTable view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
+
+                // verify that the client side cache is updated. Base table's cq counters should be updated.
+                cqCounters = baseTable.getEncodedCQCounters();
+                counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+                assertEquals(2, counter);
+                counter = cqCounters.get("A");
+                assertEquals(2, counter);
+                cqCounters = view.getEncodedCQCounters();
+                assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
+
+                // assert that the server side metadata for the base table and the view is also updated correctly.
+                assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 2);
+                assertEncodedCQCounter("A", schemaName, baseTableName, 2);
+                assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "VIEW_COL1", schemaName, viewName, 1);
+                assertEncodedCQValue("A", "VIEW_COL2", schemaName, viewName, 1);
+                assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 1);
+                assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM);
+            }
+        }
+    }
+	
+	@Test
+    public void testAddingColumnsToTablesAndViewsWithEncodedColumns() throws Exception {
+        String schemaName = "XYZ";
+        String baseTableName = "testAddingColumnsToTablesAndViewsWithEncodedColumns".toUpperCase();
+        String viewName = "VIEW1";
+        String fullTableName = schemaName + "." + baseTableName;
+        String fullViewName = schemaName + "." + viewName;
+        Properties props = new Properties();
+        props.put(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
+        try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+            conn.createStatement().execute("CREATE SCHEMA " + schemaName);
+            PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
+            conn.createStatement().execute("CREATE TABLE " + fullTableName + " ("
+                    + " ID char(1) NOT NULL,"
+                    + " COL1 integer NOT NULL,"
+                    + " COL2 bigint NOT NULL,"
+                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
+                    + " )");
+            PTable baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            long initBaseTableSeqNumber = baseTable.getSequenceNumber(); 
+
+            // Add a column to the base table and see if the client and server metadata is updated correctly
+            String alterDDL = "ALTER TABLE " + fullTableName + " ADD COL3 VARCHAR PRIMARY KEY, COL4 INTEGER, COL5 VARCHAR, B.COL6 DECIMAL (10, 2)";
+            conn.createStatement().execute(alterDDL);
+
+            // assert that the client side cache is updated.
+            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            Map<String, Integer> cqCounters = baseTable.getEncodedCQCounters();
+            int counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+            assertEquals(3, counter);
+            counter = cqCounters.get("B");
+            assertEquals(2, counter);
+
+            // assert that the server side metadata is updated correctly.
+            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 3);
+            assertEncodedCQCounter("B", schemaName, baseTableName, 2);
+            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "COL4", schemaName, baseTableName, 1);
+            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "COL5", schemaName, baseTableName, 2);
+            assertEncodedCQValue("B", "COL6", schemaName, baseTableName, 1);
+            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 1);
+
+            // Create a view
+            String viewDDL = "CREATE VIEW " + fullViewName + " ( VIEW_COL1 INTEGER, A.VIEW_COL2 VARCHAR ) AS SELECT * FROM " + fullTableName;
+            conn.createStatement().execute(viewDDL);
+            // Creating a view that adds its own columns should increment the base table's sequence number too.
+            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 2);
+
+            // Add column to the view
+            viewDDL = "ALTER VIEW " + fullViewName + " ADD VIEW_COL3 DECIMAL(10, 2), A.VIEW_COL4 VARCHAR, B.VIEW_COL5 INTEGER";
+            conn.createStatement().execute(viewDDL);
+
+            // assert that the client cache for the base table is updated
+            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            cqCounters = baseTable.getEncodedCQCounters();
+            counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+            assertEquals(5, counter);
+            counter = cqCounters.get("B");
+            assertEquals(3, counter);
+            counter = cqCounters.get("A");
+            assertEquals(3, counter);
+
+            // assert client cache for view
+            PTable view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
+            cqCounters = view.getEncodedCQCounters();
+            assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
+
+            // assert that the server side metadata for the base table and the view is also updated correctly.
+            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 5);
+            assertEncodedCQCounter("A", schemaName, baseTableName, 3);
+            assertEncodedCQCounter("B", schemaName, baseTableName, 3);
+            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "VIEW_COL3", schemaName, viewName, 4);
+            assertEncodedCQValue("A", "VIEW_COL4", schemaName, viewName, 2);
+            assertEncodedCQValue("B", "VIEW_COL5", schemaName, viewName, 2);
+            // Adding a column to the should increment the base table's sequence number too since we update the cq counters for column families.
+            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 3);
+            assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM + 1);
+            
+            // Add column to the base table which doesn't already exist in the view.
+            alterDDL = "ALTER TABLE " + fullTableName + " ADD COL10 VARCHAR, A.COL11 INTEGER";
+            conn.createStatement().execute(alterDDL);
+            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            
+            // assert that the client cache for the base table is updated 
+            cqCounters = baseTable.getEncodedCQCounters();
+            counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+            assertEquals(6, counter);
+            counter = cqCounters.get("B");
+            assertEquals(3, counter);
+            counter = cqCounters.get("A");
+            assertEquals(4, counter);
+            
+            // assert client cache for view
+            view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
+            cqCounters = view.getEncodedCQCounters();
+            assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
+            
+            // assert that the server side metadata for the base table and the view is also updated correctly.
+            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 6);
+            assertEncodedCQCounter("A", schemaName, baseTableName, 4);
+            assertEncodedCQCounter("B", schemaName, baseTableName, 3);
+            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "COL10", schemaName, viewName, 5);
+            assertEncodedCQValue("A", "COL11", schemaName, viewName, 3);
+            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 4);
+            assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM + 2);
+        }
+    }
+	
+	private void assertEncodedCQValue(String columnFamily, String columnName, String schemaName, String tableName, int expectedValue) throws Exception {
+        String query = "SELECT " + ENCODED_COLUMN_QUALIFIER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? " + " AND " + COLUMN_FAMILY + " = ?" + " AND " + COLUMN_NAME  + " = ?";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PreparedStatement stmt = conn.prepareStatement(query);
+            stmt.setString(1, schemaName);
+            stmt.setString(2, tableName);
+            stmt.setString(3, columnFamily);
+            stmt.setString(4, columnName);
+            ResultSet rs = stmt.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(expectedValue, rs.getInt(1));
+            assertFalse(rs.next());
+        }
+    }
+    
+    private void assertEncodedCQCounter(String columnFamily, String schemaName, String tableName, int expectedValue) throws Exception {
+        String query = "SELECT " + COLUMN_QUALIFIER_COUNTER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? " + " AND " + COLUMN_FAMILY + " = ? AND " + COLUMN_QUALIFIER_COUNTER + " IS NOT NULL";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PreparedStatement stmt = conn.prepareStatement(query);
+            stmt.setString(1, schemaName);
+            stmt.setString(2, tableName);
+            stmt.setString(3, columnFamily);
+            ResultSet rs = stmt.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(expectedValue, rs.getInt(1));
+            assertFalse(rs.next());
+        }
+    }
+    
+    private void assertSequenceNumber(String schemaName, String tableName, long expectedSequenceNumber) throws Exception {
+        String query = "SELECT " + TABLE_SEQ_NUM + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? AND " +  TABLE_SEQ_NUM + " IS NOT NULL AND " + COLUMN_NAME + " IS NULL AND "
+                + COLUMN_FAMILY + " IS NULL ";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PreparedStatement stmt = conn.prepareStatement(query);
+            stmt.setString(1, schemaName);
+            stmt.setString(2, tableName);
+            ResultSet rs = stmt.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(expectedSequenceNumber, rs.getInt(1));
+            assertFalse(rs.next());
+        }
+    }
+	
 }
  

http://git-wip-us.apache.org/repos/asf/phoenix/blob/390bd393/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
index 9295f51..7458ed9 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
@@ -18,14 +18,6 @@
 package org.apache.phoenix.end2end;
 
 import static org.apache.phoenix.exception.SQLExceptionCode.CANNOT_MUTATE_TABLE;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_COUNTER;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM;
-import static org.apache.phoenix.query.QueryConstants.DEFAULT_COLUMN_FAMILY;
 import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -48,12 +40,10 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.coprocessor.PhoenixTransactionalProcessor;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PNameFactory;
-import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.util.ReadOnlyProps;
@@ -686,207 +676,4 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
         } 
     }
     
-    @Test
-    public void testClientAndServerMetadataForEncodedColumns() throws Exception {
-        String schemaName = "XYZ";
-        String baseTableName = "TABLEWITHVIEW";
-        String viewName = "VIEW1";
-        String fullTableName = schemaName + "." + baseTableName;
-        String fullViewName = schemaName + "." + viewName;
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
-            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + fullTableName + " ("
-                    + " ID char(1) NOT NULL,"
-                    + " COL1 integer NOT NULL,"
-                    + " COL2 bigint NOT NULL,"
-                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
-                    + " )");
-            PTable baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
-            long initBaseTableSeqNumber = baseTable.getSequenceNumber(); 
-                    
-            // assert that the client side cache is updated.
-            Map<String, Integer> cqCounters = baseTable.getEncodedCQCounters();
-            assertEquals(1, cqCounters.size());
-            int counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
-            assertEquals(1, counter);
-            
-            // assert that the server side metadata is updated correctly.
-            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 1);
-            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber);
-            
-            // now create a view and validate client and server side metadata
-            String viewDDL = "CREATE VIEW " + fullViewName + " ( VIEW_COL1 INTEGER, A.VIEW_COL2 VARCHAR ) AS SELECT * FROM " + fullTableName;
-            conn.createStatement().execute(viewDDL);
-            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
-            PTable view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
-            
-            // verify that the client side cache is updated. Base table's cq counters should be updated.
-            cqCounters = baseTable.getEncodedCQCounters();
-            counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
-            assertEquals(2, counter);
-            counter = cqCounters.get("A");
-            assertEquals(2, counter);
-            cqCounters = view.getEncodedCQCounters();
-            assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
-            
-            // assert that the server side metadata for the base table and the view is also updated correctly.
-            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 2);
-            assertEncodedCQCounter("A", schemaName, baseTableName, 2);
-            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "VIEW_COL1", schemaName, viewName, 1);
-            assertEncodedCQValue("A", "VIEW_COL2", schemaName, viewName, 1);
-            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 1);
-            assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM);
-        }
-    }
-    
-    @Test
-    public void testAddingColumnsToTablesAndViewsWithEncodedColumns() throws Exception {
-        String schemaName = "XYZ";
-        String baseTableName = "testAddingColumnsWithEncodedColumns".toUpperCase();
-        String viewName = "VIEW1";
-        String fullTableName = schemaName + "." + baseTableName;
-        String fullViewName = schemaName + "." + viewName;
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
-            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + fullTableName + " ("
-                    + " ID char(1) NOT NULL,"
-                    + " COL1 integer NOT NULL,"
-                    + " COL2 bigint NOT NULL,"
-                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
-                    + " )");
-            PTable baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
-            long initBaseTableSeqNumber = baseTable.getSequenceNumber(); 
-
-            // Add a column to the base table and see if the client and server metadata is updated correctly
-            String alterDDL = "ALTER TABLE " + fullTableName + " ADD COL3 VARCHAR PRIMARY KEY, COL4 INTEGER, COL5 VARCHAR, B.COL6 DECIMAL (10, 2)";
-            conn.createStatement().execute(alterDDL);
-
-            // assert that the client side cache is updated.
-            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
-            Map<String, Integer> cqCounters = baseTable.getEncodedCQCounters();
-            int counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
-            assertEquals(3, counter);
-            counter = cqCounters.get("B");
-            assertEquals(2, counter);
-
-            // assert that the server side metadata is updated correctly.
-            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 3);
-            assertEncodedCQCounter("B", schemaName, baseTableName, 2);
-            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "COL4", schemaName, baseTableName, 1);
-            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "COL5", schemaName, baseTableName, 2);
-            assertEncodedCQValue("B", "COL6", schemaName, baseTableName, 1);
-            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 1);
-
-            // Create a view
-            String viewDDL = "CREATE VIEW " + fullViewName + " ( VIEW_COL1 INTEGER, A.VIEW_COL2 VARCHAR ) AS SELECT * FROM " + fullTableName;
-            conn.createStatement().execute(viewDDL);
-            // Creating a view that adds its own columns should increment the base table's sequence number too.
-            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 2);
-
-            // Add column to the view
-            viewDDL = "ALTER VIEW " + fullViewName + " ADD VIEW_COL3 DECIMAL(10, 2), A.VIEW_COL4 VARCHAR, B.VIEW_COL5 INTEGER";
-            conn.createStatement().execute(viewDDL);
-
-            // assert that the client cache for the base table is updated
-            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
-            cqCounters = baseTable.getEncodedCQCounters();
-            counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
-            assertEquals(5, counter);
-            counter = cqCounters.get("B");
-            assertEquals(3, counter);
-            counter = cqCounters.get("A");
-            assertEquals(3, counter);
-
-            // assert client cache for view
-            PTable view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
-            cqCounters = view.getEncodedCQCounters();
-            assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
-
-            // assert that the server side metadata for the base table and the view is also updated correctly.
-            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 5);
-            assertEncodedCQCounter("A", schemaName, baseTableName, 3);
-            assertEncodedCQCounter("B", schemaName, baseTableName, 3);
-            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "VIEW_COL3", schemaName, viewName, 4);
-            assertEncodedCQValue("A", "VIEW_COL4", schemaName, viewName, 2);
-            assertEncodedCQValue("B", "VIEW_COL5", schemaName, viewName, 2);
-            // Adding a column to the should increment the base table's sequence number too since we update the cq counters for column families.
-            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 3);
-            assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM + 1);
-            
-            // Add column to the base table which doesn't already exist in the view.
-            alterDDL = "ALTER TABLE " + fullTableName + " ADD COL10 VARCHAR, A.COL11 INTEGER";
-            conn.createStatement().execute(alterDDL);
-            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
-            
-            // assert that the client cache for the base table is updated 
-            cqCounters = baseTable.getEncodedCQCounters();
-            counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
-            assertEquals(6, counter);
-            counter = cqCounters.get("B");
-            assertEquals(3, counter);
-            counter = cqCounters.get("A");
-            assertEquals(4, counter);
-            
-            // assert client cache for view
-            view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
-            cqCounters = view.getEncodedCQCounters();
-            assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
-            
-            // assert that the server side metadata for the base table and the view is also updated correctly.
-            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 6);
-            assertEncodedCQCounter("A", schemaName, baseTableName, 4);
-            assertEncodedCQCounter("B", schemaName, baseTableName, 3);
-            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "COL10", schemaName, viewName, 5);
-            assertEncodedCQValue("A", "COL11", schemaName, viewName, 3);
-            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 4);
-            assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM + 2);
-        }
-    }
-    
-    private void assertEncodedCQValue(String columnFamily, String columnName, String schemaName, String tableName, int expectedValue) throws Exception {
-        String query = "SELECT " + ENCODED_COLUMN_QUALIFIER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
-                + " = ? " + " AND " + COLUMN_FAMILY + " = ?" + " AND " + COLUMN_NAME  + " = ?";
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            PreparedStatement stmt = conn.prepareStatement(query);
-            stmt.setString(1, schemaName);
-            stmt.setString(2, tableName);
-            stmt.setString(3, columnFamily);
-            stmt.setString(4, columnName);
-            ResultSet rs = stmt.executeQuery();
-            assertTrue(rs.next());
-            assertEquals(expectedValue, rs.getInt(1));
-            assertFalse(rs.next());
-        }
-    }
-    
-    private void assertEncodedCQCounter(String columnFamily, String schemaName, String tableName, int expectedValue) throws Exception {
-        String query = "SELECT " + COLUMN_QUALIFIER_COUNTER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
-                + " = ? " + " AND " + COLUMN_FAMILY + " = ? AND " + COLUMN_QUALIFIER_COUNTER + " IS NOT NULL";
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            PreparedStatement stmt = conn.prepareStatement(query);
-            stmt.setString(1, schemaName);
-            stmt.setString(2, tableName);
-            stmt.setString(3, columnFamily);
-            ResultSet rs = stmt.executeQuery();
-            assertTrue(rs.next());
-            assertEquals(expectedValue, rs.getInt(1));
-            assertFalse(rs.next());
-        }
-    }
-    
-    private void assertSequenceNumber(String schemaName, String tableName, long expectedSequenceNumber) throws Exception {
-        String query = "SELECT " + TABLE_SEQ_NUM + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
-                + " = ? AND " +  TABLE_SEQ_NUM + " IS NOT NULL AND " + COLUMN_NAME + " IS NULL AND "
-                + COLUMN_FAMILY + " IS NULL ";
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            PreparedStatement stmt = conn.prepareStatement(query);
-            stmt.setString(1, schemaName);
-            stmt.setString(2, tableName);
-            ResultSet rs = stmt.executeQuery();
-            assertTrue(rs.next());
-            assertEquals(expectedSequenceNumber, rs.getInt(1));
-            assertFalse(rs.next());
-        }
-    }
-    
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/390bd393/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
index 6055b1c..dd64ea2 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
@@ -610,4 +610,9 @@ public class CreateTableIT extends BaseClientManagedTimeIT {
             assertFalse(rs.next());
         }
     }
+    
+    @Test
+    public void testCreateTableIfNotExistsForEncodedColumnNames() throws Exception {
+        
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/390bd393/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropMetadataIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropMetadataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropMetadataIT.java
index 4c60ea3..b4492de 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropMetadataIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropMetadataIT.java
@@ -47,11 +47,13 @@ import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.ColumnNotFoundException;
+import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.ReadOnlyProps;
@@ -200,8 +202,10 @@ public class DropMetadataIT extends BaseHBaseManagedTimeIT {
             ResultScanner results = table.getScanner(scan);
             Result result = results.next();
             assertNotNull(result);
-            assertNotNull("localIndexTableName2 row is missing", result.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, 
-                IndexUtil.getIndexColumnName(QueryConstants.DEFAULT_COLUMN_FAMILY, "V1").getBytes()));
+            PTable localIndexTable2 = pconn.getTable(new PTableKey(null, localIndexTableName2));
+            PColumn column = localIndexTable2.getPColumnForColumnName(IndexUtil.getIndexColumnName(QueryConstants.DEFAULT_COLUMN_FAMILY, "V1"));
+            byte[] cq = EncodedColumnsUtil.getColumnQualifier(column, localIndexTable2);
+            assertNotNull("localIndexTableName2 row is missing", result.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, cq));
             assertNull(results.next());
         }
     }
@@ -305,9 +309,11 @@ public class DropMetadataIT extends BaseHBaseManagedTimeIT {
             ResultScanner results = table.getScanner(scan);
             Result result = results.next();
             assertNotNull(result);
+            PTable viewIndexPTable = pconn.getTable(new PTableKey(pconn.getTenantId(), "VIEWINDEX2"));
+            PColumn column = viewIndexPTable.getPColumnForColumnName(IndexUtil.getIndexColumnName(QueryConstants.DEFAULT_COLUMN_FAMILY, "V4"));
+            byte[] cq = EncodedColumnsUtil.getColumnQualifier(column, viewIndexPTable);
             // there should be a single row belonging to VIEWINDEX2 
-            assertNotNull("VIEWINDEX2 row is missing", result.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, 
-                IndexUtil.getIndexColumnName(QueryConstants.DEFAULT_COLUMN_FAMILY, "V4").getBytes()));
+            assertNotNull("VIEWINDEX2 row is missing", result.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, cq));
             assertNull(results.next());
         }
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/390bd393/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 36e04b5..eb557ea 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -3053,10 +3053,10 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             byte[] indexKey =
                     SchemaUtil.getTableKey(tenantId, index.getSchemaName().getBytes(), index
                             .getTableName().getBytes());
-            byte[] cq = SchemaUtil.getColumnQualifier(columnToDelete, index);
+            byte[] cq = EncodedColumnsUtil.getColumnQualifier(columnToDelete, index);
+            ColumnReference colRef = new ColumnReference(columnToDelete.getFamilyName().getBytes(), cq);
             // If index requires this column for its pk, then drop it
-            if (indexMaintainer.getIndexedColumns().contains(
-                new ColumnReference(columnToDelete.getFamilyName().getBytes(), cq))) {
+            if (indexMaintainer.getIndexedColumns().contains(colRef)) {
                 // Since we're dropping the index, lock it to ensure
                 // that a change in index state doesn't
                 // occur while we're dropping it.
@@ -3077,9 +3077,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 invalidateList.add(new ImmutableBytesPtr(indexKey));
             }
             // If the dropped column is a covered index column, invalidate the index
-            else if (indexMaintainer.getCoverededColumns().contains(
-                new ColumnReference(columnToDelete.getFamilyName().getBytes(), columnToDelete
-                        .getName().getBytes()))) {
+            else if (indexMaintainer.getCoverededColumns().contains(colRef)){
                 invalidateList.add(new ImmutableBytesPtr(indexKey));
             }
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/390bd393/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index 08b300b..a8cf52f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -58,6 +58,8 @@ import java.util.concurrent.LinkedBlockingQueue;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import co.cask.tephra.TransactionContext;
+
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.phoenix.call.CallRunner;
 import org.apache.phoenix.exception.SQLExceptionCode;
@@ -108,9 +110,9 @@ import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.ReadOnlyProps;
 import org.apache.phoenix.util.SQLCloseable;
 import org.apache.phoenix.util.SQLCloseables;
+import org.apache.phoenix.util.SchemaUtil;
 import org.cloudera.htrace.Sampler;
 import org.cloudera.htrace.TraceScope;
-import org.apache.phoenix.util.SchemaUtil;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Objects;
@@ -119,10 +121,6 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.collect.Lists;
 
-import co.cask.tephra.TransactionContext;
-
-import co.cask.tephra.TransactionContext;
-
 
 /**
  * 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/390bd393/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 70a1d6e..4b4caa2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -291,11 +291,12 @@ public class MetaDataClient {
             ") VALUES (?, ?, ?, ?, ?, ?)";
     private static final String UPDATE_ENCODED_COLUMN_COUNT = 
             "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
+            TENANT_ID + ", " + 
             TABLE_SCHEM + "," +
             TABLE_NAME + "," +
             COLUMN_FAMILY + "," +
             COLUMN_QUALIFIER_COUNTER + 
-            ") VALUES (?, ?, ?, ?)";
+            ") VALUES (?, ?, ?, ?, ?)";
     private static final String INCREMENT_SEQ_NUM =
             "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
             TENANT_ID + "," +
@@ -2060,13 +2061,18 @@ public class MetaDataClient {
                     PreparedStatement linkStatement = connection.prepareStatement(UPDATE_ENCODED_COLUMN_COUNT);
                     String schemaNameToUse = tableType == VIEW ? viewPhysicalTable.getSchemaName().getString() : schemaName;
                     String tableNameToUse = tableType == VIEW ? viewPhysicalTable.getTableName().getString() : tableName;
+                    // For local indexes and indexes on views, pass on the the tenant id i.e. all their meta-data rows have
+                    // tenant ids in there.
+                    boolean sharedIndex = tableType == PTableType.INDEX && (indexType == IndexType.LOCAL || parent.getType() == PTableType.VIEW);
+                    String tenantIdToUse = connection.getTenantId() != null && sharedIndex ? connection.getTenantId().getString() : null;
                     for (Entry<String, Integer> entry : mapToUse.entrySet()) {
                         String familyName = entry.getKey();
                         Integer nextQualifier = entry.getValue();
-                        linkStatement.setString(1, schemaNameToUse);
-                        linkStatement.setString(2, tableNameToUse);
-                        linkStatement.setString(3, familyName);
-                        linkStatement.setInt(4, nextQualifier);
+                        linkStatement.setString(1, tenantIdToUse);
+                        linkStatement.setString(2, schemaNameToUse);
+                        linkStatement.setString(3, tableNameToUse);
+                        linkStatement.setString(4, familyName);
+                        linkStatement.setInt(5, nextQualifier);
                         linkStatement.execute();
                     }
 
@@ -2904,6 +2910,7 @@ public class MetaDataClient {
                 Map<String, Integer> cfWithUpdatedCQCounters = null; 
                 if (columnDefs.size() > 0 ) {
                     //FIXME: samarth change this to fetch table from server if client cache doesn't have it. What about local indexes?
+                    //FIXME: samarth fix this mess of getting table names from connection
                     //TODO: samarth should these be guarded by storage scheme check. Better to have the map always available. immutable empty for views and non encoded.
                     tableForCQCounters = tableType == PTableType.VIEW ? connection.getTable(new PTableKey(null, table.getPhysicalName().getString())) : table;
                      cqCountersToUse = tableForCQCounters.getEncodedCQCounters();
@@ -2949,7 +2956,7 @@ public class MetaDataClient {
                         }
                         
                         // Add any new PK columns to end of index PK
-                        if (numPkColumnsAdded>0) {
+                        if (numPkColumnsAdded > 0) {
                             // create PK column list that includes the newly created columns
                             List<PColumn> pkColumns = Lists.newArrayListWithExpectedSize(table.getPKColumns().size()+numPkColumnsAdded);
                             pkColumns.addAll(table.getPKColumns());
@@ -3017,17 +3024,23 @@ public class MetaDataClient {
                 Collections.reverse(tableMetaData);
                 // Add column metadata afterwards, maintaining the order so columns have more predictable ordinal position
                 tableMetaData.addAll(columnMetaData);
+                boolean sharedIndex = tableType == PTableType.INDEX && (table.getIndexType() == IndexType.LOCAL || table.getViewIndexId() != null);
+                String tenantIdToUse = connection.getTenantId() != null && sharedIndex ? connection.getTenantId().getString() : null;
                 //TODO: samarth I am not sure this is going to work on server side. But for now lets add these mutations here.
                 if (cfWithUpdatedCQCounters != null && !cfWithUpdatedCQCounters.isEmpty()) {
-                    PreparedStatement linkStatement = connection.prepareStatement(UPDATE_ENCODED_COLUMN_COUNT);
-                    for (Entry<String, Integer> entry : cfWithUpdatedCQCounters.entrySet()) {
-                        String familyName = entry.getKey();
-                        Integer nextQualifier = entry.getValue();
-                        linkStatement.setString(1, tableForCQCounters.getSchemaName().getString());
-                        linkStatement.setString(2, tableForCQCounters.getTableName().getString());
-                        linkStatement.setString(3, familyName);
-                        linkStatement.setInt(4, nextQualifier);
-                        linkStatement.execute();
+                    PreparedStatement linkStatement;
+                    if (!sharedIndex) {
+                        linkStatement = connection.prepareStatement(UPDATE_ENCODED_COLUMN_COUNT);
+                        for (Entry<String, Integer> entry : cfWithUpdatedCQCounters.entrySet()) {
+                            String familyName = entry.getKey();
+                            Integer nextQualifier = entry.getValue();
+                            linkStatement.setString(1, tenantIdToUse);
+                            linkStatement.setString(2, tableForCQCounters.getSchemaName().getString());
+                            linkStatement.setString(3, tableForCQCounters.getTableName().getString());
+                            linkStatement.setString(4, familyName);
+                            linkStatement.setInt(5, nextQualifier);
+                            linkStatement.execute();
+                        }
                     }
                     // When a view adds its own columns, then we need to increase the sequence number of the base table
                     // too since we want clients to get the latest PTable of the base table.
@@ -3357,7 +3370,7 @@ public class MetaDataClient {
                         // so we need to issue deletes markers for all the rows of the index 
                         final List<TableRef> tableRefsToDrop = Lists.newArrayList();
                         Map<String, List<TableRef>> tenantIdTableRefMap = Maps.newHashMap();
-                        if (result.getSharedTablesToDelete()!=null) {
+                        if (result.getSharedTablesToDelete() != null) {
                             for (SharedTableState sharedTableState : result.getSharedTablesToDelete()) {
                                 PTableImpl viewIndexTable = new PTableImpl(sharedTableState.getTenantId(),
                                         sharedTableState.getSchemaName(), sharedTableState.getTableName(), ts,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/390bd393/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index e7b8c78..897317a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -85,8 +85,6 @@ import com.google.common.collect.Maps;
 import com.google.protobuf.HBaseZeroCopyByteString;
 import com.sun.istack.NotNull;
 
-import co.cask.tephra.TxConstants;
-
 /**
  *
  * Base class for PTable implementors.  Provides abstraction for
@@ -179,8 +177,9 @@ public class PTableImpl implements PTable {
         this.physicalNames = Collections.emptyList();
     }
     
+    // For indexes stored in shared physical tables
     public PTableImpl(PName tenantId, PName schemaName, PName tableName, long timestamp, List<PColumnFamily> families, 
-            List<PColumn> columns, List<PName> physicalNames, Short viewIndexId, boolean multiTenant, boolean isNamespaceMpped, StorageScheme storageScheme, Map<String, Integer> encodedColumnQualifierCounters) throws SQLException { // For indexes stored in shared physical tables
+            List<PColumn> columns, List<PName> physicalNames, Short viewIndexId, boolean multiTenant, boolean isNamespaceMpped, StorageScheme storageScheme, Map<String, Integer> encodedColumnQualifierCounters) throws SQLException {
         this.pkColumns = this.allColumns = Collections.emptyList();
         this.rowKeySchema = RowKeySchema.EMPTY_SCHEMA;
         this.indexes = Collections.emptyList();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/390bd393/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableKey.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableKey.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableKey.java
index 42699d9..017c75d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableKey.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableKey.java
@@ -28,7 +28,11 @@ public class PTableKey {
     public PTableKey(PName tenantId, String name) {
         Preconditions.checkNotNull(name);
         this.tenantId = tenantId;
-        this.name = name;
+        if (name.indexOf(QueryConstants.NAMESPACE_SEPARATOR) != -1) {
+            this.name = name.replace(QueryConstants.NAMESPACE_SEPARATOR, QueryConstants.NAME_SEPARATOR);
+        } else {
+            this.name = name;
+        }
     }
 
     public PName getTenantId() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/390bd393/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
index de6551a..921cb8c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
@@ -67,6 +67,7 @@ import org.apache.phoenix.schema.PDatum;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.PTable.StorageScheme;
 import org.apache.phoenix.schema.RowKeySchema;
@@ -1015,75 +1016,10 @@ public class SchemaUtil {
         }
         return getStrippedName(physicalTableName, indexPrefix);
     }
-
+    
     private static String getStrippedName(String physicalTableName, String indexPrefix) {
         return physicalTableName.indexOf(indexPrefix) == 0 ? physicalTableName.substring(indexPrefix.length())
                 : physicalTableName;
     }      
     
-    /**
-     * Return a map of column family -> next column qualifier number to use.
-     */
-//    public static Map<String, Integer> getNextEncodedColumnQualifiers(PTable table) {
-//        if (EncodedColumnsUtil.usesEncodedColumnNames(table)) {
-//            Map<String, Integer> map = Maps.newHashMapWithExpectedSize(table.getColumns().size());
-//            int max = 0; 
-//            for (PColumnFamily f : table.getColumnFamilies()) {
-//                for (PColumn column : f.getColumns()) {
-//                    if (column.getEncodedColumnQualifier() > max) {
-//                        max = column.getEncodedColumnQualifier();
-//                    }
-//                }
-//                // column qualifiers start with 1.
-//                map.put(f.getName().getString(), max + 1);
-//            }
-//            // When a table has only primary key columns table.getColumnFamilies() will be empty.
-//            // In that case, populate the map with the next column qualifier (1) for the default column
-//            // family of the table.
-//            if (map.isEmpty()) {
-//                map.put(SchemaUtil.getEmptyColumnFamilyAsString(table), 1);
-//            }
-//            return map;
-//        }
-//        return null;
-//    }
-    
-    public static boolean usesEncodedColumnNames(PTable table) {
-        return table.getStorageScheme() != null && table.getStorageScheme() == StorageScheme.ENCODED_COLUMN_NAMES;
-    }
-    
-    public static byte[] getColumnQualifier(PColumn column, PTable table) {
-      checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
-      return usesEncodedColumnNames(table) ? PInteger.INSTANCE.toBytes(column.getEncodedColumnQualifier()) : column.getName().getBytes();
-    }
-    
-    public static byte[] getColumnQualifier(PColumn column, boolean encodedColumnName) {
-        checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
-        return encodedColumnName ? PInteger.INSTANCE.toBytes(column.getEncodedColumnQualifier()) : column.getName().getBytes(); 
-    }
-    
-    /**
-     * @return pair of byte arrays. The first part of the pair is the empty key value's column qualifier, and the second
-     *         part is the value to use for it.
-     */
-    public static Pair<byte[], byte[]> getEmptyKeyValueInfo(PTable table) {
-        return usesEncodedColumnNames(table) ? new Pair<>(QueryConstants.ENCODED_EMPTY_COLUMN_BYTES,
-                QueryConstants.ENCODED_EMPTY_COLUMN_VALUE_BYTES) : new Pair<>(QueryConstants.EMPTY_COLUMN_BYTES,
-                QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
-    }
-    
-    /**
-     * @return pair of byte arrays. The first part of the pair is the empty key value's column qualifier, and the second
-     *         part is the value to use for it.
-     */
-    public static Pair<byte[], byte[]> getEmptyKeyValueInfo(boolean usesEncodedColumnNames) {
-        return usesEncodedColumnNames ? new Pair<>(QueryConstants.ENCODED_EMPTY_COLUMN_BYTES,
-                QueryConstants.ENCODED_EMPTY_COLUMN_VALUE_BYTES) : new Pair<>(QueryConstants.EMPTY_COLUMN_BYTES,
-                        QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
-    }
-    
-    public static boolean hasEncodedColumnName(PColumn column){
-        return !SchemaUtil.isPKColumn(column) && column.getEncodedColumnQualifier() != null;
-    }
-    
 }


[07/52] [abbrv] phoenix git commit: PHOENIX-2822 Tests that extend BaseHBaseManagedTimeIT are very slow(Rahul Gidwani)

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryMoreIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryMoreIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryMoreIT.java
index 8f2bc73..c4e4665 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryMoreIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryMoreIT.java
@@ -44,7 +44,7 @@ import org.junit.Test;
 import com.google.common.collect.Lists;
 
 
-public class QueryMoreIT extends BaseHBaseManagedTimeIT {
+public class QueryMoreIT extends BaseHBaseManagedTimeTableReuseIT {
     
     private String dataTableName;
     //queryAgainstTenantSpecificView = true, dataTableSalted = true 
@@ -74,8 +74,9 @@ public class QueryMoreIT extends BaseHBaseManagedTimeIT {
     private void testQueryMore(boolean queryAgainstTenantSpecificView, boolean dataTableSalted) throws Exception {
         String[] tenantIds = new String[] {"00Dxxxxxtenant1", "00Dxxxxxtenant2", "00Dxxxxxtenant3"};
         int numRowsPerTenant = 10;
-        String cursorTableName = "CURSOR_TABLE";
-        this.dataTableName = "BASE_HISTORY_TABLE" + (dataTableSalted ? "_SALTED" : "");
+        String cursorTableName = generateRandomString();
+        String base_history_table = generateRandomString();
+        this.dataTableName = base_history_table + (dataTableSalted ? "_SALTED" : "");
         String cursorTableDDL = "CREATE TABLE IF NOT EXISTS " + 
                 cursorTableName +  " (\n" +  
                 "TENANT_ID VARCHAR(15) NOT NULL\n," +  
@@ -109,7 +110,8 @@ public class QueryMoreIT extends BaseHBaseManagedTimeIT {
         String cursorQueryId = "00TcursrqueryId";
         String tableOrViewName = queryAgainstTenantSpecificView ? ("HISTORY_TABLE_" + tenantId) : dataTableName;
         
-        assertEquals(numRowsPerTenant, upsertSelectRecordsInCursorTableForTenant(tableOrViewName, queryAgainstTenantSpecificView, tenantId, cursorQueryId));
+        assertEquals(numRowsPerTenant, upsertSelectRecordsInCursorTableForTenant(tableOrViewName, queryAgainstTenantSpecificView, tenantId, cursorQueryId,
+            cursorTableName));
         
         /*// assert that the data inserted in cursor table matches the data in the data table for tenantId.
         String selectDataTable = "SELECT TENANT_ID, PARENT_ID, CREATED_DATE, ENTITY_HISTORY_ID FROM BASE_HISTORY_TABLE WHERE TENANT_ID = ? ";
@@ -142,7 +144,8 @@ public class QueryMoreIT extends BaseHBaseManagedTimeIT {
         int numRecordsThatShouldBeRetrieved = numRowsPerTenant/2; // we will test for two rounds of query more.
         
         // get first batch of cursor ids out of the cursor table.
-        String[] cursorIds = getRecordsOutofCursorTable(tableOrViewName, queryAgainstTenantSpecificView, tenantId, cursorQueryId, startOrder, endOrder);
+        String[] cursorIds = getRecordsOutofCursorTable(tableOrViewName, queryAgainstTenantSpecificView, tenantId, cursorQueryId, startOrder, endOrder,
+            cursorTableName);
         assertEquals(numRecordsThatShouldBeRetrieved, cursorIds.length);
         // now query and fetch first batch of records.
         List<String> historyIds = doQueryMore(queryAgainstTenantSpecificView, tenantId, tableOrViewName, cursorIds);
@@ -150,7 +153,8 @@ public class QueryMoreIT extends BaseHBaseManagedTimeIT {
         assertEquals(historyIdsPerTenant.get(tenantId).subList(startOrder, endOrder), historyIds);
         
         // get the next batch of cursor ids out of the cursor table.
-        cursorIds = getRecordsOutofCursorTable(tableOrViewName, queryAgainstTenantSpecificView, tenantId, cursorQueryId, startOrder + numRecordsThatShouldBeRetrieved, endOrder + numRecordsThatShouldBeRetrieved);
+        cursorIds = getRecordsOutofCursorTable(tableOrViewName, queryAgainstTenantSpecificView, tenantId, cursorQueryId, startOrder + numRecordsThatShouldBeRetrieved, endOrder + numRecordsThatShouldBeRetrieved,
+            cursorTableName);
         assertEquals(numRecordsThatShouldBeRetrieved, cursorIds.length);
         // now query and fetch the next batch of records.
         historyIds = doQueryMore(queryAgainstTenantSpecificView, tenantId, tableOrViewName, cursorIds);
@@ -158,7 +162,8 @@ public class QueryMoreIT extends BaseHBaseManagedTimeIT {
         assertEquals(historyIdsPerTenant.get(tenantId).subList(startOrder + numRecordsThatShouldBeRetrieved, endOrder+ numRecordsThatShouldBeRetrieved), historyIds);
         
          // get the next batch of cursor ids out of the cursor table.
-        cursorIds = getRecordsOutofCursorTable(tableOrViewName, queryAgainstTenantSpecificView, tenantId, cursorQueryId, startOrder + 2 * numRecordsThatShouldBeRetrieved, endOrder + 2 * numRecordsThatShouldBeRetrieved);
+        cursorIds = getRecordsOutofCursorTable(tableOrViewName, queryAgainstTenantSpecificView, tenantId, cursorQueryId, startOrder + 2 * numRecordsThatShouldBeRetrieved, endOrder + 2 * numRecordsThatShouldBeRetrieved,
+            cursorTableName);
         // assert that there are no more cursorids left for this tenant.
         assertEquals(0, cursorIds.length);
     }
@@ -193,7 +198,8 @@ public class QueryMoreIT extends BaseHBaseManagedTimeIT {
         }
     }
     
-    private int upsertSelectRecordsInCursorTableForTenant(String tableOrViewName, boolean queryAgainstTenantView, String tenantId, String cursorQueryId) throws Exception {
+    private int upsertSelectRecordsInCursorTableForTenant(String tableOrViewName, boolean queryAgainstTenantView, String tenantId, String cursorQueryId,
+        final String cursorTable) throws Exception {
         String sequenceName = "\"" + tenantId + "_SEQ\"";
         Connection conn = queryAgainstTenantView ? getTenantSpecificConnection(tenantId) : DriverManager.getConnection(getUrl());
         
@@ -207,7 +213,7 @@ public class QueryMoreIT extends BaseHBaseManagedTimeIT {
             String tenantIdFilter = queryAgainstTenantView ? "" : " WHERE TENANT_ID = ? ";
             
             // Using dynamic columns, we can use the same cursor table for storing primary keys for all the tables.  
-            String upsertSelectDML = "UPSERT INTO CURSOR_TABLE " +
+            String upsertSelectDML = "UPSERT INTO " + cursorTable + " " +
                                      "(TENANT_ID, QUERY_ID, CURSOR_ORDER, PARENT_ID CHAR(15), CREATED_DATE DATE, ENTITY_HISTORY_ID CHAR(15)) " + 
                                      "SELECT ?, ?, NEXT VALUE FOR " + sequenceName + ", PARENT_ID, CREATED_DATE, ENTITY_HISTORY_ID " +
                                      " FROM " + tableOrViewName + tenantIdFilter;
@@ -240,13 +246,14 @@ public class QueryMoreIT extends BaseHBaseManagedTimeIT {
         return tenantViewName;
     }
     
-    private String[] getRecordsOutofCursorTable(String tableOrViewName, boolean queryAgainstTenantSpecificView, String tenantId, String cursorQueryId, int startOrder, int endOrder) throws Exception {
+    private String[] getRecordsOutofCursorTable(String tableOrViewName, boolean queryAgainstTenantSpecificView, String tenantId, String cursorQueryId,
+        int startOrder, int endOrder, final String cursorTable) throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         List<String> pkIds = new ArrayList<String>();
         String cols = queryAgainstTenantSpecificView ? "PARENT_ID, CREATED_DATE, ENTITY_HISTORY_ID" : "TENANT_ID, PARENT_ID, CREATED_DATE, ENTITY_HISTORY_ID";
         String dynCols = queryAgainstTenantSpecificView ? "(PARENT_ID CHAR(15), CREATED_DATE DATE, ENTITY_HISTORY_ID CHAR(15))" : "(TENANT_ID CHAR(15), PARENT_ID CHAR(15), CREATED_DATE DATE, ENTITY_HISTORY_ID CHAR(15))";
         String selectCursorSql = "SELECT " + cols + " " +
-                "FROM CURSOR_TABLE \n" +
+            "FROM " + cursorTable + " \n" +
                  dynCols +   " \n" + 
                 "WHERE TENANT_ID = ? AND \n" +  
                 "QUERY_ID = ? AND \n" + 
@@ -335,7 +342,7 @@ public class QueryMoreIT extends BaseHBaseManagedTimeIT {
     @SuppressWarnings("deprecation")
     @Test
     public void testNullBigDecimalWithScale() throws Exception {
-        final String table = "NULLBIGDECIMAL";
+        final String table = generateRandomString();
         final Connection conn = DriverManager.getConnection(getUrl());
         conn.setAutoCommit(true);
         try (Statement stmt = conn.createStatement()) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/RTrimFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RTrimFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RTrimFunctionIT.java
index 2caca2b..f691dd0 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RTrimFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RTrimFunctionIT.java
@@ -33,7 +33,7 @@ import org.apache.phoenix.util.QueryUtil;
 import org.junit.Test;
 
 
-public class RTrimFunctionIT extends BaseHBaseManagedTimeIT {
+public class RTrimFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
     
     @Test
     public void testWithFixedLengthAscPK() throws Exception {
@@ -48,23 +48,25 @@ public class RTrimFunctionIT extends BaseHBaseManagedTimeIT {
     private void testWithFixedLengthPK(SortOrder sortOrder, List<Object> expectedResults) throws Exception {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);
-        conn.createStatement().execute("CREATE TABLE rtrim_test ( k VARCHAR PRIMARY KEY " + (sortOrder == SortOrder.DESC ? "DESC" : "") + ")");
+        String tableName = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + tableName + " ( k VARCHAR PRIMARY KEY " + (sortOrder == SortOrder.DESC ? "DESC" : "") + ")");
 
-        conn.createStatement().execute("upsert into rtrim_test (k) values ('a')");
-        conn.createStatement().execute("upsert into rtrim_test (k) values ('b')");
-        conn.createStatement().execute("upsert into rtrim_test (k) values ('b ')");
-        conn.createStatement().execute("upsert into rtrim_test (k) values ('b  ')");
-        conn.createStatement().execute("upsert into rtrim_test (k) values ('b  a')");
-        conn.createStatement().execute("upsert into rtrim_test (k) values (' b  ')");
-        conn.createStatement().execute("upsert into rtrim_test (k) values ('c')");
+        conn.createStatement().execute("upsert into " + tableName + " (k) values ('a')");
+        conn.createStatement().execute("upsert into " + tableName + " (k) values ('b')");
+        conn.createStatement().execute("upsert into " + tableName + " (k) values ('b ')");
+        conn.createStatement().execute("upsert into " + tableName + " (k) values ('b  ')");
+        conn.createStatement().execute("upsert into " + tableName + " (k) values ('b  a')");
+        conn.createStatement().execute("upsert into " + tableName + " (k) values (' b  ')");
+        conn.createStatement().execute("upsert into " + tableName + " (k) values ('c')");
         conn.commit();
 
-        String query = "select k from rtrim_test WHERE rtrim(k)='b'";
+        String query = "select k from " + tableName + " WHERE rtrim(k)='b'";
         ResultSet rs = conn.createStatement().executeQuery(query);
         assertValueEqualsResultSet(rs, expectedResults);
         
         rs = conn.createStatement().executeQuery("explain " + query);
-        assertTrue(QueryUtil.getExplainPlan(rs).contains("RANGE SCAN OVER RTRIM_TEST"));
+        assertTrue(QueryUtil.getExplainPlan(rs).contains("RANGE SCAN OVER " + tableName));
         
         conn.close();
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReadOnlyIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReadOnlyIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReadOnlyIT.java
index bcc4ee8..0b86af0 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReadOnlyIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReadOnlyIT.java
@@ -32,19 +32,20 @@ import org.apache.phoenix.util.PropertiesUtil;
 import org.junit.Test;
 
 
-public class ReadOnlyIT extends BaseHBaseManagedTimeIT {
+public class ReadOnlyIT extends BaseHBaseManagedTimeTableReuseIT {
 
     @Test
     public void testConnectionReadOnly() throws Exception {
         
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);
-        String ddl = "CREATE TABLE test_table " +
+      String testTable = generateRandomString();
+      String ddl = "CREATE TABLE " + testTable + " " +
                         "  (r varchar not null, col1 integer" +
                         "  CONSTRAINT pk PRIMARY KEY (r))\n"; 
         createTestTable(getUrl(), ddl);
 
-        String query = "UPSERT INTO test_table(r, col1) VALUES('row1', 777)";
+        String query = "UPSERT INTO " + testTable + "(r, col1) VALUES('row1', 777)";
         PreparedStatement statement = conn.prepareStatement(query);
         statement.executeUpdate();
         conn.commit();
@@ -52,7 +53,7 @@ public class ReadOnlyIT extends BaseHBaseManagedTimeIT {
 	try{    
 		conn.setReadOnly(true);
                 assertTrue(conn.isReadOnly());
-		ddl = "CREATE TABLE test_table2 " +
+		ddl = "CREATE TABLE " + testTable + "2 " +
 				"  (r varchar not null, col1 integer" +
 				"  CONSTRAINT pk PRIMARY KEY (r))\n";
 		statement = conn.prepareStatement(ddl);
@@ -63,8 +64,8 @@ public class ReadOnlyIT extends BaseHBaseManagedTimeIT {
               assertTrue(e.getMessage(), e.getMessage().contains("ERROR 518 (25502): Mutations are not permitted for a read-only connection."));
         }
 	  
-	try {  
-                query = "UPSERT INTO test_table(r, col1) VALUES('row1', 888)";
+	try {
+                query = "UPSERT INTO " + testTable + "(r, col1) VALUES('row1', 888)";
                 statement = conn.prepareStatement(query);
                 statement.executeUpdate();
                 conn.commit();
@@ -75,14 +76,14 @@ public class ReadOnlyIT extends BaseHBaseManagedTimeIT {
 
 	conn.setReadOnly(false);
         assertFalse(conn.isReadOnly());
-        ddl = "ALTER TABLE test_table ADD col2 VARCHAR";
+        ddl = "ALTER TABLE " + testTable + " ADD col2 VARCHAR";
 	statement = conn.prepareStatement(ddl);
         statement.executeUpdate();
 	conn.commit();
 
         try {   
 		conn.setReadOnly(true);
-                ddl = "ALTER TABLE test_table ADD col3 VARCHAR";
+                ddl = "ALTER TABLE " + testTable + " ADD col3 VARCHAR";
 		statement = conn.prepareStatement(ddl);
         	statement.executeUpdate();
                 fail();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/RegexpSplitFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RegexpSplitFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RegexpSplitFunctionIT.java
index 5170089..50b7a80 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RegexpSplitFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RegexpSplitFunctionIT.java
@@ -31,23 +31,32 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
 
+import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 
-public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
+public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
+
+    private static final String SPLIT_TEST = generateRandomString();
+
+    @BeforeClass
+    public static void setup() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String ddl = "CREATE TABLE " + SPLIT_TEST + " (" +
+            "ID INTEGER NOT NULL PRIMARY KEY," +
+            "VAL VARCHAR," +
+            "SEP VARCHAR," +
+            "ARR VARCHAR ARRAY)";
+        conn.createStatement().execute(ddl);
+    }
 
     private void initTable(Connection conn, String val) throws SQLException {
         initTable(conn, val, ",");
     }
 
     private void initTable(Connection conn, String val, String separator) throws SQLException {
-        String ddl = "CREATE TABLE SPLIT_TEST (" +
-                "ID INTEGER NOT NULL PRIMARY KEY," +
-                "VAL VARCHAR," +
-                "SEP VARCHAR," +
-                "ARR VARCHAR ARRAY)";
-        conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO SPLIT_TEST (ID, SEP, VAL) VALUES (?, ?, ?)";
+        String dml = "UPSERT INTO " + SPLIT_TEST + " (ID, SEP, VAL) VALUES (?, ?, ?)";
         PreparedStatement stmt = conn.prepareStatement(dml);
         stmt.setInt(1, 1);
         if (separator == null) {
@@ -70,7 +79,7 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         initTable(conn, "ONE,TWO,THREE");
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT REGEXP_SPLIT(VAL, ',')[1] FROM SPLIT_TEST");
+            "SELECT REGEXP_SPLIT(VAL, ',')[1] FROM " + SPLIT_TEST);
         assertTrue(rs.next());
         assertEquals("ONE", rs.getString(1));
         assertFalse(rs.next());
@@ -82,7 +91,7 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         initTable(conn, "ONE,TWO,THREE");
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT ID FROM SPLIT_TEST WHERE (REGEXP_SPLIT(VAL, ','))[1] = 'ONE'");
+            "SELECT ID FROM " + SPLIT_TEST + " WHERE (REGEXP_SPLIT(VAL, ','))[1] = 'ONE'");
         assertTrue(rs.next());
         assertEquals(1, rs.getInt(1));
         assertFalse(rs.next());
@@ -93,11 +102,12 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl());
         initTable(conn, "ONE,TWO,THREE");
 
-        conn.createStatement().executeUpdate("UPSERT INTO SPLIT_TEST (ID, ARR) SELECT ID, " +
-                "REGEXP_SPLIT(VAL, ',') FROM SPLIT_TEST");
+        conn.createStatement().executeUpdate(
+            "UPSERT INTO " + SPLIT_TEST + " (ID, ARR) SELECT ID, " + "REGEXP_SPLIT(VAL, ',') FROM "
+                + SPLIT_TEST);
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT ARR FROM SPLIT_TEST");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT ARR FROM " + SPLIT_TEST);
         assertTrue(rs.next());
         Array array = rs.getArray(1);
         String[] values = (String[]) array.getArray();
@@ -110,7 +120,7 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         initTable(conn, "ONE:TWO:THREE");
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT REGEXP_SPLIT(VAL, ':') FROM SPLIT_TEST");
+            "SELECT REGEXP_SPLIT(VAL, ':') FROM " + SPLIT_TEST);
         assertTrue(rs.next());
         Array array = rs.getArray(1);
         String[] values = (String[]) array.getArray();
@@ -123,7 +133,7 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         initTable(conn, "ONE,TWO,THREE");
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT REGEXP_SPLIT(VAL, SEP) FROM SPLIT_TEST");
+            "SELECT REGEXP_SPLIT(VAL, SEP) FROM " + SPLIT_TEST);
         assertTrue(rs.next());
         Array array = rs.getArray(1);
         String[] values = (String[]) array.getArray();
@@ -136,7 +146,7 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         initTable(conn, "CANNOT BE SPLIT");
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT REGEXP_SPLIT(VAL, ',') FROM SPLIT_TEST");
+            "SELECT REGEXP_SPLIT(VAL, ',') FROM " + SPLIT_TEST);
         assertTrue(rs.next());
         Array array = rs.getArray(1);
         String[] values = (String[]) array.getArray();
@@ -149,7 +159,7 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         initTable(conn, "ONE!:TWO:::!THREE::!:FOUR");
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT REGEXP_SPLIT(VAL, '[:!]+') FROM SPLIT_TEST");
+            "SELECT REGEXP_SPLIT(VAL, '[:!]+') FROM " + SPLIT_TEST);
         assertTrue(rs.next());
         Array array = rs.getArray(1);
         String[] values = (String[]) array.getArray();
@@ -162,7 +172,7 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         initTable(conn, "ONE|TWO|THREE");
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT REGEXP_SPLIT(VAL, '\\\\|') FROM SPLIT_TEST");
+            "SELECT REGEXP_SPLIT(VAL, '\\\\|') FROM " + SPLIT_TEST);
         assertTrue(rs.next());
         Array array = rs.getArray(1);
         String[] values = (String[]) array.getArray();
@@ -175,7 +185,7 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         initTable(conn, null);
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT REGEXP_SPLIT(VAL, ',') FROM SPLIT_TEST");
+            "SELECT REGEXP_SPLIT(VAL, ',') FROM " + SPLIT_TEST);
         assertTrue(rs.next());
         assertNull(rs.getString(1));
         assertFalse(rs.next());
@@ -187,7 +197,7 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         initTable(conn, "ONE,TWO,THREE");
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT REGEXP_SPLIT(VAL, NULL) FROM SPLIT_TEST");
+            "SELECT REGEXP_SPLIT(VAL, NULL) FROM " + SPLIT_TEST);
         assertTrue(rs.next());
         assertNull(rs.getString(1));
         assertFalse(rs.next());
@@ -199,7 +209,7 @@ public class RegexpSplitFunctionIT extends BaseHBaseManagedTimeIT {
         initTable(conn, "ONE,TWO,THREE", null);
 
         ResultSet rs = conn.createStatement().executeQuery(
-                "SELECT REGEXP_SPLIT(VAL, SEP) FROM SPLIT_TEST");
+            "SELECT REGEXP_SPLIT(VAL, SEP) FROM " + SPLIT_TEST);
         assertTrue(rs.next());
         assertNull(rs.getString(1));
         assertFalse(rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReverseFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReverseFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReverseFunctionIT.java
index f384d3a..3a1f8c2 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReverseFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ReverseFunctionIT.java
@@ -30,28 +30,32 @@ import java.sql.ResultSet;
 import org.junit.Test;
 
 
-public class ReverseFunctionIT extends BaseHBaseManagedTimeIT {
-    private void initTable(Connection conn, String sortOrder, String s) throws Exception {
-        String ddl = "CREATE TABLE REVERSE_TEST (pk VARCHAR NOT NULL PRIMARY KEY " + sortOrder + ", kv VARCHAR)";
+public class ReverseFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
+
+    private String initTable(Connection conn, String sortOrder, String s) throws Exception {
+        String reverseTest =  generateRandomString();
+        String ddl = "CREATE TABLE " + reverseTest + " (pk VARCHAR NOT NULL PRIMARY KEY " + sortOrder + ", kv VARCHAR)";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO REVERSE_TEST VALUES(?)";
+        String dml = "UPSERT INTO " + reverseTest + " VALUES(?)";
         PreparedStatement stmt = conn.prepareStatement(dml);
         stmt.setString(1, s);
         stmt.execute();
-        conn.commit();        
+        conn.commit();
+        return reverseTest;
     }
     
-    private void testReverse(Connection conn, String s) throws Exception {
+    private void testReverse(Connection conn, String s, String tableName) throws Exception {
         StringBuilder buf = new StringBuilder(s);
         String reverse = buf.reverse().toString();
         
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT reverse(pk) FROM REVERSE_TEST");
+        rs = conn.createStatement().executeQuery("SELECT reverse(pk) FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(reverse, rs.getString(1));
         assertFalse(rs.next());
         
-        PreparedStatement stmt = conn.prepareStatement("SELECT pk FROM REVERSE_TEST WHERE pk=reverse(?)");
+        PreparedStatement stmt = conn.prepareStatement(
+            "SELECT pk FROM " + tableName + " WHERE pk=reverse(?)");
         stmt.setString(1, reverse);
         rs = stmt.executeQuery();
         assertTrue(rs.next());
@@ -63,16 +67,16 @@ public class ReverseFunctionIT extends BaseHBaseManagedTimeIT {
     public void testSingleByteReverseAscending() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         String s = "abc";
-        initTable(conn, "ASC", s);
-        testReverse(conn, s);
+        String tableName = initTable(conn, "ASC", s);
+        testReverse(conn, s, tableName);
     }                                                           
 
     @Test
     public void testMultiByteReverseAscending() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         String s = "ɚɦɰɸ";
-        initTable(conn, "DESC", s);
-        testReverse(conn, s);
+        String tableName = initTable(conn, "DESC", s);
+        testReverse(conn, s, tableName);
     }                                                           
 
     
@@ -80,26 +84,26 @@ public class ReverseFunctionIT extends BaseHBaseManagedTimeIT {
     public void testSingleByteReverseDecending() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         String s = "abc";
-        initTable(conn, "DESC", s);
-        testReverse(conn, s);
+        String tableName = initTable(conn, "DESC", s);
+        testReverse(conn, s, tableName);
     }                                                           
 
     @Test
     public void testMultiByteReverseDecending() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         String s = "ɚɦɰɸ";
-        initTable(conn, "ASC", s);
-        testReverse(conn, s);
+        String tableName = initTable(conn, "ASC", s);
+        testReverse(conn, s, tableName);
     }
     
     @Test
     public void testNullReverse() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         String s = "abc";
-        initTable(conn, "ASC", s);
-        
+        String tableName = initTable(conn, "ASC", s);
+
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT reverse(kv) FROM REVERSE_TEST");
+        rs = conn.createStatement().executeQuery("SELECT reverse(kv) FROM " + tableName);
         assertTrue(rs.next());
         assertNull(rs.getString(1));
         assertFalse(rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/RoundFloorCeilFunctionsEnd2EndIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RoundFloorCeilFunctionsEnd2EndIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RoundFloorCeilFunctionsEnd2EndIT.java
index 753d592..c365934 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RoundFloorCeilFunctionsEnd2EndIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RoundFloorCeilFunctionsEnd2EndIT.java
@@ -55,9 +55,10 @@ import com.google.common.primitives.Floats;
  */
 
 
-public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
-    
-    private static long millisPart = 660;
+public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeTableReuseIT {
+
+  private static final String TABLE_NAME = generateRandomString();
+  private static long millisPart = 660;
     private static int nanosPart = 500100;
     private static BigDecimal decimalUpserted = BigDecimal.valueOf(1.264);
     private static double doubleUpserted = 1.264d;
@@ -72,7 +73,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
         PreparedStatement stmt = null;
         try {
             conn = DriverManager.getConnection(getUrl());
-            String ddl = "CREATE TABLE IF NOT EXISTS t1 (s VARCHAR NOT NULL PRIMARY KEY, dt DATE, t TIME, ts TIMESTAMP, dec DECIMAL, doub DOUBLE, undoub UNSIGNED_DOUBLE, fl FLOAT, unfl UNSIGNED_FLOAT)";
+            String ddl = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME
+                + " (s VARCHAR NOT NULL PRIMARY KEY, dt DATE, t TIME, ts TIMESTAMP, dec DECIMAL, doub DOUBLE, undoub UNSIGNED_DOUBLE, fl FLOAT, unfl UNSIGNED_FLOAT)";
             conn.createStatement().execute(ddl);
             
             Date dateUpserted = DateUtil.parseDate("2012-01-01 14:25:28");
@@ -82,7 +84,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
             Time timeUpserted = new Time(millis);
             Timestamp tsUpserted = DateUtil.getTimestamp(millis, nanosPart);
             
-            stmt =  conn.prepareStatement("UPSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
+            stmt =  conn.prepareStatement(
+                "UPSERT INTO " + TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
             stmt.setString(1, testString);
             stmt.setDate(2, dateUpserted);
             stmt.setTime(3, timeUpserted);
@@ -103,7 +106,7 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     public void testRoundingUpDate() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(dt, 'day'), ROUND(dt, 'hour', 1), ROUND(dt, 'minute', 1), ROUND(dt, 'second', 1), "
-                + " ROUND(dt,'week'), ROUND(dt,'month') , ROUND(dt,'year') FROM t1");
+                + " ROUND(dt,'week'), ROUND(dt,'month') , ROUND(dt,'year') FROM " + TABLE_NAME);
         assertTrue(rs.next());
         Date expectedDate = DateUtil.parseDate("2012-01-02 00:00:00");
         assertEquals(expectedDate, rs.getDate(1));
@@ -124,7 +127,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testRoundingUpDateInWhere() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE ROUND(dt, 'day') = to_date('2012-01-02 00:00:00')");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + TABLE_NAME
+            + " WHERE ROUND(dt, 'day') = to_date('2012-01-02 00:00:00')");
         assertTrue(rs.next());
     }
     
@@ -132,7 +136,7 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     public void testFloorDate() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(dt, 'day', 1), FLOOR(dt, 'hour', 1), FLOOR(dt, 'minute', 1), FLOOR(dt, 'second', 1),"
-                + " FLOOR(dt,'week'), FLOOR(dt,'month'), FLOOR(dt,'year') FROM t1");
+                + " FLOOR(dt,'week'), FLOOR(dt,'month'), FLOOR(dt,'year') FROM " + TABLE_NAME);
         assertTrue(rs.next());
         Date expectedDate = DateUtil.parseDate("2012-01-01 00:00:00");
         assertEquals(expectedDate, rs.getDate(1));
@@ -153,7 +157,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testFloorDateInWhere() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE FLOOR(dt, 'hour') = to_date('2012-01-01 14:00:00')");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + TABLE_NAME
+            + " WHERE FLOOR(dt, 'hour') = to_date('2012-01-01 14:00:00')");
         assertTrue(rs.next());
     }
     
@@ -161,7 +166,7 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     public void testCeilDate() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(dt, 'day', 1), CEIL(dt, 'hour', 1), CEIL(dt, 'minute', 1), CEIL(dt, 'second', 1), "
-                + " CEIL(dt,'week') , CEIL(dt,'month') , CEIL(dt,'year')  FROM t1");
+                + " CEIL(dt,'week') , CEIL(dt,'month') , CEIL(dt,'year')  FROM " + TABLE_NAME);
         assertTrue(rs.next());
         //Date upserted is 2012-01-01 14:25:28.660. So we will end up bumping up in every case.
         Date expectedDate = DateUtil.parseDate("2012-01-02 00:00:00");
@@ -184,14 +189,17 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testCeilDateInWhere() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE CEIL(dt, 'second') = to_date('2012-01-01 14:25:29')");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + TABLE_NAME
+            + " WHERE CEIL(dt, 'second') = to_date('2012-01-01 14:25:29')");
         assertTrue(rs.next());
     }
     
     @Test
     public void testRoundingUpTimestamp() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(ts, 'day'), ROUND(ts, 'hour', 1), ROUND(ts, 'minute', 1), ROUND(ts, 'second', 1), ROUND(ts, 'millisecond', 1) FROM t1");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT ROUND(ts, 'day'), ROUND(ts, 'hour', 1), ROUND(ts, 'minute', 1), ROUND(ts, 'second', 1), ROUND(ts, 'millisecond', 1) FROM "
+                + TABLE_NAME);
         assertTrue(rs.next());
         Timestamp expectedTimestamp;
         expectedTimestamp = new Timestamp(DateUtil.parseDate("2012-01-02 00:00:00").getTime());
@@ -212,7 +220,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testRoundingUpTimestampInWhere() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE ROUND(ts, 'second') = to_date('2012-01-01 14:25:29')");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + TABLE_NAME
+            + " WHERE ROUND(ts, 'second') = to_date('2012-01-01 14:25:29')");
         assertTrue(rs.next());
     }
     
@@ -220,7 +229,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     public void testFloorTimestamp() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(ts, 'day'), FLOOR(ts, 'hour', 1), FLOOR(ts, 'minute', 1), FLOOR(ts, 'second', 1), "
-                + " FLOOR(ts, 'millisecond', 1) , FLOOR(ts,'week') , FLOOR(ts,'month') FROM t1");
+                + " FLOOR(ts, 'millisecond', 1) , FLOOR(ts,'week') , FLOOR(ts,'month') FROM "
+            + TABLE_NAME);
         assertTrue(rs.next());
         Timestamp expectedTimestamp;
         expectedTimestamp = new Timestamp(DateUtil.parseDate("2012-01-01 00:00:00").getTime());
@@ -244,14 +254,16 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testFloorTimestampInWhere() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE FLOOR(ts, 'second') = to_date('2012-01-01 14:25:28')");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + TABLE_NAME
+            + " WHERE FLOOR(ts, 'second') = to_date('2012-01-01 14:25:28')");
         assertTrue(rs.next());
     }
     
     @Test
     public void testWeekFloorTimestampInWhere() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE FLOOR(ts, 'week') = to_date('2011-12-26 00:00:00')");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + TABLE_NAME
+            + " WHERE FLOOR(ts, 'week') = to_date('2011-12-26 00:00:00')");
         assertTrue(rs.next());
     }
     
@@ -259,7 +271,7 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     public void testCeilTimestamp() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(ts, 'day'), CEIL(ts, 'hour', 1), CEIL(ts, 'minute', 1), CEIL(ts, 'second', 1), CEIL(ts, 'millisecond', 1),"
-                + " CEIL(ts,'week'), CEIL(ts,'month') , CEIL(ts,'year') FROM t1");
+                + " CEIL(ts,'week'), CEIL(ts,'month') , CEIL(ts,'year') FROM " + TABLE_NAME);
         assertTrue(rs.next());
         Timestamp expectedTimestamp;
         expectedTimestamp = new Timestamp(DateUtil.parseDate("2012-01-02 00:00:00").getTime());
@@ -286,7 +298,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testCeilTimestampInWhere() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE CEIL(ts, 'second') = to_date('2012-01-01 14:25:29')");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + TABLE_NAME
+            + " WHERE CEIL(ts, 'second') = to_date('2012-01-01 14:25:29')");
         assertTrue(rs.next());
     }
     
@@ -294,7 +307,7 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     public void testRoundingUpTime() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(t, 'day', 1), ROUND(t, 'hour', 1), ROUND(t, 'minute', 1), ROUND(t, 'second', 1),"
-                + " ROUND(t,'week') , ROUND(t,'month') , ROUND(t,'year') FROM t1");
+                + " ROUND(t,'week') , ROUND(t,'month') , ROUND(t,'year') FROM " + TABLE_NAME);
         assertTrue(rs.next());
         Time expectedTime = new Time(DateUtil.parseDate("2012-01-02 00:00:00").getTime());
         assertEquals(expectedTime, rs.getTime(1));
@@ -316,7 +329,7 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     public void testFloorTime() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(t, 'day', 1), FLOOR(t, 'hour', 1), FLOOR(t, 'minute', 1), FLOOR(t, 'second', 1), "
-                + " FLOOR(t, 'week'),  FLOOR(t, 'month'), FLOOR(t, 'year') FROM t1");
+                + " FLOOR(t, 'week'),  FLOOR(t, 'month'), FLOOR(t, 'year') FROM " + TABLE_NAME);
         assertTrue(rs.next());
         Time expectedTime = new Time(DateUtil.parseDate("2012-01-01 00:00:00").getTime());
         assertEquals(expectedTime, rs.getTime(1));
@@ -338,7 +351,7 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     public void testCeilTime() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(t, 'day', 1), CEIL(t, 'hour', 1), CEIL(t, 'minute', 1), CEIL(t, 'second', 1),"
-                + " CEIL(t,'week') , CEIL(t,'month') , CEIL(t,'year') FROM t1");
+                + " CEIL(t,'week') , CEIL(t,'month') , CEIL(t,'year') FROM " + TABLE_NAME);
         assertTrue(rs.next());
         Time expectedTime = new Time(DateUtil.parseDate("2012-01-02 00:00:00").getTime());
         assertEquals(expectedTime, rs.getTime(1));
@@ -359,7 +372,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testRoundingUpDecimal() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(dec), ROUND(dec, 1), ROUND(dec, 2), ROUND(dec, 3) FROM t1");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT ROUND(dec), ROUND(dec, 1), ROUND(dec, 2), ROUND(dec, 3) FROM " + TABLE_NAME);
         assertTrue(rs.next());
         BigDecimal expectedBd = BigDecimal.valueOf(1);
         assertEquals(expectedBd, rs.getBigDecimal(1));
@@ -374,14 +388,16 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testRoundingUpDecimalInWhere() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE ROUND(dec, 2) = 1.26");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT * FROM " + TABLE_NAME + " WHERE ROUND(dec, 2) = 1.26");
         assertTrue(rs.next());
     }
     
     @Test
     public void testFloorDecimal() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(dec), FLOOR(dec, 1), FLOOR(dec, 2), FLOOR(dec, 3) FROM t1");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT FLOOR(dec), FLOOR(dec, 1), FLOOR(dec, 2), FLOOR(dec, 3) FROM " + TABLE_NAME);
         assertTrue(rs.next());
         BigDecimal expectedBd = BigDecimal.valueOf(1);
         assertEquals(expectedBd, rs.getBigDecimal(1));
@@ -396,14 +412,16 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testFloorDecimalInWhere() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE FLOOR(dec, 2) = 1.26");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT * FROM " + TABLE_NAME + " WHERE FLOOR(dec, 2) = 1.26");
         assertTrue(rs.next());
     }
     
     @Test
     public void testCeilDecimal() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(dec), CEIL(dec, 1), CEIL(dec, 2), CEIL(dec, 3) FROM t1");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT CEIL(dec), CEIL(dec, 1), CEIL(dec, 2), CEIL(dec, 3) FROM " + TABLE_NAME);
         assertTrue(rs.next());
         BigDecimal expectedBd = BigDecimal.valueOf(2);
         assertEquals(expectedBd, rs.getBigDecimal(1));
@@ -418,13 +436,15 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testCeilDecimalInWhere() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE CEIL(dec, 2) = 1.27");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT * FROM " + TABLE_NAME + " WHERE CEIL(dec, 2) = 1.27");
         assertTrue(rs.next());
     }
     @Test
 	public void testRoundingUpDouble() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(doub), ROUND(doub, 1), ROUND(doub, 2), ROUND(doub, 3) FROM t1");
+		ResultSet rs = conn.createStatement().executeQuery(
+        "SELECT ROUND(doub), ROUND(doub, 1), ROUND(doub, 2), ROUND(doub, 3) FROM " + TABLE_NAME);
 		assertTrue(rs.next());
 		assertEquals(0, Doubles.compare(1, rs.getDouble(1)));
 		assertEquals(0, Doubles.compare(1.3, rs.getDouble(2)));
@@ -435,14 +455,16 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void testRoundingUpDoubleInWhere() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE ROUND(dec, 2) = 1.26");
+		ResultSet rs = conn.createStatement().executeQuery(
+        "SELECT * FROM " + TABLE_NAME + " WHERE ROUND(dec, 2) = 1.26");
 		assertTrue(rs.next());
 	}
 
 	@Test
 	public void testCeilDouble() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		ResultSet rs = conn.createStatement().executeQuery("SELECT CEIL(doub), CEIL(doub, 1), CEIL(doub, 2), CEIL(doub, 3) FROM t1");
+		ResultSet rs = conn.createStatement().executeQuery(
+        "SELECT CEIL(doub), CEIL(doub, 1), CEIL(doub, 2), CEIL(doub, 3) FROM " + TABLE_NAME);
 		assertTrue(rs.next());
 		assertEquals(0, Doubles.compare(2, rs.getDouble(1)));
 		assertEquals(0, Doubles.compare(1.3, rs.getDouble(2)));
@@ -453,14 +475,16 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void testCeilDoubleInWhere() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE CEIL(doub, 2) = 1.27");
+		ResultSet rs = conn.createStatement().executeQuery(
+        "SELECT * FROM " + TABLE_NAME + " WHERE CEIL(doub, 2) = 1.27");
 		assertTrue(rs.next());
 	}
 
 	@Test
 	public void testFloorDouble() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		ResultSet rs = conn.createStatement().executeQuery("SELECT FLOOR(doub), FLOOR(doub, 1), FLOOR(doub, 2), FLOOR(doub, 3) FROM t1");
+		ResultSet rs = conn.createStatement().executeQuery(
+        "SELECT FLOOR(doub), FLOOR(doub, 1), FLOOR(doub, 2), FLOOR(doub, 3) FROM " + TABLE_NAME);
 		assertTrue(rs.next());
 		assertEquals(0, Doubles.compare(1, rs.getDouble(1)));
 		assertEquals(0, Doubles.compare(1.2, rs.getDouble(2)));
@@ -471,14 +495,16 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void testFloorDoubleInWhere() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM t1 WHERE FLOOR(doub, 2) = 1.26");
+		ResultSet rs = conn.createStatement().executeQuery(
+        "SELECT * FROM " + TABLE_NAME + " WHERE FLOOR(doub, 2) = 1.26");
 		assertTrue(rs.next());
 	}
 	
 	@Test
 	public void testRoundFloat() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(fl), ROUND(fl, 1), ROUND(fl, 2), ROUND(fl, 3) FROM t1");
+		ResultSet rs = conn.createStatement().executeQuery(
+        "SELECT ROUND(fl), ROUND(fl, 1), ROUND(fl, 2), ROUND(fl, 3) FROM " + TABLE_NAME);
 		assertTrue(rs.next());
 		assertEquals(0, Floats.compare(1, rs.getFloat(1)));
 		assertEquals(0, Floats.compare(1.3f, rs.getFloat(2)));
@@ -489,7 +515,8 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void testRoundUnsignedFloat() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(unfl), ROUND(unfl, 1), ROUND(unfl, 2), ROUND(unfl, 3) FROM t1");
+		ResultSet rs = conn.createStatement().executeQuery(
+        "SELECT ROUND(unfl), ROUND(unfl, 1), ROUND(unfl, 2), ROUND(unfl, 3) FROM " + TABLE_NAME);
 		assertTrue(rs.next());
 		assertEquals(0, Floats.compare(1, rs.getFloat(1)));
 		assertEquals(0, Floats.compare(1.3f, rs.getFloat(2)));
@@ -500,7 +527,9 @@ public class RoundFloorCeilFunctionsEnd2EndIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void testRoundUnsignedDouble() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		ResultSet rs = conn.createStatement().executeQuery("SELECT ROUND(undoub), ROUND(undoub, 1), ROUND(undoub, 2), ROUND(undoub, 3) FROM t1");
+		ResultSet rs = conn.createStatement().executeQuery(
+        "SELECT ROUND(undoub), ROUND(undoub, 1), ROUND(undoub, 2), ROUND(undoub, 3) FROM "
+            + TABLE_NAME);
 		assertTrue(rs.next());
 		assertEquals(0, Floats.compare(1, rs.getFloat(1)));
 		assertEquals(0, Floats.compare(1.3f, rs.getFloat(2)));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/ServerExceptionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ServerExceptionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ServerExceptionIT.java
index 5c8679d..e4f3c1d 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ServerExceptionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ServerExceptionIT.java
@@ -32,7 +32,7 @@ import org.apache.phoenix.util.PropertiesUtil;
 import org.junit.Test;
 
 
-public class ServerExceptionIT extends BaseHBaseManagedTimeIT {
+public class ServerExceptionIT extends BaseHBaseManagedTimeTableReuseIT {
 
     @Test
     public void testServerExceptionBackToClient() throws Exception {
@@ -40,11 +40,12 @@ public class ServerExceptionIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE IF NOT EXISTS t1(pk VARCHAR NOT NULL PRIMARY KEY, " +
+            String t1 = generateRandomString();
+            String ddl = "CREATE TABLE IF NOT EXISTS " + t1 + "(pk VARCHAR NOT NULL PRIMARY KEY, " +
                     "col1 INTEGER, col2 INTEGER)";
             createTestTable(getUrl(), ddl);
             
-            String query = "UPSERT INTO t1 VALUES(?,?,?)";
+            String query = "UPSERT INTO " + t1 + " VALUES(?,?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "1");
             stmt.setInt(2, 1);
@@ -52,7 +53,7 @@ public class ServerExceptionIT extends BaseHBaseManagedTimeIT {
             stmt.execute();
             conn.commit();
             
-            query = "SELECT * FROM t1 where col1/col2 > 0";
+            query = "SELECT * FROM " + t1 + " where col1/col2 > 0";
             stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             rs.next();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/SignFunctionEnd2EndIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SignFunctionEnd2EndIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SignFunctionEnd2EndIT.java
index 6634d23..5c86955 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SignFunctionEnd2EndIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SignFunctionEnd2EndIT.java
@@ -29,26 +29,31 @@ import java.sql.ResultSet;
 
 import org.apache.phoenix.expression.function.SignFunction;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
  * End to end tests for {@link SignFunction}
  * @since 4.0.0
  */
-public class SignFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
+public class SignFunctionEnd2EndIT extends BaseHBaseManagedTimeTableReuseIT {
 
     private static final String KEY = "key";
+    private static final String TEST_SIGNED = generateRandomString();
+    private static final String TEST_UNSIGNED = generateRandomString();
 
-    @Before
-    public void initTable() throws Exception {
+    @BeforeClass
+    public static void initTable() throws Exception {
         Connection conn = null;
         PreparedStatement stmt = null;
         try {
             conn = DriverManager.getConnection(getUrl());
             String ddl;
-            ddl = "CREATE TABLE testSigned (k VARCHAR NOT NULL PRIMARY KEY, dec DECIMAL, doub DOUBLE, fl FLOAT, inte INTEGER, lon BIGINT, smalli SMALLINT, tinyi TINYINT)";
+            ddl = "CREATE TABLE " + TEST_SIGNED
+                + " (k VARCHAR NOT NULL PRIMARY KEY, dec DECIMAL, doub DOUBLE, fl FLOAT, inte INTEGER, lon BIGINT, smalli SMALLINT, tinyi TINYINT)";
             conn.createStatement().execute(ddl);
-            ddl = "CREATE TABLE testUnsigned (k VARCHAR NOT NULL PRIMARY KEY, doub UNSIGNED_DOUBLE, fl UNSIGNED_FLOAT, inte UNSIGNED_INT, lon UNSIGNED_LONG, smalli UNSIGNED_SMALLINT, tinyi UNSIGNED_TINYINT)";
+            ddl = "CREATE TABLE " + TEST_UNSIGNED
+                + " (k VARCHAR NOT NULL PRIMARY KEY, doub UNSIGNED_DOUBLE, fl UNSIGNED_FLOAT, inte UNSIGNED_INT, lon UNSIGNED_LONG, smalli UNSIGNED_SMALLINT, tinyi UNSIGNED_TINYINT)";
             conn.createStatement().execute(ddl);
             conn.commit();
         } finally {
@@ -57,7 +62,8 @@ public class SignFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
     }
 
     private void updateSignedTable(Connection conn, double data) throws Exception {
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO testSigned VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + TEST_SIGNED + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
         stmt.setString(1, KEY);
         Double d = Double.valueOf(data);
         stmt.setBigDecimal(2, BigDecimal.valueOf(data));
@@ -72,7 +78,8 @@ public class SignFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
     }
 
     private void updateUnsignedTable(Connection conn, double data) throws Exception {
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO testUnsigned VALUES (?, ?, ?, ?, ?, ?, ?)");
+        PreparedStatement stmt = conn.prepareStatement(
+            "UPSERT INTO " + TEST_UNSIGNED + " VALUES (?, ?, ?, ?, ?, ?, ?)");
         stmt.setString(1, KEY);
         Double d = Double.valueOf(data);
         stmt.setDouble(2, d.doubleValue());
@@ -87,14 +94,17 @@ public class SignFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
 
     private void testSignedNumberSpec(Connection conn, double data, int expected) throws Exception {
         updateSignedTable(conn, data);
-        ResultSet rs = conn.createStatement().executeQuery("SELECT SIGN(dec),SIGN(doub),SIGN(fl),SIGN(inte),SIGN(lon),SIGN(smalli),SIGN(tinyi) FROM testSigned");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT SIGN(dec),SIGN(doub),SIGN(fl),SIGN(inte),SIGN(lon),SIGN(smalli),SIGN(tinyi) FROM "
+                + TEST_SIGNED);
         assertTrue(rs.next());
         for (int i = 1; i <= 7; ++i) {
             assertEquals(rs.getInt(i), expected);
         }
         assertTrue(!rs.next());
 
-        PreparedStatement stmt = conn.prepareStatement("SELECT k FROM testSigned WHERE SIGN(dec)=? AND SIGN(doub)=? AND SIGN(fl)=? AND SIGN(inte)=? AND SIGN(lon)=? AND SIGN(smalli)=? AND SIGN(tinyi)=?");
+        PreparedStatement stmt = conn.prepareStatement("SELECT k FROM " + TEST_SIGNED
+            + " WHERE SIGN(dec)=? AND SIGN(doub)=? AND SIGN(fl)=? AND SIGN(inte)=? AND SIGN(lon)=? AND SIGN(smalli)=? AND SIGN(tinyi)=?");
         for (int i = 1; i <= 7; ++i)
             stmt.setInt(i, expected);
         rs = stmt.executeQuery();
@@ -105,14 +115,17 @@ public class SignFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
 
     private void testUnsignedNumberSpec(Connection conn, double data, int expected) throws Exception {
         updateUnsignedTable(conn, data);
-        ResultSet rs = conn.createStatement().executeQuery("SELECT SIGN(doub),SIGN(fl),SIGN(inte),SIGN(lon),SIGN(smalli),SIGN(tinyi) FROM testUnsigned");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT SIGN(doub),SIGN(fl),SIGN(inte),SIGN(lon),SIGN(smalli),SIGN(tinyi) FROM "
+                + TEST_UNSIGNED);
         assertTrue(rs.next());
         for (int i = 1; i <= 6; ++i) {
             assertEquals(rs.getInt(i), expected);
         }
         assertTrue(!rs.next());
 
-        PreparedStatement stmt = conn.prepareStatement("SELECT k FROM testUnsigned WHERE SIGN(doub)=? AND SIGN(fl)=? AND SIGN(inte)=? AND SIGN(lon)=? AND SIGN(smalli)=? AND SIGN(tinyi)=?");
+        PreparedStatement stmt = conn.prepareStatement("SELECT k FROM " + TEST_UNSIGNED
+            + " WHERE SIGN(doub)=? AND SIGN(fl)=? AND SIGN(inte)=? AND SIGN(lon)=? AND SIGN(smalli)=? AND SIGN(tinyi)=?");
         for (int i = 1; i <= 6; ++i)
             stmt.setInt(i, expected);
         rs = stmt.executeQuery();


[19/52] [abbrv] phoenix git commit: PHOENIX-1311 HBase namespaces surfaced in phoenix

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 76b2f51..ad161fa 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -47,6 +47,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_STATE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_TYPE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_ARRAY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_CONSTANT;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_NAMESPACE_MAPPED;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_ROW_TIMESTAMP;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_VIEW_REFERENCED;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.JAR_PATH;
@@ -157,17 +158,20 @@ import org.apache.phoenix.parse.ColumnDefInPkConstraint;
 import org.apache.phoenix.parse.ColumnName;
 import org.apache.phoenix.parse.CreateFunctionStatement;
 import org.apache.phoenix.parse.CreateIndexStatement;
+import org.apache.phoenix.parse.CreateSchemaStatement;
 import org.apache.phoenix.parse.CreateSequenceStatement;
 import org.apache.phoenix.parse.CreateTableStatement;
 import org.apache.phoenix.parse.DropColumnStatement;
 import org.apache.phoenix.parse.DropFunctionStatement;
 import org.apache.phoenix.parse.DropIndexStatement;
+import org.apache.phoenix.parse.DropSchemaStatement;
 import org.apache.phoenix.parse.DropSequenceStatement;
 import org.apache.phoenix.parse.DropTableStatement;
 import org.apache.phoenix.parse.IndexKeyConstraint;
 import org.apache.phoenix.parse.NamedTableNode;
 import org.apache.phoenix.parse.PFunction;
 import org.apache.phoenix.parse.PFunction.FunctionArgument;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.parse.ParseNode;
 import org.apache.phoenix.parse.ParseNodeFactory;
 import org.apache.phoenix.parse.PrimaryKeyConstraint;
@@ -175,6 +179,7 @@ import org.apache.phoenix.parse.SQLParser;
 import org.apache.phoenix.parse.SelectStatement;
 import org.apache.phoenix.parse.TableName;
 import org.apache.phoenix.parse.UpdateStatisticsStatement;
+import org.apache.phoenix.parse.UseSchemaStatement;
 import org.apache.phoenix.query.ConnectionQueryServices;
 import org.apache.phoenix.query.ConnectionQueryServices.Feature;
 import org.apache.phoenix.query.QueryConstants;
@@ -206,8 +211,6 @@ import org.apache.phoenix.util.UpgradeUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import co.cask.tephra.TxConstants;
-
 import com.google.common.base.Objects;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.ListMultimap;
@@ -216,6 +219,8 @@ import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.common.primitives.Ints;
 
+import co.cask.tephra.TxConstants;
+
 public class MetaDataClient {
     private static final Logger logger = LoggerFactory.getLogger(MetaDataClient.class);
 
@@ -250,8 +255,13 @@ public class MetaDataClient {
             STORE_NULLS + "," +
             BASE_COLUMN_COUNT + "," +
             TRANSACTIONAL + "," +
-            UPDATE_CACHE_FREQUENCY +
-            ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+            UPDATE_CACHE_FREQUENCY + "," +
+            IS_NAMESPACE_MAPPED +
+            ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)";
+
+    private static final String CREATE_SCHEMA = "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE
+            + "\"( " + TABLE_SCHEM + "," + TABLE_NAME + ") VALUES (?,?)";
+
     private static final String CREATE_LINK =
             "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
             TENANT_ID + "," +
@@ -377,6 +387,8 @@ public class MetaDataClient {
             MAX_VALUE +
             ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
 
+    public static final String EMPTY_TABLE = " ";
+
 
     private final PhoenixConnection connection;
 
@@ -546,7 +558,28 @@ public class MetaDataClient {
 
         return result;
     }
-    
+
+    public MetaDataMutationResult updateCache(String schemaName) throws SQLException {
+        return updateCache(schemaName, false);
+    }
+
+    public MetaDataMutationResult updateCache(String schemaName, boolean alwaysHitServer) throws SQLException {
+        long clientTimeStamp = getClientTimeStamp();
+        PSchema schema = null;
+        try {
+            schema = connection.getMetaDataCache().getSchema(new PTableKey(null, schemaName));
+            if (schema != null
+                    && !alwaysHitServer) { return new MetaDataMutationResult(MutationCode.SCHEMA_ALREADY_EXISTS, schema,
+                            QueryConstants.UNSET_TIMESTAMP); }
+        } catch (SchemaNotFoundException e) {
+
+        }
+        MetaDataMutationResult result;
+
+        result = connection.getQueryServices().getSchema(schemaName, clientTimeStamp);
+        return result;
+    }
+
     private MetaDataMutationResult updateCache(PName tenantId, List<String> functionNames,
             boolean alwaysHitServer) throws SQLException { // TODO: pass byte[] herez
         long clientTimeStamp = getClientTimeStamp();
@@ -870,22 +903,26 @@ public class MetaDataClient {
             // then analyze all of those indexes too.
             if (table.getType() != PTableType.VIEW) {
                 List<PName> names = Lists.newArrayListWithExpectedSize(2);
-                if (table.isMultiTenant() || MetaDataUtil.hasViewIndexTable(connection, table.getName())) {
+                final List<PName> physicalNames = Lists.newArrayListWithExpectedSize(2);
+                if (table.isMultiTenant() || MetaDataUtil.hasViewIndexTable(connection, table.getPhysicalName())) {
                     names.add(PNameFactory.newName(SchemaUtil.getTableName(
                             MetaDataUtil.getViewIndexSchemaName(table.getSchemaName().getString()),
                             MetaDataUtil.getViewIndexTableName(table.getTableName().getString()))));
+                    physicalNames.add(PNameFactory.newName(MetaDataUtil.getViewIndexPhysicalName(table.getPhysicalName().getBytes())));
                 }
-                if (MetaDataUtil.hasLocalIndexTable(connection, table.getName())) {
+                if (MetaDataUtil.hasLocalIndexTable(connection, table.getPhysicalName())) {
                     names.add(PNameFactory.newName(SchemaUtil.getTableName(
                             MetaDataUtil.getLocalIndexSchemaName(table.getSchemaName().getString()),
                             MetaDataUtil.getLocalIndexTableName(table.getTableName().getString()))));
+                    physicalNames.add(PNameFactory.newName(MetaDataUtil.getLocalIndexPhysicalName(table.getPhysicalName().getBytes())));
                 }
-
+                int i = 0;
                 for (final PName name : names) {
+                    final int index = i++;
                     PTable indexLogicalTable = new DelegateTable(table) {
                         @Override
                         public PName getPhysicalName() {
-                            return name;
+                            return physicalNames.get(index);
                         }
                         @Override
                         public PTableStats getTableStats() {
@@ -1511,6 +1548,7 @@ public class MetaDataClient {
 
             TableName tableNameNode = statement.getTableName();
             String schemaName = tableNameNode.getSchemaName();
+            schemaName = connection.getSchema() != null && schemaName == null ? connection.getSchema() : schemaName;
             String tableName = tableNameNode.getTableName();
             String parentTableName = null;
             PName tenantId = connection.getTenantId();
@@ -1527,6 +1565,9 @@ public class MetaDataClient {
             boolean addSaltColumn = false;
             boolean rowKeyOrderOptimizable = true;
             Long timestamp = null;
+            boolean isNamespaceMapped = parent == null
+                    ? SchemaUtil.isNamespaceMappingEnabled(tableType, connection.getQueryServices().getProps())
+                    : parent.isNamespaceMapped();
             if (parent != null && tableType == PTableType.INDEX) {
                 timestamp = TransactionUtil.getTableTimestamp(connection, transactional);
                 storeNulls = parent.getStoreNulls();
@@ -1537,6 +1578,7 @@ public class MetaDataClient {
                 // from the table to the index, though.
                 if (indexType == IndexType.LOCAL || (parent.getType() == PTableType.VIEW && parent.getViewType() != ViewType.MAPPED)) {
                     PName physicalName = parent.getPhysicalName();
+
                     saltBucketNum = parent.getBucketNum();
                     addSaltColumn = (saltBucketNum != null && indexType != IndexType.LOCAL);
                     defaultFamilyName = parent.getDefaultFamilyName() == null ? null : parent.getDefaultFamilyName().getString();
@@ -1822,7 +1864,8 @@ public class MetaDataClient {
                         linkStatement.setString(4, physicalName.getString());
                         linkStatement.setByte(5, LinkType.PHYSICAL_TABLE.getSerializedValue());
                         if (tableType == PTableType.VIEW) {
-                            PTable physicalTable = connection.getTable(new PTableKey(null, physicalName.getString()));
+                            PTable physicalTable = connection.getTable(new PTableKey(null, physicalName.getString()
+                                    .replace(QueryConstants.NAMESPACE_SEPARATOR, QueryConstants.NAME_SEPARATOR)));
                             linkStatement.setLong(6, physicalTable.getSequenceNumber());
                         } else {
                             linkStatement.setLong(6, parent.getSequenceNumber());
@@ -1980,7 +2023,7 @@ public class MetaDataClient {
                         Collections.<PTable>emptyList(), isImmutableRows,
                         Collections.<PName>emptyList(), defaultFamilyName == null ? null :
                                 PNameFactory.newName(defaultFamilyName), null,
-                        Boolean.TRUE.equals(disableWAL), false, false, null, indexId, indexType, true, false, 0, 0L);
+                        Boolean.TRUE.equals(disableWAL), false, false, null, indexId, indexType, true, false, 0, 0L, isNamespaceMapped);
                 connection.addTable(table, MetaDataProtocol.MIN_TABLE_TIMESTAMP);
             } else if (tableType == PTableType.INDEX && indexId == null) {
                 if (tableProps.get(HTableDescriptor.MAX_FILESIZE) == null) {
@@ -2086,6 +2129,7 @@ public class MetaDataClient {
             }
             tableUpsert.setBoolean(21, transactional);
             tableUpsert.setLong(22, updateCacheFrequency);
+            tableUpsert.setBoolean(23, isNamespaceMapped);
             tableUpsert.execute();
 
             if (asyncCreatedDate != null) {
@@ -2118,7 +2162,7 @@ public class MetaDataClient {
             MetaDataMutationResult result = connection.getQueryServices().createTable(
                     tableMetaData,
                     viewType == ViewType.MAPPED || indexId != null ? physicalNames.get(0).getBytes() : null,
-                    tableType, tableProps, familyPropList, splits);
+                    tableType, tableProps, familyPropList, splits, isNamespaceMapped);
             MutationCode code = result.getMutationCode();
             switch(code) {
             case TABLE_ALREADY_EXISTS:
@@ -2150,7 +2194,7 @@ public class MetaDataClient {
                         PTable.INITIAL_SEQ_NUM, pkName == null ? null : PNameFactory.newName(pkName), saltBucketNum, columns,
                         dataTableName == null ? null : newSchemaName, dataTableName == null ? null : PNameFactory.newName(dataTableName), Collections.<PTable>emptyList(), isImmutableRows,
                         physicalNames, defaultFamilyName == null ? null : PNameFactory.newName(defaultFamilyName), viewStatement, Boolean.TRUE.equals(disableWAL), multiTenant, storeNulls, viewType,
-                        indexId, indexType, rowKeyOrderOptimizable, transactional, updateCacheFrequency, 0L);
+                        indexId, indexType, rowKeyOrderOptimizable, transactional, updateCacheFrequency, 0L, isNamespaceMapped);
                 result = new MetaDataMutationResult(code, result.getMutationTime(), table, true);
                 addTableToCache(result);
                 return table;
@@ -2298,9 +2342,6 @@ public class MetaDataClient {
                 byte[] linkKey = MetaDataUtil.getParentLinkKey(tenantIdStr, schemaName, parentTableName, tableName);
                 Delete linkDelete = new Delete(linkKey, clientTimeStamp);
                 tableMetaData.add(linkDelete);
-            } else {
-                hasViewIndexTable = MetaDataUtil.hasViewIndexTable(connection, schemaName, tableName);
-                hasLocalIndexTable = MetaDataUtil.hasLocalIndexTable(connection, schemaName, tableName);
             }
 
             MetaDataMutationResult result = connection.getQueryServices().dropTable(tableMetaData, tableType, cascade);
@@ -2337,6 +2378,15 @@ public class MetaDataClient {
                         // Create empty table and schema - they're only used to get the name from
                         // PName name, PTableType type, long timeStamp, long sequenceNumber, List<PColumn> columns
                         // All multi-tenant tables have a view index table, so no need to check in that case
+                        if (parentTableName == null) {
+                            for (PTable index : table.getIndexes()) {
+                                if (MetaDataUtil.isLocalIndex(index.getPhysicalName().getString())) {
+                                    hasLocalIndexTable = true;
+                                } 
+                            }
+                            hasViewIndexTable = true; // As there is no way to know whether table has views or not so
+                                                      // ensuring we delete sequence and cached object during drop
+                        }
                         if (tableType == PTableType.TABLE
                                 && (table.isMultiTenant() || hasViewIndexTable || hasLocalIndexTable)) {
     
@@ -2400,7 +2450,7 @@ public class MetaDataClient {
         try {
             StringBuilder buf = new StringBuilder("DELETE FROM SYSTEM.STATS WHERE PHYSICAL_NAME IN (");
             for (TableRef ref : tableRefs) {
-                buf.append("'" + ref.getTable().getName().getString() + "',");
+                buf.append("'" + ref.getTable().getPhysicalName().getString() + "',");
             }
             buf.setCharAt(buf.length() - 1, ')');
             conn.createStatement().execute(buf.toString());
@@ -2856,6 +2906,7 @@ public class MetaDataClient {
                                 storeNulls == null ? table.getStoreNulls() : storeNulls, 
                                 isTransactional == null ? table.isTransactional() : isTransactional,
                                 updateCacheFrequency == null ? table.getUpdateCacheFrequency() : updateCacheFrequency,
+                                table.isNamespaceMapped(),
                                 resolvedTimeStamp);
                     } else if (updateCacheFrequency != null) {
                         // Force removal from cache as the update cache frequency has changed
@@ -3124,11 +3175,12 @@ public class MetaDataClient {
                         final List<TableRef> tableRefsToDrop = Lists.newArrayList();
                         Map<String, List<TableRef>> tenantIdTableRefMap = Maps.newHashMap();
                         if (result.getSharedTablesToDelete()!=null) {
-                            for (SharedTableState sharedTableState : result.getSharedTablesToDelete()) { 
-                                PTableImpl viewIndexTable = new PTableImpl(sharedTableState.getTenantId(), 
-                                    sharedTableState.getSchemaName(), sharedTableState.getTableName(), 
-                                    ts, table.getColumnFamilies(), sharedTableState.getColumns(),
-                                    sharedTableState.getPhysicalNames(), sharedTableState.getViewIndexId(), table.isMultiTenant());
+                            for (SharedTableState sharedTableState : result.getSharedTablesToDelete()) {
+                                PTableImpl viewIndexTable = new PTableImpl(sharedTableState.getTenantId(),
+                                        sharedTableState.getSchemaName(), sharedTableState.getTableName(), ts,
+                                        table.getColumnFamilies(), sharedTableState.getColumns(),
+                                        sharedTableState.getPhysicalNames(), sharedTableState.getViewIndexId(),
+                                        table.isMultiTenant(), table.isNamespaceMapped());
                                 TableRef indexTableRef = new TableRef(viewIndexTable);
                                 PName indexTableTenantId = sharedTableState.getTenantId();
                                 if (indexTableTenantId==null) {
@@ -3296,6 +3348,10 @@ public class MetaDataClient {
         return result.getFunctions();
     }
 
+    private void addSchemaToCache(MetaDataMutationResult result) throws SQLException {
+        connection.addSchema(result.getSchema());
+    }
+
     public PTableStats getTableStats(PTable table) throws SQLException {
         /*
          *  The shared view index case is tricky, because we don't have
@@ -3306,10 +3362,12 @@ public class MetaDataClient {
         boolean isSharedIndex = table.getViewIndexId() != null;
         if (isSharedIndex) {
             // we are assuming the stats table is not transactional
-            return connection.getQueryServices().getTableStats(table.getPhysicalName().getBytes(), getCurrentScn());
+            return connection.getQueryServices().getTableStats(table.getPhysicalName().getBytes(),
+                    getCurrentScn());
         }
         boolean isView = table.getType() == PTableType.VIEW;
-        String physicalName = table.getPhysicalName().getString();
+        String physicalName = table.getPhysicalName().toString().replace(QueryConstants.NAMESPACE_SEPARATOR,
+                QueryConstants.NAME_SEPARATOR);
         if (isView && table.getViewType() != ViewType.MAPPED) {
             try {
                 return connection.getTable(new PTableKey(null, physicalName)).getTableStats();
@@ -3351,4 +3409,102 @@ public class MetaDataClient {
         String parentName = SchemaUtil.normalizeFullTableName(select.getFrom().toString().trim());
         return connection.getTable(new PTableKey(view.getTenantId(), parentName));
     }
+
+    public MutationState createSchema(CreateSchemaStatement create) throws SQLException {
+        boolean wasAutoCommit = connection.getAutoCommit();
+        connection.rollback();
+        try {
+            if (!SchemaUtil.isNamespaceMappingEnabled(null,
+                    connection.getQueryServices()
+                            .getProps())) { throw new SQLExceptionInfo.Builder(
+                                    SQLExceptionCode.CREATE_SCHEMA_NOT_ALLOWED).setSchemaName(create.getSchemaName())
+                                            .build().buildException(); }
+            boolean isIfNotExists = create.isIfNotExists();
+            validateSchema(create.getSchemaName());
+            PSchema schema = new PSchema(create.getSchemaName());
+            connection.setAutoCommit(false);
+            List<Mutation> schemaMutations;
+
+            try (PreparedStatement schemaUpsert = connection.prepareStatement(CREATE_SCHEMA)) {
+                schemaUpsert.setString(1, schema.getSchemaName());
+                schemaUpsert.setString(2, MetaDataClient.EMPTY_TABLE);
+                schemaUpsert.execute();
+                schemaMutations = connection.getMutationState().toMutations(null).next().getSecond();
+                connection.rollback();
+            }
+            MetaDataMutationResult result = connection.getQueryServices().createSchema(schemaMutations,
+                    schema.getSchemaName());
+            MutationCode code = result.getMutationCode();
+            switch (code) {
+            case SCHEMA_ALREADY_EXISTS:
+                if (result.getSchema() != null) {
+                    addSchemaToCache(result);
+                }
+                if (!isIfNotExists) { throw new SchemaAlreadyExistsException(schema.getSchemaName()); }
+                break;
+            case NEWER_SCHEMA_FOUND:
+                throw new NewerSchemaAlreadyExistsException(schema.getSchemaName());
+            default:
+                result = new MetaDataMutationResult(code, schema, result.getMutationTime());
+                addSchemaToCache(result);
+            }
+        } finally {
+            connection.setAutoCommit(wasAutoCommit);
+        }
+        return new MutationState(0, connection);
+    }
+
+    private void validateSchema(String schemaName) throws SQLException {
+        if (SchemaUtil.NOT_ALLOWED_SCHEMA_LIST.contains(
+                schemaName.toUpperCase())) { throw new SQLExceptionInfo.Builder(SQLExceptionCode.SCHEMA_NOT_ALLOWED)
+                        .setSchemaName(schemaName).build().buildException(); }
+    }
+
+    public MutationState dropSchema(DropSchemaStatement executableDropSchemaStatement) throws SQLException {
+        connection.rollback();
+        boolean wasAutoCommit = connection.getAutoCommit();
+        try {
+            String schemaName = executableDropSchemaStatement.getSchemaName();
+            boolean ifExists = executableDropSchemaStatement.ifExists();
+            byte[] key = SchemaUtil.getSchemaKey(schemaName);
+
+            Long scn = connection.getSCN();
+            long clientTimeStamp = scn == null ? HConstants.LATEST_TIMESTAMP : scn;
+            List<Mutation> schemaMetaData = Lists.newArrayListWithExpectedSize(2);
+            Delete schemaDelete = new Delete(key, clientTimeStamp);
+            schemaMetaData.add(schemaDelete);
+            MetaDataMutationResult result = connection.getQueryServices().dropSchema(schemaMetaData, schemaName);
+            MutationCode code = result.getMutationCode();
+            PSchema schema = result.getSchema();
+            switch (code) {
+            case SCHEMA_NOT_FOUND:
+                if (!ifExists) { throw new SchemaNotFoundException(schemaName); }
+                break;
+            case NEWER_SCHEMA_FOUND:
+                throw new NewerSchemaAlreadyExistsException(schemaName);
+            case TABLES_EXIST_ON_SCHEMA:
+                throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_MUTATE_SCHEMA).setSchemaName(schemaName)
+                        .build().buildException();
+            default:
+                connection.removeSchema(schema, result.getMutationTime());
+                break;
+            }
+            return new MutationState(0, connection);
+        } finally {
+            connection.setAutoCommit(wasAutoCommit);
+        }
+    }
+
+    public MutationState useSchema(UseSchemaStatement useSchemaStatement) throws SQLException {
+        // As we allow default namespace mapped to empty schema, so this is to reset schema in connection
+        if (useSchemaStatement.getSchemaName().equals(StringUtil.EMPTY_STRING)
+                || useSchemaStatement.getSchemaName().toUpperCase().equals(SchemaUtil.SCHEMA_FOR_DEFAULT_NAMESPACE)) {
+            connection.setSchema(null);
+        } else {
+            PSchema schema = FromCompiler.getResolverForSchema(useSchemaStatement, connection)
+                    .resolveSchema(useSchemaStatement.getSchemaName());
+            connection.setSchema(schema.getSchemaName());
+        }
+        return new MutationState(0, connection);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/NewerSchemaAlreadyExistsException.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/NewerSchemaAlreadyExistsException.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/NewerSchemaAlreadyExistsException.java
new file mode 100644
index 0000000..b90845c
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/NewerSchemaAlreadyExistsException.java
@@ -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.
+ */
+package org.apache.phoenix.schema;
+
+public class NewerSchemaAlreadyExistsException extends SchemaAlreadyExistsException {
+    private static final long serialVersionUID = 1L;
+
+    public NewerSchemaAlreadyExistsException(String schemaName) {
+        super(schemaName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaData.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaData.java
index 3adcb7e..6a710eb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaData.java
@@ -18,6 +18,7 @@
 package org.apache.phoenix.schema;
 
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.query.MetaDataMutated;
 
 public interface PMetaData extends MetaDataMutated, Iterable<PTable>, Cloneable {
@@ -33,4 +34,5 @@ public interface PMetaData extends MetaDataMutated, Iterable<PTable>, Cloneable
     public PFunction getFunction(PTableKey key) throws FunctionNotFoundException;
     public PMetaData pruneFunctions(Pruner pruner);
     public long getAge(PTableRef ref);
+    public PSchema getSchema(PTableKey key) throws SchemaNotFoundException;
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
index 413d116..67a2714 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
@@ -25,6 +25,8 @@ import java.util.Map;
 
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
+import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.TimeKeeper;
 
 import com.google.common.collect.Lists;
@@ -58,6 +60,7 @@ public class PMetaDataImpl implements PMetaData {
 
             private final Map<PTableKey,PTableRef> tables;
             private final Map<PTableKey,PFunction> functions;
+            private final Map<PTableKey,PSchema> schemas;
             
             private static Map<PTableKey,PTableRef> newMap(int expectedCapacity) {
                 // Use regular HashMap, as we cannot use a LinkedHashMap that orders by access time
@@ -73,6 +76,13 @@ public class PMetaDataImpl implements PMetaData {
                 return Maps.newHashMapWithExpectedSize(expectedCapacity);
             }
 
+            private static Map<PTableKey,PSchema> newSchemaMap(int expectedCapacity) {
+                // Use regular HashMap, as we cannot use a LinkedHashMap that orders by access time
+                // safely across multiple threads (as the underlying collection is not thread safe).
+                // Instead, we track access time and prune it based on the copy we've made.
+                return Maps.newHashMapWithExpectedSize(expectedCapacity);
+            }
+
             private static Map<PTableKey,PTableRef> cloneMap(Map<PTableKey,PTableRef> tables, int expectedCapacity) {
                 Map<PTableKey,PTableRef> newTables = newMap(Math.max(tables.size(),expectedCapacity));
                 // Copy value so that access time isn't changing anymore
@@ -82,6 +92,15 @@ public class PMetaDataImpl implements PMetaData {
                 return newTables;
             }
 
+            private static Map<PTableKey, PSchema> cloneSchemaMap(Map<PTableKey, PSchema> schemas, int expectedCapacity) {
+                Map<PTableKey, PSchema> newSchemas = newSchemaMap(Math.max(schemas.size(), expectedCapacity));
+                // Copy value so that access time isn't changing anymore
+                for (PSchema schema : schemas.values()) {
+                    newSchemas.put(schema.getSchemaKey(), new PSchema(schema));
+                }
+                return newSchemas;
+            }
+
             private static Map<PTableKey,PFunction> cloneFunctionsMap(Map<PTableKey,PFunction> functions, int expectedCapacity) {
                 Map<PTableKey,PFunction> newFunctions = newFunctionMap(Math.max(functions.size(),expectedCapacity));
                 for (PFunction functionAccess : functions.values()) {
@@ -97,6 +116,7 @@ public class PMetaDataImpl implements PMetaData {
                 this.expectedCapacity = toClone.expectedCapacity;
                 this.tables = cloneMap(toClone.tables, expectedCapacity);
                 this.functions = cloneFunctionsMap(toClone.functions, expectedCapacity);
+                this.schemas = cloneSchemaMap(toClone.schemas, expectedCapacity);
             }
             
             public PMetaDataCache(int initialCapacity, long maxByteSize, TimeKeeper timeKeeper) {
@@ -106,6 +126,7 @@ public class PMetaDataImpl implements PMetaData {
                 this.tables = newMap(this.expectedCapacity);
                 this.functions = newFunctionMap(this.expectedCapacity);
                 this.timeKeeper = timeKeeper;
+                this.schemas = newSchemaMap(this.expectedCapacity);
             }
             
             public PTableRef get(PTableKey key) {
@@ -317,7 +338,10 @@ public class PMetaDataImpl implements PMetaData {
     }
 
     @Override
-    public PMetaData addColumn(PName tenantId, String tableName, List<PColumn> columnsToAdd, long tableTimeStamp, long tableSeqNum, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls, boolean isTransactional, long updateCacheFrequency, long resolvedTime) throws SQLException {
+    public PMetaData addColumn(PName tenantId, String tableName, List<PColumn> columnsToAdd, long tableTimeStamp,
+            long tableSeqNum, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls,
+            boolean isTransactional, long updateCacheFrequency, boolean isNamespaceMapped, long resolvedTime)
+                    throws SQLException {
         PTableRef oldTableRef = metaData.get(new PTableKey(tenantId, tableName));
         if (oldTableRef == null) {
             return this;
@@ -331,9 +355,9 @@ public class PMetaDataImpl implements PMetaData {
             newColumns.addAll(oldColumns);
             newColumns.addAll(columnsToAdd);
         }
-        PTable newTable = PTableImpl.makePTable(oldTableRef.getTable(),
-                tableTimeStamp, tableSeqNum, newColumns, isImmutableRows,
-                isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency);
+        PTable newTable = PTableImpl.makePTable(oldTableRef.getTable(), tableTimeStamp, tableSeqNum, newColumns,
+                isImmutableRows, isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency,
+                isNamespaceMapped);
         return addTable(newTable, resolvedTime);
     }
 
@@ -483,4 +507,23 @@ public class PMetaDataImpl implements PMetaData {
     public long getAge(PTableRef ref) {
         return this.metaData.getAge(ref);
     }
+
+    @Override
+    public PMetaData addSchema(PSchema schema) throws SQLException {
+        this.metaData.schemas.put(schema.getSchemaKey(), schema);
+        return this;
+    }
+
+    @Override
+    public PSchema getSchema(PTableKey key) throws SchemaNotFoundException {
+        PSchema schema = metaData.schemas.get(key);
+        if (schema == null) { throw new SchemaNotFoundException(key.getName()); }
+        return schema;
+    }
+
+    @Override
+    public PMetaData removeSchema(PSchema schema, long schemaTimeStamp) {
+        this.metaData.schemas.remove(SchemaUtil.getSchemaKey(schema.getSchemaName()));
+        return this;
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
index b2a1d58..84db752 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
@@ -305,6 +305,10 @@ public interface PTable extends PMetaDataEntity {
      */
     public List<PName> getPhysicalNames();
 
+    /**
+     * For a view, return the name of table in HBase that physically stores data.
+     * @return the name of the physical HBase table storing the data.
+     */
     PName getPhysicalName();
     boolean isImmutableRows();
 
@@ -341,4 +345,6 @@ public interface PTable extends PMetaDataEntity {
      */
     int getRowTimestampColPos();
     long getUpdateCacheFrequency();
+
+    boolean isNamespaceMapped();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index 5789263..665e77f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -66,8 +66,6 @@ import org.apache.phoenix.util.SizedUtil;
 import org.apache.phoenix.util.StringUtil;
 import org.apache.phoenix.util.TrustedByteArrayOutputStream;
 
-import co.cask.tephra.TxConstants;
-
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ArrayListMultimap;
@@ -80,6 +78,8 @@ import com.google.common.collect.Maps;
 import com.google.protobuf.HBaseZeroCopyByteString;
 import com.sun.istack.NotNull;
 
+import co.cask.tephra.TxConstants;
+
 /**
  *
  * Base class for PTable implementors.  Provides abstraction for
@@ -138,6 +138,7 @@ public class PTableImpl implements PTable {
     private boolean hasColumnsRequiringUpgrade; // TODO: remove when required that tables have been upgrade for PHOENIX-2067
     private int rowTimestampColPos;
     private long updateCacheFrequency;
+    private boolean isNamespaceMapped;
 
     public PTableImpl() {
         this.indexes = Collections.emptyList();
@@ -169,7 +170,7 @@ public class PTableImpl implements PTable {
     }
     
     public PTableImpl(PName tenantId, PName schemaName, PName tableName, long timestamp, List<PColumnFamily> families, 
-            List<PColumn> columns, List<PName> physicalNames, Short viewIndexId, boolean multiTenant) throws SQLException { // For indexes stored in shared physical tables
+            List<PColumn> columns, List<PName> physicalNames, Short viewIndexId, boolean multiTenant, boolean isNamespaceMpped) throws SQLException { // For indexes stored in shared physical tables
         this.pkColumns = this.allColumns = Collections.emptyList();
         this.rowKeySchema = RowKeySchema.EMPTY_SCHEMA;
         this.indexes = Collections.emptyList();
@@ -183,7 +184,7 @@ public class PTableImpl implements PTable {
         init(tenantId, this.schemaName, this.tableName, PTableType.INDEX, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
             PTableStats.EMPTY_STATS, this.schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
             null, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
-            isTransactional, updateCacheFrequency, indexDisableTimestamp);
+            isTransactional, updateCacheFrequency, indexDisableTimestamp,isNamespaceMpped);
     }
 
     public PTableImpl(long timeStamp) { // For delete marker
@@ -226,7 +227,7 @@ public class PTableImpl implements PTable {
                 table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table), parentSchemaName, table.getParentTableName(),
                 indexes, table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), viewStatement,
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp());
+                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
     }
 
     public static PTableImpl makePTable(PTable table, List<PColumn> columns) throws SQLException {
@@ -235,7 +236,7 @@ public class PTableImpl implements PTable {
                 table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp());
+                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns) throws SQLException {
@@ -244,7 +245,7 @@ public class PTableImpl implements PTable {
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(),
                 table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp());
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows) throws SQLException {
@@ -253,17 +254,17 @@ public class PTableImpl implements PTable {
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
-                table.getIndexType(), table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp());
+                table.getIndexType(), table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
     }
     
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows, boolean isWalDisabled,
-            boolean isMultitenant, boolean storeNulls, boolean isTransactional, long updateCacheFrequency) throws SQLException {
+            boolean isMultitenant, boolean storeNulls, boolean isTransactional, long updateCacheFrequency, boolean isNamespaceMapped) throws SQLException {
         return new PTableImpl(
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp,
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 isWalDisabled, isMultitenant, storeNulls, table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), isTransactional, updateCacheFrequency, table.getIndexDisableTimestamp());
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), isTransactional, updateCacheFrequency, table.getIndexDisableTimestamp(), isNamespaceMapped);
     }
     
     public static PTableImpl makePTable(PTable table, PIndexState state) throws SQLException {
@@ -273,7 +274,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp());
+                table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
     }
 
     public static PTableImpl makePTable(PTable table, boolean rowKeyOrderOptimizable) throws SQLException {
@@ -283,7 +284,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), rowKeyOrderOptimizable, table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp());
+                table.getBaseColumnCount(), rowKeyOrderOptimizable, table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
     }
 
     public static PTableImpl makePTable(PTable table, PTableStats stats) throws SQLException {
@@ -293,7 +294,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), stats,
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp());
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
     }
 
     public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
@@ -302,12 +303,12 @@ public class PTableImpl implements PTable {
             boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
             boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
             IndexType indexType, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency,
-            long indexDisableTimestamp) throws SQLException {
+            long indexDisableTimestamp, boolean isNamespaceMapped) throws SQLException {
         return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns, dataSchemaName,
                 dataTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
                 viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId,
                 indexType, PTableStats.EMPTY_STATS, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, rowKeyOrderOptimizable, isTransactional,
-                updateCacheFrequency,indexDisableTimestamp);
+                updateCacheFrequency,indexDisableTimestamp, isNamespaceMapped);
     }
 
     public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
@@ -316,12 +317,12 @@ public class PTableImpl implements PTable {
             boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression,
             boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
             IndexType indexType, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency,
-            @NotNull PTableStats stats, int baseColumnCount, long indexDisableTimestamp)
+            @NotNull PTableStats stats, int baseColumnCount, long indexDisableTimestamp, boolean isNamespaceMapped)
             throws SQLException {
         return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName,
                 bucketNum, columns, dataSchemaName, dataTableName, indexes, isImmutableRows, physicalNames,
                 defaultFamilyName, viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId,
-                indexType, stats, baseColumnCount, rowKeyOrderOptimizable, isTransactional, updateCacheFrequency, indexDisableTimestamp);
+                indexType, stats, baseColumnCount, rowKeyOrderOptimizable, isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped);
     }
 
     private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state,
@@ -329,11 +330,11 @@ public class PTableImpl implements PTable {
             PName parentSchemaName, PName parentTableName, List<PTable> indexes, boolean isImmutableRows,
             List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL, boolean multiTenant,
             boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType,
-            PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp) throws SQLException {
+            PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped) throws SQLException {
         init(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
                 stats, schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
                 viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
-                isTransactional, updateCacheFrequency, indexDisableTimestamp);
+                isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped);
     }
     
     @Override
@@ -366,7 +367,7 @@ public class PTableImpl implements PTable {
             PName pkName, Integer bucketNum, List<PColumn> columns, PTableStats stats, PName parentSchemaName, PName parentTableName,
             List<PTable> indexes, boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL,
             boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId,
-            IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp) throws SQLException {
+            IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency, long indexDisableTimestamp, boolean isNamespaceMapped) throws SQLException {
         Preconditions.checkNotNull(schemaName);
         Preconditions.checkArgument(tenantId==null || tenantId.getBytes().length > 0); // tenantId should be null or not empty
         int estimatedSize = SizedUtil.OBJECT_SIZE * 2 + 23 * SizedUtil.POINTER_SIZE + 4 * SizedUtil.INT_SIZE + 2 * SizedUtil.LONG_SIZE + 2 * SizedUtil.INT_OBJECT_SIZE +
@@ -400,6 +401,7 @@ public class PTableImpl implements PTable {
         this.tableStats = stats;
         this.rowKeyOrderOptimizable = rowKeyOrderOptimizable;
         this.updateCacheFrequency = updateCacheFrequency;
+        this.isNamespaceMapped = isNamespaceMapped;
         List<PColumn> pkColumns;
         PColumn[] allColumns;
         
@@ -964,7 +966,8 @@ public class PTableImpl implements PTable {
 
     @Override
     public PName getPhysicalName() {
-        return physicalNames.isEmpty() ? getName() : physicalNames.get(0);
+        return SchemaUtil.getPhysicalHBaseTableName(physicalNames.isEmpty() ? getName() : physicalNames.get(0),
+                isNamespaceMapped, type);
     }
 
     @Override
@@ -1097,6 +1100,10 @@ public class PTableImpl implements PTable {
       if (table.hasUpdateCacheFrequency()) {
           updateCacheFrequency = table.getUpdateCacheFrequency();
       }
+      boolean isNamespaceMapped=false;
+      if (table.hasIsNamespaceMapped()) {
+          isNamespaceMapped = table.getIsNamespaceMapped();
+      }
       
       try {
         PTableImpl result = new PTableImpl();
@@ -1104,7 +1111,7 @@ public class PTableImpl implements PTable {
             (bucketNum == NO_SALTING) ? null : bucketNum, columns, stats, schemaName,dataTableName, indexes,
             isImmutableRows, physicalNames, defaultFamilyName, viewStatement, disableWAL,
             multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
-            isTransactional, updateCacheFrequency, indexDisableTimestamp);
+            isTransactional, updateCacheFrequency, indexDisableTimestamp, isNamespaceMapped);
         return result;
       } catch (SQLException e) {
         throw new RuntimeException(e); // Impossible
@@ -1195,7 +1202,7 @@ public class PTableImpl implements PTable {
       builder.setRowKeyOrderOptimizable(table.rowKeyOrderOptimizable());
       builder.setUpdateCacheFrequency(table.getUpdateCacheFrequency());
       builder.setIndexDisableTimestamp(table.getIndexDisableTimestamp());
-      
+      builder.setIsNamespaceMapped(table.isNamespaceMapped());
       return builder.build();
     }
 
@@ -1232,4 +1239,9 @@ public class PTableImpl implements PTable {
     public int getRowTimestampColPos() {
         return rowTimestampColPos;
     }
+
+    @Override
+    public boolean isNamespaceMapped() {
+        return isNamespaceMapped;
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableKey.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableKey.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableKey.java
index e3519ae..42699d9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableKey.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableKey.java
@@ -17,6 +17,8 @@
  */
 package org.apache.phoenix.schema;
 
+import org.apache.phoenix.query.QueryConstants;
+
 import com.google.common.base.Preconditions;
 
 public class PTableKey {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/SchemaAlreadyExistsException.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/SchemaAlreadyExistsException.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/SchemaAlreadyExistsException.java
new file mode 100644
index 0000000..2fc5f78
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/SchemaAlreadyExistsException.java
@@ -0,0 +1,53 @@
+/*
+ * 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.phoenix.schema;
+
+import java.sql.SQLException;
+
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+
+
+/**
+ * 
+ * Exception thrown when a schema name already exists
+ *
+ * 
+ * @since 0.1
+ */
+public class SchemaAlreadyExistsException extends SQLException {
+    private static final long serialVersionUID = 1L;
+    private static SQLExceptionCode code = SQLExceptionCode.SCHEMA_ALREADY_EXISTS;
+    private final String schemaName;
+
+    public SchemaAlreadyExistsException(String schemaName) {
+        this(schemaName, null);
+    }
+
+    public SchemaAlreadyExistsException(String schemaName, String msg) {
+        super(new SQLExceptionInfo.Builder(code).setSchemaName(schemaName).setMessage(msg).build().toString(),
+                code.getSQLState(), code.getErrorCode());
+        this.schemaName = schemaName;
+
+    }
+
+    public String getSchemaName() {
+        return schemaName;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/SchemaNotFoundException.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/SchemaNotFoundException.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/SchemaNotFoundException.java
new file mode 100644
index 0000000..b7313d8
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/SchemaNotFoundException.java
@@ -0,0 +1,52 @@
+/*
+ * 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.phoenix.schema;
+
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+
+public class SchemaNotFoundException extends MetaDataEntityNotFoundException {
+    private static final long serialVersionUID = 1L;
+    private static SQLExceptionCode code = SQLExceptionCode.SCHEMA_NOT_FOUND;
+    private final String schemaName;
+    private final long timestamp;
+
+    public SchemaNotFoundException(SchemaNotFoundException e, long timestamp) {
+        this(e.schemaName, timestamp);
+    }
+
+    public SchemaNotFoundException(String schemaName) {
+        this(schemaName, HConstants.LATEST_TIMESTAMP);
+    }
+
+    public SchemaNotFoundException(String schemaName, long timestamp) {
+        super(new SQLExceptionInfo.Builder(code).setSchemaName(schemaName).build().toString(), code.getSQLState(),
+                code.getErrorCode(), null);
+        this.schemaName = schemaName;
+        this.timestamp = timestamp;
+    }
+
+    public String getSchemaName() {
+        return schemaName;
+    }
+
+    public long getTimeStamp() {
+        return timestamp;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollectorFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollectorFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollectorFactory.java
index 3a0b9ad..30c560a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollectorFactory.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollectorFactory.java
@@ -24,6 +24,7 @@ import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.SchemaUtil;
 
 import com.google.common.collect.Sets;
 
@@ -63,6 +64,10 @@ public class StatisticsCollectorFactory {
         DISABLE_STATS.add(TableName.valueOf(PhoenixDatabaseMetaData.SYSTEM_FUNCTION_NAME));
         DISABLE_STATS.add(TableName.valueOf(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME));
         DISABLE_STATS.add(TableName.valueOf(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME));
+        DISABLE_STATS.add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES,true));
+        DISABLE_STATS.add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES,true));
+        DISABLE_STATS.add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES,true));
+        DISABLE_STATS.add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES,true));
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsWriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsWriter.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsWriter.java
index 0dbbf5d..3bd3cef 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsWriter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsWriter.java
@@ -28,7 +28,6 @@ import java.util.List;
 
 import org.apache.hadoop.hbase.DoNotRetryIOException;
 import org.apache.hadoop.hbase.HConstants;
-import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.Delete;
 import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Mutation;
@@ -50,6 +49,7 @@ import org.apache.phoenix.schema.types.PDate;
 import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.PrefixByteDecoder;
+import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.ServerUtil;
 import org.apache.phoenix.util.TimeKeeper;
 
@@ -73,8 +73,8 @@ public class StatisticsWriter implements Closeable {
         if (clientTimeStamp == HConstants.LATEST_TIMESTAMP) {
             clientTimeStamp = TimeKeeper.SYSTEM.getCurrentTime();
         }
-        HTableInterface statsWriterTable = env
-                .getTable(TableName.valueOf(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME_BYTES));
+        HTableInterface statsWriterTable = env.getTable(
+                SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME_BYTES, env.getConfiguration()));
         HTableInterface statsReaderTable = ServerUtil.getHTableForCoprocessorScan(env, statsWriterTable);
         StatisticsWriter statsTable = new StatisticsWriter(statsReaderTable, statsWriterTable, tableName,
                 clientTimeStamp);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
index 45d284d..2f56a93 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
@@ -285,7 +285,7 @@ public class IndexUtil {
                     byte[] regionStartKey = null;
                     byte[] regionEndkey = null;
                     if(maintainer.isLocalIndex()) {
-                        HRegionLocation tableRegionLocation = connection.getQueryServices().getTableRegionLocation(table.getName().getBytes(), dataMutation.getRow());
+                        HRegionLocation tableRegionLocation = connection.getQueryServices().getTableRegionLocation(table.getPhysicalName().getBytes(), dataMutation.getRow());
                         regionStartKey = tableRegionLocation.getRegionInfo().getStartKey();
                         regionEndkey = tableRegionLocation.getRegionInfo().getEndKey();
                     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/util/JDBCUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/JDBCUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/JDBCUtil.java
index cbe5a1a..a0672d4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/JDBCUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/JDBCUtil.java
@@ -159,4 +159,9 @@ public class JDBCUtil {
         String batchSizeStr = findProperty(url, overrideProps, PhoenixRuntime.REQUEST_METRIC_ATTRIB);
         return (batchSizeStr == null ? queryServicesProps.getBoolean(QueryServices.COLLECT_REQUEST_LEVEL_METRICS, QueryServicesOptions.DEFAULT_REQUEST_LEVEL_METRICS_ENABLED) : Boolean.parseBoolean(batchSizeStr));
     }
+
+    public static String getSchema(String url, Properties info, String defaultValue) {
+        String schema = findProperty(url, info, PhoenixRuntime.SCHEMA_ATTRIB);
+        return (schema == null || schema.equals("")) ? defaultValue : schema;
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
index 5127f5b..df37ee0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
@@ -17,12 +17,22 @@
  */
 package org.apache.phoenix.util;
 
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.LINK_TYPE;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
 import static org.apache.phoenix.util.SchemaUtil.getVarChars;
 
 import java.io.IOException;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Cell;
@@ -71,9 +81,7 @@ public class MetaDataUtil {
     private static final Logger logger = LoggerFactory.getLogger(MetaDataUtil.class);
   
     public static final String VIEW_INDEX_TABLE_PREFIX = "_IDX_";
-    public static final byte[] VIEW_INDEX_TABLE_PREFIX_BYTES = Bytes.toBytes(VIEW_INDEX_TABLE_PREFIX);
     public static final String LOCAL_INDEX_TABLE_PREFIX = "_LOCAL_IDX_";
-    public static final byte[] LOCAL_INDEX_TABLE_PREFIX_BYTES = Bytes.toBytes(LOCAL_INDEX_TABLE_PREFIX);
     public static final String VIEW_INDEX_SEQUENCE_PREFIX = "_SEQ_";
     public static final String VIEW_INDEX_SEQUENCE_NAME_PREFIX = "_ID_";
     public static final byte[] VIEW_INDEX_SEQUENCE_PREFIX_BYTES = Bytes.toBytes(VIEW_INDEX_SEQUENCE_PREFIX);
@@ -284,7 +292,7 @@ public class MetaDataUtil {
     }
     
     public static byte[] getViewIndexPhysicalName(byte[] physicalTableName) {
-        return ByteUtil.concat(VIEW_INDEX_TABLE_PREFIX_BYTES, physicalTableName);
+        return getIndexPhysicalName(physicalTableName, VIEW_INDEX_TABLE_PREFIX);
     }
 
     public static String getViewIndexTableName(String tableName) {
@@ -295,30 +303,55 @@ public class MetaDataUtil {
         return schemaName;
     }
 
+    public static byte[] getIndexPhysicalName(byte[] physicalTableName, String indexPrefix) {
+        return getIndexPhysicalName(Bytes.toString(physicalTableName), indexPrefix).getBytes();
+    }
+
+    public static String getIndexPhysicalName(String physicalTableName, String indexPrefix) {
+        if (physicalTableName.contains(QueryConstants.NAMESPACE_SEPARATOR)) {
+            String schemaName = SchemaUtil.getSchemaNameFromFullName(physicalTableName,
+                    QueryConstants.NAMESPACE_SEPARATOR);
+            String tableName = SchemaUtil.getTableNameFromFullName(physicalTableName,
+                    QueryConstants.NAMESPACE_SEPARATOR);
+            return (schemaName + QueryConstants.NAMESPACE_SEPARATOR + indexPrefix + tableName);
+        }
+        return indexPrefix + physicalTableName;
+    }
+
     public static byte[] getLocalIndexPhysicalName(byte[] physicalTableName) {
-        return ByteUtil.concat(LOCAL_INDEX_TABLE_PREFIX_BYTES, physicalTableName);
+        return getIndexPhysicalName(physicalTableName, LOCAL_INDEX_TABLE_PREFIX);
     }
-    
+
     public static String getLocalIndexTableName(String tableName) {
         return LOCAL_INDEX_TABLE_PREFIX + tableName;
     }
-    
+
     public static String getLocalIndexSchemaName(String schemaName) {
         return schemaName;
     }  
 
     public static String getUserTableName(String localIndexTableName) {
-        String schemaName = SchemaUtil.getSchemaNameFromFullName(localIndexTableName);
-        if(!schemaName.isEmpty()) schemaName = schemaName.substring(LOCAL_INDEX_TABLE_PREFIX.length());
-        String tableName = localIndexTableName.substring((schemaName.isEmpty() ? 0 : (schemaName.length() + QueryConstants.NAME_SEPARATOR.length()))
-            + LOCAL_INDEX_TABLE_PREFIX.length());
-        return SchemaUtil.getTableName(schemaName, tableName);
+        if (localIndexTableName.contains(QueryConstants.NAMESPACE_SEPARATOR)) {
+            String schemaName = SchemaUtil.getSchemaNameFromFullName(localIndexTableName,
+                    QueryConstants.NAMESPACE_SEPARATOR);
+            String tableName = SchemaUtil.getTableNameFromFullName(localIndexTableName,
+                    QueryConstants.NAMESPACE_SEPARATOR);
+            String userTableName = tableName.substring(LOCAL_INDEX_TABLE_PREFIX.length());
+            return (schemaName + QueryConstants.NAMESPACE_SEPARATOR + userTableName);
+        } else {
+            String schemaName = SchemaUtil.getSchemaNameFromFullName(localIndexTableName);
+            if (!schemaName.isEmpty()) schemaName = schemaName.substring(LOCAL_INDEX_TABLE_PREFIX.length());
+            String tableName = localIndexTableName.substring(
+                    (schemaName.isEmpty() ? 0 : (schemaName.length() + QueryConstants.NAME_SEPARATOR.length()))
+                            + LOCAL_INDEX_TABLE_PREFIX.length());
+            return SchemaUtil.getTableName(schemaName, tableName);
+        }
     }
 
     public static String getViewIndexSchemaName(PName physicalName) {
         return VIEW_INDEX_SEQUENCE_PREFIX + physicalName.getString();
     }
-    
+ 
     public static SequenceKey getViewIndexSequenceKey(String tenantId, PName physicalName, int nSaltBuckets) {
         // Create global sequence of the form: <prefixed base table name><tenant id>
         // rather than tenant-specific sequence, as it makes it much easier
@@ -337,15 +370,12 @@ public class MetaDataUtil {
         return VIEW_INDEX_ID_COLUMN_NAME;
     }
 
-    public static boolean hasViewIndexTable(PhoenixConnection connection, PName name) throws SQLException {
-        return hasViewIndexTable(connection, name.getBytes());
+    public static boolean hasViewIndexTable(PhoenixConnection connection, PName physicalName) throws SQLException {
+        return hasViewIndexTable(connection, physicalName.getBytes());
     }
-    
-    public static boolean hasViewIndexTable(PhoenixConnection connection, String schemaName, String tableName) throws SQLException {
-        return hasViewIndexTable(connection, SchemaUtil.getTableNameAsBytes(schemaName, tableName));
-    }
-    
-    public static boolean hasViewIndexTable(PhoenixConnection connection, byte[] physicalTableName) throws SQLException {
+
+    public static boolean hasViewIndexTable(PhoenixConnection connection, byte[] physicalTableName)
+            throws SQLException {
         byte[] physicalIndexName = MetaDataUtil.getViewIndexPhysicalName(physicalTableName);
         try {
             HTableDescriptor desc = connection.getQueryServices().getTableDescriptor(physicalIndexName);
@@ -355,12 +385,8 @@ public class MetaDataUtil {
         }
     }
 
-    public static boolean hasLocalIndexTable(PhoenixConnection connection, PName name) throws SQLException {
-        return hasLocalIndexTable(connection, name.getBytes());
-    }
-
-    public static boolean hasLocalIndexTable(PhoenixConnection connection, String schemaName, String tableName) throws SQLException {
-        return hasLocalIndexTable(connection, SchemaUtil.getTableNameAsBytes(schemaName, tableName));
+    public static boolean hasLocalIndexTable(PhoenixConnection connection, PName physicalName) throws SQLException {
+        return hasLocalIndexTable(connection, physicalName.getBytes());
     }
 
     public static boolean hasLocalIndexTable(PhoenixConnection connection, byte[] physicalTableName) throws SQLException {
@@ -436,6 +462,10 @@ public class MetaDataUtil {
     public static final String IS_LOCAL_INDEX_TABLE_PROP_NAME = "IS_LOCAL_INDEX_TABLE";
     public static final byte[] IS_LOCAL_INDEX_TABLE_PROP_BYTES = Bytes.toBytes(IS_LOCAL_INDEX_TABLE_PROP_NAME);
 
+    private static final String GET_VIEWS_QUERY = "SELECT " + TABLE_SCHEM + "," + TABLE_NAME + " FROM "
+            + SYSTEM_CATALOG_SCHEMA + "." + SYSTEM_CATALOG_TABLE + " WHERE " + COLUMN_FAMILY + " = ? AND " + LINK_TYPE
+            + " = " + LinkType.PHYSICAL_TABLE.getSerializedValue();
+
     public static Scan newTableRowsScan(byte[] key, long startTimeStamp, long stopTimeStamp){
         return newTableRowsScan(key, null, startTimeStamp, stopTimeStamp);
     }
@@ -465,4 +495,28 @@ public class MetaDataUtil {
         }
         return null;
     }
+
+    public static boolean isLocalIndex(String physicalName) {
+        if (physicalName.contains(LOCAL_INDEX_TABLE_PREFIX)) { return true; }
+        return false;
+    }
+
+    public static boolean isViewIndex(String physicalName) {
+        if (physicalName.contains(QueryConstants.NAMESPACE_SEPARATOR)) {
+            return SchemaUtil.getTableNameFromFullName(physicalName).startsWith(VIEW_INDEX_TABLE_PREFIX);
+        } else {
+            return physicalName.startsWith(VIEW_INDEX_TABLE_PREFIX);
+        }
+    }
+
+    public static Set<String> getViewNames(PhoenixConnection conn, String table) throws SQLException {
+        Set<String> viewNames = new HashSet<String>();
+        PreparedStatement preparedStatment = conn.prepareStatement(GET_VIEWS_QUERY);
+        preparedStatment.setString(1, SchemaUtil.normalizeIdentifier(table));
+        ResultSet rs = preparedStatment.executeQuery();
+        while (rs.next()) {
+            viewNames.add(SchemaUtil.getTableName(rs.getString(1), rs.getString(2)));
+        }
+        return viewNames;
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
index 3117fa9..f83317e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
@@ -51,6 +51,7 @@ import org.apache.commons.cli.ParseException;
 import org.apache.commons.cli.PosixParser;
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.client.Mutation;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
@@ -214,28 +215,34 @@ public class PhoenixRuntime {
         PhoenixConnection conn = null;
         try {
             Properties props = new Properties();
-            conn = DriverManager.getConnection(jdbcUrl, props)
-                    .unwrap(PhoenixConnection.class);
-
-            if (execCmd.isUpgrade()) {
-                if (conn.getClientInfo(PhoenixRuntime.CURRENT_SCN_ATTRIB) != null) {
-                    throw new SQLException("May not specify the CURRENT_SCN property when upgrading");
-                }
-                if (conn.getClientInfo(PhoenixRuntime.TENANT_ID_ATTRIB) != null) {
-                    throw new SQLException("May not specify the TENANT_ID_ATTRIB property when upgrading");
+            conn = DriverManager.getConnection(jdbcUrl, props).unwrap(PhoenixConnection.class);
+            if (execCmd.isMapNamespace()) {
+                String srcTable = execCmd.getSrcTable();
+                UpgradeUtil.upgradeTable(conn, srcTable);
+                Set<String> viewNames = MetaDataUtil.getViewNames(conn, srcTable);
+                System.out.println("Views found:"+viewNames);
+                for (String viewName : viewNames) {
+                    UpgradeUtil.upgradeTable(conn, viewName);
                 }
+            } else if (execCmd.isUpgrade()) {
+                if (conn.getClientInfo(PhoenixRuntime.CURRENT_SCN_ATTRIB) != null) { throw new SQLException(
+                        "May not specify the CURRENT_SCN property when upgrading"); }
+                if (conn.getClientInfo(PhoenixRuntime.TENANT_ID_ATTRIB) != null) { throw new SQLException(
+                        "May not specify the TENANT_ID_ATTRIB property when upgrading"); }
                 if (execCmd.getInputFiles().isEmpty()) {
                     List<String> tablesNeedingUpgrade = UpgradeUtil.getPhysicalTablesWithDescRowKey(conn);
                     if (tablesNeedingUpgrade.isEmpty()) {
                         String msg = "No tables are required to be upgraded due to incorrect row key order (PHOENIX-2067 and PHOENIX-2120)";
                         System.out.println(msg);
                     } else {
-                        String msg = "The following tables require upgrade due to a bug causing the row key to be incorrectly ordered (PHOENIX-2067 and PHOENIX-2120):\n" + Joiner.on(' ').join(tablesNeedingUpgrade);
+                        String msg = "The following tables require upgrade due to a bug causing the row key to be incorrectly ordered (PHOENIX-2067 and PHOENIX-2120):\n"
+                                + Joiner.on(' ').join(tablesNeedingUpgrade);
                         System.out.println("WARNING: " + msg);
                     }
                     List<String> unsupportedTables = UpgradeUtil.getPhysicalTablesWithDescVarbinaryRowKey(conn);
                     if (!unsupportedTables.isEmpty()) {
-                        String msg = "The following tables use an unsupported VARBINARY DESC construct and need to be changed:\n" + Joiner.on(' ').join(unsupportedTables);
+                        String msg = "The following tables use an unsupported VARBINARY DESC construct and need to be changed:\n"
+                                + Joiner.on(' ').join(unsupportedTables);
                         System.out.println("WARNING: " + msg);
                     }
                 } else {
@@ -244,21 +251,18 @@ public class PhoenixRuntime {
             } else {
                 for (String inputFile : execCmd.getInputFiles()) {
                     if (inputFile.endsWith(SQL_FILE_EXT)) {
-                        PhoenixRuntime.executeStatements(conn,
-                                new FileReader(inputFile), Collections.emptyList());
+                        PhoenixRuntime.executeStatements(conn, new FileReader(inputFile), Collections.emptyList());
                     } else if (inputFile.endsWith(CSV_FILE_EXT)) {
-    
+
                         String tableName = execCmd.getTableName();
                         if (tableName == null) {
                             tableName = SchemaUtil.normalizeIdentifier(
                                     inputFile.substring(inputFile.lastIndexOf(File.separatorChar) + 1,
                                             inputFile.length() - CSV_FILE_EXT.length()));
                         }
-                        CSVCommonsLoader csvLoader =
-                                new CSVCommonsLoader(conn, tableName, execCmd.getColumns(),
-                                        execCmd.isStrict(), execCmd.getFieldDelimiter(),
-                                        execCmd.getQuoteCharacter(), execCmd.getEscapeCharacter(),
-                                        execCmd.getArrayElementSeparator());
+                        CSVCommonsLoader csvLoader = new CSVCommonsLoader(conn, tableName, execCmd.getColumns(),
+                                execCmd.isStrict(), execCmd.getFieldDelimiter(), execCmd.getQuoteCharacter(),
+                                execCmd.getEscapeCharacter(), execCmd.getArrayElementSeparator());
                         csvLoader.upsert(inputFile);
                     }
                 }
@@ -279,6 +283,7 @@ public class PhoenixRuntime {
     }
 
     public static final String PHOENIX_TEST_DRIVER_URL_PARAM = "test=true";
+    public static final String SCHEMA_ATTRIB = "schema";
 
     private PhoenixRuntime() {
     }
@@ -513,6 +518,8 @@ public class PhoenixRuntime {
         private List<String> inputFiles;
         private boolean isUpgrade;
         private boolean isBypassUpgrade;
+        private boolean mapNamespace;
+        private String srcTable;
 
         /**
          * Factory method to build up an {@code ExecutionCommand} based on supplied parameters.
@@ -551,6 +558,9 @@ public class PhoenixRuntime {
                     "This would only be the case if you have not relied on auto padding for BINARY and CHAR data, " +
                     "but instead have always provided data up to the full max length of the column. See PHOENIX-2067 " +
                     "and PHOENIX-2120 for more information. ");
+            Option mapNamespaceOption = new Option("m", "map-namespace", true,
+                    "Used to map table to a namespace matching with schema, require "+ QueryServices.IS_NAMESPACE_MAPPING_ENABLED +
+                    " to be enabled");
             Options options = new Options();
             options.addOption(tableOption);
             options.addOption(headerOption);
@@ -561,6 +571,7 @@ public class PhoenixRuntime {
             options.addOption(arrayValueSeparatorOption);
             options.addOption(upgradeOption);
             options.addOption(bypassUpgradeOption);
+            options.addOption(mapNamespaceOption);
 
             CommandLineParser parser = new PosixParser();
             CommandLine cmdLine = null;
@@ -571,7 +582,10 @@ public class PhoenixRuntime {
             }
 
             ExecutionCommand execCmd = new ExecutionCommand();
-
+            if(cmdLine.hasOption(mapNamespaceOption.getOpt())){
+                execCmd.mapNamespace = true;
+                execCmd.srcTable = validateTableName(cmdLine.getOptionValue(mapNamespaceOption.getOpt()));
+            }
             if (cmdLine.hasOption(tableOption.getOpt())) {
                 execCmd.tableName = cmdLine.getOptionValue(tableOption.getOpt());
             }
@@ -627,7 +641,7 @@ public class PhoenixRuntime {
                 }
             }
 
-            if (inputFiles.isEmpty() && !execCmd.isUpgrade) {
+            if (inputFiles.isEmpty() && !execCmd.isUpgrade && !execCmd.isMapNamespace()) {
                 usageError("At least one input file must be supplied", options);
             }
 
@@ -636,6 +650,16 @@ public class PhoenixRuntime {
             return execCmd;
         }
 
+        private static String validateTableName(String tableName) {
+            if (tableName.contains(QueryConstants.NAMESPACE_SEPARATOR)) {
+                throw new IllegalArgumentException(
+                        "tablename:" + tableName + " cannot have '" + QueryConstants.NAMESPACE_SEPARATOR + "' ");
+            } else {
+                return tableName;
+            }
+
+        }
+
         private static char getCharacter(String s) {
             String unescaped = StringEscapeUtils.unescapeJava(s);
             if (unescaped.length() > 1) {
@@ -708,6 +732,14 @@ public class PhoenixRuntime {
         public boolean isBypassUpgrade() {
             return isBypassUpgrade;
         }
+
+        public boolean isMapNamespace() {
+            return mapNamespace;
+        }
+
+        public String getSrcTable() {
+            return srcTable;
+        }
     }
     
     /**
@@ -1192,4 +1224,9 @@ public class PhoenixRuntime {
     public static long getWallClockTimeFromCellTimeStamp(long tsOfCell) {
         return TxUtils.isPreExistingVersion(tsOfCell) ? tsOfCell : TransactionUtil.convertToMilliseconds(tsOfCell);
     }
+
+    public static long getCurrentScn(ReadOnlyProps props) {
+        String scn = props.get(CURRENT_SCN_ATTRIB);
+        return scn != null ? Long.parseLong(scn) : HConstants.LATEST_TIMESTAMP;
+    }
  }


[10/52] [abbrv] phoenix git commit: PHOENIX-2822 Tests that extend BaseHBaseManagedTimeIT are very slow(Rahul Gidwani)

Posted by sa...@apache.org.
PHOENIX-2822 Tests that extend BaseHBaseManagedTimeIT are very slow(Rahul Gidwani)


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

Branch: refs/heads/encodecolumns
Commit: ecc5ff2d5d2b675591c4071c45b8577545269d70
Parents: caea1a5
Author: Samarth <sa...@salesforce.com>
Authored: Fri Apr 8 15:09:16 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Fri Apr 8 15:09:16 2016 -0700

----------------------------------------------------------------------
 .../phoenix/end2end/AbsFunctionEnd2EndIT.java   |  12 +-
 .../phoenix/end2end/ArithmeticQueryIT.java      | 296 ++++++++++-------
 .../phoenix/end2end/ArrayFillFunctionIT.java    | 175 ++++++----
 .../end2end/ArrayToStringFunctionIT.java        | 326 +++++++++----------
 .../phoenix/end2end/ArraysWithNullsIT.java      | 152 ++++++---
 .../apache/phoenix/end2end/AutoCommitIT.java    |  21 +-
 .../phoenix/end2end/BaseHBaseManagedTimeIT.java |   5 +-
 .../BaseHBaseManagedTimeTableReuseIT.java       |  56 ++++
 .../phoenix/end2end/CbrtFunctionEnd2EndIT.java  |  35 +-
 .../end2end/ConvertTimezoneFunctionIT.java      |  71 ++--
 .../phoenix/end2end/DecodeFunctionIT.java       |  49 ++-
 .../apache/phoenix/end2end/DynamicFamilyIT.java |  31 +-
 .../phoenix/end2end/FirstValueFunctionIT.java   | 144 +++++---
 .../end2end/GetSetByteBitFunctionEnd2EndIT.java |  26 +-
 .../phoenix/end2end/LikeExpressionIT.java       |  34 +-
 .../apache/phoenix/end2end/MD5FunctionIT.java   |  30 +-
 .../phoenix/end2end/MappingTableDataTypeIT.java |  15 +-
 .../end2end/MinMaxAggregateFunctionIT.java      |  24 +-
 .../phoenix/end2end/NthValueFunctionIT.java     | 252 +++++++++-----
 .../end2end/OctetLengthFunctionEnd2EndIT.java   |  13 +-
 .../phoenix/end2end/PowerFunctionEnd2EndIT.java |  21 +-
 .../apache/phoenix/end2end/PrimitiveTypeIT.java |  63 ++--
 .../org/apache/phoenix/end2end/QueryMoreIT.java |  31 +-
 .../apache/phoenix/end2end/RTrimFunctionIT.java |  24 +-
 .../org/apache/phoenix/end2end/ReadOnlyIT.java  |  17 +-
 .../phoenix/end2end/RegexpSplitFunctionIT.java  |  52 +--
 .../phoenix/end2end/ReverseFunctionIT.java      |  42 +--
 .../RoundFloorCeilFunctionsEnd2EndIT.java       | 101 ++++--
 .../phoenix/end2end/ServerExceptionIT.java      |   9 +-
 .../phoenix/end2end/SignFunctionEnd2EndIT.java  |  35 +-
 .../org/apache/phoenix/end2end/SortOrderIT.java | 303 ++++++++++-------
 .../phoenix/end2end/StatementHintsIT.java       |  12 +-
 .../apache/phoenix/end2end/StoreNullsIT.java    |  51 +--
 .../end2end/StringToArrayFunctionIT.java        | 164 ++++++----
 .../end2end/TimezoneOffsetFunctionIT.java       |  63 ++--
 .../end2end/UpsertSelectAutoCommitIT.java       |  50 ++-
 .../phoenix/end2end/index/DropViewIT.java       |   1 +
 .../salted/SaltedTableUpsertSelectIT.java       |  86 +++--
 .../salted/SaltedTableVarLengthRowKeyIT.java    |  11 +-
 .../phoenix/iterate/PhoenixQueryTimeoutIT.java  |  23 +-
 .../phoenix/memory/GlobalMemoryManager.java     |  29 +-
 .../phoenix/memory/MemoryManagerTest.java       |  87 +++--
 .../java/org/apache/phoenix/query/BaseTest.java |   8 +
 43 files changed, 1875 insertions(+), 1175 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/AbsFunctionEnd2EndIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AbsFunctionEnd2EndIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AbsFunctionEnd2EndIT.java
index 0c6204c..2aba334 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AbsFunctionEnd2EndIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AbsFunctionEnd2EndIT.java
@@ -34,8 +34,9 @@ import org.junit.Test;
 /**
  * End to end tests for {@link AbsFunction}
  */
-public class AbsFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
+public class AbsFunctionEnd2EndIT extends BaseHBaseManagedTimeTableReuseIT {
 
+    private static final String TABLE_NAME = generateRandomString();
     private static final String KEY = "key";
 
     @Before
@@ -43,9 +44,10 @@ public class AbsFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
         Connection conn = null;
         PreparedStatement stmt = null;
         try {
+            System.out.println("TABLE_NAME = " + TABLE_NAME);
             conn = DriverManager.getConnection(getUrl());
             String ddl;
-            ddl = "CREATE TABLE testSigned (k VARCHAR NOT NULL PRIMARY KEY, dec DECIMAL, doub DOUBLE, fl FLOAT, inte INTEGER, lon BIGINT, smalli SMALLINT, tinyi TINYINT)";
+            ddl = "CREATE TABLE " + TABLE_NAME + " (k VARCHAR NOT NULL PRIMARY KEY, dec DECIMAL, doub DOUBLE, fl FLOAT, inte INTEGER, lon BIGINT, smalli SMALLINT, tinyi TINYINT)";
             conn.createStatement().execute(ddl);
             conn.commit();
         } finally {
@@ -54,7 +56,7 @@ public class AbsFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
     }
 
     private void updateSignedTable(Connection conn, double data) throws Exception {
-        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO testSigned VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
+        PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
         stmt.setString(1, KEY);
         Double d = Double.valueOf(data);
         stmt.setBigDecimal(2, BigDecimal.valueOf(data));
@@ -70,7 +72,7 @@ public class AbsFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
 
     private void testSignedNumberSpec(Connection conn, double data) throws Exception {
         updateSignedTable(conn, data);
-        ResultSet rs = conn.createStatement() .executeQuery("SELECT ABS(dec),ABS(doub),ABS(fl),ABS(inte),ABS(lon),ABS(smalli),ABS(tinyi) FROM testSigned");
+        ResultSet rs = conn.createStatement() .executeQuery("SELECT ABS(dec),ABS(doub),ABS(fl),ABS(inte),ABS(lon),ABS(smalli),ABS(tinyi) FROM " + TABLE_NAME);
         assertTrue(rs.next());
         Double d = Double.valueOf(data);
         assertEquals(rs.getBigDecimal(1).compareTo(BigDecimal.valueOf(data).abs()), 0);
@@ -82,7 +84,7 @@ public class AbsFunctionEnd2EndIT extends BaseHBaseManagedTimeIT {
         assertEquals(rs.getByte(7), Math.abs(d.byteValue()));
         assertTrue(!rs.next());
 
-        PreparedStatement stmt = conn.prepareStatement("SELECT k FROM testSigned WHERE ABS(dec)=? AND ABS(doub)=? AND ABS(fl)=? AND ABS(inte)=? AND ABS(lon)=? AND ABS(smalli)=? AND ABS(tinyi)=?");
+        PreparedStatement stmt = conn.prepareStatement("SELECT k FROM " + TABLE_NAME + " WHERE ABS(dec)=? AND ABS(doub)=? AND ABS(fl)=? AND ABS(inte)=? AND ABS(lon)=? AND ABS(smalli)=? AND ABS(tinyi)=?");
         stmt.setBigDecimal(1, BigDecimal.valueOf(data).abs());
         stmt.setDouble(2, Math.abs(d.doubleValue()));
         stmt.setFloat(3, Math.abs(d.floatValue()));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArithmeticQueryIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArithmeticQueryIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArithmeticQueryIT.java
index f56c965..4dba393 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArithmeticQueryIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArithmeticQueryIT.java
@@ -40,7 +40,7 @@ import com.google.common.primitives.Doubles;
 import com.google.common.primitives.Floats;
 
 
-public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
+public class ArithmeticQueryIT extends BaseHBaseManagedTimeTableReuseIT {
 
     @Test
     public void testDecimalUpsertValue() throws Exception {
@@ -48,13 +48,15 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE testDecimalArithmetic" + 
+            String testDecimalArithmetic = generateRandomString();
+            String ddl = "CREATE TABLE " + testDecimalArithmetic +
                     "  (pk VARCHAR NOT NULL PRIMARY KEY, " +
                     "col1 DECIMAL(31,0), col2 DECIMAL(5), col3 DECIMAL(5,2), col4 DECIMAL)";
             createTestTable(getUrl(), ddl);
             
             // Test upsert correct values 
-            String query = "UPSERT INTO testDecimalArithmetic(pk, col1, col2, col3, col4) VALUES(?,?,?,?,?)";
+            String query = "UPSERT INTO " + testDecimalArithmetic
+                + "(pk, col1, col2, col3, col4) VALUES(?,?,?,?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "valueOne");
             stmt.setBigDecimal(2, new BigDecimal("123456789123456789"));
@@ -64,7 +66,8 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             stmt.execute();
             conn.commit();
             
-            query = "SELECT col1, col2, col3, col4 FROM testDecimalArithmetic WHERE pk = 'valueOne'";
+            query = "SELECT col1, col2, col3, col4 FROM " + testDecimalArithmetic
+                + " WHERE pk = 'valueOne'";
             stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -74,7 +77,8 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertEquals(new BigDecimal("12345.6789"), rs.getBigDecimal(4));
             assertFalse(rs.next());
             
-            query = "UPSERT INTO testDecimalArithmetic(pk, col1, col2, col3) VALUES(?,?,?,?)";
+            query =
+                "UPSERT INTO " + testDecimalArithmetic + "(pk, col1, col2, col3) VALUES(?,?,?,?)";
             stmt = conn.prepareStatement(query);
             stmt.setString(1, "valueTwo");
             stmt.setBigDecimal(2, new BigDecimal("1234567890123456789012345678901.12345"));
@@ -83,7 +87,8 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             stmt.execute();
             conn.commit();
             
-            query = "SELECT col1, col2, col3 FROM testDecimalArithmetic WHERE pk = 'valueTwo'";
+            query =
+                "SELECT col1, col2, col3 FROM " + testDecimalArithmetic + " WHERE pk = 'valueTwo'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -94,7 +99,8 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             
             // Test upsert incorrect values and confirm exceptions would be thrown.
             try {
-                query = "UPSERT INTO testDecimalArithmetic(pk, col1, col2, col3) VALUES(?,?,?,?)";
+                query = "UPSERT INTO " + testDecimalArithmetic
+                    + "(pk, col1, col2, col3) VALUES(?,?,?,?)";
                 stmt = conn.prepareStatement(query);
                 stmt.setString(1, "badValues");
                 // one more than max_precision
@@ -108,7 +114,8 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
                 assertEquals(SQLExceptionCode.DATA_EXCEEDS_MAX_CAPACITY.getErrorCode(),e.getErrorCode());
             }
             try {
-                query = "UPSERT INTO testDecimalArithmetic(pk, col1, col2, col3) VALUES(?,?,?,?)";
+                query = "UPSERT INTO " + testDecimalArithmetic
+                    + "(pk, col1, col2, col3) VALUES(?,?,?,?)";
                 stmt = conn.prepareStatement(query);
                 stmt.setString(1, "badValues");
                 stmt.setBigDecimal(2, new BigDecimal("123456"));
@@ -132,14 +139,16 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE source" + 
+            String source = generateRandomString();
+            String ddl = "CREATE TABLE " + source +
                     " (pk VARCHAR NOT NULL PRIMARY KEY, col1 DECIMAL(5,2), col2 DECIMAL(5,1), col3 DECIMAL(5,2), col4 DECIMAL(4,4))";
             createTestTable(getUrl(), ddl);
-            ddl = "CREATE TABLE target" + 
+            String target = generateRandomString();
+            ddl = "CREATE TABLE " + target +
                     " (pk VARCHAR NOT NULL PRIMARY KEY, col1 DECIMAL(5,1), col2 DECIMAL(5,2), col3 DECIMAL(4,4))";
             createTestTable(getUrl(), ddl);
             
-            String query = "UPSERT INTO source(pk, col1) VALUES(?,?)";
+            String query = "UPSERT INTO " + source + "(pk, col1) VALUES(?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "1");
             stmt.setBigDecimal(2, new BigDecimal("100.12"));
@@ -152,11 +161,11 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             
             // Evaluated on client side.
             // source and target in different tables, values scheme compatible.
-            query = "UPSERT INTO target(pk, col2) SELECT pk, col1 from source";
+            query = "UPSERT INTO " + target + "(pk, col2) SELECT pk, col1 from " + source;
             stmt = conn.prepareStatement(query);
             stmt.execute();
             conn.commit();
-            query = "SELECT col2 FROM target";
+            query = "SELECT col2 FROM " + target;
             stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -165,11 +174,11 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertEquals(new BigDecimal("100.34"), rs.getBigDecimal(1));
             assertFalse(rs.next());
             // source and target in different tables, values requires scale chopping.
-            query = "UPSERT INTO target(pk, col1) SELECT pk, col1 from source";
+            query = "UPSERT INTO " + target + "(pk, col1) SELECT pk, col1 from " + source;
             stmt = conn.prepareStatement(query);
             stmt.execute();
             conn.commit();
-            query = "SELECT col1 FROM target";
+            query = "SELECT col1 FROM " + target;
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -179,7 +188,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertFalse(rs.next());
             // source and target in different tables, values scheme incompatible.
             try {
-                query = "UPSERT INTO target(pk, col3) SELECT pk, col1 from source";
+                query = "UPSERT INTO " + target + "(pk, col3) SELECT pk, col1 from " + source;
                 stmt = conn.prepareStatement(query);
                 stmt.execute();
                 conn.commit();
@@ -191,11 +200,11 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             // Evaluate on server side.
             conn.setAutoCommit(true);
             // source and target in same table, values scheme compatible.
-            query = "UPSERT INTO source(pk, col3) SELECT pk, col1 from source";
+            query = "UPSERT INTO " + source + "(pk, col3) SELECT pk, col1 from " + source;
             stmt = conn.prepareStatement(query);
             stmt.execute();
             conn.commit();
-            query = "SELECT col3 FROM source";
+            query = "SELECT col3 FROM " + source;
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -204,11 +213,11 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertEquals(new BigDecimal("100.34"), rs.getBigDecimal(1));
             assertFalse(rs.next());
             // source and target in same table, values requires scale chopping.
-            query = "UPSERT INTO source(pk, col2) SELECT pk, col1 from source";
+            query = "UPSERT INTO " + source + "(pk, col2) SELECT pk, col1 from " + source;
             stmt = conn.prepareStatement(query);
             stmt.execute();
             conn.commit();
-            query = "SELECT col2 FROM source";
+            query = "SELECT col2 FROM " + source;
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -217,11 +226,11 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertEquals(new BigDecimal("100.3"), rs.getBigDecimal(1));
             assertFalse(rs.next());
             // source and target in same table, values scheme incompatible.
-            query = "UPSERT INTO source(pk, col4) SELECT pk, col1 from source";
+            query = "UPSERT INTO " + source + "(pk, col4) SELECT pk, col1 from " + source;
             stmt = conn.prepareStatement(query);
             stmt.execute();
             conn.commit();
-            query = "SELECT col4 FROM source";
+            query = "SELECT col4 FROM " + source;
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -240,11 +249,13 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE testDecimalArithmetic" + 
+            String testDecimalArithmetic = generateRandomString();
+            String ddl = "CREATE TABLE " + testDecimalArithmetic +
                     "  (pk VARCHAR NOT NULL PRIMARY KEY, col1 DECIMAL(31, 11), col2 DECIMAL(31,1), col3 DECIMAL(38,1))";
             createTestTable(getUrl(), ddl);
             
-            String query = "UPSERT INTO testDecimalArithmetic(pk, col1, col2, col3) VALUES(?,?,?,?)";
+            String query =
+                "UPSERT INTO " + testDecimalArithmetic + "(pk, col1, col2, col3) VALUES(?,?,?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "1");
             stmt.setBigDecimal(2, new BigDecimal("99999999999999999999.1"));
@@ -268,14 +279,14 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             // Averaging
             // result scale should be: max(max(ls, rs), 4).
             // We are not imposing restriction on precisioin.
-            query = "SELECT avg(col1) FROM testDecimalArithmetic";
+            query = "SELECT avg(col1) FROM " + testDecimalArithmetic;
             stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             assertTrue(rs.next());
             BigDecimal result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("33333333333333333333.03333333333"), result);
             
-            query = "SELECT avg(col2) FROM testDecimalArithmetic";
+            query = "SELECT avg(col2) FROM " + testDecimalArithmetic;
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -283,7 +294,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertEquals(new BigDecimal("33333333333333333333.0333"), result);
             
             // We cap our decimal to a precision of 38.
-            query = "SELECT avg(col3) FROM testDecimalArithmetic";
+            query = "SELECT avg(col3) FROM " + testDecimalArithmetic;
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -300,14 +311,17 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE testRandomFunction (pk VARCHAR NOT NULL PRIMARY KEY)";
+            String testRandomFunction = generateRandomString();
+            String ddl =
+                "CREATE TABLE " + testRandomFunction + " (pk VARCHAR NOT NULL PRIMARY KEY)";
             createTestTable(getUrl(), ddl);
-            conn.createStatement().execute("upsert into testRandomFunction values ('x')");
-            conn.createStatement().execute("upsert into testRandomFunction values ('y')");
-            conn.createStatement().execute("upsert into testRandomFunction values ('z')");
+            conn.createStatement().execute("upsert into " + testRandomFunction + " values ('x')");
+            conn.createStatement().execute("upsert into " + testRandomFunction + " values ('y')");
+            conn.createStatement().execute("upsert into " + testRandomFunction + " values ('z')");
             conn.commit();
 
-            ResultSet rs = conn.createStatement().executeQuery("select rand(), rand(), rand(1), rand(2), rand(1) from testRandomFunction");
+            ResultSet rs = conn.createStatement().executeQuery(
+                "select rand(), rand(), rand(1), rand(2), rand(1) from " + testRandomFunction);
             assertTrue(rs.next());
             double rand0 = rs.getDouble(1);
             double rand1 = rs.getDouble(3);
@@ -337,7 +351,8 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertTrue(rs.getDouble(4) != rs.getDouble(5));
             double rand12 = rs.getDouble(3);
 
-            rs = conn.createStatement().executeQuery("select rand(), rand(), rand(1), rand(2), rand(1) from testRandomFunction");
+            rs = conn.createStatement().executeQuery(
+                "select rand(), rand(), rand(1), rand(2), rand(1) from " + testRandomFunction);
             assertTrue(rs.next());
             assertTrue(rs.getDouble(1) != rs.getDouble(2));
             assertTrue(rs.getDouble(2) != rs.getDouble(3));
@@ -353,40 +368,52 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertTrue(rs.next());
             assertTrue(rand12 == rs.getDouble(3));
 
-            ddl = "CREATE TABLE testRandomFunction1 (pk VARCHAR NOT NULL PRIMARY KEY, v1 UNSIGNED_DOUBLE)";
+            String testRandomFunction1 = generateRandomString();
+            ddl = "CREATE TABLE " + testRandomFunction1
+                + " (pk VARCHAR NOT NULL PRIMARY KEY, v1 UNSIGNED_DOUBLE)";
             createTestTable(getUrl(), ddl);
-            conn.createStatement().execute("upsert into testRandomFunction1 select pk, rand(1) from testRandomFunction");
+            conn.createStatement().execute(
+                "upsert into " + testRandomFunction1 + " select pk, rand(1) from " + testRandomFunction);
             conn.commit();
 
-            rs = conn.createStatement().executeQuery("select count(*) from testRandomFunction1 where v1 = rand(1)");
+            rs = conn.createStatement().executeQuery(
+                "select count(*) from " + testRandomFunction1 + " where v1 = rand(1)");
             assertTrue(rs.next());
             assertEquals(3, rs.getInt(1));
 
-            rs = conn.createStatement().executeQuery("select count(*) from testRandomFunction1 where v1 = rand(2)");
+            rs = conn.createStatement().executeQuery(
+                "select count(*) from " + testRandomFunction1 + " where v1 = rand(2)");
             assertTrue(rs.next());
             assertEquals(0, rs.getInt(1));
 
-            conn.createStatement().execute("delete from testRandomFunction1 where v1 = rand(2)");
+            conn.createStatement().execute(
+                "delete from " + testRandomFunction1 + " where v1 = rand(2)");
             conn.commit();
 
-            rs = conn.createStatement().executeQuery("select count(*) from testRandomFunction1 where v1 = rand(1)");
+            rs = conn.createStatement().executeQuery(
+                "select count(*) from " + testRandomFunction1 + " where v1 = rand(1)");
             assertTrue(rs.next());
             assertEquals(3, rs.getInt(1));
 
             conn.setAutoCommit(true);
-            conn.createStatement().execute("upsert into testRandomFunction1 select pk, rand(2) from testRandomFunction1");
+            conn.createStatement().execute("upsert into " + testRandomFunction1
+                + " select pk, rand(2) from " + testRandomFunction1);
 
-            rs = conn.createStatement().executeQuery("select count(*) from testRandomFunction1 where v1 = rand(1)");
+            rs = conn.createStatement().executeQuery(
+                "select count(*) from " + testRandomFunction1 + " where v1 = rand(1)");
             assertTrue(rs.next());
             assertEquals(0, rs.getInt(1));
 
-            rs = conn.createStatement().executeQuery("select count(*) from testRandomFunction1 where v1 = rand(2)");
+            rs = conn.createStatement().executeQuery(
+                "select count(*) from " + testRandomFunction1 + " where v1 = rand(2)");
             assertTrue(rs.next());
             assertEquals(3, rs.getInt(1));
 
-            conn.createStatement().execute("delete from testRandomFunction1 where v1 = rand(2)");
+            conn.createStatement().execute(
+                "delete from " + testRandomFunction1 + " where v1 = rand(2)");
 
-            rs = conn.createStatement().executeQuery("select count(*) from testRandomFunction1 where v1 = rand(2)");
+            rs = conn.createStatement().executeQuery(
+                "select count(*) from " + testRandomFunction1 + " where v1 = rand(2)");
             assertTrue(rs.next());
             assertEquals(0, rs.getInt(1));
         } finally {
@@ -400,12 +427,14 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(false);
         try {
-            String ddl = "CREATE TABLE testDecimalArithmetic" + 
+            String testDecimalArithmetic = generateRandomString();
+            String ddl = "CREATE TABLE " + testDecimalArithmetic +
                     "  (pk VARCHAR NOT NULL PRIMARY KEY, " +
                     "col1 DECIMAL(38,0), col2 DECIMAL(5, 2), col3 INTEGER, col4 BIGINT, col5 DECIMAL)";
             createTestTable(getUrl(), ddl);
             
-            String query = "UPSERT INTO testDecimalArithmetic(pk, col1, col2, col3, col4, col5) VALUES(?,?,?,?,?,?)";
+            String query = "UPSERT INTO " + testDecimalArithmetic
+                + "(pk, col1, col2, col3, col4, col5) VALUES(?,?,?,?,?,?)";
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, "testValueOne");
             stmt.setBigDecimal(2, new BigDecimal("1234567890123456789012345678901"));
@@ -427,105 +456,105 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             
             // INT has a default precision and scale of (10, 0)
             // LONG has a default precision and scale of (19, 0)
-            query = "SELECT col1 + col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col1 + col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             assertTrue(rs.next());
             BigDecimal result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("1234567890123456789012345678911"), result);
             
-            query = "SELECT col1 + col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col1 + col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("1234567890123456789012345678911"), result);
             
-            query = "SELECT col2 + col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col2 + col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("133.45"), result);
             
-            query = "SELECT col2 + col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col2 + col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("133.45"), result);
             
-            query = "SELECT col5 + col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col5 + col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("121.111"), result);
             
-            query = "SELECT col5 + col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col5 + col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("121.111"), result);
             
-            query = "SELECT col1 - col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col1 - col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("1234567890123456789012345678891"), result);
             
-            query = "SELECT col1 - col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col1 - col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("1234567890123456789012345678891"), result);
             
-            query = "SELECT col2 - col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col2 - col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("113.45"), result);
             
-            query = "SELECT col2 - col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col2 - col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("113.45"), result);
             
-            query = "SELECT col5 - col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col5 - col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("101.111"), result);
             
-            query = "SELECT col5 - col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col5 - col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("101.111"), result);
             
-            query = "SELECT col1 * col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col1 * col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("1.234567890123456789012345678901E+31"), result);
             
-            query = "SELECT col1 * col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col1 * col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("1.234567890123456789012345678901E+31"), result);
 
-            query = "SELECT col1 * col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col1 * col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -533,7 +562,8 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertEquals(new BigDecimal("1.234567890123456789012345678901E+31"), result);
             
             try {
-            	query = "SELECT col1 * col3 FROM testDecimalArithmetic WHERE pk='testValueTwo'";
+            	query =
+                  "SELECT col1 * col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueTwo'";
             	stmt = conn.prepareStatement(query);
             	rs = stmt.executeQuery();
             	assertTrue(rs.next());
@@ -544,7 +574,8 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             }
             
             try {
-            	query = "SELECT col1 * col4 FROM testDecimalArithmetic WHERE pk='testValueTwo'";
+            	query =
+                  "SELECT col1 * col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueTwo'";
             	stmt = conn.prepareStatement(query);
             	rs = stmt.executeQuery();
             	assertTrue(rs.next());
@@ -554,21 +585,21 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
                 assertEquals(SQLExceptionCode.DATA_EXCEEDS_MAX_CAPACITY.getErrorCode(),e.getErrorCode());
             }
             
-            query = "SELECT col4 * col5 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col4 * col5 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(0, result.compareTo(new BigDecimal("1111.11")));
 
-            query = "SELECT col3 * col5 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col3 * col5 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(0, result.compareTo(new BigDecimal("1111.11")));
             
-            query = "SELECT col2 * col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col2 * col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -576,14 +607,14 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertEquals(new BigDecimal("1234.5"), result);
             
             // Result scale has value of 0
-            query = "SELECT col1 / col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col1 / col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("1.2345678901234567890123456789E+29"), result);
             
-            query = "SELECT col1 / col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col1 / col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -591,14 +622,14 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertEquals(new BigDecimal("1.2345678901234567890123456789E+29"), result);
             
             // Result scale is 2.
-            query = "SELECT col2 / col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col2 / col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("12.34"), result);
             
-            query = "SELECT col2 / col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col2 / col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -606,14 +637,14 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
             assertEquals(new BigDecimal("12.34"), result);
             
             // col5 has NO_SCALE, so the result's scale is not expected to be truncated to col5 value's scale of 4
-            query = "SELECT col5 / col3 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col5 / col3 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
             result = rs.getBigDecimal(1);
             assertEquals(new BigDecimal("11.1111"), result);
             
-            query = "SELECT col5 / col4 FROM testDecimalArithmetic WHERE pk='testValueOne'";
+            query = "SELECT col5 / col4 FROM " + testDecimalArithmetic + " WHERE pk='testValueOne'";
             stmt = conn.prepareStatement(query);
             rs = stmt.executeQuery();
             assertTrue(rs.next());
@@ -691,24 +722,27 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         }
     }
     
-    private void initIntegerTable(Connection conn) throws SQLException {
-        String ddl = "CREATE TABLE ARITHMETIC_TEST (six INTEGER PRIMARY KEY, four INTEGER, three INTEGER)";
+    private String initIntegerTable(Connection conn) throws SQLException {
+        String arithmetic_test = generateRandomString();
+        String ddl = "CREATE TABLE " + arithmetic_test
+            + " (six INTEGER PRIMARY KEY, four INTEGER, three INTEGER)";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO ARITHMETIC_TEST VALUES(6, 4, 3)";
+        String dml = "UPSERT INTO " + arithmetic_test + " VALUES(6, 4, 3)";
         conn.createStatement().execute(dml);
-        conn.commit();        
+        conn.commit();
+        return arithmetic_test;
     }
     
     @Test
     public void testOrderOfOperationsAdditionSubtraction() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initIntegerTable(conn);
+        String tableName = initIntegerTable(conn);
         ResultSet rs;
         
         // 6 + 4 - 3
         // 10 - 3
         // 7
-        rs = conn.createStatement().executeQuery("SELECT six + four - three FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT six + four - three FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(7, rs.getLong(1));
         assertFalse(rs.next());
@@ -716,7 +750,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         // 4 - 3 + 6
         // 1 + 6
         // 7
-        rs = conn.createStatement().executeQuery("SELECT four - three + six FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT four - three + six FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(7, rs.getLong(1));
         assertFalse(rs.next());
@@ -725,13 +759,13 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testOrderOfOperationsAdditionMultiplication() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initIntegerTable(conn);
+        String tableName = initIntegerTable(conn);
         ResultSet rs;
         
         // 6 + 4 * 3
         // 6 + 12
         // 18
-        rs = conn.createStatement().executeQuery("SELECT six + four * three FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT six + four * three FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(18, rs.getLong(1));
         assertFalse(rs.next());
@@ -739,7 +773,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         // 4 * 3 + 6
         // 12 * 6     
         // 18
-        rs = conn.createStatement().executeQuery("SELECT four * three + six FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT four * three + six FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(18, rs.getLong(1));
         assertFalse(rs.next());
@@ -748,13 +782,13 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testOrderOfOperationsAdditionDivision() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initIntegerTable(conn);
+        String tableName = initIntegerTable(conn);
         ResultSet rs;
         
         // 6 + 4 / 3
         // 6 + 1
         // 7
-        rs = conn.createStatement().executeQuery("SELECT six + four / three FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT six + four / three FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(7, rs.getLong(1));
         assertFalse(rs.next());
@@ -762,7 +796,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         // 4 / 3 + 6
         // 1 + 6     
         // 7
-        rs = conn.createStatement().executeQuery("SELECT four / three + six FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT four / three + six FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(7, rs.getLong(1));
         assertFalse(rs.next());
@@ -771,13 +805,13 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testOrderOfOperationsAdditionModulus() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initIntegerTable(conn);
+        String tableName = initIntegerTable(conn);
         ResultSet rs;
         
         // 6 + 4 % 3
         // 6 + 1
         // 7
-        rs = conn.createStatement().executeQuery("SELECT six + four % three FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT six + four % three FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(7, rs.getLong(1));
         assertFalse(rs.next());
@@ -785,7 +819,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         // 4 % 3 + 6
         // 1 + 6
         // 7
-        rs = conn.createStatement().executeQuery("SELECT four % three + six FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT four % three + six FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(7, rs.getLong(1));
         assertFalse(rs.next());
@@ -794,13 +828,13 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testOrderOfOperationsSubtrationMultiplication() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initIntegerTable(conn);
+        String tableName = initIntegerTable(conn);
         ResultSet rs;
         
         // 6 - 4 * 3
         // 6 - 12
         // -6
-        rs = conn.createStatement().executeQuery("SELECT six - four * three FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT six - four * three FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(-6, rs.getLong(1));
         assertFalse(rs.next());
@@ -808,7 +842,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         // 4 * 3 - 6
         // 12 - 6     
         // 6
-        rs = conn.createStatement().executeQuery("SELECT four * three - six FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT four * three - six FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(6, rs.getLong(1));
         assertFalse(rs.next());
@@ -817,13 +851,13 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testOrderOfOperationsSubtractionDivision() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initIntegerTable(conn);
+        String tableName = initIntegerTable(conn);
         ResultSet rs;
         
         // 6 - 4 / 3
         // 6 - 1     (integer division)
         // 5
-        rs = conn.createStatement().executeQuery("SELECT six - four / three FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT six - four / three FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(5, rs.getLong(1));
         assertFalse(rs.next());
@@ -831,7 +865,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         // 4 / 3 - 6
         // 1 - 6     (integer division)
         // -5
-        rs = conn.createStatement().executeQuery("SELECT four / three - six FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT four / three - six FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(-5, rs.getLong(1));
         assertFalse(rs.next());
@@ -840,13 +874,13 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testOrderOfOperationsSubtractionModulus() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initIntegerTable(conn);
+        String tableName = initIntegerTable(conn);
         ResultSet rs;
         
         // 6 - 4 % 3
         // 6 - 1
         // 5
-        rs = conn.createStatement().executeQuery("SELECT six - four % three FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT six - four % three FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(5, rs.getLong(1));
         assertFalse(rs.next());
@@ -854,7 +888,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         // 4 % 3 - 6
         // 1 - 6
         // -5
-        rs = conn.createStatement().executeQuery("SELECT four % three - six FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT four % three - six FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(-5, rs.getLong(1));
         assertFalse(rs.next());
@@ -863,13 +897,13 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testOrderOfOperationsMultiplicationDivision() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initIntegerTable(conn);
+        String tableName = initIntegerTable(conn);
         ResultSet rs;
         
         // 6 * 4 / 3
         // 24 / 3
         // 8
-        rs = conn.createStatement().executeQuery("SELECT six * four / three FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT six * four / three FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(8, rs.getLong(1));
         assertFalse(rs.next());
@@ -877,7 +911,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         // 4 / 3 * 6
         // 1 * 6     (integer division)
         // 6
-        rs = conn.createStatement().executeQuery("SELECT four / three * six FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT four / three * six FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(6, rs.getLong(1));
         assertFalse(rs.next());
@@ -886,13 +920,13 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testOrderOfOperationsMultiplicationModulus() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initIntegerTable(conn);
+        String tableName = initIntegerTable(conn);
         ResultSet rs;
         
         // 6 * 4 % 3
         // 24 % 3
         // 0
-        rs = conn.createStatement().executeQuery("SELECT six * four % three FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT six * four % three FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(0, rs.getLong(1));
         assertFalse(rs.next());
@@ -900,7 +934,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         // 4 % 3 * 6
         // 1 * 6
         // 6
-        rs = conn.createStatement().executeQuery("SELECT four % three * six FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT four % three * six FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(6, rs.getLong(1));
         assertFalse(rs.next());
@@ -909,13 +943,13 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testOrderOfOperationsDivisionModulus() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initIntegerTable(conn);
+        String tableName = initIntegerTable(conn);
         ResultSet rs;
         
         // 6 / 4 % 3
         // 1 % 3     (integer division)
         // 1
-        rs = conn.createStatement().executeQuery("SELECT six / four % three FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT six / four % three FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(1, rs.getLong(1));
         assertFalse(rs.next());
@@ -923,7 +957,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         // 4 % 3 / 6
         // 1 / 6
         // 0         (integer division)
-        rs = conn.createStatement().executeQuery("SELECT four % three / six FROM ARITHMETIC_TEST");
+        rs = conn.createStatement().executeQuery("SELECT four % three / six FROM " + tableName);
         assertTrue(rs.next());
         assertEquals(0, rs.getLong(1));
         assertFalse(rs.next());
@@ -932,13 +966,16 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testCastingOnConstantAddInArithmeticEvaluation() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE IF NOT EXISTS test_table (k1 INTEGER NOT NULL, v1 INTEGER CONSTRAINT pk PRIMARY KEY (k1))";
+        String testTable = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + testTable
+            + " (k1 INTEGER NOT NULL, v1 INTEGER CONSTRAINT pk PRIMARY KEY (k1))";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO test_table (k1, v1) VALUES (2, 2)";
+        String dml = "UPSERT INTO " + testTable + " (k1, v1) VALUES (2, 2)";
         conn.createStatement().execute(dml);
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT k1 / (v1 + 0.5) FROM test_table");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT k1 / (v1 + 0.5) FROM " + testTable);
         assertTrue(rs.next());
         double d = rs.getDouble(1);
         assertEquals(0.8, d, 0.01);
@@ -947,13 +984,16 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testCastingOnConstantSubInArithmeticEvaluation() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE IF NOT EXISTS test_table (k1 INTEGER NOT NULL, v1 INTEGER CONSTRAINT pk PRIMARY KEY (k1))";
+        String testTable = generateRandomString();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + testTable
+            + " (k1 INTEGER NOT NULL, v1 INTEGER CONSTRAINT pk PRIMARY KEY (k1))";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO test_table (k1, v1) VALUES (2, 2)";
+        String dml = "UPSERT INTO " + testTable + " (k1, v1) VALUES (2, 2)";
         conn.createStatement().execute(dml);
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT k1 / (v1 - 0.5) FROM test_table");
+        ResultSet rs = conn.createStatement().executeQuery(
+            "SELECT k1 / (v1 - 0.5) FROM " + testTable);
         assertTrue(rs.next());
         assertEquals(1.333333333, rs.getDouble(1), 0.001);
     }
@@ -961,13 +1001,15 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testFloatingPointUpsert() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE test (id VARCHAR not null primary key, name VARCHAR, lat FLOAT)";
+        String test = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + test + " (id VARCHAR not null primary key, name VARCHAR, lat FLOAT)";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO test(id,name,lat) VALUES ('testid', 'testname', -1.00)";
+        String dml = "UPSERT INTO " + test + "(id,name,lat) VALUES ('testid', 'testname', -1.00)";
         conn.createStatement().execute(dml);
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT lat FROM test");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT lat FROM " + test);
         assertTrue(rs.next());
         assertEquals(-1.0f, rs.getFloat(1), 0.001);
     }
@@ -975,13 +1017,16 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testFloatingPointMultiplicationUpsert() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE test (id VARCHAR not null primary key, name VARCHAR, lat FLOAT)";
+        String test = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + test + " (id VARCHAR not null primary key, name VARCHAR, lat FLOAT)";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO test(id,name,lat) VALUES ('testid', 'testname', -1.00 * 1)";
+        String dml =
+            "UPSERT INTO " + test + "(id,name,lat) VALUES ('testid', 'testname', -1.00 * 1)";
         conn.createStatement().execute(dml);
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT lat FROM test");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT lat FROM " + test);
         assertTrue(rs.next());
         assertEquals(-1.0f, rs.getFloat(1), 0.001);
     }
@@ -989,9 +1034,10 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testSystemTableHasDoubleForExponentialNumber() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE test (id VARCHAR not null primary key, num FLOAT)";
+        String test = generateRandomString();
+        String ddl = "CREATE TABLE " + test + " (id VARCHAR not null primary key, num FLOAT)";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO test(id,num) VALUES ('testid', 1.2E3)";
+        String dml = "UPSERT INTO " + test + "(id,num) VALUES ('testid', 1.2E3)";
         conn.createStatement().execute(dml);
         conn.commit();
 
@@ -1022,8 +1068,10 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
     
     private ResultSet createTableWithValues(String[] values, String valueType) throws SQLException {
     	Connection conn = DriverManager.getConnection(getUrl());
-        StringBuilder ddl = new StringBuilder("CREATE TABLE test (id VARCHAR not null primary key");
-        StringBuilder dmll = new StringBuilder("UPSERT INTO test(id,");
+        String test = generateRandomString();
+        StringBuilder ddl = new StringBuilder(
+            "CREATE TABLE " + test + " (id VARCHAR not null primary key");
+        StringBuilder dmll = new StringBuilder("UPSERT INTO " + test + "(id,");
         StringBuilder dmlr = new StringBuilder(") VALUES ('testid'");
         StringBuilder select = new StringBuilder("SELECT");
         for(int i = 0; i < values.length; i++) {
@@ -1036,7 +1084,7 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         dmlr.append(")");
         dmll.deleteCharAt(dmll.length()-1);
         select.deleteCharAt(select.length()-1);
-        select.append(" FROM test");
+        select.append(" FROM " + test);
         conn.createStatement().execute(ddl.toString());
         conn.createStatement().execute(dmll.toString() + dmlr.toString());
         conn.commit();
@@ -1045,4 +1093,4 @@ public class ArithmeticQueryIT extends BaseHBaseManagedTimeIT {
         rs.next();
         return rs;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java
index f9ce88d..dd9a64a 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayFillFunctionIT.java
@@ -25,14 +25,22 @@ import static org.junit.Assert.assertTrue;
 import java.math.BigDecimal;
 import java.sql.*;
 
+import org.junit.BeforeClass;
 import org.junit.Test;
 
-public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
+public class ArrayFillFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
 
-    private void initTables(Connection conn) throws Exception {
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,length1 INTEGER, length2 INTEGER,date DATE,time TIME,timestamp TIMESTAMP,varchar VARCHAR,integer INTEGER,double DOUBLE,bigint BIGINT,char CHAR(15),double1 DOUBLE,char1 CHAR(17),nullcheck INTEGER,chars2 CHAR(15)[], varchars2 VARCHAR[])";
+    private static final String REGIONS = generateRandomString();
+
+    @BeforeClass
+    public static void initTables() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String ddl = "CREATE TABLE " + REGIONS
+            + " (region_name VARCHAR PRIMARY KEY,length1 INTEGER, length2 INTEGER,date DATE,time TIME,timestamp TIMESTAMP,varchar VARCHAR,integer INTEGER,double DOUBLE,bigint BIGINT,char CHAR(15),double1 DOUBLE,char1 CHAR(17),nullcheck INTEGER,chars2 CHAR(15)[], varchars2 VARCHAR[])";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO regions(region_name,length1,length2,date,time,timestamp,varchar,integer,double,bigint,char,double1,char1,nullcheck,chars2,varchars2) VALUES('SF Bay Area'," +
+        String dml = "UPSERT INTO " + REGIONS
+            + "(region_name,length1,length2,date,time,timestamp,varchar,integer,double,bigint,char,double1,char1,nullcheck,chars2,varchars2) VALUES('SF Bay Area',"
+            +
                 "0," +
                 "-3," +
                 "to_date('2015-05-20 06:12:14.184')," +
@@ -57,10 +65,10 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionVarchar() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(varchar,5) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(varchar,5) FROM " + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String[] strings = new String[]{"foo", "foo", "foo", "foo", "foo"};
@@ -74,10 +82,10 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionInteger() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(integer,4) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(integer,4) FROM " + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{34, 34, 34, 34};
@@ -91,10 +99,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionDouble() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(double,4) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(double,4) FROM " + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{23.45, 23.45, 23.45, 23.45};
@@ -108,10 +117,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionBigint() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(bigint,4) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(bigint,4) FROM " + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{34567l, 34567l, 34567l, 34567l};
@@ -125,10 +135,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionChar() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(char,4) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(char,4) FROM " + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{"foo", "foo", "foo", "foo"};
@@ -141,10 +152,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionVarChar() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(varchar,4) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(varchar,4) FROM " + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{"foo", "foo", "foo", "foo"};
@@ -157,10 +169,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionDate() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(date,3) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(date,3) FROM " + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{new Date(1432102334184l), new Date(1432102334184l), new Date(1432102334184l)};
@@ -173,10 +186,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionTime() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(time,3) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(time,3) FROM " + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{new Time(1432102334184l), new Time(1432102334184l), new Time(1432102334184l)};
@@ -189,10 +203,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionTimestamp() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(timestamp,3) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(timestamp,3) FROM " + REGIONS + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{new Timestamp(1432102334184l), new Timestamp(1432102334184l), new Timestamp(1432102334184l)};
@@ -205,10 +220,12 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test(expected = IllegalArgumentException.class)
     public void testArrayFillFunctionInvalidLength1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(timestamp,length2) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(timestamp,length2) FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{new Timestamp(1432102334184l), new Timestamp(1432102334184l), new Timestamp(1432102334184l)};
@@ -221,10 +238,12 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test(expected = IllegalArgumentException.class)
     public void testArrayFillFunctionInvalidLength2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(timestamp,length1) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(timestamp,length1) FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{new Timestamp(1432102334184l), new Timestamp(1432102334184l), new Timestamp(1432102334184l)};
@@ -237,10 +256,12 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionWithNestedFunctions1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(ARRAY_ELEM(ARRAY[23,45],1),3) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(ARRAY_ELEM(ARRAY[23,45],1),3) FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Integer[] integers = new Integer[]{23, 23, 23};
@@ -254,10 +275,12 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionWithNestedFunctions2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL('hello', ARRAY_LENGTH(ARRAY[34, 45])) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL('hello', ARRAY_LENGTH(ARRAY[34, 45])) FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{"hello", "hello"};
@@ -271,10 +294,12 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionWithNestedFunctions3() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_FILL(3.4, ARRAY_LENGTH(ARRAY[34, 45])) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_FILL(3.4, ARRAY_LENGTH(ARRAY[34, 45])) FROM " + REGIONS
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Object[] objects = new Object[]{BigDecimal.valueOf(3.4), BigDecimal.valueOf(3.4)};
@@ -289,15 +314,19 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     public void testArrayFillFunctionWithUpsert1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
+        String regions = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + regions + " (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO regions(region_name,varchars) VALUES('SF Bay Area',ARRAY_FILL('hello',3))";
+        String dml = "UPSERT INTO " + regions
+            + "(region_name,varchars) VALUES('SF Bay Area',ARRAY_FILL('hello',3))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchars FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT varchars FROM " + regions + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         String[] strings = new String[]{"hello", "hello", "hello"};
@@ -312,15 +341,19 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     public void testArrayFillFunctionWithUpsert2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,integers INTEGER[])";
+        String regions = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + regions + " (region_name VARCHAR PRIMARY KEY,integers INTEGER[])";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO regions(region_name,integers) VALUES('SF Bay Area',ARRAY_FILL(3456,3))";
+        String dml = "UPSERT INTO " + regions
+            + "(region_name,integers) VALUES('SF Bay Area',ARRAY_FILL(3456,3))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT integers FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT integers FROM " + regions + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Integer[] integers = new Integer[]{3456, 3456, 3456};
@@ -335,15 +368,19 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     public void testArrayFillFunctionWithUpsert3() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,doubles DOUBLE[])";
+        String regions = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + regions + " (region_name VARCHAR PRIMARY KEY,doubles DOUBLE[])";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO regions(region_name,doubles) VALUES('SF Bay Area',ARRAY_FILL(2.5,3))";
+        String dml = "UPSERT INTO " + regions
+            + "(region_name,doubles) VALUES('SF Bay Area',ARRAY_FILL(2.5,3))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT doubles FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT doubles FROM " + regions + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         Double[] doubles = new Double[]{2.5, 2.5, 2.5};
@@ -400,25 +437,34 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     public void testArrayFillFunctionWithUpsertSelect2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE source (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
+        String source = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + source + " (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
         conn.createStatement().execute(ddl);
 
-        ddl = "CREATE TABLE target (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[],varchars2 VARCHAR[])";
+        String target = generateRandomString();
+        ddl = "CREATE TABLE " + target
+            + " (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[],varchars2 VARCHAR[])";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO source(region_name,varchars) VALUES('SF Bay Area',ARRAY_FILL('foo',3))";
+        String dml = "UPSERT INTO " + source
+            + "(region_name,varchars) VALUES('SF Bay Area',ARRAY_FILL('foo',3))";
         conn.createStatement().execute(dml);
 
-        dml = "UPSERT INTO source(region_name,varchars) VALUES('SF Bay Area2',ARRAY_FILL('hello',3))";
+        dml = "UPSERT INTO " + source
+            + "(region_name,varchars) VALUES('SF Bay Area2',ARRAY_FILL('hello',3))";
         conn.createStatement().execute(dml);
         conn.commit();
 
-        dml = "UPSERT INTO target(region_name, varchars, varchars2) SELECT region_name, varchars,ARRAY_FILL(':-)',5) FROM source";
+        dml =
+            "UPSERT INTO " + target
+                + "(region_name, varchars, varchars2) SELECT region_name, varchars,ARRAY_FILL(':-)',5) FROM "
+                + source;
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchars, varchars2 FROM target");
+        rs = conn.createStatement().executeQuery("SELECT varchars, varchars2 FROM " + target);
         assertTrue(rs.next());
 
         String[] strings = new String[]{"foo", "foo", "foo"};
@@ -441,10 +487,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionInWhere1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY[12, 12, 12, 12]=ARRAY_FILL(12,4)");
+        rs = conn.createStatement().executeQuery(
+            "SELECT region_name FROM " + REGIONS + " WHERE ARRAY[12, 12, 12, 12]=ARRAY_FILL(12,4)");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -454,10 +501,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionInWhere2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE varchar=ANY(ARRAY_FILL('foo',3))");
+        rs = conn.createStatement().executeQuery(
+            "SELECT region_name FROM " + REGIONS + " WHERE varchar=ANY(ARRAY_FILL('foo',3))");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -467,10 +515,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionInWhere3() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY['2345', '2345', '2345', '2345']=ARRAY_FILL('2345', 4)");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + REGIONS
+            + " WHERE ARRAY['2345', '2345', '2345', '2345']=ARRAY_FILL('2345', 4)");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -480,10 +529,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionInWhere4() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY[23.45, 23.45, 23.45]=ARRAY_FILL(23.45, 3)");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + REGIONS
+            + " WHERE ARRAY[23.45, 23.45, 23.45]=ARRAY_FILL(23.45, 3)");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -493,10 +543,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionInWhere5() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY['foo','foo','foo','foo','foo']=ARRAY_FILL(varchar,5)");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + REGIONS
+            + " WHERE ARRAY['foo','foo','foo','foo','foo']=ARRAY_FILL(varchar,5)");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -506,10 +557,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionInWhere6() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE varchars2=ARRAY_FILL('hello',3)");
+        rs = conn.createStatement().executeQuery(
+            "SELECT region_name FROM " + REGIONS + " WHERE varchars2=ARRAY_FILL('hello',3)");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -519,10 +571,11 @@ public class ArrayFillFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testArrayFillFunctionInWhere7() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
+        
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY[2,2,2,2]=ARRAY_FILL(2,4)");
+        rs = conn.createStatement().executeQuery(
+            "SELECT region_name FROM " + REGIONS + " WHERE ARRAY[2,2,2,2]=ARRAY_FILL(2,4)");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));


[47/52] [abbrv] phoenix git commit: Replace empty key value with unit tests passing

Posted by sa...@apache.org.
Replace empty key value with unit tests passing


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

Branch: refs/heads/encodecolumns
Commit: 55c5a72847d68719e49674e5d0513197014b6d6c
Parents: 2fda59a
Author: Samarth <sa...@salesforce.com>
Authored: Mon Mar 21 13:52:53 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:31 2016 -0700

----------------------------------------------------------------------
 .../apache/phoenix/end2end/AlterTableIT.java    |  16 +-
 .../apache/phoenix/end2end/UpsertValuesIT.java  |  42 ++++
 .../phoenix/end2end/index/IndexTestUtil.java    |  12 +-
 .../phoenix/compile/CreateTableCompiler.java    |   2 +-
 .../phoenix/compile/ExpressionCompiler.java     |   2 +-
 .../apache/phoenix/compile/FromCompiler.java    |  29 ++-
 .../apache/phoenix/compile/JoinCompiler.java    |  16 +-
 .../phoenix/compile/ListJarsQueryPlan.java      |   2 +-
 .../apache/phoenix/compile/PostDDLCompiler.java |  11 +-
 .../phoenix/compile/ProjectionCompiler.java     |   9 +-
 .../apache/phoenix/compile/TraceQueryPlan.java  |   2 +-
 .../compile/TupleProjectionCompiler.java        |   6 +-
 .../apache/phoenix/compile/UnionCompiler.java   |   5 +-
 .../apache/phoenix/compile/WhereCompiler.java   |   6 +-
 .../coprocessor/BaseScannerRegionObserver.java  |   3 +-
 .../coprocessor/MetaDataEndpointImpl.java       |  46 ++--
 .../coprocessor/SequenceRegionObserver.java     |   1 +
 .../UngroupedAggregateRegionObserver.java       |   8 +-
 .../coprocessor/generated/PTableProtos.java     | 243 ++++++++++++++++---
 .../apache/phoenix/execute/MutationState.java   |   2 +-
 .../expression/KeyValueColumnExpression.java    |  13 +-
 .../expression/ProjectedColumnExpression.java   |   1 +
 .../phoenix/filter/ColumnProjectionFilter.java  |  24 +-
 .../filter/MultiKeyValueComparisonFilter.java   |   2 +-
 .../filter/SingleKeyValueComparisonFilter.java  |   2 +-
 .../apache/phoenix/index/IndexMaintainer.java   |  42 ++--
 .../index/PhoenixTransactionalIndexer.java      |  12 +-
 .../phoenix/iterate/BaseResultIterators.java    |   5 +-
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java   |   4 +
 .../phoenix/mapreduce/AbstractBulkLoadTool.java |   2 +-
 .../mapreduce/FormatToBytesWritableMapper.java  |  44 ++--
 .../mapreduce/FormatToKeyValueReducer.java      |  10 +-
 .../query/ConnectionQueryServicesImpl.java      |   1 +
 .../apache/phoenix/query/QueryConstants.java    |  14 +-
 .../org/apache/phoenix/schema/ColumnRef.java    |   4 +-
 .../apache/phoenix/schema/DelegateColumn.java   |   5 +
 .../apache/phoenix/schema/DelegateTable.java    |  14 +-
 .../apache/phoenix/schema/MetaDataClient.java   | 103 ++++++--
 .../java/org/apache/phoenix/schema/PColumn.java |   7 +-
 .../apache/phoenix/schema/PColumnFamily.java    |  14 +-
 .../phoenix/schema/PColumnFamilyImpl.java       |  47 ++--
 .../org/apache/phoenix/schema/PColumnImpl.java  |  24 +-
 .../apache/phoenix/schema/PMetaDataImpl.java    |   4 +-
 .../java/org/apache/phoenix/schema/PName.java   |  26 ++
 .../java/org/apache/phoenix/schema/PTable.java  |  42 +++-
 .../org/apache/phoenix/schema/PTableImpl.java   | 136 +++++++++--
 .../apache/phoenix/schema/ProjectedColumn.java  |   1 +
 .../org/apache/phoenix/schema/SaltingUtil.java  |   2 +-
 .../java/org/apache/phoenix/util/IndexUtil.java |   7 +-
 .../org/apache/phoenix/util/PhoenixRuntime.java |   8 +-
 .../org/apache/phoenix/util/SchemaUtil.java     |  57 ++++-
 .../phoenix/compile/HavingCompilerTest.java     |   2 +-
 .../phoenix/compile/QueryCompilerTest.java      |   2 +-
 .../phoenix/compile/WhereCompilerTest.java      |  26 +-
 .../phoenix/execute/CorrelatePlanTest.java      |   4 +-
 .../execute/LiteralResultIteratorPlanTest.java  |   4 +-
 .../phoenix/execute/UnnestArrayPlanTest.java    |   4 +-
 .../expression/ColumnExpressionTest.java        |  16 +-
 .../phoenix/index/IndexMaintainerTest.java      |   3 +-
 .../iterate/AggregateResultScannerTest.java     |   6 +-
 .../query/BaseConnectionlessQueryTest.java      |  18 +-
 .../phoenix/query/ConnectionlessTest.java       |  15 +-
 .../java/org/apache/phoenix/util/TestUtil.java  |   4 +-
 phoenix-protocol/src/main/PTable.proto          |   2 +
 64 files changed, 943 insertions(+), 303 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index 2dc0913..6f31955 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -44,6 +44,7 @@ import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.KeepDeletedCells;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.ResultScanner;
 import org.apache.hadoop.hbase.client.Scan;
@@ -56,6 +57,7 @@ import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.PropertiesUtil;
@@ -2134,23 +2136,23 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
             PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class); 
             PTable table = phxConn.getTable(new PTableKey(phxConn.getTenantId(), "T1"));
             // Assert that the column shows up as row time stamp in the cache.
-            assertTrue(table.getColumn("PK1").isRowTimestamp());
-            assertFalse(table.getColumn("PK2").isRowTimestamp());
+            assertTrue(table.getPColumnForColumnName("PK1").isRowTimestamp());
+            assertFalse(table.getPColumnForColumnName("PK2").isRowTimestamp());
             assertIsRowTimestampSet("T1", "PK1");
             
             conn.createStatement().execute("CREATE TABLE T6 (PK1 VARCHAR, PK2 DATE PRIMARY KEY ROW_TIMESTAMP, KV1 VARCHAR, KV2 INTEGER)");
             table = phxConn.getTable(new PTableKey(phxConn.getTenantId(), "T6"));
             // Assert that the column shows up as row time stamp in the cache.
-            assertFalse(table.getColumn("PK1").isRowTimestamp());
-            assertTrue(table.getColumn("PK2").isRowTimestamp());
+            assertFalse(table.getPColumnForColumnName("PK1").isRowTimestamp());
+            assertTrue(table.getPColumnForColumnName("PK2").isRowTimestamp());
             assertIsRowTimestampSet("T6", "PK2");
             
             // Create an index on a table has a row time stamp pk column. The column should show up as a row time stamp column for the index too. 
             conn.createStatement().execute("CREATE INDEX T6_IDX ON T6 (KV1) include (KV2)");
             PTable indexTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), "T6_IDX"));
-            String indexColName = IndexUtil.getIndexColumnName(table.getColumn("PK2"));
+            String indexColName = IndexUtil.getIndexColumnName(table.getPColumnForColumnName("PK2"));
             // Assert that the column shows up as row time stamp in the cache.
-            assertTrue(indexTable.getColumn(indexColName).isRowTimestamp());
+            assertTrue(indexTable.getPColumnForColumnName(indexColName).isRowTimestamp());
             assertIsRowTimestampSet("T6_IDX", indexColName);
             
             // Creating a view with a row_timestamp column in its pk constraint is not allowed
@@ -2215,6 +2217,6 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
 			}
 		}
 	}
-    
+	
 }
  

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
index 78dce80..3fec718 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertValuesIT.java
@@ -37,12 +37,20 @@ import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Properties;
 
+import org.apache.hadoop.hbase.client.HTableInterface;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.util.DateUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.TestUtil;
 import org.junit.Test;
 
@@ -922,6 +930,40 @@ public class UpsertValuesIT extends BaseClientManagedTimeIT {
         }
     }
     
+    @Test
+    public void testColumnQualifierForUpsertedValues() throws Exception {
+        String schemaName = "A";
+        String tableName = "TEST";
+        String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
+        String ddl = "create table " + fullTableName 
+                + " (" 
+                + " K varchar primary key,"
+                + " CF1.V1 varchar, CF2.V2 VARCHAR, CF2.V3 VARCHAR)";
+        try (Connection conn = getConnection(nextTimestamp())) {
+            conn.createStatement().execute(ddl);
+        }
+        String dml = "UPSERT INTO " + fullTableName + " VALUES (?, ?, ?, ?)";
+        try (Connection conn = getConnection(nextTimestamp())) {
+            PreparedStatement stmt = conn.prepareStatement(dml);
+            stmt.setString(1, "KEY1");
+            stmt.setString(2, "VALUE1");
+            stmt.setString(3, "VALUE2");
+            stmt.setString(4, "VALUE3");
+            stmt.executeUpdate();
+            conn.commit();
+        }
+        // Issue a raw hbase scan and assert that key values have the expected column qualifiers.
+        try (Connection conn = getConnection(nextTimestamp())) {
+            HTableInterface table = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes(fullTableName));
+            ResultScanner scanner = table.getScanner(new Scan());
+            Result next = scanner.next();
+            assertTrue(next.containsColumn(Bytes.toBytes("CF1"), PInteger.INSTANCE.toBytes(1)));
+            assertTrue(next.containsColumn(Bytes.toBytes("CF2"), PInteger.INSTANCE.toBytes(1)));
+            assertTrue(next.containsColumn(Bytes.toBytes("CF2"), PInteger.INSTANCE.toBytes(2)));
+        }
+    }
+    
+    
     private static Connection getConnection(long ts) throws SQLException {
         Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexTestUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexTestUtil.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexTestUtil.java
index ba04ad7..42c0264 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexTestUtil.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexTestUtil.java
@@ -39,15 +39,14 @@ import org.apache.hadoop.hbase.client.Mutation;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
-import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.ColumnNotFoundException;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PColumnFamily;
-import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.PRow;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.RowKeySchema;
 import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.MetaDataUtil;
 import org.apache.phoenix.util.SchemaUtil;
@@ -115,7 +114,7 @@ public class IndexTestUtil {
         while ((hasValue = dataRowKeySchema.next(ptr, i, maxOffset)) != null) {
             if (hasValue) {
                 PColumn dataColumn = dataPKColumns.get(i);
-                PColumn indexColumn = indexTable.getColumn(IndexUtil.getIndexColumnName(dataColumn));
+                PColumn indexColumn = indexTable.getPColumnForColumnName(IndexUtil.getIndexColumnName(dataColumn));
                 coerceDataValueToIndexValue(dataColumn, indexColumn, ptr);
                 indexValues[indexColumn.getPosition()-indexOffset] = ptr.copyBytes();
             }
@@ -135,10 +134,11 @@ public class IndexTestUtil {
                     for (Cell kv : entry.getValue()) {
                         @SuppressWarnings("deprecation")
                         byte[] cq = kv.getQualifier();
-                        if (Bytes.compareTo(QueryConstants.EMPTY_COLUMN_BYTES, cq) != 0) {
+                        byte[] emptyKVQualifier = SchemaUtil.getEmptyKeyValueInfo(dataTable).getFirst();
+                        if (Bytes.compareTo(emptyKVQualifier, cq) != 0) {
                             try {
-                                PColumn dataColumn = family.getColumn(cq);
-                                PColumn indexColumn = indexTable.getColumn(IndexUtil.getIndexColumnName(family.getName().getString(), dataColumn.getName().getString()));
+                                PColumn dataColumn = family.getPColumnForColumnQualifier(cq);
+                                PColumn indexColumn = indexTable.getPColumnForColumnName(IndexUtil.getIndexColumnName(family.getName().getString(), dataColumn.getName().getString()));
                                 ptr.set(kv.getValueArray(),kv.getValueOffset(),kv.getValueLength());
                                 coerceDataValueToIndexValue(dataColumn, indexColumn, ptr);
                                 indexValues[indexPKColumns.indexOf(indexColumn)-indexOffset] = ptr.copyBytes();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
index e032feb..03f679b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java
@@ -290,7 +290,7 @@ public class CreateTableCompiler {
         @Override
         public Boolean visit(KeyValueColumnExpression node) {
             try {
-                this.position = table.getColumnFamily(node.getColumnFamily()).getColumn(node.getColumnName()).getPosition();
+                this.position = table.getColumnFamily(node.getColumnFamily()).getPColumnForColumnQualifier(node.getColumnQualifier()).getPosition();
             } catch (SQLException e) {
                 throw new RuntimeException(e); // Impossible
             }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
index 1278494..31a2f82 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
@@ -407,7 +407,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
             return LiteralExpression.newConstant(column.getDataType().toObject(ptr), column.getDataType());
         }
         if (tableRef.equals(context.getCurrentTable()) && !SchemaUtil.isPKColumn(column)) { // project only kv columns
-            context.getScan().addColumn(column.getFamilyName().getBytes(), column.getName().getBytes());
+            context.getScan().addColumn(column.getFamilyName().getBytes(), SchemaUtil.getColumnQualifier(column, tableRef.getTable()));
         }
         Expression expression = ref.newColumnExpression(node.isTableNameCaseSensitive(), node.isCaseSensitive());
         Expression wrappedExpression = wrapGroupByExpression(expression);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
index a2fc371..d420036 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
@@ -125,10 +125,12 @@ public class FromCompiler {
             throw new ColumnNotFoundException(schemaName, tableName, null, colName);
         }
         
+        @Override
         public PFunction resolveFunction(String functionName) throws SQLException {
             throw new FunctionNotFoundException(functionName);
         }
 
+        @Override
         public boolean hasUDFs() {
             return false;
         }
@@ -182,7 +184,7 @@ public class FromCompiler {
                     if (htable != null) Closeables.closeQuietly(htable);
                 }
                 tableNode = NamedTableNode.create(null, baseTable, statement.getColumnDefs());
-                return new SingleTableColumnResolver(connection, tableNode, e.getTimeStamp(), new HashMap<String, UDFParseNode>(1));
+                return new SingleTableColumnResolver(connection, tableNode, e.getTimeStamp(), new HashMap<String, UDFParseNode>(1), false);
             }
             throw e;
         }
@@ -250,7 +252,7 @@ public class FromCompiler {
             Expression sourceExpression = projector.getColumnProjector(column.getPosition()).getExpression();
             PColumnImpl projectedColumn = new PColumnImpl(column.getName(), column.getFamilyName(),
                     sourceExpression.getDataType(), sourceExpression.getMaxLength(), sourceExpression.getScale(), sourceExpression.isNullable(),
-                    column.getPosition(), sourceExpression.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic());
+                    column.getPosition(), sourceExpression.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic(), column.getColumnQualifier());
             projectedColumns.add(projectedColumn);
         }
         PTable t = PTableImpl.makePTable(table, projectedColumns);
@@ -325,12 +327,12 @@ public class FromCompiler {
     	private final String alias;
         private final List<PSchema> schemas;
 
-       public SingleTableColumnResolver(PhoenixConnection connection, NamedTableNode table, long timeStamp, Map<String, UDFParseNode> udfParseNodes) throws SQLException  {
+       public SingleTableColumnResolver(PhoenixConnection connection, NamedTableNode table, long timeStamp, Map<String, UDFParseNode> udfParseNodes, boolean useEncodedColumnNames) throws SQLException  {
            super(connection, 0, false, udfParseNodes);
            List<PColumnFamily> families = Lists.newArrayListWithExpectedSize(table.getDynamicColumns().size());
            for (ColumnDef def : table.getDynamicColumns()) {
                if (def.getColumnDefName().getFamilyName() != null) {
-                   families.add(new PColumnFamilyImpl(PNameFactory.newName(def.getColumnDefName().getFamilyName()),Collections.<PColumn>emptyList()));
+                   families.add(new PColumnFamilyImpl(PNameFactory.newName(def.getColumnDefName().getFamilyName()),Collections.<PColumn>emptyList(), useEncodedColumnNames));
                }
             }
             Long scn = connection.getSCN();
@@ -440,8 +442,8 @@ public class FromCompiler {
 
 			}
         	PColumn column = resolveCF
-        	        ? tableRef.getTable().getColumnFamily(tableName).getColumn(colName)
-        			: tableRef.getTable().getColumn(colName);
+        	        ? tableRef.getTable().getColumnFamily(tableName).getPColumnForColumnName(colName)
+        			: tableRef.getTable().getPColumnForColumnName(colName);
             return new ColumnRef(tableRef, column.getPosition());
 		}
 
@@ -664,8 +666,9 @@ public class FromCompiler {
                         theTable.getColumnFamily(family); // Verifies that column family exists
                         familyName = PNameFactory.newName(family);
                     }
+                    // Dynamic columns don't have a corresponding column qualifier
                     allcolumns.add(new PColumnImpl(name, familyName, dynColumn.getDataType(), dynColumn.getMaxLength(),
-                            dynColumn.getScale(), dynColumn.isNull(), position, dynColumn.getSortOrder(), dynColumn.getArraySize(), null, false, dynColumn.getExpression(), false, true));
+                            dynColumn.getScale(), dynColumn.isNull(), position, dynColumn.getSortOrder(), dynColumn.getArraySize(), null, false, dynColumn.getExpression(), false, true, null));
                     position++;
                 }
                 theTable = PTableImpl.makePTable(theTable, allcolumns);
@@ -767,16 +770,18 @@ public class FromCompiler {
                     // referenced by an outer wild-card select.
                     alias = String.valueOf(position);
                 }
+                //TODO: samarth confirm this is the right change i.e. using null for column qualifier
                 PColumnImpl column = new PColumnImpl(PNameFactory.newName(alias),
                         PNameFactory.newName(QueryConstants.DEFAULT_COLUMN_FAMILY),
-                        null, 0, 0, true, position++, SortOrder.ASC, null, null, false, null, false, false);
+                        null, 0, 0, true, position++, SortOrder.ASC, null, null, false, null, false, false, null);
                 columns.add(column);
             }
+            //TODO: samarth confirm if the storage scheme should be passed as null here. Could it be non-encoded column names?
             PTable t = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,
                     MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM, null, null, columns, null, null,
                     Collections.<PTable> emptyList(), false, Collections.<PName> emptyList(), null, null, false, false,
                     false, null, null, null, false, false, 0, 0L, SchemaUtil
-                            .isNamespaceMappingEnabled(PTableType.SUBQUERY, connection.getQueryServices().getProps()));
+                            .isNamespaceMappingEnabled(PTableType.SUBQUERY, connection.getQueryServices().getProps()), null);
 
             String alias = subselectNode.getAlias();
             TableRef tableRef = new TableRef(alias, t, MetaDataProtocol.MIN_TABLE_TIMESTAMP, false);
@@ -851,7 +856,7 @@ public class FromCompiler {
                 while (iterator.hasNext()) {
                     TableRef tableRef = iterator.next();
                     try {
-                        PColumn column = tableRef.getTable().getColumn(colName);
+                        PColumn column = tableRef.getTable().getPColumnForColumnName(colName);
                         if (theTableRef != null) { throw new AmbiguousColumnException(colName); }
                         theTableRef = tableRef;
                         theColumnPosition = column.getPosition();
@@ -864,12 +869,12 @@ public class FromCompiler {
             } else {
                 try {
                     TableRef tableRef = resolveTable(schemaName, tableName);
-                    PColumn column = tableRef.getTable().getColumn(colName);
+                    PColumn column = tableRef.getTable().getPColumnForColumnName(colName);
                     return new ColumnRef(tableRef, column.getPosition());
                 } catch (TableNotFoundException e) {
                     // Try using the tableName as a columnFamily reference instead
                     ColumnFamilyRef cfRef = resolveColumnFamily(schemaName, tableName);
-                    PColumn column = cfRef.getFamily().getColumn(colName);
+                    PColumn column = cfRef.getFamily().getPColumnForColumnName(colName);
                     return new ColumnRef(cfRef.getTableRef(), column.getPosition());
                 }
             }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
index 93b32de..a753b04 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
@@ -74,6 +74,7 @@ import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTable.IndexType;
+import org.apache.phoenix.schema.PTable.StorageScheme;
 import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.ProjectedColumn;
@@ -716,7 +717,7 @@ public class JoinCompiler {
                 if (columnRef.getTableRef().equals(tableRef)
                         && !SchemaUtil.isPKColumn(columnRef.getColumn())
                         && !(columnRef instanceof LocalIndexColumnRef)) {
-                    scan.addColumn(columnRef.getColumn().getFamilyName().getBytes(), columnRef.getColumn().getName().getBytes());
+                    scan.addColumn(columnRef.getColumn().getFamilyName().getBytes(), SchemaUtil.getColumnQualifier(columnRef.getColumn(), tableRef.getTable()));
                 }
             }
         }
@@ -1299,15 +1300,14 @@ public class JoinCompiler {
         if (left.getBucketNum() != null) {
             merged.remove(0);
         }
-        
+        //TODO: samarth should projected join table should always have non-encoded column names?
         return PTableImpl.makePTable(left.getTenantId(), left.getSchemaName(),
                 PNameFactory.newName(SchemaUtil.getTableName(left.getName().getString(), right.getName().getString())),
-                left.getType(), left.getIndexState(), left.getTimeStamp(), left.getSequenceNumber(), left.getPKName(),
-                left.getBucketNum(), merged, left.getParentSchemaName(), left.getParentTableName(), left.getIndexes(),
-                left.isImmutableRows(), Collections.<PName> emptyList(), null, null, PTable.DEFAULT_DISABLE_WAL,
-                left.isMultiTenant(), left.getStoreNulls(), left.getViewType(), left.getViewIndexId(),
-                left.getIndexType(), left.rowKeyOrderOptimizable(), left.isTransactional(),
-                left.getUpdateCacheFrequency(), left.getIndexDisableTimestamp(), left.isNamespaceMapped());
+                left.getType(), left.getIndexState(), left.getTimeStamp(), left.getSequenceNumber(), left.getPKName(), 
+                left.getBucketNum(), merged,left.getParentSchemaName(), left.getParentTableName(), left.getIndexes(),
+                left.isImmutableRows(), Collections.<PName>emptyList(), null, null, PTable.DEFAULT_DISABLE_WAL,
+                left.isMultiTenant(), left.getStoreNulls(), left.getViewType(), left.getViewIndexId(), left.getIndexType(),
+                left.rowKeyOrderOptimizable(), left.isTransactional(), left.getUpdateCacheFrequency(), left.getIndexDisableTimestamp(), left.isNamespaceMapped(), StorageScheme.NON_ENCODED_COLUMN_NAMES);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
index 1047334..cceef9a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
@@ -80,7 +80,7 @@ public class ListJarsQueryPlan implements QueryPlan {
         PColumn column =
                 new PColumnImpl(PNameFactory.newName("jar_location"), null,
                         PVarchar.INSTANCE, null, null, false, 0, SortOrder.getDefault(), 0, null,
-                        false, null, false, false);
+                        false, null, false, false, null);
         List<PColumn> columns = new ArrayList<PColumn>();
         columns.add(column);
         Expression expression =

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
index a786438..f7cd2b1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
@@ -51,6 +51,7 @@ import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.util.ScanUtil;
+import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.TransactionUtil;
 
 import com.google.common.collect.Lists;
@@ -176,8 +177,8 @@ public class PostDDLCompiler {
                             @Override
                             public ColumnRef resolveColumn(String schemaName, String tableName, String colName) throws SQLException {
                                 PColumn column = tableName != null
-                                        ? tableRef.getTable().getColumnFamily(tableName).getColumn(colName)
-                                        : tableRef.getTable().getColumn(colName);
+                                        ? tableRef.getTable().getColumnFamily(tableName).getPColumnForColumnName(colName)
+                                        : tableRef.getTable().getPColumnForColumnName(colName);
                                 return new ColumnRef(tableRef, column.getPosition());
                             }
                             
@@ -213,6 +214,7 @@ public class PostDDLCompiler {
                         ScanUtil.setTimeRange(scan, ts);
                         if (emptyCF != null) {
                             scan.setAttribute(BaseScannerRegionObserver.EMPTY_CF, emptyCF);
+                            scan.setAttribute(BaseScannerRegionObserver.EMPTY_COLUMN_QUALIFIER, SchemaUtil.getEmptyKeyValueInfo(tableRef.getTable()).getFirst());
                         }
                         ServerCache cache = null;
                         try {
@@ -236,11 +238,12 @@ public class PostDDLCompiler {
                                     // data empty column family to stay the same, while the index empty column family
                                     // changes.
                                     PColumn column = deleteList.get(0);
+                                    byte[] cq = SchemaUtil.getColumnQualifier(column, tableRef.getTable());
                                     if (emptyCF == null) {
-                                        scan.addColumn(column.getFamilyName().getBytes(), column.getName().getBytes());
+                                        scan.addColumn(column.getFamilyName().getBytes(), cq);
                                     }
                                     scan.setAttribute(BaseScannerRegionObserver.DELETE_CF, column.getFamilyName().getBytes());
-                                    scan.setAttribute(BaseScannerRegionObserver.DELETE_CQ, column.getName().getBytes());
+                                    scan.setAttribute(BaseScannerRegionObserver.DELETE_CQ, cq);
                                 }
                             }
                             List<byte[]> columnFamilies = Lists.newArrayListWithExpectedSize(tableRef.getTable().getColumnFamilies().size());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
index 3cf3934..b6a6771 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
@@ -217,7 +217,7 @@ public class ProjectionCompiler {
             PColumn indexColumn = null;
             ColumnRef ref = null;
             try {
-                indexColumn = index.getColumn(indexColName);
+                indexColumn = index.getPColumnForColumnName(indexColName);
                 ref = new ColumnRef(tableRef, indexColumn.getPosition());
             } catch (ColumnNotFoundException e) {
                 if (index.getIndexType() == IndexType.LOCAL) {
@@ -288,7 +288,7 @@ public class ProjectionCompiler {
             PColumn indexColumn = null;
             ColumnRef ref = null;
             try {
-                indexColumn = index.getColumn(indexColName);
+                indexColumn = index.getPColumnForColumnName(indexColName);
                 ref = new ColumnRef(tableRef, indexColumn.getPosition());
             } catch (ColumnNotFoundException e) {
                 if (index.getIndexType() == IndexType.LOCAL) {
@@ -476,7 +476,7 @@ public class ProjectionCompiler {
                 }
             } else {
                 for (byte[] cq : entry.getValue()) {
-                    PColumn column = family.getColumn(cq);
+                    PColumn column = family.getPColumnForColumnQualifier(cq);
                     Integer maxLength = column.getMaxLength();
                     int byteSize = column.getDataType().isFixedWidth() ? maxLength == null ? column.getDataType().getByteSize() : maxLength : RowKeySchema.ESTIMATED_VARIABLE_LENGTH_SIZE;
                     estimatedByteSize += SizedUtil.KEY_VALUE_SIZE + estimatedKeySize + byteSize;
@@ -702,7 +702,8 @@ public class ProjectionCompiler {
                      public Void visit(ProjectedColumnExpression expression) {
                          if (expression.getDataType().isArrayType()) {
                              indexProjectedColumns.add(expression);
-                             KeyValueColumnExpression keyValueColumnExpression = new KeyValueColumnExpression(expression.getColumn());
+                             //TODO: samarth confirm this change that column names 
+                             KeyValueColumnExpression keyValueColumnExpression = new KeyValueColumnExpression(expression.getColumn(), false);
                              indexKVs.add(keyValueColumnExpression);
                              copyOfChildren.set(0, keyValueColumnExpression);
                              Integer count = arrayExpressionCounts.get(expression);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
index 699643b..79d212f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
@@ -78,7 +78,7 @@ public class TraceQueryPlan implements QueryPlan {
         PColumn column =
                 new PColumnImpl(PNameFactory.newName(MetricInfo.TRACE.columnName), null,
                         PLong.INSTANCE, null, null, false, 0, SortOrder.getDefault(), 0, null,
-                        false, null, false, false);
+                        false, null, false, false, null);
         List<PColumn> columns = new ArrayList<PColumn>();
         columns.add(column);
         Expression expression =

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
index a9199c6..51d4cf9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
@@ -136,7 +136,7 @@ public class TupleProjectionCompiler {
             projectedColumns.add(column);
             // Wildcard or FamilyWildcard will be handled by ProjectionCompiler.
             if (!isWildcard && !families.contains(sourceColumn.getFamilyName())) {
-                context.getScan().addColumn(sourceColumn.getFamilyName().getBytes(), sourceColumn.getName().getBytes());
+                context.getScan().addColumn(sourceColumn.getFamilyName().getBytes(), SchemaUtil.getColumnQualifier(column, table));
             }
         }
         // add LocalIndexDataColumnRef
@@ -153,7 +153,7 @@ public class TupleProjectionCompiler {
                 table.getParentName(), table.getIndexes(), table.isImmutableRows(), Collections.<PName> emptyList(),
                 null, null, table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(),
                 table.getViewIndexId(),
-                table.getIndexType(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
+                table.getIndexType(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
     }
 
     public static PTable createProjectedTable(TableRef tableRef, List<ColumnRef> sourceColumnRefs, boolean retainPKColumns) throws SQLException {
@@ -181,7 +181,7 @@ public class TupleProjectionCompiler {
                 Collections.<PTable> emptyList(), table.isImmutableRows(), Collections.<PName> emptyList(), null, null,
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(),
                 table.getViewIndexId(), null, table.rowKeyOrderOptimizable(), table.isTransactional(),
-                table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped());
+                table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
     }
 
     // For extracting column references from single select statement

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
index 32fa8fe..9c79bfb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
@@ -74,9 +74,10 @@ public class UnionCompiler {
             ColumnProjector colProj = plan.getProjector().getColumnProjector(i);
             Expression sourceExpression = colProj.getExpression();
             String name = selectNodes == null ? colProj.getName() : selectNodes.get(i).getAlias();
+            //TODO: samarth confirm this is the right change
             PColumnImpl projectedColumn = new PColumnImpl(PNameFactory.newName(name), UNION_FAMILY_NAME,
                     sourceExpression.getDataType(), sourceExpression.getMaxLength(), sourceExpression.getScale(), sourceExpression.isNullable(),
-                    i, sourceExpression.getSortOrder(), 500, null, false, sourceExpression.toString(), false, false);
+                    i, sourceExpression.getSortOrder(), 500, null, false, sourceExpression.toString(), false, false, null);
             projectedColumns.add(projectedColumn);
         }
         Long scn = statement.getConnection().getSCN();
@@ -85,7 +86,7 @@ public class UnionCompiler {
                 scn == null ? HConstants.LATEST_TIMESTAMP : scn, null, null, projectedColumns, null, null, null, true,
                 null, null, null, true, true, true, null, null, null, false, false, 0, 0L,
                 SchemaUtil.isNamespaceMappingEnabled(PTableType.SUBQUERY,
-                        statement.getConnection().getQueryServices().getProps()));
+                        statement.getConnection().getQueryServices().getProps()), null);
         TableRef tableRef = new TableRef(null, tempTable, 0, false);
         return tableRef;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
index 13963d7..c2e42f2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
@@ -170,8 +170,8 @@ public class WhereCompiler {
             TableRef tableRef = ref.getTableRef();
             if (tableRef.equals(context.getCurrentTable()) && !SchemaUtil.isPKColumn(ref.getColumn())) {
                 // track the where condition columns. Later we need to ensure the Scan in HRS scans these column CFs
-                context.addWhereCoditionColumn(ref.getColumn().getFamilyName().getBytes(), ref.getColumn().getName()
-                        .getBytes());
+                byte[] cq = SchemaUtil.getColumnQualifier(ref.getColumn(), tableRef.getTable());
+                context.addWhereCoditionColumn(ref.getColumn().getFamilyName().getBytes(), cq);
             }
             return ref.newColumnExpression(node.isTableNameCaseSensitive(), node.isCaseSensitive());
         }
@@ -194,7 +194,7 @@ public class WhereCompiler {
             // just use that.
             try {
                 if (!SchemaUtil.isPKColumn(ref.getColumn())) {
-                    table.getColumn(ref.getColumn().getName().getString());
+                    table.getPColumnForColumnName(ref.getColumn().getName().getString());
                 }
             } catch (AmbiguousColumnException e) {
                 disambiguateWithFamily = true;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
index 96ee543..d66c7ae 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
@@ -77,6 +77,7 @@ abstract public class BaseScannerRegionObserver extends BaseRegionObserver {
     public static final String DELETE_CQ = "_DeleteCQ";
     public static final String DELETE_CF = "_DeleteCF";
     public static final String EMPTY_CF = "_EmptyCF";
+    public static final String EMPTY_COLUMN_QUALIFIER = "_EmptyColumnQualifier";
     public static final String SPECIFIC_ARRAY_INDEX = "_SpecificArrayIndex";
     public static final String GROUP_BY_LIMIT = "_GroupByLimit";
     public static final String LOCAL_INDEX = "_LocalIndex";
@@ -400,7 +401,7 @@ abstract public class BaseScannerRegionObserver extends BaseRegionObserver {
                             Cell kv = tuple.getValue(idx);
                             if (Bytes.equals(kvExp.getColumnFamily(), 0, kvExp.getColumnFamily().length,
                                     kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength())
-                                && Bytes.equals(kvExp.getColumnName(), 0, kvExp.getColumnName().length,
+                                && Bytes.equals(kvExp.getColumnQualifier(), 0, kvExp.getColumnQualifier().length,
                                         kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength())) {
                                 // remove the kv that has the full array values.
                                 result.remove(idx);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 1fd4f44..20b5e89 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -19,12 +19,14 @@ package org.apache.phoenix.coprocessor;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
+import static org.apache.phoenix.schema.PTable.StorageScheme;
 import static org.apache.hadoop.hbase.KeyValue.createFirstOnRow;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ARRAY_SIZE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CLASS_NAME_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME_INDEX;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TYPE_BYTES;
@@ -55,6 +57,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.RETURN_TYPE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SALT_BUCKETS_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SORT_ORDER_BYTES;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORAGE_SCHEME_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORE_NULLS_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME_INDEX;
@@ -196,6 +199,7 @@ import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.schema.types.PSmallint;
+import org.apache.phoenix.schema.types.PTinyint;
 import org.apache.phoenix.schema.types.PVarbinary;
 import org.apache.phoenix.schema.types.PVarchar;
 import org.apache.phoenix.trace.util.Tracing;
@@ -266,6 +270,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final KeyValue UPDATE_CACHE_FREQUENCY_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, UPDATE_CACHE_FREQUENCY_BYTES);
     private static final KeyValue IS_NAMESPACE_MAPPED_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY,
             TABLE_FAMILY_BYTES, IS_NAMESPACE_MAPPED_BYTES);
+    private static final KeyValue STORAGE_SCHEME_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, STORAGE_SCHEME_BYTES);
     
     private static final List<KeyValue> TABLE_KV_COLUMNS = Arrays.<KeyValue>asList(
             EMPTY_KEYVALUE_KV,
@@ -290,7 +295,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             ROW_KEY_ORDER_OPTIMIZABLE_KV,
             TRANSACTIONAL_KV,
             UPDATE_CACHE_FREQUENCY_KV,
-            IS_NAMESPACE_MAPPED_KV
+            IS_NAMESPACE_MAPPED_KV,
+            STORAGE_SCHEME_KV
             );
     static {
         Collections.sort(TABLE_KV_COLUMNS, KeyValue.COMPARATOR);
@@ -318,6 +324,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final int UPDATE_CACHE_FREQUENCY_INDEX = TABLE_KV_COLUMNS.indexOf(UPDATE_CACHE_FREQUENCY_KV);
     private static final int INDEX_DISABLE_TIMESTAMP = TABLE_KV_COLUMNS.indexOf(INDEX_DISABLE_TIMESTAMP_KV);
     private static final int IS_NAMESPACE_MAPPED_INDEX = TABLE_KV_COLUMNS.indexOf(IS_NAMESPACE_MAPPED_KV);
+    private static final int STORAGE_SCHEME_INDEX = TABLE_KV_COLUMNS.indexOf(STORAGE_SCHEME_KV);
 
     // KeyValues for Column
     private static final KeyValue DECIMAL_DIGITS_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, DECIMAL_DIGITS_BYTES);
@@ -331,6 +338,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final KeyValue IS_VIEW_REFERENCED_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, IS_VIEW_REFERENCED_BYTES);
     private static final KeyValue COLUMN_DEF_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_DEF_BYTES);
     private static final KeyValue IS_ROW_TIMESTAMP_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, IS_ROW_TIMESTAMP_BYTES);
+    private static final KeyValue COLUMN_QUALIFIER_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_QUALIFIER_BYTES);
     private static final List<KeyValue> COLUMN_KV_COLUMNS = Arrays.<KeyValue>asList(
             DECIMAL_DIGITS_KV,
             COLUMN_SIZE_KV,
@@ -343,7 +351,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             VIEW_CONSTANT_KV,
             IS_VIEW_REFERENCED_KV,
             COLUMN_DEF_KV,
-            IS_ROW_TIMESTAMP_KV
+            IS_ROW_TIMESTAMP_KV,
+            COLUMN_QUALIFIER_KV
             );
     static {
         Collections.sort(COLUMN_KV_COLUMNS, KeyValue.COMPARATOR);
@@ -359,6 +368,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final int IS_VIEW_REFERENCED_INDEX = COLUMN_KV_COLUMNS.indexOf(IS_VIEW_REFERENCED_KV);
     private static final int COLUMN_DEF_INDEX = COLUMN_KV_COLUMNS.indexOf(COLUMN_DEF_KV);
     private static final int IS_ROW_TIMESTAMP_INDEX = COLUMN_KV_COLUMNS.indexOf(IS_ROW_TIMESTAMP_KV);
+    private static final int COLUMN_QUALIFIER_INDEX = COLUMN_KV_COLUMNS.indexOf(COLUMN_QUALIFIER_KV);
     
     private static final int LINK_TYPE_INDEX = 0;
 
@@ -697,8 +707,11 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 isRowTimestampKV == null ? false : Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(
                         isRowTimestampKV.getValueArray(), isRowTimestampKV.getValueOffset(),
                         isRowTimestampKV.getValueLength()));
+        Cell columnQualifierKV = colKeyValues[COLUMN_QUALIFIER_INDEX];
+        Integer columnQualifier = columnQualifierKV == null ? null :
+            PInteger.INSTANCE.getCodec().decodeInt(columnQualifierKV.getValueArray(), columnQualifierKV.getValueOffset(), SortOrder.getDefault());
 
-        PColumn column = new PColumnImpl(colName, famName, dataType, maxLength, scale, isNullable, position-1, sortOrder, arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, false);
+        PColumn column = new PColumnImpl(colName, famName, dataType, maxLength, scale, isNullable, position-1, sortOrder, arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, false, columnQualifier);
         columns.add(column);
     }
     
@@ -899,7 +912,9 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         boolean isNamespaceMapped = isNamespaceMappedKv == null ? false
                 : Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(isNamespaceMappedKv.getValueArray(),
                         isNamespaceMappedKv.getValueOffset(), isNamespaceMappedKv.getValueLength()));
-
+        Cell storageSchemeKv = tableKeyValues[STORAGE_SCHEME_INDEX];
+        byte v = (byte)PTinyint.INSTANCE.toObject(storageSchemeKv.getValueArray(), storageSchemeKv.getValueOffset(), storageSchemeKv.getValueLength());
+        StorageScheme storageScheme = storageSchemeKv == null ? null : StorageScheme.fromSerializedValue(v);
         List<PColumn> columns = Lists.newArrayListWithExpectedSize(columnCount);
         List<PTable> indexes = new ArrayList<PTable>();
         List<PName> physicalTables = new ArrayList<PName>();
@@ -949,7 +964,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 tableType == INDEX ? dataTableName : null, indexes, isImmutableRows, physicalTables, defaultFamilyName,
                 viewStatement, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType,
                 rowKeyOrderOptimizable, transactional, updateCacheFrequency, stats, baseColumnCount,
-                indexDisableTimestamp, isNamespaceMapped);
+                indexDisableTimestamp, isNamespaceMapped, storageScheme);
     }
 
     private PSchema getSchema(RegionScanner scanner, long clientTimeStamp) throws IOException, SQLException {
@@ -2057,8 +2072,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 String columnName = Bytes.toString(rkmd[COLUMN_NAME_INDEX]);
                 String columnFamily = rkmd[FAMILY_NAME_INDEX] == null ? null : Bytes.toString(rkmd[FAMILY_NAME_INDEX]);
                 try {
-                    existingViewColumn = columnFamily == null ? view.getColumn(columnName) : view.getColumnFamily(
-                            columnFamily).getColumn(columnName);
+                    existingViewColumn = columnFamily == null ? view.getPColumnForColumnName(columnName) : view.getColumnFamily(
+                            columnFamily).getPColumnForColumnName(columnName);
                 } catch (ColumnFamilyNotFoundException e) {
                     // ignore since it means that the column family is not present for the column to be added.
                 } catch (ColumnNotFoundException e) {
@@ -2362,8 +2377,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 byte[] columnKey = getColumnKey(viewKey, columnName, columnFamily);
                 try {
                     existingViewColumn =
-                            columnFamily == null ? view.getColumn(columnName) : view
-                                    .getColumnFamily(columnFamily).getColumn(columnName);
+                            columnFamily == null ? view.getPColumnForColumnName(columnName) : view
+                                    .getColumnFamily(columnFamily).getPColumnForColumnName(columnName);
                 } catch (ColumnFamilyNotFoundException e) {
                     // ignore since it means that the column family is not present for the column to
                     // be added.
@@ -2672,7 +2687,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                                         && rowKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX].length > 0) {
                                     PColumnFamily family =
                                             table.getColumnFamily(rowKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]);
-                                    family.getColumn(rowKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]);
+                                    family.getPColumnForColumnNameBytes(rowKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]);
                                 } else if (pkCount > COLUMN_NAME_INDEX
                                         && rowKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX].length > 0) {
                                     addingPKColumn = true;
@@ -2925,7 +2940,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                                         PColumnFamily family =
                                                 table.getColumnFamily(rowKeyMetaData[PhoenixDatabaseMetaData.FAMILY_NAME_INDEX]);
                                         columnToDelete =
-                                                family.getColumn(rowKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]);
+                                                family.getPColumnForColumnNameBytes(rowKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX]);
                                     } else if (pkCount > COLUMN_NAME_INDEX
                                             && rowKeyMetaData[PhoenixDatabaseMetaData.COLUMN_NAME_INDEX].length > 0) {
                                         deletePKColumn = true;
@@ -3014,10 +3029,10 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             byte[] indexKey =
                     SchemaUtil.getTableKey(tenantId, index.getSchemaName().getBytes(), index
                             .getTableName().getBytes());
+            byte[] cq = SchemaUtil.getColumnQualifier(columnToDelete, index);
             // If index requires this column for its pk, then drop it
             if (indexMaintainer.getIndexedColumns().contains(
-                new ColumnReference(columnToDelete.getFamilyName().getBytes(), columnToDelete
-                        .getName().getBytes()))) {
+                new ColumnReference(columnToDelete.getFamilyName().getBytes(), cq))) {
                 // Since we're dropping the index, lock it to ensure
                 // that a change in index state doesn't
                 // occur while we're dropping it.
@@ -3204,7 +3219,10 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                         tableMetadata = new ArrayList<Mutation>(tableMetadata);
                         // insert an empty KV to trigger time stamp update on data table row
                         Put p = new Put(dataTableKey);
-                        p.add(TABLE_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, timeStamp, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+                        // Decide on what column qualifier to use for empty key value.
+                        PTable currentTable = doGetTable(key, HConstants.LATEST_TIMESTAMP, rowLock);
+                        Pair<byte[], byte[]> emptyKeyValuePair = SchemaUtil.getEmptyKeyValueInfo(currentTable);
+                        p.add(TABLE_FAMILY_BYTES, emptyKeyValuePair.getFirst(), timeStamp, emptyKeyValuePair.getSecond());
                         tableMetadata.add(p);
                     }
                     boolean setRowKeyOrderOptimizableCell = newState == PIndexState.BUILDING && !rowKeyOrderOptimizable;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java
index 2e2d580..89ccff0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java
@@ -80,6 +80,7 @@ public class SequenceRegionObserver extends BaseRegionObserver {
     public static final String NUM_TO_ALLOCATE = "NUM_TO_ALLOCATE";
     private static final byte[] SUCCESS_VALUE = PInteger.INSTANCE.toBytes(Integer.valueOf(Sequence.SUCCESS));
     
+    //TODO: samarth verify that it is ok to send non-encoded empty column here. Probably is.
     private static Result getErrorResult(byte[] row, long timestamp, int errorCode) {
         byte[] errorCodeBuf = new byte[PInteger.INSTANCE.getByteSize()];
         PInteger.INSTANCE.getCodec().encodeInt(errorCode, errorCodeBuf, 0);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
index 5481910..3bdcee3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
@@ -231,6 +231,7 @@ public class UngroupedAggregateRegionObserver extends BaseScannerRegionObserver
         byte[] deleteCQ = null;
         byte[] deleteCF = null;
         byte[] emptyCF = null;
+        byte[] emptyKVQualifier = null;
         ImmutableBytesWritable ptr = new ImmutableBytesWritable();
         if (upsertSelectTable != null) {
             isUpsert = true;
@@ -245,6 +246,7 @@ public class UngroupedAggregateRegionObserver extends BaseScannerRegionObserver
                 deleteCQ = scan.getAttribute(BaseScannerRegionObserver.DELETE_CQ);
             }
             emptyCF = scan.getAttribute(BaseScannerRegionObserver.EMPTY_CF);
+            emptyKVQualifier = scan.getAttribute(BaseScannerRegionObserver.EMPTY_COLUMN_QUALIFIER);
         }
         TupleProjector tupleProjector = null;
         HRegion dataRegion = null;
@@ -495,8 +497,10 @@ public class UngroupedAggregateRegionObserver extends BaseScannerRegionObserver
                                     if (!timeStamps.contains(kvts)) {
                                         Put put = new Put(kv.getRowArray(), kv.getRowOffset(),
                                             kv.getRowLength());
-                                        put.add(emptyCF, QueryConstants.EMPTY_COLUMN_BYTES, kvts,
-                                            ByteUtil.EMPTY_BYTE_ARRAY);
+                                        // FIXME: Use the right byte array value. Transactional tables can't
+                                        // have empty byte arrays since Tephra seems them as delete markers.
+                                        put.add(emptyCF, emptyKVQualifier != null ? emptyKVQualifier
+                                                : QueryConstants.EMPTY_COLUMN_BYTES, kvts, ByteUtil.EMPTY_BYTE_ARRAY);
                                         mutations.add(put);
                                     }
                                 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
index 126c0dd..b6b913c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
@@ -269,6 +269,16 @@ public final class PTableProtos {
      * <code>optional bool isDynamic = 14;</code>
      */
     boolean getIsDynamic();
+
+    // optional int32 columnQualifier = 15;
+    /**
+     * <code>optional int32 columnQualifier = 15;</code>
+     */
+    boolean hasColumnQualifier();
+    /**
+     * <code>optional int32 columnQualifier = 15;</code>
+     */
+    int getColumnQualifier();
   }
   /**
    * Protobuf type {@code PColumn}
@@ -391,6 +401,11 @@ public final class PTableProtos {
               isDynamic_ = input.readBool();
               break;
             }
+            case 120: {
+              bitField0_ |= 0x00004000;
+              columnQualifier_ = input.readInt32();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -709,6 +724,22 @@ public final class PTableProtos {
       return isDynamic_;
     }
 
+    // optional int32 columnQualifier = 15;
+    public static final int COLUMNQUALIFIER_FIELD_NUMBER = 15;
+    private int columnQualifier_;
+    /**
+     * <code>optional int32 columnQualifier = 15;</code>
+     */
+    public boolean hasColumnQualifier() {
+      return ((bitField0_ & 0x00004000) == 0x00004000);
+    }
+    /**
+     * <code>optional int32 columnQualifier = 15;</code>
+     */
+    public int getColumnQualifier() {
+      return columnQualifier_;
+    }
+
     private void initFields() {
       columnNameBytes_ = com.google.protobuf.ByteString.EMPTY;
       familyNameBytes_ = com.google.protobuf.ByteString.EMPTY;
@@ -724,6 +755,7 @@ public final class PTableProtos {
       expression_ = "";
       isRowTimestamp_ = false;
       isDynamic_ = false;
+      columnQualifier_ = 0;
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -799,6 +831,9 @@ public final class PTableProtos {
       if (((bitField0_ & 0x00002000) == 0x00002000)) {
         output.writeBool(14, isDynamic_);
       }
+      if (((bitField0_ & 0x00004000) == 0x00004000)) {
+        output.writeInt32(15, columnQualifier_);
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -864,6 +899,10 @@ public final class PTableProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeBoolSize(14, isDynamic_);
       }
+      if (((bitField0_ & 0x00004000) == 0x00004000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(15, columnQualifier_);
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -957,6 +996,11 @@ public final class PTableProtos {
         result = result && (getIsDynamic()
             == other.getIsDynamic());
       }
+      result = result && (hasColumnQualifier() == other.hasColumnQualifier());
+      if (hasColumnQualifier()) {
+        result = result && (getColumnQualifier()
+            == other.getColumnQualifier());
+      }
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -1026,6 +1070,10 @@ public final class PTableProtos {
         hash = (37 * hash) + ISDYNAMIC_FIELD_NUMBER;
         hash = (53 * hash) + hashBoolean(getIsDynamic());
       }
+      if (hasColumnQualifier()) {
+        hash = (37 * hash) + COLUMNQUALIFIER_FIELD_NUMBER;
+        hash = (53 * hash) + getColumnQualifier();
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -1163,6 +1211,8 @@ public final class PTableProtos {
         bitField0_ = (bitField0_ & ~0x00001000);
         isDynamic_ = false;
         bitField0_ = (bitField0_ & ~0x00002000);
+        columnQualifier_ = 0;
+        bitField0_ = (bitField0_ & ~0x00004000);
         return this;
       }
 
@@ -1247,6 +1297,10 @@ public final class PTableProtos {
           to_bitField0_ |= 0x00002000;
         }
         result.isDynamic_ = isDynamic_;
+        if (((from_bitField0_ & 0x00004000) == 0x00004000)) {
+          to_bitField0_ |= 0x00004000;
+        }
+        result.columnQualifier_ = columnQualifier_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -1309,6 +1363,9 @@ public final class PTableProtos {
         if (other.hasIsDynamic()) {
           setIsDynamic(other.getIsDynamic());
         }
+        if (other.hasColumnQualifier()) {
+          setColumnQualifier(other.getColumnQualifier());
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -1909,6 +1966,39 @@ public final class PTableProtos {
         return this;
       }
 
+      // optional int32 columnQualifier = 15;
+      private int columnQualifier_ ;
+      /**
+       * <code>optional int32 columnQualifier = 15;</code>
+       */
+      public boolean hasColumnQualifier() {
+        return ((bitField0_ & 0x00004000) == 0x00004000);
+      }
+      /**
+       * <code>optional int32 columnQualifier = 15;</code>
+       */
+      public int getColumnQualifier() {
+        return columnQualifier_;
+      }
+      /**
+       * <code>optional int32 columnQualifier = 15;</code>
+       */
+      public Builder setColumnQualifier(int value) {
+        bitField0_ |= 0x00004000;
+        columnQualifier_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int32 columnQualifier = 15;</code>
+       */
+      public Builder clearColumnQualifier() {
+        bitField0_ = (bitField0_ & ~0x00004000);
+        columnQualifier_ = 0;
+        onChanged();
+        return this;
+      }
+
       // @@protoc_insertion_point(builder_scope:PColumn)
     }
 
@@ -3348,6 +3438,16 @@ public final class PTableProtos {
      * <code>optional bool isNamespaceMapped = 30;</code>
      */
     boolean getIsNamespaceMapped();
+
+    // optional bytes storageScheme = 31;
+    /**
+     * <code>optional bytes storageScheme = 31;</code>
+     */
+    boolean hasStorageScheme();
+    /**
+     * <code>optional bytes storageScheme = 31;</code>
+     */
+    com.google.protobuf.ByteString getStorageScheme();
   }
   /**
    * Protobuf type {@code PTable}
@@ -3568,6 +3668,11 @@ public final class PTableProtos {
               isNamespaceMapped_ = input.readBool();
               break;
             }
+            case 250: {
+              bitField0_ |= 0x04000000;
+              storageScheme_ = input.readBytes();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -4194,6 +4299,22 @@ public final class PTableProtos {
       return isNamespaceMapped_;
     }
 
+    // optional bytes storageScheme = 31;
+    public static final int STORAGESCHEME_FIELD_NUMBER = 31;
+    private com.google.protobuf.ByteString storageScheme_;
+    /**
+     * <code>optional bytes storageScheme = 31;</code>
+     */
+    public boolean hasStorageScheme() {
+      return ((bitField0_ & 0x04000000) == 0x04000000);
+    }
+    /**
+     * <code>optional bytes storageScheme = 31;</code>
+     */
+    public com.google.protobuf.ByteString getStorageScheme() {
+      return storageScheme_;
+    }
+
     private void initFields() {
       schemaNameBytes_ = com.google.protobuf.ByteString.EMPTY;
       tableNameBytes_ = com.google.protobuf.ByteString.EMPTY;
@@ -4225,6 +4346,7 @@ public final class PTableProtos {
       updateCacheFrequency_ = 0L;
       indexDisableTimestamp_ = 0L;
       isNamespaceMapped_ = false;
+      storageScheme_ = com.google.protobuf.ByteString.EMPTY;
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -4382,6 +4504,9 @@ public final class PTableProtos {
       if (((bitField0_ & 0x02000000) == 0x02000000)) {
         output.writeBool(30, isNamespaceMapped_);
       }
+      if (((bitField0_ & 0x04000000) == 0x04000000)) {
+        output.writeBytes(31, storageScheme_);
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -4516,6 +4641,10 @@ public final class PTableProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeBoolSize(30, isNamespaceMapped_);
       }
+      if (((bitField0_ & 0x04000000) == 0x04000000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(31, storageScheme_);
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -4677,6 +4806,11 @@ public final class PTableProtos {
         result = result && (getIsNamespaceMapped()
             == other.getIsNamespaceMapped());
       }
+      result = result && (hasStorageScheme() == other.hasStorageScheme());
+      if (hasStorageScheme()) {
+        result = result && getStorageScheme()
+            .equals(other.getStorageScheme());
+      }
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -4810,6 +4944,10 @@ public final class PTableProtos {
         hash = (37 * hash) + ISNAMESPACEMAPPED_FIELD_NUMBER;
         hash = (53 * hash) + hashBoolean(getIsNamespaceMapped());
       }
+      if (hasStorageScheme()) {
+        hash = (37 * hash) + STORAGESCHEME_FIELD_NUMBER;
+        hash = (53 * hash) + getStorageScheme().hashCode();
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -4994,6 +5132,8 @@ public final class PTableProtos {
         bitField0_ = (bitField0_ & ~0x10000000);
         isNamespaceMapped_ = false;
         bitField0_ = (bitField0_ & ~0x20000000);
+        storageScheme_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x40000000);
         return this;
       }
 
@@ -5158,6 +5298,10 @@ public final class PTableProtos {
           to_bitField0_ |= 0x02000000;
         }
         result.isNamespaceMapped_ = isNamespaceMapped_;
+        if (((from_bitField0_ & 0x40000000) == 0x40000000)) {
+          to_bitField0_ |= 0x04000000;
+        }
+        result.storageScheme_ = storageScheme_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -5342,6 +5486,9 @@ public final class PTableProtos {
         if (other.hasIsNamespaceMapped()) {
           setIsNamespaceMapped(other.getIsNamespaceMapped());
         }
+        if (other.hasStorageScheme()) {
+          setStorageScheme(other.getStorageScheme());
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -7144,6 +7291,42 @@ public final class PTableProtos {
         return this;
       }
 
+      // optional bytes storageScheme = 31;
+      private com.google.protobuf.ByteString storageScheme_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>optional bytes storageScheme = 31;</code>
+       */
+      public boolean hasStorageScheme() {
+        return ((bitField0_ & 0x40000000) == 0x40000000);
+      }
+      /**
+       * <code>optional bytes storageScheme = 31;</code>
+       */
+      public com.google.protobuf.ByteString getStorageScheme() {
+        return storageScheme_;
+      }
+      /**
+       * <code>optional bytes storageScheme = 31;</code>
+       */
+      public Builder setStorageScheme(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x40000000;
+        storageScheme_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bytes storageScheme = 31;</code>
+       */
+      public Builder clearStorageScheme() {
+        bitField0_ = (bitField0_ & ~0x40000000);
+        storageScheme_ = getDefaultInstance().getStorageScheme();
+        onChanged();
+        return this;
+      }
+
       // @@protoc_insertion_point(builder_scope:PTable)
     }
 
@@ -7179,7 +7362,7 @@ public final class PTableProtos {
       descriptor;
   static {
     java.lang.String[] descriptorData = {
-      "\n\014PTable.proto\032\021PGuidePosts.proto\"\246\002\n\007PC" +
+      "\n\014PTable.proto\032\021PGuidePosts.proto\"\277\002\n\007PC" +
       "olumn\022\027\n\017columnNameBytes\030\001 \002(\014\022\027\n\017family" +
       "NameBytes\030\002 \001(\014\022\020\n\010dataType\030\003 \002(\t\022\021\n\tmax" +
       "Length\030\004 \001(\005\022\r\n\005scale\030\005 \001(\005\022\020\n\010nullable\030" +
@@ -7187,32 +7370,34 @@ public final class PTableProtos {
       "(\005\022\021\n\tarraySize\030\t \001(\005\022\024\n\014viewConstant\030\n " +
       "\001(\014\022\026\n\016viewReferenced\030\013 \001(\010\022\022\n\nexpressio" +
       "n\030\014 \001(\t\022\026\n\016isRowTimestamp\030\r \001(\010\022\021\n\tisDyn" +
-      "amic\030\016 \001(\010\"\232\001\n\013PTableStats\022\013\n\003key\030\001 \002(\014\022" +
-      "\016\n\006values\030\002 \003(\014\022\033\n\023guidePostsByteCount\030\003",
-      " \001(\003\022\025\n\rkeyBytesCount\030\004 \001(\003\022\027\n\017guidePost" +
-      "sCount\030\005 \001(\005\022!\n\013pGuidePosts\030\006 \001(\0132\014.PGui" +
-      "dePosts\"\336\005\n\006PTable\022\027\n\017schemaNameBytes\030\001 " +
-      "\002(\014\022\026\n\016tableNameBytes\030\002 \002(\014\022\036\n\ttableType" +
-      "\030\003 \002(\0162\013.PTableType\022\022\n\nindexState\030\004 \001(\t\022" +
-      "\026\n\016sequenceNumber\030\005 \002(\003\022\021\n\ttimeStamp\030\006 \002" +
-      "(\003\022\023\n\013pkNameBytes\030\007 \001(\014\022\021\n\tbucketNum\030\010 \002" +
-      "(\005\022\031\n\007columns\030\t \003(\0132\010.PColumn\022\030\n\007indexes" +
-      "\030\n \003(\0132\007.PTable\022\027\n\017isImmutableRows\030\013 \002(\010" +
-      "\022 \n\nguidePosts\030\014 \003(\0132\014.PTableStats\022\032\n\022da",
-      "taTableNameBytes\030\r \001(\014\022\031\n\021defaultFamilyN" +
-      "ame\030\016 \001(\014\022\022\n\ndisableWAL\030\017 \002(\010\022\023\n\013multiTe" +
-      "nant\030\020 \002(\010\022\020\n\010viewType\030\021 \001(\014\022\025\n\rviewStat" +
-      "ement\030\022 \001(\014\022\025\n\rphysicalNames\030\023 \003(\014\022\020\n\010te" +
-      "nantId\030\024 \001(\014\022\023\n\013viewIndexId\030\025 \001(\005\022\021\n\tind" +
-      "exType\030\026 \001(\014\022\026\n\016statsTimeStamp\030\027 \001(\003\022\022\n\n" +
-      "storeNulls\030\030 \001(\010\022\027\n\017baseColumnCount\030\031 \001(" +
-      "\005\022\036\n\026rowKeyOrderOptimizable\030\032 \001(\010\022\025\n\rtra" +
-      "nsactional\030\033 \001(\010\022\034\n\024updateCacheFrequency" +
-      "\030\034 \001(\003\022\035\n\025indexDisableTimestamp\030\035 \001(\003\022\031\n",
-      "\021isNamespaceMapped\030\036 \001(\010*A\n\nPTableType\022\n" +
-      "\n\006SYSTEM\020\000\022\010\n\004USER\020\001\022\010\n\004VIEW\020\002\022\t\n\005INDEX\020" +
-      "\003\022\010\n\004JOIN\020\004B@\n(org.apache.phoenix.coproc" +
-      "essor.generatedB\014PTableProtosH\001\210\001\001\240\001\001"
+      "amic\030\016 \001(\010\022\027\n\017columnQualifier\030\017 \001(\005\"\232\001\n\013" +
+      "PTableStats\022\013\n\003key\030\001 \002(\014\022\016\n\006values\030\002 \003(\014",
+      "\022\033\n\023guidePostsByteCount\030\003 \001(\003\022\025\n\rkeyByte" +
+      "sCount\030\004 \001(\003\022\027\n\017guidePostsCount\030\005 \001(\005\022!\n" +
+      "\013pGuidePosts\030\006 \001(\0132\014.PGuidePosts\"\365\005\n\006PTa" +
+      "ble\022\027\n\017schemaNameBytes\030\001 \002(\014\022\026\n\016tableNam" +
+      "eBytes\030\002 \002(\014\022\036\n\ttableType\030\003 \002(\0162\013.PTable" +
+      "Type\022\022\n\nindexState\030\004 \001(\t\022\026\n\016sequenceNumb" +
+      "er\030\005 \002(\003\022\021\n\ttimeStamp\030\006 \002(\003\022\023\n\013pkNameByt" +
+      "es\030\007 \001(\014\022\021\n\tbucketNum\030\010 \002(\005\022\031\n\007columns\030\t" +
+      " \003(\0132\010.PColumn\022\030\n\007indexes\030\n \003(\0132\007.PTable" +
+      "\022\027\n\017isImmutableRows\030\013 \002(\010\022 \n\nguidePosts\030",
+      "\014 \003(\0132\014.PTableStats\022\032\n\022dataTableNameByte" +
+      "s\030\r \001(\014\022\031\n\021defaultFamilyName\030\016 \001(\014\022\022\n\ndi" +
+      "sableWAL\030\017 \002(\010\022\023\n\013multiTenant\030\020 \002(\010\022\020\n\010v" +
+      "iewType\030\021 \001(\014\022\025\n\rviewStatement\030\022 \001(\014\022\025\n\r" +
+      "physicalNames\030\023 \003(\014\022\020\n\010tenantId\030\024 \001(\014\022\023\n" +
+      "\013viewIndexId\030\025 \001(\005\022\021\n\tindexType\030\026 \001(\014\022\026\n" +
+      "\016statsTimeStamp\030\027 \001(\003\022\022\n\nstoreNulls\030\030 \001(" +
+      "\010\022\027\n\017baseColumnCount\030\031 \001(\005\022\036\n\026rowKeyOrde" +
+      "rOptimizable\030\032 \001(\010\022\025\n\rtransactional\030\033 \001(" +
+      "\010\022\034\n\024updateCacheFrequency\030\034 \001(\003\022\035\n\025index",
+      "DisableTimestamp\030\035 \001(\003\022\031\n\021isNamespaceMap" +
+      "ped\030\036 \001(\010\022\025\n\rstorageScheme\030\037 \001(\014*A\n\nPTab" +
+      "leType\022\n\n\006SYSTEM\020\000\022\010\n\004USER\020\001\022\010\n\004VIEW\020\002\022\t" +
+      "\n\005INDEX\020\003\022\010\n\004JOIN\020\004B@\n(org.apache.phoeni" +
+      "x.coprocessor.generatedB\014PTableProtosH\001\210" +
+      "\001\001\240\001\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -7224,7 +7409,7 @@ public final class PTableProtos {
           internal_static_PColumn_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_PColumn_descriptor,
-              new java.lang.String[] { "ColumnNameBytes", "FamilyNameBytes", "DataType", "MaxLength", "Scale", "Nullable", "Position", "SortOrder", "ArraySize", "ViewConstant", "ViewReferenced", "Expression", "IsRowTimestamp", "IsDynamic", });
+              new java.lang.String[] { "ColumnNameBytes", "FamilyNameBytes", "DataType", "MaxLength", "Scale", "Nullable", "Position", "SortOrder", "ArraySize", "ViewConstant", "ViewReferenced", "Expression", "IsRowTimestamp", "IsDynamic", "ColumnQualifier", });
           internal_static_PTableStats_descriptor =
             getDescriptor().getMessageTypes().get(1);
           internal_static_PTableStats_fieldAccessorTable = new
@@ -7236,7 +7421,7 @@ public final class PTableProtos {
           internal_static_PTable_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_PTable_descriptor,
-              new java.lang.String[] { "SchemaNameBytes", "TableNameBytes", "TableType", "IndexState", "SequenceNumber", "TimeStamp", "PkNameBytes", "BucketNum", "Columns", "Indexes", "IsImmutableRows", "GuidePosts", "DataTableNameBytes", "DefaultFamilyName", "DisableWAL", "MultiTenant", "ViewType", "ViewStatement", "PhysicalNames", "TenantId", "ViewIndexId", "IndexType", "StatsTimeStamp", "StoreNulls", "BaseColumnCount", "RowKeyOrderOptimizable", "Transactional", "UpdateCacheFrequency", "IndexDisableTimestamp", "IsNamespaceMapped", });
+              new java.lang.String[] { "SchemaNameBytes", "TableNameBytes", "TableType", "IndexState", "SequenceNumber", "TimeStamp", "PkNameBytes", "BucketNum", "Columns", "Indexes", "IsImmutableRows", "GuidePosts", "DataTableNameBytes", "DefaultFamilyName", "DisableWAL", "MultiTenant", "ViewType", "ViewStatement", "PhysicalNames", "TenantId", "ViewIndexId", "IndexType", "StatsTimeStamp", "StoreNulls", "BaseColumnCount", "RowKeyOrderOptimizable", "Transactional", "UpdateCacheFrequency", "IndexDisableTimestamp", "IsNamespaceMapped", "StorageScheme", });
           return null;
         }
       };

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
index cc8f7a5..71af992 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
@@ -767,7 +767,7 @@ public class MutationState implements SQLCloseable {
                 }
                 for (PColumn column : columns) {
                     if (column != null) {
-                        resolvedTable.getColumnFamily(column.getFamilyName().getString()).getColumn(column.getName().getString());
+                        resolvedTable.getColumnFamily(column.getFamilyName().getString()).getPColumnForColumnName(column.getName().getString());
                     }
                 }
             }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
index 4b5fdbb..163cc72 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
@@ -46,8 +46,8 @@ public class KeyValueColumnExpression extends ColumnExpression {
     public KeyValueColumnExpression() {
     }
 
-    public KeyValueColumnExpression(PColumn column) {
-        this(column, null);
+    public KeyValueColumnExpression(PColumn column, boolean encodedColumnName) {
+        this(column, null, encodedColumnName);
     }
 
     public KeyValueColumnExpression(PDatum column, byte[] cf, byte[] cq) {
@@ -56,18 +56,19 @@ public class KeyValueColumnExpression extends ColumnExpression {
         this.cq = cq;
     }
 
-    public KeyValueColumnExpression(PColumn column, String displayName) {
+    public KeyValueColumnExpression(PColumn column, String displayName, boolean encodedColumnName) {
         super(column);
         this.cf = column.getFamilyName().getBytes();
-        this.cq = column.getName().getBytes();
+        this.cq = SchemaUtil.getColumnQualifier(column, encodedColumnName);
         this.displayName = displayName;
     }
 
     public byte[] getColumnFamily() {
         return cf;
     }
-
-    public byte[] getColumnName() {
+    
+    //TODO: samarth look for the callers of this.
+    public byte[] getColumnQualifier() {
         return cq;
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/55c5a728/phoenix-core/src/main/java/org/apache/phoenix/expression/ProjectedColumnExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/ProjectedColumnExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/ProjectedColumnExpression.java
index 3a38dee..2744f35 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/ProjectedColumnExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/ProjectedColumnExpression.java
@@ -154,6 +154,7 @@ public class ProjectedColumnExpression extends ColumnExpression {
         return Determinism.PER_INVOCATION;
     }
 
+    @Override
     public ProjectedColumnExpression clone() {
         return new ProjectedColumnExpression(this.column, this.columns, this.position, this.displayName);
     }


[31/52] [abbrv] phoenix git commit: PHOENIX-2743 HivePhoenixHandler for big-big join with

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRecordUpdater.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRecordUpdater.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRecordUpdater.java
new file mode 100644
index 0000000..089a299
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRecordUpdater.java
@@ -0,0 +1,336 @@
+/*
+ * 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.phoenix.hive;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hive.ql.io.AcidOutputFormat;
+import org.apache.hadoop.hive.ql.io.RecordUpdater;
+import org.apache.hadoop.hive.serde2.SerDeException;
+import org.apache.hadoop.hive.serde2.SerDeStats;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+import org.apache.phoenix.hive.PhoenixSerializer.DmlType;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.hive.mapreduce.PhoenixResultWritable;
+import org.apache.phoenix.hive.util.PhoenixConnectionUtil;
+import org.apache.phoenix.hive.util.PhoenixStorageHandlerUtil;
+import org.apache.phoenix.hive.util.PhoenixUtil;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
+import org.apache.phoenix.schema.ConcurrentTableMutationException;
+import org.apache.phoenix.schema.MetaDataClient;
+import org.apache.phoenix.util.QueryUtil;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class PhoenixRecordUpdater implements RecordUpdater {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixRecordUpdater.class);
+
+    private final Connection conn;
+    private final PreparedStatement pstmt;
+    private final long batchSize;
+    private long numRecords = 0;
+
+    private Configuration config;
+    private String tableName;
+    private MetaDataClient metaDataClient;
+    private boolean restoreWalMode;
+
+    private long rowCountDelta = 0;
+
+    private PhoenixSerializer phoenixSerializer;
+    private ObjectInspector objInspector;
+    private PreparedStatement pstmtForDelete;
+
+    public PhoenixRecordUpdater(Path path, AcidOutputFormat.Options options) throws IOException {
+        this.config = options.getConfiguration();
+        tableName = config.get(PhoenixStorageHandlerConstants.PHOENIX_TABLE_NAME);
+
+        Properties props = new Properties();
+
+        try {
+            // Disable WAL
+            String walConfigName = tableName.toLowerCase() + PhoenixStorageHandlerConstants
+                    .DISABLE_WAL;
+            boolean disableWal = config.getBoolean(walConfigName, false);
+            if (disableWal) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug(walConfigName + " is true. batch.mode will be set true.");
+                }
+
+                props.setProperty(PhoenixStorageHandlerConstants.BATCH_MODE, "true");
+            }
+
+            this.conn = PhoenixConnectionUtil.getInputConnection(config, props);
+
+            if (disableWal) {
+                metaDataClient = new MetaDataClient((PhoenixConnection) conn);
+
+                if (!PhoenixUtil.isDisabledWal(metaDataClient, tableName)) {
+                    // execute alter tablel statement if disable_wal is not true.
+                    try {
+                        PhoenixUtil.alterTableForWalDisable(conn, tableName, true);
+                    } catch (ConcurrentTableMutationException e) {
+                        if (LOG.isWarnEnabled()) {
+                            LOG.warn("Concurrent modification of disableWAL");
+                        }
+                    }
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug(tableName + "s wal disabled.");
+                    }
+
+                    // restore original value of disable_wal at the end.
+                    restoreWalMode = true;
+                }
+            }
+
+            this.batchSize = PhoenixConfigurationUtil.getBatchSize(config);
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Batch-size : " + batchSize);
+            }
+
+            String upsertQuery = QueryUtil.constructUpsertStatement(tableName, PhoenixUtil
+                    .getColumnInfoList(conn, tableName));
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Upsert-query : " + upsertQuery);
+            }
+            this.pstmt = this.conn.prepareStatement(upsertQuery);
+        } catch (SQLException e) {
+            throw new IOException(e);
+        }
+
+        this.objInspector = options.getInspector();
+        try {
+            phoenixSerializer = new PhoenixSerializer(config, options.getTableProperties());
+        } catch (SerDeException e) {
+            throw new IOException(e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.hive.ql.io.RecordUpdater#insert(long, java.lang.Object)
+     */
+    @Override
+    public void insert(long currentTransaction, Object row) throws IOException {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Insert - currentTranscation : " + currentTransaction + ", row : " +
+                    PhoenixStorageHandlerUtil.toString(row));
+        }
+
+        PhoenixResultWritable pResultWritable = (PhoenixResultWritable) phoenixSerializer
+                .serialize(row, objInspector, DmlType.INSERT);
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Data : " + pResultWritable.getValueList());
+        }
+
+        write(pResultWritable);
+
+        rowCountDelta++;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.hive.ql.io.RecordUpdater#update(long, java.lang.Object)
+     */
+    @Override
+    public void update(long currentTransaction, Object row) throws IOException {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Update - currentTranscation : " + currentTransaction + ", row : " +
+                    PhoenixStorageHandlerUtil.toString(row));
+        }
+
+        PhoenixResultWritable pResultWritable = (PhoenixResultWritable) phoenixSerializer
+                .serialize(row, objInspector, DmlType.UPDATE);
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Data : " + pResultWritable.getValueList());
+        }
+
+        write(pResultWritable);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.hive.ql.io.RecordUpdater#delete(long, java.lang.Object)
+     */
+    @Override
+    public void delete(long currentTransaction, Object row) throws IOException {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Delete - currentTranscation : " + currentTransaction + ", row : " +
+                    PhoenixStorageHandlerUtil.toString(row));
+        }
+
+        PhoenixResultWritable pResultWritable = (PhoenixResultWritable) phoenixSerializer
+                .serialize(row, objInspector, DmlType.DELETE);
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Data : " + pResultWritable.getValueList());
+        }
+
+        if (pstmtForDelete == null) {
+            try {
+                String deleteQuery = PhoenixUtil.constructDeleteStatement(conn, tableName);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Delete query : " + deleteQuery);
+                }
+
+                pstmtForDelete = conn.prepareStatement(deleteQuery);
+            } catch (SQLException e) {
+                throw new IOException(e);
+            }
+        }
+
+        delete(pResultWritable);
+
+        rowCountDelta--;
+    }
+
+    private void delete(PhoenixResultWritable pResultWritable) throws IOException {
+        try {
+            pResultWritable.delete(pstmtForDelete);
+            numRecords++;
+            pstmtForDelete.executeUpdate();
+
+            if (numRecords % batchSize == 0) {
+                LOG.debug("Commit called on a batch of size : " + batchSize);
+                conn.commit();
+            }
+        } catch (SQLException e) {
+            throw new IOException("Exception while deleting to table.", e);
+        }
+    }
+
+    private void write(PhoenixResultWritable pResultWritable) throws IOException {
+        try {
+            pResultWritable.write(pstmt);
+            numRecords++;
+            pstmt.executeUpdate();
+
+            if (numRecords % batchSize == 0) {
+                LOG.debug("Commit called on a batch of size : " + batchSize);
+                conn.commit();
+            }
+        } catch (SQLException e) {
+            throw new IOException("Exception while writing to table.", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.hive.ql.io.RecordUpdater#flush()
+     */
+    @Override
+    public void flush() throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Flush called");
+        }
+
+        try {
+            conn.commit();
+
+            if (LOG.isInfoEnabled()) {
+                LOG.info("Written row : " + numRecords);
+            }
+        } catch (SQLException e) {
+            LOG.error("SQLException while performing the commit for the task.");
+            throw new IOException(e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.hive.ql.io.RecordUpdater#close(boolean)
+     */
+    @Override
+    public void close(boolean abort) throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("abort : " + abort);
+        }
+
+        try {
+            conn.commit();
+
+            if (LOG.isInfoEnabled()) {
+                LOG.info("Written row : " + numRecords);
+            }
+        } catch (SQLException e) {
+            LOG.error("SQLException while performing the commit for the task.");
+            throw new IOException(e);
+        } finally {
+            try {
+                if (restoreWalMode && PhoenixUtil.isDisabledWal(metaDataClient, tableName)) {
+                    try {
+                        PhoenixUtil.alterTableForWalDisable(conn, tableName, false);
+                    } catch (ConcurrentTableMutationException e) {
+                        if (LOG.isWarnEnabled()) {
+                            LOG.warn("Concurrent modification of disableWAL");
+                        }
+                    }
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug(tableName + "s wal enabled.");
+                    }
+                }
+
+                // flush when [table-name].auto.flush is true.
+                String autoFlushConfigName = tableName.toLowerCase() +
+                        PhoenixStorageHandlerConstants.AUTO_FLUSH;
+                boolean autoFlush = config.getBoolean(autoFlushConfigName, false);
+                if (autoFlush) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("autoFlush is " + autoFlush);
+                    }
+
+                    PhoenixUtil.flush(conn, tableName);
+                }
+
+                PhoenixUtil.closeResource(pstmt);
+                PhoenixUtil.closeResource(pstmtForDelete);
+                PhoenixUtil.closeResource(conn);
+            } catch (SQLException ex) {
+                LOG.error("SQLException while closing the connection for the task.");
+                throw new IOException(ex);
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.hive.ql.io.RecordUpdater#getStats()
+     */
+    @Override
+    public SerDeStats getStats() {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("getStats called");
+        }
+
+        SerDeStats stats = new SerDeStats();
+        stats.setRowCount(rowCountDelta);
+        // Don't worry about setting raw data size diff.  There is no reasonable way  to calculate
+        // that without finding the row we are updating or deleting, which would be a mess.
+        return stats;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRow.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRow.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRow.java
new file mode 100644
index 0000000..fa307ce
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRow.java
@@ -0,0 +1,64 @@
+/*
+ * 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.phoenix.hive;
+
+import com.google.common.collect.Lists;
+import org.apache.hadoop.hive.serde2.StructObject;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation for Hive SerDe StructObject
+ */
+public class PhoenixRow implements StructObject {
+
+    private List<String> columnList;
+    private Map<String, Object> resultRowMap;
+
+    public PhoenixRow(List<String> columnList) {
+        this.columnList = columnList;
+    }
+
+    public PhoenixRow setResultRowMap(Map<String, Object> resultRowMap) {
+        this.resultRowMap = resultRowMap;
+        return this;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.hive.serde2.StructObject#getField(int)
+     */
+    @Override
+    public Object getField(int fieldID) {
+        return resultRowMap.get(columnList.get(fieldID));
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.hadoop.hive.serde2.StructObject#getFieldsAsList()
+     */
+    @Override
+    public List<Object> getFieldsAsList() {
+        return Lists.newArrayList(resultRowMap.values());
+    }
+
+
+    @Override
+    public String toString() {
+        return resultRowMap.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRowKey.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRowKey.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRowKey.java
new file mode 100644
index 0000000..c4cbb2c
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixRowKey.java
@@ -0,0 +1,69 @@
+/*
+ * 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.phoenix.hive;
+
+import com.google.common.collect.Maps;
+import org.apache.hadoop.hive.ql.io.RecordIdentifier;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+/**
+ * Hive's RecordIdentifier implementation.
+ */
+
+public class PhoenixRowKey extends RecordIdentifier {
+
+    private Map<String, Object> rowKeyMap = Maps.newHashMap();
+
+    public PhoenixRowKey() {
+
+    }
+
+    public void setRowKeyMap(Map<String, Object> rowKeyMap) {
+        this.rowKeyMap = rowKeyMap;
+    }
+
+    @Override
+    public void write(DataOutput dataOutput) throws IOException {
+        super.write(dataOutput);
+
+        try (ObjectOutputStream oos = new ObjectOutputStream((OutputStream) dataOutput)) {
+            oos.writeObject(rowKeyMap);
+            oos.flush();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void readFields(DataInput dataInput) throws IOException {
+        super.readFields(dataInput);
+
+        try (ObjectInputStream ois = new ObjectInputStream((InputStream) dataInput)) {
+            rowKeyMap = (Map<String, Object>) ois.readObject();
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixSerDe.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixSerDe.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixSerDe.java
new file mode 100644
index 0000000..dd38cfb
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixSerDe.java
@@ -0,0 +1,159 @@
+/*
+ * 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.phoenix.hive;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.serde.serdeConstants;
+import org.apache.hadoop.hive.serde2.AbstractSerDe;
+import org.apache.hadoop.hive.serde2.SerDeException;
+import org.apache.hadoop.hive.serde2.SerDeStats;
+import org.apache.hadoop.hive.serde2.lazy.LazySerDeParameters;
+import org.apache.hadoop.hive.serde2.lazy.objectinspector.LazyObjectInspectorFactory;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory.ObjectInspectorOptions;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils;
+import org.apache.hadoop.io.Writable;
+import org.apache.phoenix.hive.PhoenixSerializer.DmlType;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.hive.mapreduce.PhoenixResultWritable;
+import org.apache.phoenix.hive.objectinspector.PhoenixObjectInspectorFactory;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * SerDe implementation for Phoenix Hive Storage
+ *
+ */
+public class PhoenixSerDe extends AbstractSerDe {
+
+    public static final Log LOG = LogFactory.getLog(PhoenixSerDe.class);
+
+    private PhoenixSerializer serializer;
+    private ObjectInspector objectInspector;
+
+    private LazySerDeParameters serdeParams;
+    private PhoenixRow row;
+
+    private Properties tableProperties;
+
+    /**
+     * @throws SerDeException
+     */
+    public PhoenixSerDe() throws SerDeException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("PhoenixSerDe created");
+        }
+    }
+
+    @Override
+    public void initialize(Configuration conf, Properties tbl) throws SerDeException {
+        tableProperties = tbl;
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("SerDe initialize : " + tbl.getProperty("name"));
+        }
+
+        serdeParams = new LazySerDeParameters(conf, tbl, getClass().getName());
+        objectInspector = createLazyPhoenixInspector(conf, tbl);
+
+        String inOutWork = tbl.getProperty(PhoenixStorageHandlerConstants.IN_OUT_WORK);
+        if (inOutWork == null) {
+            return;
+        }
+
+        serializer = new PhoenixSerializer(conf, tbl);
+        row = new PhoenixRow(Lists.transform(serdeParams.getColumnNames(), new Function<String,
+                String>() {
+
+            @Override
+            public String apply(String input) {
+                return input.toUpperCase();
+            }
+        }));
+    }
+
+    @Override
+    public Object deserialize(Writable result) throws SerDeException {
+        if (!(result instanceof PhoenixResultWritable)) {
+            throw new SerDeException(result.getClass().getName() + ": expects " +
+                    "PhoenixResultWritable!");
+        }
+
+        return row.setResultRowMap(((PhoenixResultWritable) result).getResultMap());
+    }
+
+    @Override
+    public Class<? extends Writable> getSerializedClass() {
+        return PhoenixResultWritable.class;
+    }
+
+    @Override
+    public Writable serialize(Object obj, ObjectInspector objInspector) throws SerDeException {
+        try {
+            return serializer.serialize(obj, objInspector, DmlType.NONE);
+        } catch (Exception e) {
+            throw new SerDeException(e);
+        }
+    }
+
+    @Override
+    public SerDeStats getSerDeStats() {
+        // no support for statistics
+        return null;
+    }
+
+    public Properties getTableProperties() {
+        return tableProperties;
+    }
+
+    public LazySerDeParameters getSerdeParams() {
+        return serdeParams;
+    }
+
+    @Override
+    public ObjectInspector getObjectInspector() throws SerDeException {
+        return objectInspector;
+    }
+
+    private ObjectInspector createLazyPhoenixInspector(Configuration conf, Properties tbl) throws
+            SerDeException {
+        List<String> columnNameList = Arrays.asList(tbl.getProperty(serdeConstants.LIST_COLUMNS)
+                .split(PhoenixStorageHandlerConstants.COMMA));
+        List<TypeInfo> columnTypeList = TypeInfoUtils.getTypeInfosFromTypeString(tbl.getProperty
+                (serdeConstants.LIST_COLUMN_TYPES));
+
+        List<ObjectInspector> columnObjectInspectors = Lists.newArrayListWithExpectedSize
+                (columnTypeList.size());
+
+        for (TypeInfo typeInfo : columnTypeList) {
+            columnObjectInspectors.add(PhoenixObjectInspectorFactory.createObjectInspector
+                    (typeInfo, serdeParams));
+        }
+
+        return LazyObjectInspectorFactory.getLazySimpleStructObjectInspector(columnNameList,
+                columnObjectInspectors, null, serdeParams.getSeparators()[0], serdeParams,
+                ObjectInspectorOptions.JAVA);
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixSerializer.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixSerializer.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixSerializer.java
new file mode 100644
index 0000000..e43ed0e
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixSerializer.java
@@ -0,0 +1,169 @@
+/*
+ * 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.phoenix.hive;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.common.type.HiveChar;
+import org.apache.hadoop.hive.common.type.HiveDecimal;
+import org.apache.hadoop.hive.serde2.SerDeException;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.StandardStructObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.StructField;
+import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
+import org.apache.hadoop.io.BytesWritable;
+import org.apache.hadoop.io.Writable;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.hive.mapreduce.PhoenixResultWritable;
+import org.apache.phoenix.hive.util.PhoenixConnectionUtil;
+import org.apache.phoenix.hive.util.PhoenixStorageHandlerUtil;
+import org.apache.phoenix.hive.util.PhoenixUtil;
+import org.apache.phoenix.util.ColumnInfo;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Serializer used in PhoenixSerDe and PhoenixRecordUpdater to produce Writable.
+ */
+public class PhoenixSerializer {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixSerializer.class);
+
+    public static enum DmlType {
+        NONE,
+        SELECT,
+        INSERT,
+        UPDATE,
+        DELETE
+    }
+
+    private int columnCount = 0;
+    private PhoenixResultWritable pResultWritable;
+
+    public PhoenixSerializer(Configuration config, Properties tbl) throws SerDeException {
+        try (Connection conn = PhoenixConnectionUtil.getInputConnection(config, tbl)) {
+            List<ColumnInfo> columnMetadata = PhoenixUtil.getColumnInfoList(conn, tbl.getProperty
+                    (PhoenixStorageHandlerConstants.PHOENIX_TABLE_NAME));
+
+            columnCount = columnMetadata.size();
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Column-meta : " + columnMetadata);
+            }
+
+            pResultWritable = new PhoenixResultWritable(config, columnMetadata);
+        } catch (SQLException | IOException e) {
+            throw new SerDeException(e);
+        }
+    }
+
+    public Writable serialize(Object values, ObjectInspector objInspector, DmlType dmlType) {
+        pResultWritable.clear();
+
+        final StructObjectInspector structInspector = (StructObjectInspector) objInspector;
+        final List<? extends StructField> fieldList = structInspector.getAllStructFieldRefs();
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("FieldList : " + fieldList + " values(" + values.getClass() + ") : " +
+                    values);
+        }
+
+        int fieldCount = columnCount;
+        if (dmlType == DmlType.UPDATE || dmlType == DmlType.DELETE) {
+            fieldCount++;
+        }
+
+        for (int i = 0; i < fieldCount; i++) {
+            if (fieldList.size() <= i) {
+                break;
+            }
+
+            StructField structField = fieldList.get(i);
+
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("structField[" + i + "] : " + structField);
+            }
+
+            if (structField != null) {
+                Object fieldValue = structInspector.getStructFieldData(values, structField);
+                ObjectInspector fieldOI = structField.getFieldObjectInspector();
+
+                String fieldName = structField.getFieldName();
+
+                if (LOG.isTraceEnabled()) {
+                    LOG.trace("Field " + fieldName + "[" + i + "] : " + fieldValue + ", " +
+                            fieldOI);
+                }
+
+                Object value = null;
+                switch (fieldOI.getCategory()) {
+                    case PRIMITIVE:
+                        value = ((PrimitiveObjectInspector) fieldOI).getPrimitiveJavaObject
+                                (fieldValue);
+
+                        if (LOG.isTraceEnabled()) {
+                            LOG.trace("Field " + fieldName + "[" + i + "] : " + value + "(" + value
+                                    .getClass() + ")");
+                        }
+
+                        if (value instanceof HiveDecimal) {
+                            value = ((HiveDecimal) value).bigDecimalValue();
+                        } else if (value instanceof HiveChar) {
+                            value = ((HiveChar) value).getValue().trim();
+                        }
+
+                        pResultWritable.add(value);
+                        break;
+                    case LIST:
+                    // Not support for arrays in insert statement yet
+                        break;
+                    case STRUCT:
+                        if (dmlType == DmlType.DELETE) {
+                            // When update/delete, First value is struct<transactionid:bigint,
+                            // bucketid:int,rowid:bigint,primaryKey:binary>>
+                            List<Object> fieldValueList = ((StandardStructObjectInspector)
+                                    fieldOI).getStructFieldsDataAsList(fieldValue);
+
+                            // convert to map from binary of primary key.
+                            @SuppressWarnings("unchecked")
+                            Map<String, Object> primaryKeyMap = (Map<String, Object>)
+                                    PhoenixStorageHandlerUtil.toMap(((BytesWritable)
+                                            fieldValueList.get(3)).getBytes());
+                            for (Object pkValue : primaryKeyMap.values()) {
+                                pResultWritable.add(pkValue);
+                            }
+                        }
+
+                        break;
+                    default:
+                        new SerDeException("Phoenix Unsupported column type: " + fieldOI
+                                .getCategory());
+                }
+            }
+        }
+
+        return pResultWritable;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixStorageHandler.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixStorageHandler.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixStorageHandler.java
new file mode 100644
index 0000000..e8b5b19
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixStorageHandler.java
@@ -0,0 +1,212 @@
+/*
+ * 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.phoenix.hive;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hive.common.JavaUtils;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.metastore.HiveMetaHook;
+import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
+import org.apache.hadoop.hive.ql.exec.TableScanOperator;
+import org.apache.hadoop.hive.ql.metadata.DefaultStorageHandler;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
+import org.apache.hadoop.hive.ql.metadata.HiveStoragePredicateHandler;
+import org.apache.hadoop.hive.ql.metadata.InputEstimator;
+import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
+import org.apache.hadoop.hive.ql.plan.TableDesc;
+import org.apache.hadoop.hive.serde2.Deserializer;
+import org.apache.hadoop.hive.serde2.SerDe;
+import org.apache.hadoop.mapred.InputFormat;
+import org.apache.hadoop.mapred.JobConf;
+import org.apache.hadoop.mapred.OutputFormat;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.hive.mapreduce.PhoenixInputFormat;
+import org.apache.phoenix.hive.mapreduce.PhoenixOutputFormat;
+import org.apache.phoenix.hive.ppd.PhoenixPredicateDecomposer;
+import org.apache.phoenix.hive.ppd.PhoenixPredicateDecomposerManager;
+import org.apache.phoenix.hive.util.PhoenixStorageHandlerUtil;
+import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This class manages all the Phoenix/Hive table initial configurations and SerDe Election
+ */
+@SuppressWarnings("deprecation")
+public class PhoenixStorageHandler extends DefaultStorageHandler implements
+        HiveStoragePredicateHandler, InputEstimator {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixStorageHandler.class);
+
+    public PhoenixStorageHandler() {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("PhoenixStorageHandler created");
+        }
+    }
+
+    @Override
+    public HiveMetaHook getMetaHook() {
+        return new PhoenixMetaHook();
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Class<? extends OutputFormat> getOutputFormatClass() {
+        return PhoenixOutputFormat.class;
+    }
+
+    @Override
+    public void configureInputJobProperties(TableDesc tableDesc, Map<String, String>
+            jobProperties) {
+        configureJobProperties(tableDesc, jobProperties);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Configuring input job for table : " + tableDesc.getTableName());
+        }
+
+        // initialization efficiency. Inform to SerDe about in/out work.
+        tableDesc.getProperties().setProperty(PhoenixStorageHandlerConstants.IN_OUT_WORK,
+                PhoenixStorageHandlerConstants.IN_WORK);
+    }
+
+    @Override
+    public void configureOutputJobProperties(TableDesc tableDesc, Map<String, String>
+            jobProperties) {
+        configureJobProperties(tableDesc, jobProperties);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Configuring output job for  table : " + tableDesc.getTableName());
+        }
+
+        // initialization efficiency. Inform to SerDe about in/out work.
+        tableDesc.getProperties().setProperty(PhoenixStorageHandlerConstants.IN_OUT_WORK,
+                PhoenixStorageHandlerConstants.OUT_WORK);
+    }
+
+    @Override
+    public void configureTableJobProperties(TableDesc tableDesc, Map<String, String>
+            jobProperties) {
+        configureJobProperties(tableDesc, jobProperties);
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    protected void configureJobProperties(TableDesc tableDesc, Map<String, String> jobProperties) {
+        Properties tableProperties = tableDesc.getProperties();
+
+        String inputFormatClassName =
+                tableProperties.getProperty(PhoenixStorageHandlerConstants
+                        .HBASE_INPUT_FORMAT_CLASS);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(PhoenixStorageHandlerConstants.HBASE_INPUT_FORMAT_CLASS + " is " +
+                    inputFormatClassName);
+        }
+
+        Class<?> inputFormatClass;
+        try {
+            if (inputFormatClassName != null) {
+                inputFormatClass = JavaUtils.loadClass(inputFormatClassName);
+            } else {
+                inputFormatClass = PhoenixInputFormat.class;
+            }
+        } catch (Exception e) {
+            LOG.error(e.getMessage(), e);
+            throw new RuntimeException(e);
+        }
+
+        if (inputFormatClass != null) {
+            tableDesc.setInputFileFormatClass((Class<? extends InputFormat>) inputFormatClass);
+        }
+
+        String tableName = tableProperties.getProperty(PhoenixStorageHandlerConstants
+                .PHOENIX_TABLE_NAME);
+        if (tableName == null) {
+            tableName = tableDesc.getTableName();
+            tableProperties.setProperty(PhoenixStorageHandlerConstants.PHOENIX_TABLE_NAME,
+                    tableName);
+        }
+
+        jobProperties.put(PhoenixConfigurationUtil.INPUT_TABLE_NAME, tableName);
+        jobProperties.put(PhoenixStorageHandlerConstants.ZOOKEEPER_QUORUM, tableProperties
+                .getProperty(PhoenixStorageHandlerConstants.ZOOKEEPER_QUORUM,
+                        PhoenixStorageHandlerConstants.DEFAULT_ZOOKEEPER_QUORUM));
+        jobProperties.put(PhoenixStorageHandlerConstants.ZOOKEEPER_PORT, tableProperties
+                .getProperty(PhoenixStorageHandlerConstants.ZOOKEEPER_PORT, String.valueOf
+                        (PhoenixStorageHandlerConstants.DEFAULT_ZOOKEEPER_PORT)));
+        jobProperties.put(PhoenixStorageHandlerConstants.ZOOKEEPER_PARENT, tableProperties
+                .getProperty(PhoenixStorageHandlerConstants.ZOOKEEPER_PARENT,
+                        PhoenixStorageHandlerConstants.DEFAULT_ZOOKEEPER_PARENT));
+
+        jobProperties.put(hive_metastoreConstants.META_TABLE_STORAGE, this.getClass().getName());
+
+        // set configuration when direct work with HBase.
+        jobProperties.put(HConstants.ZOOKEEPER_QUORUM, jobProperties.get
+                (PhoenixStorageHandlerConstants.ZOOKEEPER_QUORUM));
+        jobProperties.put(HConstants.ZOOKEEPER_CLIENT_PORT, jobProperties.get
+                (PhoenixStorageHandlerConstants.ZOOKEEPER_PORT));
+        jobProperties.put(HConstants.ZOOKEEPER_ZNODE_PARENT, jobProperties.get
+                (PhoenixStorageHandlerConstants.ZOOKEEPER_PARENT));
+    }
+
+    @Override
+    public Class<? extends SerDe> getSerDeClass() {
+        return PhoenixSerDe.class;
+    }
+
+    @Override
+    public DecomposedPredicate decomposePredicate(JobConf jobConf, Deserializer deserializer,
+                                                  ExprNodeDesc predicate) {
+        PhoenixSerDe phoenixSerDe = (PhoenixSerDe) deserializer;
+        String tableName = phoenixSerDe.getTableProperties().getProperty
+                (PhoenixStorageHandlerConstants.PHOENIX_TABLE_NAME);
+        String predicateKey = PhoenixStorageHandlerUtil.getTableKeyOfSession(jobConf, tableName);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Decomposing predicate with predicateKey : " + predicateKey);
+        }
+
+        List<String> columnNameList = phoenixSerDe.getSerdeParams().getColumnNames();
+        PhoenixPredicateDecomposer predicateDecomposer = PhoenixPredicateDecomposerManager
+                .createPredicateDecomposer(predicateKey, columnNameList);
+
+        return predicateDecomposer.decomposePredicate(predicate);
+    }
+
+    @Override
+    public Estimation estimate(JobConf job, TableScanOperator ts, long remaining) throws
+            HiveException {
+        String hiveTableName = ts.getConf().getTableMetadata().getTableName();
+        int reducerCount = job.getInt(hiveTableName + PhoenixStorageHandlerConstants
+                .PHOENIX_REDUCER_NUMBER, 1);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Estimating input size for table: " + hiveTableName + " with reducer count " +
+                    reducerCount + ". Remaining : " + remaining);
+        }
+
+        long bytesPerReducer = job.getLong(HiveConf.ConfVars.BYTESPERREDUCER.varname,
+                Long.parseLong(HiveConf.ConfVars.BYTESPERREDUCER.getDefaultValue()));
+        long totalLength = reducerCount * bytesPerReducer;
+
+        return new Estimation(0, totalLength);
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/constants/PhoenixStorageHandlerConstants.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/constants/PhoenixStorageHandlerConstants.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/constants/PhoenixStorageHandlerConstants.java
new file mode 100644
index 0000000..07c374e
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/constants/PhoenixStorageHandlerConstants.java
@@ -0,0 +1,108 @@
+/*
+ * 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.phoenix.hive.constants;
+
+import com.google.common.collect.Lists;
+import org.apache.hadoop.io.IntWritable;
+
+import java.util.List;
+
+/**
+ * Constants using for Hive Storage Handler implementation
+ */
+public class PhoenixStorageHandlerConstants {
+
+    public static final String HBASE_INPUT_FORMAT_CLASS = "phoenix.input.format.class";
+
+    public static final String PHOENIX_TABLE_NAME = "phoenix.table.name";
+
+    public static final String DEFAULT_PHOENIX_INPUT_CLASS = "org.apache.phoenix.hive.mapreduce" +
+            ".PhoenixResultWritable";
+
+    public static final String ZOOKEEPER_QUORUM = "phoenix.zookeeper.quorum";
+    public static final String ZOOKEEPER_PORT = "phoenix.zookeeper.client.port";
+    public static final String ZOOKEEPER_PARENT = "phoenix.zookeeper.znode.parent";
+    public static final String DEFAULT_ZOOKEEPER_QUORUM = "localhost";
+    public static final int DEFAULT_ZOOKEEPER_PORT = 2181;
+    public static final String DEFAULT_ZOOKEEPER_PARENT = "/hbase";
+
+    public static final String PHOENIX_ROWKEYS = "phoenix.rowkeys";
+    public static final String PHOENIX_COLUMN_MAPPING = "phoenix.column.mapping";
+    public static final String PHOENIX_TABLE_OPTIONS = "phoenix.table.options";
+
+    public static final String PHOENIX_TABLE_QUERY_HINT = ".query.hint";
+    public static final String PHOENIX_REDUCER_NUMBER = ".reducer.count";
+    public static final String DISABLE_WAL = ".disable.wal";
+    public static final String BATCH_MODE = "batch.mode";
+    public static final String AUTO_FLUSH = ".auto.flush";
+
+    public static final String COLON = ":";
+    public static final String COMMA = ",";
+    public static final String EMPTY_STRING = "";
+    public static final String SPACE = " ";
+    public static final String LEFT_ROUND_BRACKET = "(";
+    public static final String RIGHT_ROUND_BRACKET = ")";
+    public static final String QUOTATION_MARK = "'";
+    public static final String EQUAL = "=";
+    public static final String IS = "is";
+    public static final String QUESTION = "?";
+
+    public static final String SPLIT_BY_STATS = "split.by.stats";
+    public static final String HBASE_SCAN_CACHE = "hbase.scan.cache";
+    public static final String HBASE_SCAN_CACHEBLOCKS = "hbase.scan.cacheblock";
+    public static final String HBASE_DATE_FORMAT = "hbase.date.format";
+    public static final String HBASE_TIMESTAMP_FORMAT = "hbase.timestamp.format";
+    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
+    public static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
+
+    public static final String IN_OUT_WORK = "in.out.work";
+    public static final String IN_WORK = "input";
+    public static final String OUT_WORK = "output";
+
+    public static final String MR = "mr";
+    public static final String TEZ = "tez";
+    public static final String SPARK = "spark";
+
+    public static final String DATE_TYPE = "date";
+    public static final String TIMESTAMP_TYPE = "timestamp";
+    public static final String BETWEEN_COMPARATOR = "between";
+    public static final String IN_COMPARATOR = "in";
+    public static final List<String> COMMON_COMPARATOR = Lists.newArrayList("=", "<", ">", "<=",
+            ">=");
+
+    // date/timestamp
+    public static final String COLUMNE_MARKER = "$columnName$";
+    public static final String PATERN_MARKER = "$targetPattern$";
+    public static final String DATE_PATTERN = "'?\\d{4}-\\d{2}-\\d{2}'?";
+    public static final String TIMESTAMP_PATTERN = "'?\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\" +
+            ".?\\d{0,3}'?";
+    public static final String COMMON_OPERATOR_PATTERN = "(\\(?" + COLUMNE_MARKER + "\\)?\\s*" +
+            "(=|>|<|<=|>=)\\s*(" + PATERN_MARKER + "))";
+    public static final String BETWEEN_OPERATOR_PATTERN = "(\\(?" + COLUMNE_MARKER + "\\)?\\s*(" +
+            "(?i)not)?\\s*(?i)between\\s*(" + PATERN_MARKER + ")\\s*(?i)and\\s*(" + PATERN_MARKER
+            + "))";
+    public static final String IN_OPERATOR_PATTERN = "(\\(?" + COLUMNE_MARKER + "\\)?\\s*((?i)" +
+            "not)?\\s*(?i)in\\s*\\((" + PATERN_MARKER + ",?\\s*)+\\))";
+
+    public static final String FUNCTION_VALUE_MARKER = "$value$";
+    public static final String DATE_FUNCTION_TEMPLETE = "to_date(" + FUNCTION_VALUE_MARKER + ")";
+    public static final String TIMESTAMP_FUNCTION_TEMPLATE = "to_timestamp(" +
+            FUNCTION_VALUE_MARKER + ")";
+
+    public static final IntWritable INT_ZERO = new IntWritable(0);
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixInputFormat.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixInputFormat.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixInputFormat.java
new file mode 100644
index 0000000..0944bb7
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixInputFormat.java
@@ -0,0 +1,269 @@
+/*
+ * 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.phoenix.hive.mapreduce;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.HRegionLocation;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.HConnection;
+import org.apache.hadoop.hbase.client.HConnectionManager;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.RegionSizeCalculator;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.ql.plan.TableScanDesc;
+import org.apache.hadoop.hive.serde2.ColumnProjectionUtils;
+import org.apache.hadoop.hive.shims.ShimLoader;
+import org.apache.hadoop.io.WritableComparable;
+import org.apache.hadoop.mapred.InputFormat;
+import org.apache.hadoop.mapred.InputSplit;
+import org.apache.hadoop.mapred.JobConf;
+import org.apache.hadoop.mapred.RecordReader;
+import org.apache.hadoop.mapred.Reporter;
+import org.apache.hadoop.mapreduce.Job;
+import org.apache.hadoop.mapreduce.lib.db.DBWritable;
+import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
+import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.hive.ppd.PhoenixPredicateDecomposer;
+import org.apache.phoenix.hive.ppd.PhoenixPredicateDecomposerManager;
+import org.apache.phoenix.hive.ql.index.IndexSearchCondition;
+import org.apache.phoenix.hive.query.PhoenixQueryBuilder;
+import org.apache.phoenix.hive.util.PhoenixConnectionUtil;
+import org.apache.phoenix.hive.util.PhoenixStorageHandlerUtil;
+import org.apache.phoenix.iterate.MapReduceParallelScanGrouper;
+import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
+import org.apache.phoenix.query.KeyRange;
+import org.apache.phoenix.util.PhoenixRuntime;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.Statement;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Custom InputFormat to feed into Hive
+ */
+@SuppressWarnings({"deprecation", "rawtypes"})
+public class PhoenixInputFormat<T extends DBWritable> implements InputFormat<WritableComparable,
+        T> {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixInputFormat.class);
+
+    public PhoenixInputFormat() {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("PhoenixInputFormat created");
+        }
+    }
+
+    @Override
+    public InputSplit[] getSplits(JobConf jobConf, int numSplits) throws IOException {
+        String tableName = jobConf.get(PhoenixConfigurationUtil.INPUT_TABLE_NAME);
+        List<IndexSearchCondition> conditionList = null;
+        String query;
+        String executionEngine = jobConf.get(HiveConf.ConfVars.HIVE_EXECUTION_ENGINE.varname,
+                HiveConf.ConfVars.HIVE_EXECUTION_ENGINE.getDefaultValue());
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Target table name at split phase : " + tableName + "with whereCondition :" +
+                    jobConf.get(TableScanDesc.FILTER_TEXT_CONF_STR) +
+                    " and " + HiveConf.ConfVars.HIVE_EXECUTION_ENGINE.varname + " : " +
+                    executionEngine);
+        }
+
+        if (PhoenixStorageHandlerConstants.MR.equals(executionEngine)) {
+            String predicateKey = PhoenixStorageHandlerUtil.getTableKeyOfSession(jobConf,
+                    tableName);
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("PredicateKey for MR job : " + predicateKey);
+            }
+
+            PhoenixPredicateDecomposer predicateDecomposer =
+                    PhoenixPredicateDecomposerManager.getPredicateDecomposer(predicateKey);
+            if (predicateDecomposer != null && predicateDecomposer.isCalledPPD()) {
+                conditionList = predicateDecomposer.getSearchConditionList();
+            }
+
+            query = PhoenixQueryBuilder.getInstance().buildQuery(jobConf, tableName,
+                    ColumnProjectionUtils.getReadColumnNames(jobConf), conditionList);
+        } else if (PhoenixStorageHandlerConstants.TEZ.equals(executionEngine)) {
+            Map<String, String> columnTypeMap = PhoenixStorageHandlerUtil.createColumnTypeMap
+                    (jobConf);
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Column type map for TEZ : " + columnTypeMap);
+            }
+
+            String whereClause = jobConf.get(TableScanDesc.FILTER_TEXT_CONF_STR);
+            query = PhoenixQueryBuilder.getInstance().buildQuery(jobConf, tableName,
+                    ColumnProjectionUtils.getReadColumnNames(jobConf), whereClause, columnTypeMap);
+        } else {
+            throw new IOException(executionEngine + " execution engine unsupported yet.");
+        }
+
+        final QueryPlan queryPlan = getQueryPlan(jobConf, query);
+        final List<KeyRange> allSplits = queryPlan.getSplits();
+        final List<InputSplit> splits = generateSplits(jobConf, queryPlan, allSplits, query);
+
+        return splits.toArray(new InputSplit[splits.size()]);
+    }
+
+    private List<InputSplit> generateSplits(final JobConf jobConf, final QueryPlan qplan,
+                                            final List<KeyRange> splits, String query) throws
+            IOException {
+        Preconditions.checkNotNull(qplan);
+        Preconditions.checkNotNull(splits);
+        final List<InputSplit> psplits = Lists.newArrayListWithExpectedSize(splits.size());
+
+        Path[] tablePaths = FileInputFormat.getInputPaths(ShimLoader.getHadoopShims()
+                .newJobContext(new Job(jobConf)));
+        boolean splitByStats = jobConf.getBoolean(PhoenixStorageHandlerConstants.SPLIT_BY_STATS,
+                false);
+        int scanCacheSize = jobConf.getInt(PhoenixStorageHandlerConstants.HBASE_SCAN_CACHE, -1);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Generating splits with scanCacheSize : " + scanCacheSize);
+        }
+        String tableName = qplan
+                .getTableRef().getTable().getPhysicalName().toString();
+        HTable table = new HTable(jobConf, tableName);
+        // Adding Localization
+        HConnection connection = HConnectionManager.createConnection(jobConf);
+        RegionSizeCalculator sizeCalculator = new RegionSizeCalculator(table);
+
+        for (List<Scan> scans : qplan.getScans()) {
+            PhoenixInputSplit inputSplit;
+
+            HRegionLocation location =
+            connection.getRegionLocation(TableName.valueOf(tableName),scans.get(0)
+                    .getStartRow(), false);
+            long regionSize = sizeCalculator.getRegionSize(location.getRegionInfo().getRegionName
+                    ());
+            String regionLocation = PhoenixStorageHandlerUtil.getRegionLocation(location, LOG);
+
+            if (splitByStats) {
+                for (Scan aScan : scans) {
+                    if (scanCacheSize > 0) {
+                        aScan.setCaching(scanCacheSize);
+                    }
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Split for  scan : " + aScan + "with scanAttribute : " + aScan
+                                .getAttributesMap() + " [scanCache, cacheBlock, scanBatch] : [" +
+                                aScan.getCaching() + ", " + aScan.getCacheBlocks() + ", " + aScan
+                                .getBatch() + "] and  regionLocation : " + regionLocation);
+                    }
+
+                    inputSplit = new PhoenixInputSplit(Lists.newArrayList(aScan), tablePaths[0],
+                            regionLocation, regionSize);
+                    inputSplit.setQuery(query);
+                    psplits.add(inputSplit);
+                }
+            } else {
+                if (scanCacheSize > 0) {
+                    for (Scan aScan : scans) {
+                        aScan.setCaching(scanCacheSize);
+                    }
+                }
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Scan count[" + scans.size() + "] : " + Bytes.toStringBinary(scans
+                            .get(0).getStartRow()) + " ~ " + Bytes.toStringBinary(scans.get(scans
+                            .size() - 1).getStopRow()));
+                    LOG.debug("First scan : " + scans.get(0) + "with scanAttribute : " + scans
+                            .get(0).getAttributesMap() + " [scanCache, cacheBlock, scanBatch] : " +
+                            "[" + scans.get(0).getCaching() + ", " + scans.get(0).getCacheBlocks()
+                            + ", " + scans.get(0).getBatch() + "] and  regionLocation : " +
+                            regionLocation);
+
+                    for (int i = 0, limit = scans.size(); i < limit; i++) {
+                        LOG.debug("EXPECTED_UPPER_REGION_KEY[" + i + "] : " + Bytes
+                                .toStringBinary(scans.get(i).getAttribute
+                                        (BaseScannerRegionObserver.EXPECTED_UPPER_REGION_KEY)));
+                    }
+                }
+
+                inputSplit = new PhoenixInputSplit(scans, tablePaths[0], regionLocation,
+                        regionSize);
+                inputSplit.setQuery(query);
+                psplits.add(inputSplit);
+            }
+        }
+
+        return psplits;
+    }
+
+    @Override
+    public RecordReader<WritableComparable, T> getRecordReader(InputSplit split, JobConf job,
+                                                               Reporter reporter) throws
+            IOException {
+        final QueryPlan queryPlan = getQueryPlan(job, ((PhoenixInputSplit) split).getQuery());
+        @SuppressWarnings("unchecked")
+        final Class<T> inputClass = (Class<T>) job.getClass(PhoenixConfigurationUtil.INPUT_CLASS,
+                PhoenixResultWritable.class);
+
+        PhoenixRecordReader<T> recordReader = new PhoenixRecordReader<T>(inputClass, job,
+                queryPlan);
+        recordReader.initialize(split);
+
+        return recordReader;
+    }
+
+    /**
+     * Returns the query plan associated with the select query.
+     */
+    private QueryPlan getQueryPlan(final Configuration configuration, String selectStatement)
+            throws IOException {
+        try {
+            final String currentScnValue = configuration.get(PhoenixConfigurationUtil
+                    .CURRENT_SCN_VALUE);
+            final Properties overridingProps = new Properties();
+            if (currentScnValue != null) {
+                overridingProps.put(PhoenixRuntime.CURRENT_SCN_ATTRIB, currentScnValue);
+            }
+            final Connection connection = PhoenixConnectionUtil.getInputConnection(configuration,
+                    overridingProps);
+            Preconditions.checkNotNull(selectStatement);
+            final Statement statement = connection.createStatement();
+            final PhoenixStatement pstmt = statement.unwrap(PhoenixStatement.class);
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Compiled query : " + selectStatement);
+            }
+
+            // Optimize the query plan so that we potentially use secondary indexes
+            final QueryPlan queryPlan = pstmt.optimizeQuery(selectStatement);
+            // Initialize the query plan so it sets up the parallel scans
+            queryPlan.iterator(MapReduceParallelScanGrouper.getInstance());
+            return queryPlan;
+        } catch (Exception exception) {
+            LOG.error(String.format("Failed to get the query plan with error [%s]", exception.getMessage()));
+            throw new RuntimeException(exception);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixInputSplit.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixInputSplit.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixInputSplit.java
new file mode 100644
index 0000000..d76e863
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixInputSplit.java
@@ -0,0 +1,160 @@
+/*
+ * 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.phoenix.hive.mapreduce;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
+import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
+import org.apache.hadoop.io.WritableUtils;
+import org.apache.hadoop.mapred.FileSplit;
+import org.apache.hadoop.mapred.InputSplit;
+import org.apache.phoenix.query.KeyRange;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * InputSplit implementation. Represents the data to be processed by an individual Mapper
+ */
+public class PhoenixInputSplit extends FileSplit implements InputSplit {
+
+    private List<Scan> scans;
+    private KeyRange keyRange;
+
+    private long regionSize;
+
+    //  query is in the  split because it is not delivered in jobConf.
+    private String query;
+
+    public PhoenixInputSplit() {
+    }
+
+    public PhoenixInputSplit(final List<Scan> scans, Path dummyPath, String regionLocation, long
+            length) {
+        super(dummyPath, 0, 0, new String[]{regionLocation});
+
+        regionSize = length;
+
+        Preconditions.checkNotNull(scans);
+        Preconditions.checkState(!scans.isEmpty());
+        this.scans = scans;
+        init();
+    }
+
+    public List<Scan> getScans() {
+        return scans;
+    }
+
+    public KeyRange getKeyRange() {
+        return keyRange;
+    }
+
+    public String getQuery() {
+        return query;
+    }
+
+    public void setQuery(String query) {
+        this.query = query;
+    }
+
+    private void init() {
+        this.keyRange = KeyRange.getKeyRange(scans.get(0).getStartRow(), scans.get(scans.size() -
+                1).getStopRow());
+    }
+
+    @Override
+    public void write(DataOutput out) throws IOException {
+        super.write(out);
+
+        Preconditions.checkNotNull(scans);
+        WritableUtils.writeVInt(out, scans.size());
+        for (Scan scan : scans) {
+            ClientProtos.Scan protoScan = ProtobufUtil.toScan(scan);
+            byte[] protoScanBytes = protoScan.toByteArray();
+            WritableUtils.writeVInt(out, protoScanBytes.length);
+            out.write(protoScanBytes);
+        }
+
+        WritableUtils.writeString(out, query);
+        WritableUtils.writeVLong(out, regionSize);
+    }
+
+    @Override
+    public void readFields(DataInput in) throws IOException {
+        super.readFields(in);
+
+        int count = WritableUtils.readVInt(in);
+        scans = Lists.newArrayListWithExpectedSize(count);
+        for (int i = 0; i < count; i++) {
+            byte[] protoScanBytes = new byte[WritableUtils.readVInt(in)];
+            in.readFully(protoScanBytes);
+            ClientProtos.Scan protoScan = ClientProtos.Scan.parseFrom(protoScanBytes);
+            Scan scan = ProtobufUtil.toScan(protoScan);
+            scans.add(scan);
+        }
+        init();
+
+        query = WritableUtils.readString(in);
+        regionSize = WritableUtils.readVLong(in);
+    }
+
+    @Override
+    public long getLength() {
+        return regionSize;
+    }
+
+    @Override
+    public String[] getLocations() throws IOException {
+        return new String[]{};
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + keyRange.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof PhoenixInputSplit)) {
+            return false;
+        }
+        PhoenixInputSplit other = (PhoenixInputSplit) obj;
+        if (keyRange == null) {
+            if (other.keyRange != null) {
+                return false;
+            }
+        } else if (!keyRange.equals(other.keyRange)) {
+            return false;
+        }
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixOutputFormat.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixOutputFormat.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixOutputFormat.java
new file mode 100644
index 0000000..ed47176
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixOutputFormat.java
@@ -0,0 +1,112 @@
+/*
+ * 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.phoenix.hive.mapreduce;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hive.ql.io.AcidOutputFormat;
+import org.apache.hadoop.hive.ql.io.RecordUpdater;
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.mapred.JobConf;
+import org.apache.hadoop.mapred.OutputFormat;
+import org.apache.hadoop.mapred.RecordWriter;
+import org.apache.hadoop.mapreduce.lib.db.DBWritable;
+import org.apache.hadoop.util.Progressable;
+import org.apache.phoenix.hive.util.PhoenixStorageHandlerUtil;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Properties;
+
+/**
+ * Custom OutputFormat to feed into Hive. Describes the output-specification for a Map-Reduce job.
+ */
+public class PhoenixOutputFormat<T extends DBWritable> implements OutputFormat<NullWritable, T>,
+        AcidOutputFormat<NullWritable, T> {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixOutputFormat.class);
+
+    public PhoenixOutputFormat() {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("PhoenixOutputFormat created");
+        }
+    }
+
+    @Override
+    public RecordWriter<NullWritable, T> getRecordWriter(FileSystem ignored, JobConf jobConf,
+                                                         String name, Progressable progress)
+            throws IOException {
+        return createRecordWriter(jobConf, new Properties());
+    }
+
+    @Override
+    public void checkOutputSpecs(FileSystem ignored, JobConf job) throws IOException {
+
+    }
+
+    @Override
+    public org.apache.hadoop.hive.ql.exec.FileSinkOperator.RecordWriter getHiveRecordWriter
+            (JobConf jobConf, Path finalOutPath, Class<? extends Writable> valueClass, boolean
+                    isCompressed, Properties tableProperties, Progressable progress) throws
+            IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Get RecordWriter for finalOutPath : " + finalOutPath + ", valueClass" +
+                    " : " +
+                    valueClass
+                            .getName() + ", isCompressed : " + isCompressed + ", tableProperties " +
+                    ": " + tableProperties + ", progress : " + progress);
+        }
+
+        return createRecordWriter(jobConf, new Properties());
+    }
+
+    @Override
+    public RecordUpdater getRecordUpdater(Path path, org.apache.hadoop.hive.ql.io
+            .AcidOutputFormat.Options options) throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Get RecordWriter for  path : " + path + ", options : " +
+                    PhoenixStorageHandlerUtil
+                            .getOptionsValue(options));
+        }
+        return new PhoenixRecordWriter<T>(path, options);
+    }
+
+    @Override
+    public org.apache.hadoop.hive.ql.exec.FileSinkOperator.RecordWriter getRawRecordWriter(Path path,
+            org.apache.hadoop.hive.ql.io.AcidOutputFormat.Options options) throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Get RawRecordWriter for path : " + path + ", options : " +
+                    PhoenixStorageHandlerUtil.getOptionsValue(options));
+        }
+
+        return new PhoenixRecordWriter<T>(path, options);
+    }
+
+    private PhoenixRecordWriter<T> createRecordWriter(Configuration config, Properties properties) {
+        try {
+            return new PhoenixRecordWriter<T>(config, properties);
+        } catch (SQLException e) {
+            LOG.error("Error during PhoenixRecordWriter instantiation :" + e.getMessage());
+            throw new RuntimeException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixRecordReader.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixRecordReader.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixRecordReader.java
new file mode 100644
index 0000000..72719a1
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixRecordReader.java
@@ -0,0 +1,216 @@
+/*
+ * 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.phoenix.hive.mapreduce;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.Lists;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.io.WritableComparable;
+import org.apache.hadoop.mapred.InputSplit;
+import org.apache.hadoop.mapred.RecordReader;
+import org.apache.hadoop.mapreduce.lib.db.DBWritable;
+import org.apache.hadoop.util.ReflectionUtils;
+import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
+import org.apache.phoenix.hive.PhoenixRowKey;
+import org.apache.phoenix.hive.util.PhoenixStorageHandlerUtil;
+import org.apache.phoenix.iterate.ConcatResultIterator;
+import org.apache.phoenix.iterate.LookAheadResultIterator;
+import org.apache.phoenix.iterate.PeekingResultIterator;
+import org.apache.phoenix.iterate.ResultIterator;
+import org.apache.phoenix.iterate.RoundRobinResultIterator;
+import org.apache.phoenix.iterate.SequenceResultIterator;
+import org.apache.phoenix.iterate.TableResultIterator;
+import org.apache.phoenix.jdbc.PhoenixResultSet;
+import org.apache.phoenix.monitoring.ReadMetricQueue;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.List;
+
+import static org.apache.phoenix.monitoring.MetricType.SCAN_BYTES;
+
+/**
+ * @RecordReader implementation that iterates over the the records.
+ */
+@SuppressWarnings("rawtypes")
+public class PhoenixRecordReader<T extends DBWritable> implements
+        RecordReader<WritableComparable, T> {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixRecordReader.class);
+
+    private final Configuration configuration;
+    private final QueryPlan queryPlan;
+    private WritableComparable key;
+    private T value = null;
+    private Class<T> inputClass;
+    private ResultIterator resultIterator = null;
+    private PhoenixResultSet resultSet;
+    private long readCount;
+
+    private boolean isTransactional;
+
+    public PhoenixRecordReader(Class<T> inputClass, final Configuration configuration, final
+    QueryPlan queryPlan) throws IOException {
+        this.inputClass = inputClass;
+        this.configuration = configuration;
+        this.queryPlan = queryPlan;
+
+        isTransactional = PhoenixStorageHandlerUtil.isTransactionalTable(configuration);
+    }
+
+    public void initialize(InputSplit split) throws IOException {
+        final PhoenixInputSplit pSplit = (PhoenixInputSplit) split;
+        final List<Scan> scans = pSplit.getScans();
+
+        if (LOG.isInfoEnabled()) {
+            LOG.info("Target table : " + queryPlan.getTableRef().getTable().getPhysicalName());
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Scan count[" + scans.size() + "] : " + Bytes.toStringBinary(scans.get(0)
+                    .getStartRow()) + " ~ " + Bytes.toStringBinary(scans.get(scans.size() - 1)
+                    .getStopRow()));
+            LOG.debug("First scan : " + scans.get(0) + " scanAttribute : " + scans.get(0)
+                    .getAttributesMap());
+
+            for (int i = 0, limit = scans.size(); i < limit; i++) {
+                LOG.debug("EXPECTED_UPPER_REGION_KEY[" + i + "] : " +
+                        Bytes.toStringBinary(scans.get(i).getAttribute(BaseScannerRegionObserver
+                                .EXPECTED_UPPER_REGION_KEY)));
+            }
+        }
+
+        try {
+            List<PeekingResultIterator> iterators = Lists.newArrayListWithExpectedSize(scans.size
+                    ());
+            StatementContext ctx = queryPlan.getContext();
+            ReadMetricQueue readMetrics = ctx.getReadMetricsQueue();
+            String tableName = queryPlan.getTableRef().getTable().getPhysicalName().getString();
+            long renewScannerLeaseThreshold = queryPlan.getContext().getConnection()
+                    .getQueryServices().getRenewLeaseThresholdMilliSeconds();
+            for (Scan scan : scans) {
+                scan.setAttribute(BaseScannerRegionObserver.SKIP_REGION_BOUNDARY_CHECK, Bytes
+                        .toBytes(true));
+                final TableResultIterator tableResultIterator = new TableResultIterator(queryPlan
+                        .getContext().getConnection().getMutationState(),
+                        queryPlan.getTableRef(), scan, readMetrics.allotMetric(SCAN_BYTES,
+                        tableName), renewScannerLeaseThreshold);
+
+
+                PeekingResultIterator peekingResultIterator = LookAheadResultIterator.wrap
+                        (tableResultIterator);
+                iterators.add(peekingResultIterator);
+            }
+            ResultIterator iterator = queryPlan.useRoundRobinIterator()
+                    ? RoundRobinResultIterator.newIterator(iterators, queryPlan)
+                    : ConcatResultIterator.newIterator(iterators);
+            if (queryPlan.getContext().getSequenceManager().getSequenceCount() > 0) {
+                iterator = new SequenceResultIterator(iterator, queryPlan.getContext()
+                        .getSequenceManager());
+            }
+            this.resultIterator = iterator;
+            // Clone the row projector as it's not thread safe and would be used
+            // simultaneously by multiple threads otherwise.
+            this.resultSet = new PhoenixResultSet(this.resultIterator, queryPlan.getProjector()
+                    .cloneIfNecessary(),
+                    queryPlan.getContext());
+        } catch (SQLException e) {
+            LOG.error(String.format(" Error [%s] initializing PhoenixRecordReader. ", e
+                    .getMessage()));
+            Throwables.propagate(e);
+        }
+    }
+
+    @Override
+    public boolean next(WritableComparable key, T value) throws IOException {
+        try {
+            if (!resultSet.next()) {
+                return false;
+            }
+            value.readFields(resultSet);
+
+            if (isTransactional) {
+                ((PhoenixResultWritable) value).readPrimaryKey((PhoenixRowKey) key);
+            }
+
+            ++readCount;
+
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Result[" + readCount + "] : " + ((PhoenixResultWritable) value)
+                        .getResultMap());
+            }
+
+            return true;
+        } catch (SQLException e) {
+            LOG.error(String.format(" Error [%s] occurred while iterating over the resultset. ",
+                    e.getMessage()));
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public WritableComparable createKey() {
+        if (isTransactional) {
+            key = new PhoenixRowKey();
+        } else {
+            key = NullWritable.get();
+        }
+
+        return key;
+    }
+
+    @Override
+    public T createValue() {
+        value = ReflectionUtils.newInstance(inputClass, this.configuration);
+        return value;
+    }
+
+    @Override
+    public long getPos() throws IOException {
+        return 0;
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (LOG.isInfoEnabled()) {
+            LOG.info("Read Count : " + readCount);
+        }
+
+        if (resultIterator != null) {
+            try {
+                resultIterator.close();
+            } catch (SQLException e) {
+                LOG.error(" Error closing resultset.");
+                throw new RuntimeException(e);
+            }
+        }
+
+    }
+
+    @Override
+    public float getProgress() throws IOException {
+        return 0;
+    }
+}


[13/52] [abbrv] phoenix git commit: PHOENIX-2156 Support drop of column from table with views

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropViewIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropViewIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropViewIT.java
deleted file mode 100644
index e52f8cc..0000000
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropViewIT.java
+++ /dev/null
@@ -1,105 +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.phoenix.end2end.index;
-
-import static org.apache.phoenix.util.TestUtil.HBASE_NATIVE;
-import static org.apache.phoenix.util.TestUtil.HBASE_NATIVE_SCHEMA_NAME;
-import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
-import static org.junit.Assert.fail;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.hadoop.hbase.HColumnDescriptor;
-import org.apache.hadoop.hbase.HTableDescriptor;
-import org.apache.hadoop.hbase.client.HBaseAdmin;
-import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
-import org.apache.phoenix.end2end.BaseHBaseManagedTimeTableReuseIT;
-import org.apache.phoenix.end2end.Shadower;
-import org.apache.phoenix.query.QueryServices;
-import org.apache.phoenix.util.PropertiesUtil;
-import org.apache.phoenix.util.ReadOnlyProps;
-import org.apache.phoenix.util.SchemaUtil;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.google.common.collect.Maps;
-
-public class DropViewIT extends BaseHBaseManagedTimeIT {
-    private static final byte[] HBASE_NATIVE_BYTES = SchemaUtil.getTableNameAsBytes(HBASE_NATIVE_SCHEMA_NAME, HBASE_NATIVE);
-    private static final byte[] FAMILY_NAME = Bytes.toBytes(SchemaUtil.normalizeIdentifier("1"));
-    
-    @Shadower(classBeingShadowed = BaseHBaseManagedTimeIT.class)
-    @BeforeClass 
-    public static void doSetup() throws Exception {
-        Map<String,String> props = Maps.newHashMapWithExpectedSize(1);
-        // Drop the HBase table metadata for this test
-        props.put(QueryServices.DROP_METADATA_ATTRIB, Boolean.toString(true));
-        // Must update config before starting server
-        setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
-    }
-    
-    @Test
-    public void testDropViewKeepsHTable() throws Exception {
-        HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TEST_PROPERTIES).getAdmin();
-        try {
-            try {
-                admin.disableTable(HBASE_NATIVE_BYTES);
-                admin.deleteTable(HBASE_NATIVE_BYTES);
-            } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
-            }
-            @SuppressWarnings("deprecation")
-            HTableDescriptor descriptor = new HTableDescriptor(HBASE_NATIVE_BYTES);
-            HColumnDescriptor columnDescriptor =  new HColumnDescriptor(FAMILY_NAME);
-            columnDescriptor.setKeepDeletedCells(true);
-            descriptor.addFamily(columnDescriptor);
-            admin.createTable(descriptor);
-        } finally {
-            admin.close();
-        }
-        
-        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        conn.createStatement().execute("create view " + HBASE_NATIVE +
-                "   (uint_key unsigned_int not null," +
-                "    ulong_key unsigned_long not null," +
-                "    string_key varchar not null,\n" +
-                "    \"1\".uint_col unsigned_int," +
-                "    \"1\".ulong_col unsigned_long" +
-                "    CONSTRAINT pk PRIMARY KEY (uint_key, ulong_key, string_key))\n" +
-                     HColumnDescriptor.DATA_BLOCK_ENCODING + "='" + DataBlockEncoding.NONE + "'");
-        conn.createStatement().execute("drop view " + HBASE_NATIVE);
-        
-        admin = driver.getConnectionQueryServices(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).getAdmin();
-        try {
-            try {
-                admin.disableTable(HBASE_NATIVE_BYTES);
-                admin.deleteTable(HBASE_NATIVE_BYTES);
-            } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
-                fail(); // The underlying HBase table should still exist
-            }
-        } finally {
-            admin.close();
-        }
-    }
-}
-        

http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index bcfdf20..770917f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -83,7 +83,6 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellUtil;
@@ -116,7 +115,11 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.cache.GlobalCache;
 import org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr;
+import org.apache.phoenix.compile.ColumnResolver;
+import org.apache.phoenix.compile.FromCompiler;
 import org.apache.phoenix.compile.ScanRanges;
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.compile.WhereCompiler;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.AddColumnRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearCacheRequest;
@@ -134,7 +137,13 @@ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetVersionRequest
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetVersionResponse;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.MetaDataResponse;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.UpdateIndexStateRequest;
+import org.apache.phoenix.expression.ColumnExpression;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.KeyValueColumnExpression;
 import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.ProjectedColumnExpression;
+import org.apache.phoenix.expression.RowKeyColumnExpression;
+import org.apache.phoenix.expression.visitor.StatelessTraverseAllExpressionVisitor;
 import org.apache.phoenix.hbase.index.covered.update.ColumnReference;
 import org.apache.phoenix.hbase.index.util.GenericKeyValueBuilder;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
@@ -142,18 +151,21 @@ import org.apache.phoenix.hbase.index.util.IndexManagementUtil;
 import org.apache.phoenix.index.IndexMaintainer;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.metrics.Metrics;
 import org.apache.phoenix.parse.LiteralParseNode;
 import org.apache.phoenix.parse.PFunction;
 import org.apache.phoenix.parse.PFunction.FunctionArgument;
+import org.apache.phoenix.parse.ParseNode;
+import org.apache.phoenix.parse.SQLParser;
 import org.apache.phoenix.protobuf.ProtobufUtil;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.query.QueryServicesOptions;
-import org.apache.phoenix.schema.AmbiguousColumnException;
 import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
 import org.apache.phoenix.schema.ColumnNotFoundException;
+import org.apache.phoenix.schema.ColumnRef;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PColumnFamily;
 import org.apache.phoenix.schema.PColumnImpl;
@@ -169,6 +181,7 @@ import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.stats.PTableStats;
 import org.apache.phoenix.schema.stats.StatisticsUtil;
 import org.apache.phoenix.schema.tuple.ResultTuple;
@@ -1420,6 +1433,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 return;
             }
             List<byte[]> tableNamesToDelete = Lists.newArrayList();
+            List<SharedTableState> sharedTablesToDelete = Lists.newArrayList();
             byte[] parentTableName = MetaDataUtil.getParentTableName(tableMetadata);
             byte[] lockTableName = parentTableName == null ? tableName : parentTableName;
             byte[] lockKey = SchemaUtil.getTableKey(tenantIdBytes, schemaName, lockTableName);
@@ -1444,7 +1458,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 result =
                         doDropTable(key, tenantIdBytes, schemaName, tableName, parentTableName,
                             PTableType.fromSerializedValue(tableType), tableMetadata,
-                            invalidateList, locks, tableNamesToDelete, isCascade);
+                            invalidateList, locks, tableNamesToDelete, sharedTablesToDelete, isCascade);
                 if (result.getMutationCode() != MutationCode.TABLE_ALREADY_EXISTS) {
                     done.run(MetaDataMutationResult.toProto(result));
                     return;
@@ -1475,7 +1489,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private MetaDataMutationResult doDropTable(byte[] key, byte[] tenantId, byte[] schemaName,
         byte[] tableName, byte[] parentTableName, PTableType tableType, List<Mutation> rowsToDelete,
         List<ImmutableBytesPtr> invalidateList, List<RowLock> locks,
-        List<byte[]> tableNamesToDelete, boolean isCascade) throws IOException, SQLException {
+        List<byte[]> tableNamesToDelete, List<SharedTableState> sharedTablesToDelete, boolean isCascade) throws IOException, SQLException {
 
 
         long clientTimeStamp = MetaDataUtil.getClientTimeStamp(rowsToDelete);
@@ -1550,7 +1564,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                                 acquireLock(region, viewKey, locks);
                                 MetaDataMutationResult result = doDropTable(viewKey, viewTenantId, viewSchemaName,
                                         viewName, null, PTableType.VIEW, rowsToDelete, invalidateList, locks,
-                                        tableNamesToDelete, false);
+                                        tableNamesToDelete, sharedTablesToDelete, false);
                                 if (result.getMutationCode() != MutationCode.TABLE_ALREADY_EXISTS) { return result; }
                             }
                         }
@@ -1562,9 +1576,13 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 }
             }
 
-            if (tableType != PTableType.VIEW) { // Add to list of HTables to delete, unless it's a view
+            // Add to list of HTables to delete, unless it's a view or its a shared index
+            if (tableType != PTableType.VIEW && table.getViewIndexId()==null) { 
                 tableNamesToDelete.add(table.getName().getBytes());
             }
+            else {
+                sharedTablesToDelete.add(new SharedTableState(table));
+            }
             invalidateList.add(cacheKey);
             byte[][] rowKeyMetaData = new byte[5][];
             do {
@@ -1601,7 +1619,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             acquireLock(region, indexKey, locks);
             MetaDataMutationResult result =
                     doDropTable(indexKey, tenantId, schemaName, indexName, tableName, PTableType.INDEX,
-                        rowsToDelete, invalidateList, locks, tableNamesToDelete, false);
+                        rowsToDelete, invalidateList, locks, tableNamesToDelete, sharedTablesToDelete, false);
             if (result.getMutationCode() != MutationCode.TABLE_ALREADY_EXISTS) {
                 return result;
             }
@@ -1708,7 +1726,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 }
                 result = mutator.updateMutation(table, rowKeyMetaData, tableMetadata, region,
                             invalidateList, locks, clientTimeStamp);
-                if (result != null) {
+                // if the update mutation caused tables to be deleted, the mutation code returned will be MutationCode.TABLE_ALREADY_EXISTS 
+                if (result != null && result.getMutationCode()!=MutationCode.TABLE_ALREADY_EXISTS) {
                     return result;
                 }
                 region.mutateRowsWithLocks(tableMetadata, Collections.<byte[]> emptySet());
@@ -1719,8 +1738,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 // Get client timeStamp from mutations, since it may get updated by the
                 // mutateRowsWithLocks call
                 long currentTime = MetaDataUtil.getClientTimeStamp(tableMetadata);
-                return new MetaDataMutationResult(MutationCode.TABLE_ALREADY_EXISTS, currentTime,
-                        null);
+                // if the update mutation caused tables to be deleted just return the result which will contain the table to be deleted
+                return result != null ? result : new MetaDataMutationResult(MutationCode.TABLE_ALREADY_EXISTS, currentTime, null);
             } finally {
                 region.releaseRowLocks(locks);
             }
@@ -1771,6 +1790,24 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             this.offset = lowestOrdinalPos;
         }
 
+        private void addColumn(byte[] columnKey) {
+            columnKeys.add(columnKey);
+        }
+
+        private void dropColumn(byte[] columnKey) {
+            // Check if an entry for this column key exists
+            int index = -1;
+            for (int i = 0; i < columnKeys.size(); i++) {
+                if (Bytes.equals(columnKeys.get(i), columnKey)) {
+                    index = i;
+                    break;
+                }
+            }
+            if (index != -1) {
+                columnKeys.remove(index);
+            }
+        }
+        
         private void addColumn(byte[] columnKey, int position) {
             checkArgument(position >= this.offset);
             int index = position - offset;
@@ -1857,7 +1894,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         return false;
     }
     
-    private MetaDataMutationResult addRowsToChildViews(PTable basePhysicalTable, List<Mutation> tableMetadata, List<Mutation> mutationsForAddingColumnsToViews, byte[] schemaName, byte[] tableName,
+    private MetaDataMutationResult addColumnsToChildViews(PTable basePhysicalTable, List<Mutation> tableMetadata, List<Mutation> mutationsForAddingColumnsToViews, byte[] schemaName, byte[] tableName,
             List<ImmutableBytesPtr> invalidateList, long clientTimeStamp, TableViewFinderResult childViewsResult,
             HRegion region, List<RowLock> locks) throws IOException, SQLException {
         List<PutWithOrdinalPosition> columnPutsForBaseTable = new ArrayList<>(tableMetadata.size());
@@ -1866,7 +1903,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             if (m instanceof Put) {
                 byte[][] rkmd = new byte[5][];
                 int pkCount = getVarChars(m.getRow(), rkmd);
-                if (m instanceof Put && pkCount > COLUMN_NAME_INDEX
+                if (pkCount > COLUMN_NAME_INDEX
                         && Bytes.compareTo(schemaName, rkmd[SCHEMA_NAME_INDEX]) == 0
                         && Bytes.compareTo(tableName, rkmd[TABLE_NAME_INDEX]) == 0) {
                     columnPutsForBaseTable.add(new PutWithOrdinalPosition((Put)m, getInteger((Put)m, TABLE_FAMILY_BYTES, ORDINAL_POSITION_BYTES)));
@@ -2039,71 +2076,235 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             addViewIndexesHeaderRowMutations(mutationsForAddingColumnsToViews, invalidateList, clientTimeStamp, view,
                     deltaNumPkColsSoFar);
             
-            // Update the view header rows with new column counts.
-            Put viewHeaderRowPut = new Put(viewKey, clientTimeStamp);
-            if (!isDivergedView(view) && columnsAddedToBaseTable > 0) {
-                // Base column count should only be updated for diverged views.
-                int oldBaseColumnCount = view.getBaseColumnCount();
-                byte[] baseColumnCountPtr = new byte[PInteger.INSTANCE.getByteSize()];
-                PInteger.INSTANCE.getCodec().encodeInt(oldBaseColumnCount + columnsAddedToBaseTable, baseColumnCountPtr, 0);
-                viewHeaderRowPut.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
-                        PhoenixDatabaseMetaData.BASE_COLUMN_COUNT_BYTES, clientTimeStamp, baseColumnCountPtr);
-            }
-            
-            if (columnsAddedToView > 0) {
-                byte[] columnCountPtr = new byte[PInteger.INSTANCE.getByteSize()];
-                PInteger.INSTANCE.getCodec().encodeInt(numCols + columnsAddedToView, columnCountPtr, 0);
-                viewHeaderRowPut.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
-                        PhoenixDatabaseMetaData.COLUMN_COUNT_BYTES, clientTimeStamp, columnCountPtr);
-            }
-            
             /*
              * Increment the sequence number by 1 if:
              * 1) For a diverged view, there were columns (pk columns) added to the view.
              * 2) For a non-diverged view if the base column count changed.
-             *    
              */
             boolean changeSequenceNumber = (isDivergedView(view) && columnsAddedToView > 0)
                     || (!isDivergedView(view) && columnsAddedToBaseTable > 0);
-            if (changeSequenceNumber) {
-                byte[] viewSequencePtr = new byte[PLong.INSTANCE.getByteSize()];
-                PLong.INSTANCE.getCodec().encodeLong(view.getSequenceNumber() + 1, viewSequencePtr, 0);
-                viewHeaderRowPut.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
-                        PhoenixDatabaseMetaData.TABLE_SEQ_NUM_BYTES, clientTimeStamp, viewSequencePtr);
-
-                mutationsForAddingColumnsToViews.add(viewHeaderRowPut);
-
-                // only invalidate if the sequence number is about to change
-                invalidateList.add(new ImmutableBytesPtr(viewKey));
-
-                // Update the ordinal positions. The list would be non-empty only if the sequence
-                // number will change.
-                int i = 0;
-                for (byte[] columnKey : ordinalPositionList.columnKeys) {
-                    int ordinalPosition = ordinalPositionList.getOrdinalPositionFromListIdx(i);
-                    Put positionUpdatePut = new Put(columnKey, clientTimeStamp);
-                    byte[] ptr = new byte[PInteger.INSTANCE.getByteSize()];
-                    PInteger.INSTANCE.getCodec().encodeInt(ordinalPosition, ptr, 0);
-                    positionUpdatePut.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
-                            PhoenixDatabaseMetaData.ORDINAL_POSITION_BYTES, clientTimeStamp, ptr);
-                    mutationsForAddingColumnsToViews.add(positionUpdatePut);
-                    i++;
-                }
+            updateViewHeaderRow(basePhysicalTable, tableMetadata, mutationsForAddingColumnsToViews,
+                invalidateList, clientTimeStamp, columnsAddedToView, columnsAddedToBaseTable,
+                viewKey, view, ordinalPositionList, numCols, changeSequenceNumber);
+        }
+        return null;
+    }
+
+    /**
+     * Updates the base table column count, column count, sequence number and ordinal postions of
+     * columns of the view based on the columns being added or dropped.
+     */
+    private void updateViewHeaderRow(PTable basePhysicalTable, List<Mutation> tableMetadata,
+            List<Mutation> mutationsForAddingColumnsToViews,
+            List<ImmutableBytesPtr> invalidateList, long clientTimeStamp, short viewColumnDelta,
+            short baseTableColumnDelta, byte[] viewKey, PTable view,
+            ColumnOrdinalPositionUpdateList ordinalPositionList, int numCols, boolean changeSequenceNumber) {
+        // Update the view header rows with new column counts.
+        Put viewHeaderRowPut = new Put(viewKey, clientTimeStamp);
+        if (!isDivergedView(view) && baseTableColumnDelta != 0) {
+            // Base column count should only be updated for diverged views.
+            int oldBaseColumnCount = view.getBaseColumnCount();
+            byte[] baseColumnCountPtr = new byte[PInteger.INSTANCE.getByteSize()];
+            PInteger.INSTANCE.getCodec().encodeInt(oldBaseColumnCount + baseTableColumnDelta, baseColumnCountPtr, 0);
+            viewHeaderRowPut.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
+                    PhoenixDatabaseMetaData.BASE_COLUMN_COUNT_BYTES, clientTimeStamp, baseColumnCountPtr);
+        }
+        
+        if (viewColumnDelta != 0) {
+            byte[] columnCountPtr = new byte[PInteger.INSTANCE.getByteSize()];
+            PInteger.INSTANCE.getCodec().encodeInt(numCols + viewColumnDelta, columnCountPtr, 0);
+            viewHeaderRowPut.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
+                    PhoenixDatabaseMetaData.COLUMN_COUNT_BYTES, clientTimeStamp, columnCountPtr);
+        }
+        
+        if (changeSequenceNumber) {
+            byte[] viewSequencePtr = new byte[PLong.INSTANCE.getByteSize()];
+            PLong.INSTANCE.getCodec().encodeLong(view.getSequenceNumber() + 1, viewSequencePtr, 0);
+            viewHeaderRowPut.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
+                    PhoenixDatabaseMetaData.TABLE_SEQ_NUM_BYTES, clientTimeStamp, viewSequencePtr);
+
+            mutationsForAddingColumnsToViews.add(viewHeaderRowPut);
+
+            // only invalidate if the sequence number is about to change
+            invalidateList.add(new ImmutableBytesPtr(viewKey));
+
+            // Update the ordinal positions. The list would be non-empty only if the sequence
+            // number will change.
+            int i = 0;
+            for (byte[] columnKey : ordinalPositionList.columnKeys) {
+                int ordinalPosition = ordinalPositionList.getOrdinalPositionFromListIdx(i);
+                Put positionUpdatePut = new Put(columnKey, clientTimeStamp);
+                byte[] ptr = new byte[PInteger.INSTANCE.getByteSize()];
+                PInteger.INSTANCE.getCodec().encodeInt(ordinalPosition, ptr, 0);
+                positionUpdatePut.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
+                        PhoenixDatabaseMetaData.ORDINAL_POSITION_BYTES, clientTimeStamp, ptr);
+                mutationsForAddingColumnsToViews.add(positionUpdatePut);
+                i++;
             }
-            
-            if (view.rowKeyOrderOptimizable()) {
-                UpgradeUtil.addRowKeyOrderOptimizableCell(mutationsForAddingColumnsToViews, viewKey, clientTimeStamp);
+        }
+        
+        if (view.rowKeyOrderOptimizable()) {
+            UpgradeUtil.addRowKeyOrderOptimizableCell(mutationsForAddingColumnsToViews, viewKey, clientTimeStamp);
+        }
+        
+        // if switching from from non tx to tx
+        if (!basePhysicalTable.isTransactional() && switchAttribute(basePhysicalTable, basePhysicalTable.isTransactional(), tableMetadata, TRANSACTIONAL_BYTES)) {
+        	invalidateList.add(new ImmutableBytesPtr(viewKey));
+        	Put put = new Put(viewKey);
+            put.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
+            		TRANSACTIONAL_BYTES, clientTimeStamp, PBoolean.INSTANCE.toBytes(true));
+            mutationsForAddingColumnsToViews.add(put);
+        }
+    }
+    
+    private class ColumnFinder extends StatelessTraverseAllExpressionVisitor<Void> {
+        private boolean columnFound;
+        private final ColumnExpression columnExpression;
+
+        public ColumnFinder(ColumnExpression columnExpression) {
+            this.columnExpression = columnExpression;
+            columnFound = false;
+        }
+
+        private Void process(ColumnExpression expression) {
+            if (expression.equals(columnExpression)) {
+                columnFound = true;
             }
-            
-            // if switching from from non tx to tx
-            if (!basePhysicalTable.isTransactional() && switchAttribute(basePhysicalTable, basePhysicalTable.isTransactional(), tableMetadata, TRANSACTIONAL_BYTES)) {
-            	invalidateList.add(new ImmutableBytesPtr(viewKey));
-            	Put put = new Put(viewKey);
-                put.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES,
-                		TRANSACTIONAL_BYTES, clientTimeStamp, PBoolean.INSTANCE.toBytes(true));
-                mutationsForAddingColumnsToViews.add(put);
+            return null;
+        }
+
+        @Override
+        public Void visit(KeyValueColumnExpression expression) {
+            return process(expression);
+        }
+
+        @Override
+        public Void visit(RowKeyColumnExpression expression) {
+            return process(expression);
+        }
+
+        @Override
+        public Void visit(ProjectedColumnExpression expression) {
+            return process(expression);
+        }
+
+        public boolean getColumnFound() {
+            return columnFound;
+        }
+    }
+
+    private MetaDataMutationResult dropColumnsFromChildViews(HRegion region,
+            PTable basePhysicalTable, List<RowLock> locks, List<Mutation> tableMetadata,
+            List<Mutation> mutationsForAddingColumnsToViews, byte[] schemaName, byte[] tableName,
+            List<ImmutableBytesPtr> invalidateList, long clientTimeStamp,
+            TableViewFinderResult childViewsResult, List<byte[]> tableNamesToDelete, List<SharedTableState> sharedTablesToDelete)
+            throws IOException, SQLException {
+        List<Delete> columnDeletesForBaseTable = new ArrayList<>(tableMetadata.size());
+        // Isolate the deletes relevant to dropping columns. Also figure out what kind of columns
+        // are being added.
+        for (Mutation m : tableMetadata) {
+            if (m instanceof Delete) {
+                byte[][] rkmd = new byte[5][];
+                int pkCount = getVarChars(m.getRow(), rkmd);
+                if (pkCount > COLUMN_NAME_INDEX
+                        && Bytes.compareTo(schemaName, rkmd[SCHEMA_NAME_INDEX]) == 0
+                        && Bytes.compareTo(tableName, rkmd[TABLE_NAME_INDEX]) == 0) {
+                    columnDeletesForBaseTable.add((Delete) m);
+                }
             }
         }
+        for (Result viewResult : childViewsResult.getResults()) {
+            short numColsDeleted = 0;
+            byte[][] rowViewKeyMetaData = new byte[3][];
+            getVarChars(viewResult.getRow(), 3, rowViewKeyMetaData);
+            byte[] viewKey =
+                    SchemaUtil.getTableKey(
+                        rowViewKeyMetaData[PhoenixDatabaseMetaData.TENANT_ID_INDEX],
+                        rowViewKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX],
+                        rowViewKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX]);
+
+            // lock the rows corresponding to views so that no other thread can modify the view
+            // meta-data
+            RowLock viewRowLock = acquireLock(region, viewKey, locks);
+            PTable view = doGetTable(viewKey, clientTimeStamp, viewRowLock);
+
+            ColumnOrdinalPositionUpdateList ordinalPositionList =
+                    new ColumnOrdinalPositionUpdateList();
+            int numCols = view.getColumns().size();
+            int minDroppedColOrdinalPos = Integer.MAX_VALUE;
+            for (Delete columnDeleteForBaseTable : columnDeletesForBaseTable) {
+                PColumn existingViewColumn = null;
+                byte[][] rkmd = new byte[5][];
+                getVarChars(columnDeleteForBaseTable.getRow(), rkmd);
+                String columnName = Bytes.toString(rkmd[COLUMN_NAME_INDEX]);
+                String columnFamily =
+                        rkmd[FAMILY_NAME_INDEX] == null ? null : Bytes
+                                .toString(rkmd[FAMILY_NAME_INDEX]);
+                byte[] columnKey = getColumnKey(viewKey, columnName, columnFamily);
+                try {
+                    existingViewColumn =
+                            columnFamily == null ? view.getColumn(columnName) : view
+                                    .getColumnFamily(columnFamily).getColumn(columnName);
+                } catch (ColumnFamilyNotFoundException e) {
+                    // ignore since it means that the column family is not present for the column to
+                    // be added.
+                } catch (ColumnNotFoundException e) {
+                    // ignore since it means the column is not present in the view
+                }
+
+                // check if the view where expression contains the column being dropped and prevent
+                // it
+                if (existingViewColumn != null && view.getViewStatement() != null) {
+                    ParseNode viewWhere =
+                            new SQLParser(view.getViewStatement()).parseQuery().getWhere();
+                    PhoenixConnection conn=null;
+                    try {
+                        conn = QueryUtil.getConnection(env.getConfiguration()).unwrap(
+                            PhoenixConnection.class);
+                    } catch (ClassNotFoundException e) {
+                    }
+                    PhoenixStatement statement = new PhoenixStatement(conn);
+                    TableRef baseTableRef = new TableRef(basePhysicalTable);
+                    ColumnResolver columnResolver = FromCompiler.getResolver(baseTableRef);
+                    StatementContext context = new StatementContext(statement, columnResolver);
+                    Expression whereExpression = WhereCompiler.compile(context, viewWhere);
+                    ColumnExpression colExpression =
+                            new ColumnRef(baseTableRef, existingViewColumn.getPosition())
+                                    .newColumnExpression();
+                    ColumnFinder columnFinder = new ColumnFinder(colExpression);
+                    whereExpression.accept(columnFinder);
+                    if (columnFinder.getColumnFound()) {
+                        return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION,
+                                EnvironmentEdgeManager.currentTimeMillis(), basePhysicalTable);
+                    }
+                }
+
+                minDroppedColOrdinalPos =
+                        Math.min(getOrdinalPosition(view, existingViewColumn),
+                            minDroppedColOrdinalPos);
+                if (existingViewColumn != null) {
+                    --numColsDeleted;
+                    if (ordinalPositionList.size() == 0) {
+                        ordinalPositionList.setOffset(view.getBucketNum() == null ? 1 : 0);
+                        for (PColumn col : view.getColumns()) {
+                            ordinalPositionList.addColumn(getColumnKey(viewKey, col));
+                        }
+                    }
+                    ordinalPositionList.dropColumn(columnKey);
+                    Delete viewColumnDelete = new Delete(columnKey, clientTimeStamp);
+                    mutationsForAddingColumnsToViews.add(viewColumnDelete);
+                    // drop any view indexes that need this column
+                    dropIndexes(view, region, invalidateList, locks, clientTimeStamp,
+                        schemaName, view.getName().getBytes(),
+                        mutationsForAddingColumnsToViews, existingViewColumn,
+                        tableNamesToDelete, sharedTablesToDelete);
+                }
+            }
+
+            updateViewHeaderRow(basePhysicalTable, tableMetadata, mutationsForAddingColumnsToViews,
+                invalidateList, clientTimeStamp, numColsDeleted, numColsDeleted, viewKey, view,
+                ordinalPositionList, numCols, true);
+        }
         return null;
     }
     
@@ -2332,7 +2533,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                                         EnvironmentEdgeManager.currentTimeMillis(), null);
                             } else {
                                 mutationsForAddingColumnsToViews = new ArrayList<>(childViewsResult.getResults().size() * tableMetaData.size());
-                                MetaDataMutationResult mutationResult = addRowsToChildViews(table, tableMetaData, mutationsForAddingColumnsToViews, schemaName, tableName, invalidateList, clientTimeStamp,
+                                MetaDataMutationResult mutationResult = addColumnsToChildViews(table, tableMetaData, mutationsForAddingColumnsToViews, schemaName, tableName, invalidateList, clientTimeStamp,
                                         childViewsResult, region, locks);
                                 // return if we were not able to add the column successfully
                                 if (mutationResult!=null)
@@ -2555,10 +2756,10 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     public void dropColumn(RpcController controller, DropColumnRequest request,
             RpcCallback<MetaDataResponse> done) {
         List<Mutation> tableMetaData = null;
-
+        final List<byte[]> tableNamesToDelete = Lists.newArrayList();
+        final List<SharedTableState> sharedTablesToDelete = Lists.newArrayList();
         try {
             tableMetaData = ProtobufUtil.getMutations(request);
-            final List<byte[]> tableNamesToDelete = Lists.newArrayList();
             MetaDataMutationResult result = mutateColumn(tableMetaData, new ColumnMutator() {
                 @Override
                 public MetaDataMutationResult updateMutation(PTable table, byte[][] rowKeyMetaData,
@@ -2580,8 +2781,13 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                         TableViewFinderResult childViewsResult = 
                                 findChildViews(region, tenantId, table, PHYSICAL_TABLE_BYTES);
                         if (childViewsResult.hasViews()) {
-                            return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION, EnvironmentEdgeManager
-                                    .currentTimeMillis(), null);
+                            MetaDataMutationResult mutationResult =
+                                    dropColumnsFromChildViews(region, table,
+                                        locks, tableMetaData, additionalTableMetaData,
+                                        schemaName, tableName, invalidateList,
+                                        clientTimeStamp, childViewsResult, tableNamesToDelete, sharedTablesToDelete);
+                            // return if we were not able to drop the column successfully
+                            if (mutationResult != null) return mutationResult;
                         }
                     }
                     
@@ -2633,42 +2839,11 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                                     if (columnToDelete.isViewReferenced()) { // Disallow deletion of column referenced in WHERE clause of view
                                         return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION, EnvironmentEdgeManager.currentTimeMillis(), table, columnToDelete);
                                     }
-                                    // Look for columnToDelete in any indexes. If found as PK column, get lock and drop the index and then invalidate it
-                                    // Covered columns are deleted from the index by the client
-                                    PhoenixConnection connection = table.getIndexes().isEmpty() ? null : QueryUtil.getConnection(env.getConfiguration()).unwrap(PhoenixConnection.class);
-                                    for (PTable index : table.getIndexes()) {
-                                        try {
-                                            IndexMaintainer indexMaintainer = index.getIndexMaintainer(table, connection);
-                                            // get the columns required for the index pk
-                                            Set<ColumnReference> indexColumns = indexMaintainer.getIndexedColumns();
-                                            byte[] indexKey =
-                                                    SchemaUtil.getTableKey(tenantId, index
-                                                            .getSchemaName().getBytes(), index.getTableName().getBytes());
-                                            // If index requires this column for its pk, then drop it
-                                            if (indexColumns.contains(new ColumnReference(columnToDelete.getFamilyName().getBytes(), columnToDelete.getName().getBytes()))) {
-                                                // Since we're dropping the index, lock it to ensure
-                                                // that a change in index state doesn't
-                                                // occur while we're dropping it.
-                                                acquireLock(region, indexKey, locks);
-                                                // Drop the index table. The doDropTable will expand
-                                                // this to all of the table rows and invalidate the
-                                                // index table
-                                                additionalTableMetaData.add(new Delete(indexKey, clientTimeStamp));
-                                                byte[] linkKey = MetaDataUtil.getParentLinkKey(tenantId,
-                                                            schemaName, tableName, index.getTableName().getBytes());
-                                                // Drop the link between the data table and the
-                                                // index table
-                                                additionalTableMetaData.add(new Delete(linkKey, clientTimeStamp));
-                                                doDropTable(indexKey, tenantId, index.getSchemaName().getBytes(), index.getTableName().getBytes(), tableName,
-                                                    index.getType(), additionalTableMetaData, invalidateList, locks, tableNamesToDelete, false);
-                                                // TODO: return in result?
-                                            } else {
-                                                invalidateList.add(new ImmutableBytesPtr(indexKey));
-                                            }
-                                        } catch (ColumnNotFoundException e) {
-                                        } catch (AmbiguousColumnException e) {
-                                        }
-                                    }
+                                    // drop any indexes that need the column that is going to be dropped
+                                    dropIndexes(table, region, invalidateList, locks,
+                                        clientTimeStamp, schemaName, tableName,
+                                        additionalTableMetaData, columnToDelete,
+                                        tableNamesToDelete, sharedTablesToDelete);
                                 } catch (ColumnFamilyNotFoundException e) {
                                     return new MetaDataMutationResult(
                                             MutationCode.COLUMN_NOT_FOUND, EnvironmentEdgeManager
@@ -2677,8 +2852,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                                     return new MetaDataMutationResult(
                                             MutationCode.COLUMN_NOT_FOUND, EnvironmentEdgeManager
                                                     .currentTimeMillis(), table, columnToDelete);
-                                } catch (ClassNotFoundException e1) {
-                                }
+                                } 
                             }
                         }
                     }
@@ -2689,7 +2863,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                         }
                     }
                     tableMetaData.addAll(additionalTableMetaData);
-                    return null;
+                    long currentTime = MetaDataUtil.getClientTimeStamp(tableMetaData);
+                    return new MetaDataMutationResult(MutationCode.TABLE_ALREADY_EXISTS, currentTime, null, tableNamesToDelete, sharedTablesToDelete);
                 }
             });
             if (result != null) {
@@ -2699,6 +2874,58 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             ProtobufUtil.setControllerException(controller, ioe);
         }
     }
+    
+    private void dropIndexes(PTable table, HRegion region, List<ImmutableBytesPtr> invalidateList,
+            List<RowLock> locks, long clientTimeStamp, byte[] schemaName,
+            byte[] tableName, List<Mutation> additionalTableMetaData, PColumn columnToDelete, 
+            List<byte[]> tableNamesToDelete, List<SharedTableState> sharedTablesToDelete)
+            throws IOException, SQLException {
+        // Look for columnToDelete in any indexes. If found as PK column, get lock and drop the
+        // index and then invalidate it
+        // Covered columns are deleted from the index by the client
+        PhoenixConnection connection = null;
+        try {
+            connection = table.getIndexes().isEmpty() ? null : QueryUtil.getConnection(
+                env.getConfiguration()).unwrap(PhoenixConnection.class);
+        } catch (ClassNotFoundException e) {
+        }
+        for (PTable index : table.getIndexes()) {
+            byte[] tenantId = index.getTenantId() == null ? ByteUtil.EMPTY_BYTE_ARRAY : index.getTenantId().getBytes(); 
+            IndexMaintainer indexMaintainer = index.getIndexMaintainer(table, connection);
+            byte[] indexKey =
+                    SchemaUtil.getTableKey(tenantId, index.getSchemaName().getBytes(), index
+                            .getTableName().getBytes());
+            // If index requires this column for its pk, then drop it
+            if (indexMaintainer.getIndexedColumns().contains(
+                new ColumnReference(columnToDelete.getFamilyName().getBytes(), columnToDelete
+                        .getName().getBytes()))) {
+                // Since we're dropping the index, lock it to ensure
+                // that a change in index state doesn't
+                // occur while we're dropping it.
+                acquireLock(region, indexKey, locks);
+                // Drop the index table. The doDropTable will expand
+                // this to all of the table rows and invalidate the
+                // index table
+                additionalTableMetaData.add(new Delete(indexKey, clientTimeStamp));
+                byte[] linkKey =
+                        MetaDataUtil.getParentLinkKey(tenantId, schemaName, tableName, index
+                                .getTableName().getBytes());
+                // Drop the link between the data table and the
+                // index table
+                additionalTableMetaData.add(new Delete(linkKey, clientTimeStamp));
+                doDropTable(indexKey, tenantId, index.getSchemaName().getBytes(), index
+                        .getTableName().getBytes(), tableName, index.getType(),
+                    additionalTableMetaData, invalidateList, locks, tableNamesToDelete, sharedTablesToDelete, false);
+                invalidateList.add(new ImmutableBytesPtr(indexKey));
+            }
+            // If the dropped column is a covered index column, invalidate the index
+            else if (indexMaintainer.getCoverededColumns().contains(
+                new ColumnReference(columnToDelete.getFamilyName().getBytes(), columnToDelete
+                        .getName().getBytes()))) {
+                invalidateList.add(new ImmutableBytesPtr(indexKey));
+            }
+        }
+    }
 
     @Override
     public void clearCache(RpcController controller, ClearCacheRequest request,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
index 7a7cf31..f8b4c79 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
@@ -29,10 +29,14 @@ import org.apache.phoenix.coprocessor.generated.PFunctionProtos;
 import org.apache.phoenix.hbase.index.util.VersionUtil;
 import org.apache.phoenix.parse.PFunction;
 import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PColumnImpl;
+import org.apache.phoenix.schema.PName;
+import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.util.ByteUtil;
 
+import com.google.common.base.Function;
 import com.google.common.collect.Lists;
 import com.google.protobuf.ByteString;
 
@@ -98,11 +102,77 @@ public abstract class MetaDataProtocol extends MetaDataService {
         NO_OP
     };
 
+  public static class SharedTableState {
+        private PName tenantId;
+        private PName schemaName;
+        private PName tableName;
+        private List<PColumn> columns;
+        private List<PName> physicalNames;
+        private Short viewIndexId;
+        
+        public SharedTableState(PTable table) {
+            this.tenantId = table.getTenantId();
+            this.schemaName = table.getSchemaName();
+            this.tableName = table.getTableName();
+            this.columns = table.getColumns();
+            this.physicalNames = table.getPhysicalNames();
+            this.viewIndexId = table.getViewIndexId();
+        }
+        
+        public SharedTableState(
+                org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState sharedTable) {
+            this.tenantId = sharedTable.hasTenantId() ? PNameFactory.newName(sharedTable.getTenantId().toByteArray()) : null;
+            this.schemaName = PNameFactory.newName(sharedTable.getSchemaName().toByteArray());
+            this.tableName = PNameFactory.newName(sharedTable.getTableName().toByteArray());
+            this.columns = Lists.transform(sharedTable.getColumnsList(),
+                new Function<org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn, PColumn>() {
+                @Override
+                public PColumn apply(org.apache.phoenix.coprocessor.generated.PTableProtos.PColumn column) {
+                    return PColumnImpl.createFromProto(column);
+                }
+            });
+            this.physicalNames = Lists.transform(sharedTable.getPhysicalNamesList(),
+                new Function<ByteString, PName>() {
+                @Override
+                public PName apply(ByteString physicalName) {
+                    return PNameFactory.newName(physicalName.toByteArray());
+                }
+            });
+            this.viewIndexId = (short)sharedTable.getViewIndexId();
+        }
+
+        public PName getTenantId() {
+            return tenantId;
+        }
+
+        public PName getSchemaName() {
+            return schemaName;
+        }
+
+        public PName getTableName() {
+            return tableName;
+        }
+
+        public List<PColumn> getColumns() {
+            return columns;
+        }
+
+        public List<PName> getPhysicalNames() {
+            return physicalNames;
+        }
+
+        public Short getViewIndexId() {
+            return viewIndexId;
+        }
+        
+  }
+    
   public static class MetaDataMutationResult {
         private MutationCode returnCode;
         private long mutationTime;
         private PTable table;
         private List<byte[]> tableNamesToDelete;
+        private List<SharedTableState> sharedTablesToDelete;
         private byte[] columnName;
         private byte[] familyName;
         private boolean wasUpdated;
@@ -142,6 +212,11 @@ public abstract class MetaDataProtocol extends MetaDataService {
             this.table = table;
             this.tableNamesToDelete = tableNamesToDelete;
         }
+        
+        public MetaDataMutationResult(MutationCode returnCode, long currentTime, PTable table, List<byte[]> tableNamesToDelete, List<SharedTableState> sharedTablesToDelete) {
+            this(returnCode, currentTime, table, tableNamesToDelete);
+            this.sharedTablesToDelete = sharedTablesToDelete;
+        }
 
         public MutationCode getMutationCode() {
             return returnCode;
@@ -182,6 +257,10 @@ public abstract class MetaDataProtocol extends MetaDataService {
         public List<PFunction> getFunctions() {
             return functions;
         }
+        
+        public List<SharedTableState> getSharedTablesToDelete() {
+            return sharedTablesToDelete;
+        }
 
         public static MetaDataMutationResult constructFromProto(MetaDataResponse proto) {
           MetaDataMutationResult result = new MetaDataMutationResult();
@@ -210,6 +289,14 @@ public abstract class MetaDataProtocol extends MetaDataService {
           if(proto.hasFamilyName()){
             result.familyName = proto.getFamilyName().toByteArray();
           }
+          if(proto.getSharedTablesToDeleteCount() > 0) {
+              result.sharedTablesToDelete = 
+                 Lists.newArrayListWithExpectedSize(proto.getSharedTablesToDeleteCount());
+              for (org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState sharedTable : 
+                  proto.getSharedTablesToDeleteList()) {
+                result.sharedTablesToDelete.add(new SharedTableState(sharedTable));
+                }
+          }
           return result;
         }
 
@@ -234,6 +321,25 @@ public abstract class MetaDataProtocol extends MetaDataService {
             if(result.getFamilyName() != null){
               builder.setFamilyName(ByteStringer.wrap(result.getFamilyName()));
             }
+            if (result.getSharedTablesToDelete() !=null){
+              for (SharedTableState sharedTableState : result.sharedTablesToDelete) {
+                org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.Builder sharedTableStateBuilder =
+                        org.apache.phoenix.coprocessor.generated.MetaDataProtos.SharedTableState.newBuilder();
+                for (PColumn col : sharedTableState.getColumns()) {
+                    sharedTableStateBuilder.addColumns(PColumnImpl.toProto(col));
+                }
+                for (PName physicalName : sharedTableState.getPhysicalNames()) {
+                    sharedTableStateBuilder.addPhysicalNames(ByteStringer.wrap(physicalName.getBytes()));
+                }
+                if (sharedTableState.getTenantId()!=null) {
+                    sharedTableStateBuilder.setTenantId(ByteStringer.wrap(sharedTableState.getTenantId().getBytes()));
+                }
+                sharedTableStateBuilder.setSchemaName(ByteStringer.wrap(sharedTableState.getSchemaName().getBytes()));
+                sharedTableStateBuilder.setTableName(ByteStringer.wrap(sharedTableState.getTableName().getBytes()));
+                sharedTableStateBuilder.setViewIndexId(sharedTableState.getViewIndexId());
+                builder.addSharedTablesToDelete(sharedTableStateBuilder.build());
+              }
+            }
           }
           return builder.build();
         }


[24/52] [abbrv] phoenix git commit: PHOENIX-1311 HBase namespaces surfaced in phoenix

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
index 8c804bb..68fcae3 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
@@ -30,6 +30,8 @@ import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -73,19 +75,38 @@ import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.MetaDataUtil;
 import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.StringUtil;
 import org.apache.phoenix.util.TestUtil;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
 import com.google.common.collect.Maps;
 
+@RunWith(Parameterized.class)
 public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     private static CountDownLatch latch1 = new CountDownLatch(1);
     private static CountDownLatch latch2 = new CountDownLatch(1);
     private static final int WAIT_TIME_SECONDS = 60;
+    private String schemaName="TEST";
+    private boolean isNamespaceMapped;
+    private String tableName = schemaName + ".T";
+    private String indexTableName = schemaName + ".I";
+    private String indexName = "I";
+    private String indexPhysicalTableName;
+    private TableName physicalTableName;
 
+    public LocalIndexIT(boolean isNamespaceMapped) {
+        this.isNamespaceMapped = isNamespaceMapped;
+        this.physicalTableName = SchemaUtil.getPhysicalTableName(tableName.getBytes(), isNamespaceMapped);
+        this.indexPhysicalTableName = Bytes
+                .toString(MetaDataUtil.getLocalIndexPhysicalName(physicalTableName.getName()));
+    }
+    
     @BeforeClass 
     @Shadower(classBeingShadowed = BaseHBaseManagedTimeIT.class)
     public static void doSetup() throws Exception {
@@ -97,7 +118,10 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
     }
 
     private void createBaseTable(String tableName, Integer saltBuckets, String splits) throws SQLException {
-        Connection conn = DriverManager.getConnection(getUrl());
+        Connection conn = getConnection();
+        if (isNamespaceMapped) {
+            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName);
+        }
         String ddl = "CREATE TABLE " + tableName + " (t_id VARCHAR NOT NULL,\n" +
                 "k1 INTEGER NOT NULL,\n" +
                 "k2 INTEGER NOT NULL,\n" +
@@ -109,79 +133,94 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
         conn.createStatement().execute(ddl);
         conn.close();
     }
-    
+
+    @Parameters(name = "isNamespaceMapped = {0}")
+    public static Collection<Boolean> data() {
+        return Arrays.asList(true, false);
+    }
+
     @Test
     public void testLocalIndexRoundTrip() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, null);
+        createBaseTable(tableName, null, null);
         Connection conn1 = DriverManager.getConnection(getUrl());
-        conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-        conn1.createStatement().executeQuery("SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME).next();
-        PTable localIndex = conn1.unwrap(PhoenixConnection.class).getTable(new PTableKey(null,TestUtil.DEFAULT_INDEX_TABLE_NAME));
+        conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+        conn1.createStatement().executeQuery("SELECT * FROM " + tableName).next();
+        PTable localIndex = conn1.unwrap(PhoenixConnection.class).getTable(new PTableKey(null, indexTableName));
         assertEquals(IndexType.LOCAL, localIndex.getIndexType());
         assertNotNull(localIndex.getViewIndexId());
     }
-    
+
     @Test
     public void testLocalIndexCreationWithSplitsShouldFail() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, null);
-        Connection conn1 = DriverManager.getConnection(getUrl());
-        Connection conn2 = DriverManager.getConnection(getUrl());
+        createBaseTable(tableName, null, null);
+        Connection conn1 = getConnection();
+        Connection conn2 = getConnection();
         try {
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)"+" split on (1,2,3)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)"+" split on (1,2,3)");
             fail("Local index cannot be pre-split");
         } catch (SQLException e) { }
         try {
-            conn2.createStatement().executeQuery("SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME).next();
-            conn2.unwrap(PhoenixConnection.class).getTable(new PTableKey(null,TestUtil.DEFAULT_INDEX_TABLE_NAME));
+            conn2.createStatement().executeQuery("SELECT * FROM " + tableName).next();
+            conn2.unwrap(PhoenixConnection.class).getTable(new PTableKey(null,indexName));
             fail("Local index should not be created.");
         } catch (TableNotFoundException e) { }
     }
 
     @Test
     public void testLocalIndexCreationWithSaltingShouldFail() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, null);
-        Connection conn1 = DriverManager.getConnection(getUrl());
-        Connection conn2 = DriverManager.getConnection(getUrl());
+        createBaseTable(tableName, null, null);
+        Connection conn1 = getConnection();
+        Connection conn2 = getConnection();
         try {
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)"+" salt_buckets=16");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)"+" salt_buckets=16");
             fail("Local index cannot be salted.");
         } catch (SQLException e) { }
         try {
-            conn2.createStatement().executeQuery("SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME).next();
-            conn2.unwrap(PhoenixConnection.class).getTable(new PTableKey(null,TestUtil.DEFAULT_INDEX_TABLE_NAME));
+            conn2.createStatement().executeQuery("SELECT * FROM " + tableName).next();
+            conn2.unwrap(PhoenixConnection.class).getTable(new PTableKey(null,indexName));
             fail("Local index should not be created.");
         } catch (TableNotFoundException e) { }
     }
 
     @Test
     public void testLocalIndexTableRegionSplitPolicyAndSplitKeys() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null,"('e','i','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
-        Connection conn2 = DriverManager.getConnection(getUrl());
-        conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-        conn2.createStatement().executeQuery("SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME).next();
+        createBaseTable(tableName, null,"('e','i','o')");
+        Connection conn1 = getConnection();
+        Connection conn2 = getConnection();
+        conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+        conn2.createStatement().executeQuery("SELECT * FROM " + tableName).next();
         HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-        HTableDescriptor htd = admin.getTableDescriptor(TableName.valueOf(MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)));
+        HTableDescriptor htd = admin
+                .getTableDescriptor(Bytes.toBytes(indexPhysicalTableName));
         assertEquals(IndexRegionSplitPolicy.class.getName(), htd.getValue(HTableDescriptor.SPLIT_POLICY));
-        try (HTable userTable = new HTable(admin.getConfiguration(),TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME))) {
-            try (HTable indexTable = new HTable(admin.getConfiguration(),TableName.valueOf(MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)))) {
-                assertArrayEquals("Both user table and index table should have same split keys.", userTable.getStartKeys(), indexTable.getStartKeys());
+        try (HTable userTable = new HTable(admin.getConfiguration(),
+                SchemaUtil.getPhysicalTableName(tableName.getBytes(), isNamespaceMapped))) {
+            try (HTable indexTable = new HTable(admin.getConfiguration(), Bytes.toBytes(indexPhysicalTableName))) {
+                assertArrayEquals("Both user table and index table should have same split keys.",
+                        userTable.getStartKeys(), indexTable.getStartKeys());
             }
         }
     }
+    
+    public Connection getConnection() throws SQLException{
+        Properties props = new Properties();
+        props.put(QueryServices.DROP_METADATA_ATTRIB, Boolean.toString(true));
+        props.put(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
+        return DriverManager.getConnection(getUrl(),props);
+    }
 
     @Test
     public void testDropLocalIndexTable() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, null);
-        Connection conn1 = DriverManager.getConnection(getUrl());
-        Connection conn2 = DriverManager.getConnection(getUrl());
-        conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-        conn2.createStatement().executeQuery("SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME).next();
+        createBaseTable(tableName, null, null);
+        Connection conn1 = getConnection();
+        Connection conn2 = getConnection();
+        conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+        conn2.createStatement().executeQuery("SELECT * FROM " + tableName).next();
         HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-        assertTrue("Local index table should be present.", admin.tableExists(TableName.valueOf(MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME))));
-        conn1.createStatement().execute("DROP TABLE "+ TestUtil.DEFAULT_DATA_TABLE_NAME);
+        assertTrue("Local index table should be present.", admin.tableExists(indexPhysicalTableName));
+        conn1.createStatement().execute("DROP TABLE "+ tableName);
         admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-        assertFalse("Local index table should be deleted.", admin.tableExists(TableName.valueOf(MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME))));
+        assertFalse("Local index table should be deleted.", admin.tableExists(indexPhysicalTableName));
         ResultSet rs = conn2.createStatement().executeQuery("SELECT "
                 + PhoenixDatabaseMetaData.SEQUENCE_SCHEMA + ","
                 + PhoenixDatabaseMetaData.SEQUENCE_NAME
@@ -191,19 +230,19 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
     
     @Test
     public void testPutsToLocalIndexTable() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','i','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
-        conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('b',1,2,4,'z')");
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('f',1,2,3,'z')");
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('j',2,4,2,'a')");
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('q',3,1,1,'c')");
+        createBaseTable(tableName, null, "('e','i','o')");
+        Connection conn1 = getConnection();
+        conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('b',1,2,4,'z')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('f',1,2,3,'z')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('j',2,4,2,'a')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('q',3,1,1,'c')");
         conn1.commit();
-        ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + TestUtil.DEFAULT_INDEX_TABLE_NAME);
+        ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + indexTableName);
         assertTrue(rs.next());
         assertEquals(4, rs.getInt(1));
         HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-        HTable indexTable = new HTable(admin.getConfiguration() ,TableName.valueOf(MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)));
+        HTable indexTable = new HTable(admin.getConfiguration(), indexPhysicalTableName);
         Pair<byte[][], byte[][]> startEndKeys = indexTable.getStartEndKeys();
         byte[][] startKeys = startEndKeys.getFirst();
         byte[][] endKeys = startEndKeys.getSecond();
@@ -224,19 +263,19 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
     
     @Test
     public void testBuildIndexWhenUserTableAlreadyHasData() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','i','o')");
+        createBaseTable(tableName, null, "('e','i','o')");
         Connection conn1 = DriverManager.getConnection(getUrl());
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('b',1,2,4,'z')");
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('f',1,2,3,'z')");
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('j',2,4,2,'a')");
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('q',3,1,1,'c')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('b',1,2,4,'z')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('f',1,2,3,'z')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('j',2,4,2,'a')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('q',3,1,1,'c')");
         conn1.commit();
-        conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-        ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + TestUtil.DEFAULT_INDEX_TABLE_NAME);
+        conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+        ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + indexTableName);
         assertTrue(rs.next());
         assertEquals(4, rs.getInt(1));
         HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-        HTable indexTable = new HTable(admin.getConfiguration() ,TableName.valueOf(MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)));
+        HTable indexTable = new HTable(admin.getConfiguration(),Bytes.toBytes(indexPhysicalTableName));
         Pair<byte[][], byte[][]> startEndKeys = indexTable.getStartEndKeys();
         byte[][] startKeys = startEndKeys.getFirst();
         byte[][] endKeys = startEndKeys.getSecond();
@@ -257,30 +296,30 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testLocalIndexScan() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','i','o')");
+        createBaseTable(tableName, null, "('e','i','o')");
         Connection conn1 = DriverManager.getConnection(getUrl());
         try{
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('a',1,2,5,'y')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('b',1,2,4,'z')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('f',1,2,3,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('e',1,2,3,'b')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('j',2,4,2,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('a',1,2,5,'y')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('e',1,2,3,'b')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
             conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
             
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + TestUtil.DEFAULT_INDEX_TABLE_NAME);
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + indexTableName);
             assertTrue(rs.next());
             
             HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-            int numRegions = admin.getTableRegions(TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME)).size();
+            int numRegions = admin.getTableRegions(physicalTableName).size();
             
-            String query = "SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME +" where v1 like 'a%'";
+            String query = "SELECT * FROM " + tableName +" where v1 like 'a%'";
             rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
             
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
-                        + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME) + " [-32768,'a'] - [-32768,'b']\n"
+                        + indexPhysicalTableName + " [-32768,'a'] - [-32768,'b']\n"
                                 + "    SERVER FILTER BY FIRST KEY ONLY\n"
                                 + "CLIENT MERGE SORT",
                         QueryUtil.getExplainPlan(rs));
@@ -299,12 +338,12 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             assertEquals("a", rs.getString("v1"));
             assertEquals(2, rs.getInt("k3"));
             assertFalse(rs.next());
-            query = "SELECT t_id, k1, k2,V1 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME +" where v1='a'";
+            query = "SELECT t_id, k1, k2,V1 FROM " + tableName +" where v1='a'";
             rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
             
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
-                        + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME) + " [-32768,'a']\n"
+                        + indexPhysicalTableName + " [-32768,'a']\n"
                         + "    SERVER FILTER BY FIRST KEY ONLY\n"
                         + "CLIENT MERGE SORT",
                         QueryUtil.getExplainPlan(rs));
@@ -319,14 +358,12 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             assertEquals(2, rs.getInt("k1"));
             assertEquals(4, rs.getInt("k2"));
             assertFalse(rs.next());
-            query = "SELECT t_id, k1, k2,V1, k3 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME +" where v1<='z' order by k3";
+            query = "SELECT t_id, k1, k2,V1, k3 FROM " + tableName +" where v1<='z' order by k3";
             rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
             
-            assertEquals(
-                  "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER " + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME) + " [-32768,*] - [-32768,'z']\n"
-                + "    SERVER FILTER BY FIRST KEY ONLY\n"
-                + "    SERVER SORTED BY [\"K3\"]\n" +
-                "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+            assertEquals("CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER " + indexPhysicalTableName
+                    + " [-32768,*] - [-32768,'z']\n" + "    SERVER FILTER BY FIRST KEY ONLY\n"
+                    + "    SERVER SORTED BY [\"K3\"]\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
  
             rs = conn1.createStatement().executeQuery(query);
             assertTrue(rs.next());
@@ -343,12 +380,12 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             assertEquals(5, rs.getInt("k3"));
             assertFalse(rs.next());
             
-            query = "SELECT t_id, k1, k2,v1 from " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME + " order by V1,t_id";
+            query = "SELECT t_id, k1, k2,v1 from " + tableName + " order by V1,t_id";
             rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
             
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
-                        + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)+" [-32768]\n"
+                        + indexPhysicalTableName +" [-32768]\n"
                         + "    SERVER FILTER BY FIRST KEY ONLY\n"
                         + "CLIENT MERGE SORT",
                 QueryUtil.getExplainPlan(rs));
@@ -391,28 +428,28 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testLocalIndexScanJoinColumnsFromDataTable() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','i','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
+        createBaseTable(tableName, null, "('e','i','o')");
+        Connection conn1 = getConnection();
         try{
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('b',1,2,4,'z')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('f',1,2,3,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('j',2,4,2,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
             conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
             
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + TestUtil.DEFAULT_INDEX_TABLE_NAME);
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + indexTableName);
             assertTrue(rs.next());
             
             HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-            int numRegions = admin.getTableRegions(TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME)).size();
+            int numRegions = admin.getTableRegions(physicalTableName).size();
             
-            String query = "SELECT t_id, k1, k2, k3, V1 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME +" where v1='a'";
+            String query = "SELECT t_id, k1, k2, k3, V1 FROM " + tableName +" where v1='a'";
             rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
             
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
-                        + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME) + " [-32768,'a']\n"
+                        + indexPhysicalTableName + " [-32768,'a']\n"
                                 + "    SERVER FILTER BY FIRST KEY ONLY\n"
                                 + "CLIENT MERGE SORT",
                         QueryUtil.getExplainPlan(rs));
@@ -430,12 +467,12 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             assertEquals(2, rs.getInt("k3"));
             assertFalse(rs.next());
             
-            query = "SELECT t_id, k1, k2, k3, V1 from " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME + "  where v1<='z' order by V1,t_id";
+            query = "SELECT t_id, k1, k2, k3, V1 from " + tableName + "  where v1<='z' order by V1,t_id";
             rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
             
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
-                        + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)+" [-32768,*] - [-32768,'z']\n"
+                        + indexPhysicalTableName +" [-32768,*] - [-32768,'z']\n"
                         + "    SERVER FILTER BY FIRST KEY ONLY\n"
                          + "CLIENT MERGE SORT",
                 QueryUtil.getExplainPlan(rs));
@@ -466,12 +503,12 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             assertEquals(4, rs.getInt("k3"));
             assertEquals("z", rs.getString("V1"));
             
-            query = "SELECT t_id, V1, k3 from " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME + "  where v1 <='z' group by v1,t_id, k3";
+            query = "SELECT t_id, V1, k3 from " + tableName + "  where v1 <='z' group by v1,t_id, k3";
             rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
             
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
-                        + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)+" [-32768,*] - [-32768,'z']\n"
+                        + indexPhysicalTableName +" [-32768,*] - [-32768,'z']\n"
                         + "    SERVER FILTER BY FIRST KEY ONLY\n"
                         + "    SERVER AGGREGATE INTO DISTINCT ROWS BY [\"V1\", \"T_ID\", \"K3\"]\nCLIENT MERGE SORT",
                 QueryUtil.getExplainPlan(rs));
@@ -494,12 +531,12 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             assertEquals(4, rs.getInt("k3"));
             assertEquals("z", rs.getString("V1"));
             
-            query = "SELECT v1,sum(k3) from " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME + " where v1 <='z'  group by v1 order by v1";
+            query = "SELECT v1,sum(k3) from " + tableName + " where v1 <='z'  group by v1 order by v1";
             
             rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
             assertEquals(
                 "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
-                        + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)+" [-32768,*] - [-32768,'z']\n"
+                        + indexPhysicalTableName +" [-32768,*] - [-32768,'z']\n"
                         + "    SERVER FILTER BY FIRST KEY ONLY\n"
                         + "    SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [\"V1\"]\nCLIENT MERGE SORT",
                 QueryUtil.getExplainPlan(rs));
@@ -507,7 +544,7 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             PhoenixStatement stmt = conn1.createStatement().unwrap(PhoenixStatement.class);
             rs = stmt.executeQuery(query);
             QueryPlan plan = stmt.getQueryPlan();
-            assertEquals(TestUtil.DEFAULT_INDEX_TABLE_NAME, plan.getContext().getCurrentTable().getTable().getName().getString());
+            assertEquals(indexTableName, plan.getContext().getCurrentTable().getTable().getName().getString());
             assertEquals(BaseScannerRegionObserver.KEY_ORDERED_GROUP_BY_EXPRESSIONS, plan.getGroupBy().getScanAttribName());
             assertTrue(rs.next());
             assertEquals("a", rs.getString(1));
@@ -525,36 +562,37 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testIndexPlanSelectionIfBothGlobalAndLocalIndexesHasSameColumnsAndOrder() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','i','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('b',1,2,4,'z')");
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('f',1,2,3,'a')");
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('j',2,4,3,'a')");
-        conn1.createStatement().execute("UPSERT INTO "+TestUtil.DEFAULT_DATA_TABLE_NAME+" values('q',3,1,1,'c')");
+        createBaseTable(tableName, null, "('e','i','o')");
+        Connection conn1 = getConnection();
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('b',1,2,4,'z')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('f',1,2,3,'a')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('j',2,4,3,'a')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('q',3,1,1,'c')");
         conn1.commit();
-        conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-        conn1.createStatement().execute("CREATE INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + "2" + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-        String query = "SELECT t_id, k1, k2,V1 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME +" where v1='a'";
+        conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+        conn1.createStatement().execute("CREATE INDEX " + indexName + "2" + " ON " + tableName + "(v1)");
+        String query = "SELECT t_id, k1, k2,V1 FROM " + tableName +" where v1='a'";
         ResultSet rs1 = conn1.createStatement().executeQuery("EXPLAIN "+ query);
-        assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + TestUtil.DEFAULT_INDEX_TABLE_NAME + "2" + " ['a']\n"
-                + "    SERVER FILTER BY FIRST KEY ONLY",QueryUtil.getExplainPlan(rs1));
+        assertEquals("CLIENT PARALLEL 1-WAY RANGE SCAN OVER "
+                + SchemaUtil.getPhysicalTableName(Bytes.toBytes(indexTableName), isNamespaceMapped) + "2" + " ['a']\n"
+                + "    SERVER FILTER BY FIRST KEY ONLY", QueryUtil.getExplainPlan(rs1));
         conn1.close();
     }
 
     @Test
     public void testDropLocalIndexShouldDeleteDataFromLocalIndexTable() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','i','o')");
+        createBaseTable(tableName, null, "('e','i','o')");
         Connection conn1 = DriverManager.getConnection(getUrl());
         try {
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('b',1,2,4,'z')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('f',1,2,3,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('j',2,4,2,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
             conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-            conn1.createStatement().execute("DROP INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME);
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+            conn1.createStatement().execute("DROP INDEX " + indexName + " ON " + tableName);
             HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-            HTable indexTable = new HTable(admin.getConfiguration() ,TableName.valueOf(MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)));
+            HTable indexTable = new HTable(admin.getConfiguration() ,TableName.valueOf(MetaDataUtil.getLocalIndexTableName(tableName)));
             Pair<byte[][], byte[][]> startEndKeys = indexTable.getStartEndKeys();
             byte[][] startKeys = startEndKeys.getFirst();
             byte[][] endKeys = startEndKeys.getSecond();
@@ -579,19 +617,19 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testLocalIndexRowsShouldBeDeletedWhenUserTableRowsDeleted() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','i','o')");
+        createBaseTable(tableName, null, "('e','i','o')");
         Connection conn1 = DriverManager.getConnection(getUrl());
         try {
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('b',1,2,4,'z')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('f',1,2,3,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('j',2,4,2,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
             conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-            conn1.createStatement().execute("DELETE FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME + " where v1='a'");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+            conn1.createStatement().execute("DELETE FROM " + tableName + " where v1='a'");
             conn1.commit();
             conn1 = DriverManager.getConnection(getUrl());
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + TestUtil.DEFAULT_INDEX_TABLE_NAME);
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + indexTableName);
             assertTrue(rs.next());
             assertEquals(2, rs.getInt(1));
         } finally {
@@ -601,19 +639,19 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
     
     @Test
     public void testScanWhenATableHasMultipleLocalIndexes() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','i','o')");
+        createBaseTable(tableName, null, "('e','i','o')");
         Connection conn1 = DriverManager.getConnection(getUrl());
         try {
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('b',1,2,4,'z')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('f',1,2,3,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('j',2,4,2,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
             conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + "2 ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(k3)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + "2 ON " + tableName + "(k3)");
             conn1.commit();
             conn1 = DriverManager.getConnection(getUrl());
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME);
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + tableName);
             assertTrue(rs.next());
             assertEquals(4, rs.getInt(1));
         } finally {
@@ -623,23 +661,23 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testLocalIndexesOnTableWithImmutableRows() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','i','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
+        createBaseTable(tableName, null, "('e','i','o')");
+        Connection conn1 = getConnection();
         try {
-            conn1.createStatement().execute("ALTER TABLE "+ TestUtil.DEFAULT_DATA_TABLE_NAME + " SET IMMUTABLE_ROWS=true");
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-            conn1.createStatement().execute("CREATE INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + "2 ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(k3)");
+            conn1.createStatement().execute("ALTER TABLE "+ tableName + " SET IMMUTABLE_ROWS=true");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+            conn1.createStatement().execute("CREATE INDEX " + indexName + "2 ON " + tableName + "(k3)");
             conn1.commit();
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('b',1,2,4,'z')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('f',1,2,3,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('j',2,4,2,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
             conn1.commit();
             conn1 = DriverManager.getConnection(getUrl());
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME);
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + tableName);
             assertTrue(rs.next());
             assertEquals(4, rs.getInt(1));
-            rs = conn1.createStatement().executeQuery("SELECT v1 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME);
+            rs = conn1.createStatement().executeQuery("SELECT v1 FROM " + tableName);
             assertTrue(rs.next());
             assertEquals("a", rs.getString("v1"));
             assertTrue(rs.next());
@@ -649,7 +687,7 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             assertTrue(rs.next());
             assertEquals("z", rs.getString("v1"));
             assertFalse(rs.next());
-            rs = conn1.createStatement().executeQuery("SELECT k3 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME);
+            rs = conn1.createStatement().executeQuery("SELECT k3 FROM " + tableName);
             assertTrue(rs.next());
             assertEquals(1, rs.getInt("k3"));
             assertTrue(rs.next());
@@ -666,20 +704,20 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testLocalIndexScanWithInList() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','i','o')");
+        createBaseTable(tableName, null, "('e','i','o')");
         Connection conn1 = DriverManager.getConnection(getUrl());
         try{
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('b',1,2,4,'z')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('f',1,2,3,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('j',2,4,2,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('q',3,1,1,'c')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
             conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1) include (k3)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1) include (k3)");
             
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + TestUtil.DEFAULT_INDEX_TABLE_NAME);
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + indexTableName);
             assertTrue(rs.next());
             
-            String query = "SELECT t_id FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME +" where (v1,k3) IN (('z',4),('a',2))";
+            String query = "SELECT t_id FROM " + tableName +" where (v1,k3) IN (('z',4),('a',2))";
             rs = conn1.createStatement().executeQuery(query);
             assertTrue(rs.next());
             assertEquals("j", rs.getString("t_id"));
@@ -711,36 +749,37 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testLocalIndexScanAfterRegionSplit() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','j','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
+        if (isNamespaceMapped) { return; }
+        createBaseTable(tableName, null, "('e','j','o')");
+        Connection conn1 = getConnection();
         try{
             String[] strings = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
             for (int i = 0; i < 26; i++) {
                 conn1.createStatement().execute(
-                    "UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('"+strings[i]+"'," + i + ","
+                    "UPSERT INTO " + tableName + " values('"+strings[i]+"'," + i + ","
                             + (i + 1) + "," + (i + 2) + ",'" + strings[25 - i] + "')");
             }
             conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + "_2 ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(k3)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + "_2 ON " + tableName + "(k3)");
 
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME);
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT * FROM " + tableName);
             assertTrue(rs.next());
             
-            HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+            HBaseAdmin admin = conn1.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
             for (int i = 1; i < 5; i++) {
                 CatalogTracker ct = new CatalogTracker(admin.getConfiguration());
-                admin.split(Bytes.toBytes(TestUtil.DEFAULT_DATA_TABLE_NAME), ByteUtil.concat(Bytes.toBytes(strings[3*i])));
+                admin.split(physicalTableName.getName(), ByteUtil.concat(Bytes.toBytes(strings[3*i])));
                 List<HRegionInfo> regionsOfUserTable =
-                        MetaReader.getTableRegions(ct, TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME), false);
+                        MetaReader.getTableRegions(ct, physicalTableName, false);
 
                 while (regionsOfUserTable.size() != (4+i)) {
                     Thread.sleep(100);
-                    regionsOfUserTable = MetaReader.getTableRegions(ct, TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME), false);
+                    regionsOfUserTable = MetaReader.getTableRegions(ct, physicalTableName, false);
                 }
                 assertEquals(4+i, regionsOfUserTable.size());
                 TableName indexTable =
-                        TableName.valueOf(MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME));
+                        TableName.valueOf(indexPhysicalTableName);
                 List<HRegionInfo> regionsOfIndexTable =
                         MetaReader.getTableRegions(ct, indexTable, false);
 
@@ -749,7 +788,7 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
                     regionsOfIndexTable = MetaReader.getTableRegions(ct, indexTable, false);
                 }
                 assertEquals(4 + i, regionsOfIndexTable.size());
-                String query = "SELECT t_id,k1,v1 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME;
+                String query = "SELECT t_id,k1,v1 FROM " + tableName;
                 rs = conn1.createStatement().executeQuery(query);
                 Thread.sleep(1000);
                 for (int j = 0; j < 26; j++) {
@@ -761,17 +800,17 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
                 rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
                 assertEquals(
                         "CLIENT PARALLEL " + (4 + i) + "-WAY RANGE SCAN OVER "
-                                + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME) + " [-32768]\n"
+                                + indexPhysicalTableName + " [-32768]\n"
                                         + "    SERVER FILTER BY FIRST KEY ONLY\n"
                                 + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
                 
-                query = "SELECT t_id,k1,k3 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME;
+                query = "SELECT t_id,k1,k3 FROM " + tableName;
                 rs = conn1.createStatement().executeQuery("EXPLAIN "+query);
                 assertEquals(
                     "CLIENT PARALLEL "
                             + ((strings[3 * i].compareTo("j") < 0) ? (4 + i) : (4 + i - 1))
                             + "-WAY RANGE SCAN OVER "
-                            + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME) + " [-32767]\n"
+                            + indexPhysicalTableName + " [-32767]\n"
                                     + "    SERVER FILTER BY FIRST KEY ONLY\n"
                             + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
                 rs = conn1.createStatement().executeQuery(query);
@@ -790,25 +829,26 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testLocalIndexScanWithSmallChunks() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, 3, null);
+        createBaseTable(tableName, 3, null);
         Properties props = new Properties();
         props.setProperty(QueryServices.SCAN_RESULT_CHUNK_SIZE, "2");
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
         Connection conn1 = DriverManager.getConnection(getUrl(), props);
         try{
             String[] strings = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
             for (int i = 0; i < 26; i++) {
                conn1.createStatement().execute(
-                    "UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('"+strings[i]+"'," + i + ","
+                    "UPSERT INTO " + tableName + " values('"+strings[i]+"'," + i + ","
                             + (i + 1) + "," + (i + 2) + ",'" + strings[25 - i] + "')");
             }
             conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + "_2 ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(k3)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + "_2 ON " + tableName + "(k3)");
 
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME);
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT * FROM " + tableName);
             assertTrue(rs.next());
 
-            String query = "SELECT t_id,k1,v1 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME;
+            String query = "SELECT t_id,k1,v1 FROM " + tableName;
             rs = conn1.createStatement().executeQuery(query);
             for (int j = 0; j < 26; j++) {
                 assertTrue(rs.next());
@@ -816,7 +856,7 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
                 assertEquals(25 - j, rs.getInt("k1"));
                 assertEquals(strings[j], rs.getString("V1"));
             }
-            query = "SELECT t_id,k1,k3 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME;
+            query = "SELECT t_id,k1,k3 FROM " + tableName;
             rs = conn1.createStatement().executeQuery(query);
             Thread.sleep(1000);
             for (int j = 0; j < 26; j++) {
@@ -832,43 +872,43 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testLocalIndexScanAfterRegionsMerge() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, null, "('e','j','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
+        if (isNamespaceMapped) { return; }
+        createBaseTable(tableName, null, "('e','j','o')");
+        Connection conn1 = getConnection();
         try{
             String[] strings = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
             for (int i = 0; i < 26; i++) {
                 conn1.createStatement().execute(
-                    "UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME + " values('"+strings[i]+"'," + i + ","
+                    "UPSERT INTO " + tableName + " values('"+strings[i]+"'," + i + ","
                             + (i + 1) + "," + (i + 2) + ",'" + strings[25 - i] + "')");
             }
             conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(v1)");
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + "_2 ON " + TestUtil.DEFAULT_DATA_TABLE_NAME + "(k3)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + "_2 ON " + tableName + "(k3)");
 
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME);
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT * FROM " + tableName);
             assertTrue(rs.next());
 
-            HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+            HBaseAdmin admin = conn1.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
             CatalogTracker ct = new CatalogTracker(admin.getConfiguration());
             List<HRegionInfo> regionsOfUserTable =
                     MetaReader.getTableRegions(ct,
-                        TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME), false);
+                            physicalTableName, false);
             admin.mergeRegions(regionsOfUserTable.get(0).getEncodedNameAsBytes(),
                 regionsOfUserTable.get(1).getEncodedNameAsBytes(), false);
             regionsOfUserTable =
                     MetaReader.getTableRegions(ct,
-                        TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME), false);
+                            physicalTableName, false);
 
             while (regionsOfUserTable.size() != 3) {
                 Thread.sleep(100);
                 regionsOfUserTable =
                         MetaReader.getTableRegions(ct,
-                            TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME), false);
+                                physicalTableName, false);
             }
             assertEquals(3, regionsOfUserTable.size());
             TableName indexTable =
-                    TableName.valueOf(MetaDataUtil
-                            .getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME));
+                    TableName.valueOf(indexPhysicalTableName);
             List<HRegionInfo> regionsOfIndexTable =
                     MetaReader.getTableRegions(ct, indexTable, false);
 
@@ -877,7 +917,7 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
                 regionsOfIndexTable = MetaReader.getTableRegions(ct, indexTable, false);
             }
             assertEquals(3, regionsOfIndexTable.size());
-            String query = "SELECT t_id,k1,v1 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME;
+            String query = "SELECT t_id,k1,v1 FROM " + tableName;
             rs = conn1.createStatement().executeQuery(query);
             Thread.sleep(1000);
             for (int j = 0; j < 26; j++) {
@@ -889,15 +929,15 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
             assertEquals(
                 "CLIENT PARALLEL " + 3 + "-WAY RANGE SCAN OVER "
-                        + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)
+                        + indexPhysicalTableName
                         + " [-32768]\n" + "    SERVER FILTER BY FIRST KEY ONLY\n"
                         + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
 
-            query = "SELECT t_id,k1,k3 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME;
+            query = "SELECT t_id,k1,k3 FROM " + tableName;
             rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
             assertEquals(
                 "CLIENT PARALLEL " + 3 + "-WAY RANGE SCAN OVER "
-                        + MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME)
+                        + indexPhysicalTableName
                         + " [-32767]\n" + "    SERVER FILTER BY FIRST KEY ONLY\n"
                         + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
 
@@ -916,31 +956,32 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testLocalIndexStateWhenSplittingInProgress() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME+"2", null, "('e','j','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
+        if (isNamespaceMapped) { return; }
+        createBaseTable(tableName+"2", null, "('e','j','o')");
+        Connection conn1 = getConnection();
         try{
             String[] strings = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
             for (int i = 0; i < 26; i++) {
                 conn1.createStatement().execute(
-                    "UPSERT INTO " + TestUtil.DEFAULT_DATA_TABLE_NAME+"2" + " values('"+strings[i]+"'," + i + ","
+                    "UPSERT INTO " + tableName+"2" + " values('"+strings[i]+"'," + i + ","
                             + (i + 1) + "," + (i + 2) + ",'" + strings[25 - i] + "')");
             }
             conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + TestUtil.DEFAULT_DATA_TABLE_NAME+"2" + "(v1)");
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + "_2 ON " + TestUtil.DEFAULT_DATA_TABLE_NAME+"2" + "(k3)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName+"2" + "(v1)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + "_2 ON " + tableName+"2" + "(k3)");
 
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME+"2");
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT * FROM " + tableName+"2");
             assertTrue(rs.next());
             HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-            HTableDescriptor tableDesc = admin.getTableDescriptor(TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME+"2"));
+            HTableDescriptor tableDesc = admin.getTableDescriptor(SchemaUtil.getPhysicalTableName((tableName+"2").getBytes(),isNamespaceMapped));
             tableDesc.removeCoprocessor(LocalIndexSplitter.class.getName());
             tableDesc.addCoprocessor(MockedLocalIndexSplitter.class.getName(), null,
                 1, null);
             admin.disableTable(tableDesc.getTableName());
             admin.modifyTable(tableDesc.getTableName(), tableDesc);
             admin.enableTable(tableDesc.getTableName());
-            TableName indexTable =
-                    TableName.valueOf(MetaDataUtil.getLocalIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME+"2"));
+            TableName indexTable = TableName.valueOf(MetaDataUtil.getLocalIndexTableName(
+                    SchemaUtil.getPhysicalTableName((tableName + "2").getBytes(), isNamespaceMapped).getNameAsString()));
             HTableDescriptor indexTableDesc = admin.getTableDescriptor(indexTable);
             indexTableDesc.removeCoprocessor(IndexHalfStoreFileReaderGenerator.class.getName());
             indexTableDesc.addCoprocessor(MockedIndexHalfStoreFileReaderGenerator.class.getName(), null,
@@ -949,13 +990,14 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             admin.modifyTable(indexTable, indexTableDesc);
             admin.enableTable(indexTable);
 
-            admin.split(Bytes.toBytes(TestUtil.DEFAULT_DATA_TABLE_NAME+"2"), ByteUtil.concat(Bytes.toBytes(strings[3])));
+            admin.split(SchemaUtil.getPhysicalTableName(Bytes.toBytes(tableName + "2"), isNamespaceMapped).getName(),
+                    ByteUtil.concat(Bytes.toBytes(strings[3])));
             List<HRegionInfo> regionsOfUserTable =
-                    admin.getTableRegions(TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME+"2"));
+                    admin.getTableRegions(SchemaUtil.getPhysicalTableName(Bytes.toBytes(tableName + "2"), isNamespaceMapped));
 
             while (regionsOfUserTable.size() != 5) {
                 Thread.sleep(100);
-                regionsOfUserTable = admin.getTableRegions(TableName.valueOf(TestUtil.DEFAULT_DATA_TABLE_NAME+"2"));
+                regionsOfUserTable = admin.getTableRegions(SchemaUtil.getPhysicalTableName(Bytes.toBytes(tableName + "2"), isNamespaceMapped));
             }
             assertEquals(5, regionsOfUserTable.size());
 
@@ -970,22 +1012,22 @@ public class LocalIndexIT extends BaseHBaseManagedTimeIT {
             boolean success = latch1.await(WAIT_TIME_SECONDS, TimeUnit.SECONDS);
             assertTrue("Timed out waiting for MockedLocalIndexSplitter.preSplitAfterPONR to complete", success);
             // Verify the metadata for index is correct.
-            rs = conn1.getMetaData().getTables(null, StringUtil.escapeLike(TestUtil.DEFAULT_SCHEMA_NAME), TestUtil.DEFAULT_INDEX_TABLE_NAME,
+            rs = conn1.getMetaData().getTables(null, StringUtil.escapeLike(schemaName), indexName,
                     new String[] { PTableType.INDEX.toString() });
             assertTrue(rs.next());
-            assertEquals(TestUtil.DEFAULT_INDEX_TABLE_NAME, rs.getString(3));
+            assertEquals(indexName, rs.getString(3));
             assertEquals(PIndexState.INACTIVE.toString(), rs.getString("INDEX_STATE"));
             assertFalse(rs.next());
-            rs = conn1.getMetaData().getTables(null, StringUtil.escapeLike(TestUtil.DEFAULT_SCHEMA_NAME), TestUtil.DEFAULT_INDEX_TABLE_NAME+"_2",
+            rs = conn1.getMetaData().getTables(null, StringUtil.escapeLike(schemaName), indexName+"_2",
                 new String[] { PTableType.INDEX.toString() });
             assertTrue(rs.next());
-            assertEquals(TestUtil.DEFAULT_INDEX_TABLE_NAME+"_2", rs.getString(3));
+            assertEquals(indexName+"_2", rs.getString(3));
             assertEquals(PIndexState.INACTIVE.toString(), rs.getString("INDEX_STATE"));
             assertFalse(rs.next());
 
-            String query = "SELECT t_id,k1,v1 FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME+"2";
+            String query = "SELECT t_id,k1,v1 FROM " + tableName+"2";
             rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
-            assertEquals("CLIENT PARALLEL " + 1 + "-WAY FULL SCAN OVER " + TestUtil.DEFAULT_DATA_TABLE_NAME+"2",
+            assertEquals("CLIENT PARALLEL " + 1 + "-WAY FULL SCAN OVER " + tableName+"2",
                 QueryUtil.getExplainPlan(rs));
             latch2.countDown();
        } finally {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexFailureIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexFailureIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexFailureIT.java
index ebc6988..7818bcc 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexFailureIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexFailureIT.java
@@ -41,6 +41,7 @@ import org.apache.hadoop.hbase.coprocessor.ObserverContext;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.SimpleRegionObserver;
 import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
+import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.end2end.BaseOwnClusterHBaseManagedTimeIT;
 import org.apache.phoenix.end2end.NeedsOwnMiniClusterTest;
 import org.apache.phoenix.query.QueryServices;
@@ -83,15 +84,19 @@ public class MutableIndexFailureIT extends BaseOwnClusterHBaseManagedTimeIT {
     private final boolean transactional;
     private final boolean localIndex;
     private final String tableDDLOptions;
+    private final boolean isNamespaceMapped;
+    private String schema = "TEST";
 
-    public MutableIndexFailureIT(boolean transactional, boolean localIndex) {
+    public MutableIndexFailureIT(boolean transactional, boolean localIndex, boolean isNamespaceMapped) {
         this.transactional = transactional;
         this.localIndex = localIndex;
         this.tableDDLOptions = transactional ? " TRANSACTIONAL=true " : "";
-        this.tableName = (localIndex ? "L_" : "") + TestUtil.DEFAULT_DATA_TABLE_NAME + (transactional ? "_TXN" : "");
+        this.tableName = (localIndex ? "L_" : "") + TestUtil.DEFAULT_DATA_TABLE_NAME + (transactional ? "_TXN" : "")
+                + (isNamespaceMapped ? "_NM" : "");
         this.indexName = INDEX_NAME;
-        this.fullTableName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, tableName);
-        this.fullIndexName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, indexName);
+        this.fullTableName = SchemaUtil.getTableName(schema, tableName);
+        this.fullIndexName = SchemaUtil.getTableName(schema, indexName);
+        this.isNamespaceMapped = isNamespaceMapped;
     }
 
     @BeforeClass
@@ -108,9 +113,11 @@ public class MutableIndexFailureIT extends BaseOwnClusterHBaseManagedTimeIT {
         setUpTestDriver(new ReadOnlyProps(serverProps.entrySet().iterator()), new ReadOnlyProps(clientProps.entrySet().iterator()));
     }
 
-    @Parameters(name = "transactional = {0}, localIndex = {1}")
+    @Parameters(name = "transactional = {0}, localIndex = {1}, isNamespaceMapped = {2}")
     public static Collection<Boolean[]> data() {
-        return Arrays.asList(new Boolean[][] { { false, false }, { false, true }, { true, false }, { true, true } });
+        return Arrays.asList(new Boolean[][] { { false, false, true }, { false, false, false }, { false, true, true },
+                { false, true, false }, { true, false, true }, { true, true, true }, { true, false, false },
+                { true, true, false } });
     }
 
     @Test
@@ -120,12 +127,16 @@ public class MutableIndexFailureIT extends BaseOwnClusterHBaseManagedTimeIT {
 
     public void helpTestWriteFailureDisablesIndex() throws Exception {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        props.put(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, String.valueOf(isNamespaceMapped));
         try (Connection conn = driver.connect(url, props)) {
             String query;
             ResultSet rs;
             conn.setAutoCommit(false);
-            conn.createStatement().execute(
-                    "CREATE TABLE " + fullTableName + " (k VARCHAR NOT NULL PRIMARY KEY, v1 VARCHAR, v2 VARCHAR) "+tableDDLOptions);
+            if (isNamespaceMapped) {
+                conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schema);
+            }
+            conn.createStatement().execute("CREATE TABLE " + fullTableName
+                    + " (k VARCHAR NOT NULL PRIMARY KEY, v1 VARCHAR, v2 VARCHAR) " + tableDDLOptions);
             query = "SELECT * FROM " + fullTableName;
             rs = conn.createStatement().executeQuery(query);
             assertFalse(rs.next());
@@ -139,7 +150,7 @@ public class MutableIndexFailureIT extends BaseOwnClusterHBaseManagedTimeIT {
             assertFalse(rs.next());
 
             // Verify the metadata for index is correct.
-            rs = conn.getMetaData().getTables(null, StringUtil.escapeLike(TestUtil.DEFAULT_SCHEMA_NAME), indexName,
+            rs = conn.getMetaData().getTables(null, StringUtil.escapeLike(schema), indexName,
                     new String[] { PTableType.INDEX.toString() });
             assertTrue(rs.next());
             assertEquals(indexName, rs.getString(3));
@@ -163,8 +174,8 @@ public class MutableIndexFailureIT extends BaseOwnClusterHBaseManagedTimeIT {
 
             query = "SELECT /*+ NO_INDEX */ k,v1 FROM " + fullTableName;
             rs = conn.createStatement().executeQuery("EXPLAIN " + query);
-            String expectedPlan =
-                    "CLIENT PARALLEL 1-WAY FULL SCAN OVER " + fullTableName;
+            String expectedPlan = "CLIENT PARALLEL 1-WAY FULL SCAN OVER "
+                    + SchemaUtil.getPhysicalTableName(fullTableName.getBytes(), isNamespaceMapped);
             assertEquals(expectedPlan, QueryUtil.getExplainPlan(rs));
             rs = conn.createStatement().executeQuery(query);
             assertTrue(rs.next());
@@ -202,7 +213,7 @@ public class MutableIndexFailureIT extends BaseOwnClusterHBaseManagedTimeIT {
             }
 
             // Verify the metadata for index is correct.
-            rs = conn.getMetaData().getTables(null, StringUtil.escapeLike(TestUtil.DEFAULT_SCHEMA_NAME), indexName,
+            rs = conn.getMetaData().getTables(null, StringUtil.escapeLike(schema), indexName,
                     new String[] { PTableType.INDEX.toString() });
             assertTrue(rs.next());
             assertEquals(indexName, rs.getString(3));
@@ -230,8 +241,8 @@ public class MutableIndexFailureIT extends BaseOwnClusterHBaseManagedTimeIT {
                 // Verify previous writes succeeded to data table
                 query = "SELECT /*+ NO_INDEX */ k,v1 FROM " + fullTableName;
                 rs = conn.createStatement().executeQuery("EXPLAIN " + query);
-                expectedPlan =
-                        "CLIENT PARALLEL 1-WAY FULL SCAN OVER " + fullTableName;
+                expectedPlan = "CLIENT PARALLEL 1-WAY FULL SCAN OVER "
+                        + SchemaUtil.getPhysicalTableName(fullTableName.getBytes(), isNamespaceMapped);
                 assertEquals(expectedPlan, QueryUtil.getExplainPlan(rs));
                 rs = conn.createStatement().executeQuery(query);
                 assertTrue(rs.next());
@@ -257,7 +268,7 @@ public class MutableIndexFailureIT extends BaseOwnClusterHBaseManagedTimeIT {
                 int maxTries = 3, nTries = 0;
                 do {
                     Thread.sleep(15 * 1000); // sleep 15 secs
-                    rs = conn.getMetaData().getTables(null, StringUtil.escapeLike(TestUtil.DEFAULT_SCHEMA_NAME), indexName,
+                    rs = conn.getMetaData().getTables(null, StringUtil.escapeLike(schema), indexName,
                             new String[] { PTableType.INDEX.toString() });
                     assertTrue(rs.next());
                     if(PIndexState.ACTIVE.toString().equals(rs.getString("INDEX_STATE"))){
@@ -279,8 +290,11 @@ public class MutableIndexFailureIT extends BaseOwnClusterHBaseManagedTimeIT {
             // verify index table has correct data
             query = "SELECT /*+ INDEX(" + indexName + ") */ k,v1 FROM " + fullTableName;
             rs = conn.createStatement().executeQuery("EXPLAIN " + query);
-            expectedPlan =
-                    " OVER " + (localIndex ? MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + tableName : fullIndexName);
+            expectedPlan = " OVER "
+                    + (localIndex
+                            ? Bytes.toString(MetaDataUtil.getLocalIndexPhysicalName(SchemaUtil
+                                    .getPhysicalTableName(fullTableName.getBytes(), isNamespaceMapped).getName()))
+                            : SchemaUtil.getPhysicalTableName(fullIndexName.getBytes(), isNamespaceMapped).getNameAsString());
             String explainPlan = QueryUtil.getExplainPlan(rs);
             assertTrue(explainPlan.contains(expectedPlan));
             rs = conn.createStatement().executeQuery(query);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
index 34094d5..450cffa 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/ViewIndexIT.java
@@ -26,6 +26,8 @@ import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Map;
 import java.util.Properties;
 
@@ -38,16 +40,26 @@ import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.util.MetaDataUtil;
 import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.TestUtil;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
 import com.google.common.collect.Maps;
 
-
+@RunWith(Parameterized.class)
 public class ViewIndexIT extends BaseHBaseManagedTimeIT {
 
     private String VIEW_NAME = "MY_VIEW";
+    private String schemaName="TEST";
+    private boolean isNamespaceMapped;
+    private String tableName = schemaName + ".T";
+    private String indexName = "I";
+    private String viewIndexPhysicalTableName;
+    private TableName physicalTableName;
 
     @BeforeClass
     @Shadower(classBeingShadowed = BaseHBaseManagedTimeIT.class)
@@ -59,8 +71,17 @@ public class ViewIndexIT extends BaseHBaseManagedTimeIT {
         setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
     }
 
-    private void createBaseTable(String tableName, boolean multiTenant, Integer saltBuckets, String splits) throws SQLException {
-        Connection conn = DriverManager.getConnection(getUrl());
+    @Parameters(name = "isNamespaceMapped = {0}")
+    public static Collection<Boolean> data() {
+        return Arrays.asList(true, false);
+    }
+
+    private void createBaseTable(String tableName, boolean multiTenant, Integer saltBuckets, String splits)
+            throws SQLException {
+        Connection conn = getConnection();
+        if (isNamespaceMapped) {
+            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName);
+        }
         String ddl = "CREATE TABLE " + tableName + " (t_id VARCHAR NOT NULL,\n" +
                 "k1 VARCHAR NOT NULL,\n" +
                 "k2 INTEGER NOT NULL,\n" +
@@ -81,20 +102,34 @@ public class ViewIndexIT extends BaseHBaseManagedTimeIT {
         conn.createStatement().execute(ddl + ddlOptions);
         conn.close();
     }
+    
+    public Connection getConnection() throws SQLException{
+        Properties props = new Properties();
+        props.put(QueryServices.DROP_METADATA_ATTRIB, Boolean.toString(true));
+        props.put(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
+        return DriverManager.getConnection(getUrl(),props);
+    }
+    
+    public ViewIndexIT(boolean isNamespaceMapped) {
+        this.isNamespaceMapped = isNamespaceMapped;
+        this.physicalTableName = SchemaUtil.getPhysicalTableName(tableName.getBytes(), isNamespaceMapped);
+        this.viewIndexPhysicalTableName = MetaDataUtil.getLocalIndexTableName(physicalTableName.getNameAsString());
+    }
+
 
     @Test
     public void testDeleteViewIndexSequences() throws Exception {
-        createBaseTable(TestUtil.DEFAULT_DATA_TABLE_NAME, false, null, null);
-        Connection conn1 = DriverManager.getConnection(getUrl());
-        Connection conn2 = DriverManager.getConnection(getUrl());
-        conn1.createStatement().execute("CREATE VIEW " + VIEW_NAME + " AS SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_NAME);
-        conn1.createStatement().execute("CREATE INDEX " + TestUtil.DEFAULT_INDEX_TABLE_NAME + " ON " + VIEW_NAME + " (v1)");
-        conn2.createStatement().executeQuery("SELECT * FROM " + TestUtil.DEFAULT_DATA_TABLE_FULL_NAME).next();
+        createBaseTable(tableName, false, null, null);
+        Connection conn1 = getConnection();
+        Connection conn2 = getConnection();
+        conn1.createStatement().execute("CREATE VIEW " + VIEW_NAME + " AS SELECT * FROM " + tableName);
+        conn1.createStatement().execute("CREATE INDEX " + indexName + " ON " + VIEW_NAME + " (v1)");
+        conn2.createStatement().executeQuery("SELECT * FROM " + tableName).next();
         HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
         conn1.createStatement().execute("DROP VIEW " + VIEW_NAME);
-        conn1.createStatement().execute("DROP TABLE "+ TestUtil.DEFAULT_DATA_TABLE_NAME);
+        conn1.createStatement().execute("DROP TABLE "+ tableName);
         admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-        assertFalse("View index table should be deleted.", admin.tableExists(TableName.valueOf(MetaDataUtil.getViewIndexTableName(TestUtil.DEFAULT_DATA_TABLE_NAME))));
+        assertFalse("View index table should be deleted.", admin.tableExists(TableName.valueOf(viewIndexPhysicalTableName)));
         ResultSet rs = conn2.createStatement().executeQuery("SELECT "
                 + PhoenixDatabaseMetaData.SEQUENCE_SCHEMA + ","
                 + PhoenixDatabaseMetaData.SEQUENCE_NAME

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/it/java/org/apache/phoenix/tx/TxCheckpointIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/tx/TxCheckpointIT.java b/phoenix-core/src/it/java/org/apache/phoenix/tx/TxCheckpointIT.java
index e9ba592..c7fc053 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/tx/TxCheckpointIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/tx/TxCheckpointIT.java
@@ -37,6 +37,7 @@ import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
 import org.apache.phoenix.end2end.Shadower;
 import org.apache.phoenix.execute.MutationState;
 import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.query.BaseTest;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.ReadOnlyProps;
@@ -48,10 +49,10 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
-import co.cask.tephra.Transaction.VisibilityLevel;
-
 import com.google.common.collect.Maps;
 
+import co.cask.tephra.Transaction.VisibilityLevel;
+
 @RunWith(Parameterized.class)
 public class TxCheckpointIT extends BaseHBaseManagedTimeIT {
 	

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/antlr3/PhoenixSQL.g
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/antlr3/PhoenixSQL.g b/phoenix-core/src/main/antlr3/PhoenixSQL.g
index a042090..99f8029 100644
--- a/phoenix-core/src/main/antlr3/PhoenixSQL.g
+++ b/phoenix-core/src/main/antlr3/PhoenixSQL.g
@@ -71,6 +71,7 @@ tokens
     ALTER='alter';
     COLUMN='column';
     TABLE='table';
+    SCHEMA='schema';
     ADD='add';
     SPLIT='split';
     EXPLAIN='explain';
@@ -125,6 +126,7 @@ tokens
     LIST = 'list';
     JARS='jars';
     ROW_TIMESTAMP='row_timestamp';
+    USE='use';
     OFFSET ='offset';
     FETCH = 'fetch';
     ROW = 'row';
@@ -397,6 +399,7 @@ oneStatement returns [BindableStatement ret]
     |	s=upsert_node
     |   s=delete_node
     |   s=create_table_node
+    |   s=create_schema_node
     |   s=create_view_node
     |   s=create_index_node
     |   s=drop_table_node
@@ -411,6 +414,8 @@ oneStatement returns [BindableStatement ret]
     |   s=delete_jar_node
     |	s=create_sequence_node
     |	s=drop_sequence_node
+    |	s=drop_schema_node
+    |	s=use_schema_node
     |   s=update_statistics_node
     |   s=explain_node) { $ret = s; }
     ;
@@ -428,6 +433,12 @@ create_table_node returns [CreateTableStatement ret]
         (SPLIT ON s=value_expression_list)?
         {ret = factory.createTable(t, p, c, pk, s, PTableType.TABLE, ex!=null, null, null, getBindCount()); }
     ;
+   
+// Parse a create schema statement.
+create_schema_node returns [CreateSchemaStatement ret]
+    :   CREATE SCHEMA (IF NOT ex=EXISTS)? s=identifier
+        {ret = factory.createSchema(s, ex!=null); }
+    ;
 
 // Parse a create view statement.
 create_view_node returns [CreateTableStatement ret]
@@ -533,6 +544,12 @@ drop_table_node returns [DropTableStatement ret]
         {ret = factory.dropTable(t, v==null ? (QueryConstants.SYSTEM_SCHEMA_NAME.equals(t.getSchemaName()) ? PTableType.SYSTEM : PTableType.TABLE) : PTableType.VIEW, ex!=null, c!=null); }
     ;
 
+drop_schema_node returns [DropSchemaStatement ret]
+    :   DROP SCHEMA (IF ex=EXISTS)? s=identifier (c=CASCADE)?
+        {ret = factory.dropSchema(s, ex!=null, c!=null); }
+    ;
+
+
 // Parse a drop index statement
 drop_index_node returns [DropIndexStatement ret]
     : DROP INDEX (IF ex=EXISTS)? i=index_name ON t=from_table_name
@@ -869,6 +886,11 @@ multiply_divide_modulo_expression returns [ParseNode ret]
         { $ret = lhs; }
     ;
 
+use_schema_node returns [UseSchemaStatement ret]
+	:   USE s=identifier
+        {ret = factory.useSchema(s); }
+    ;
+
 negate_expression returns [ParseNode ret]
     :   m=MINUS? e=array_expression { $ret = m==null ? e : factory.negate(e); }
     ;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/MetadataRpcController.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/MetadataRpcController.java b/phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/MetadataRpcController.java
index ab463e9..df833f9 100644
--- a/phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/MetadataRpcController.java
+++ b/phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/MetadataRpcController.java
@@ -25,6 +25,7 @@ import org.apache.hadoop.hbase.ipc.DelegatingPayloadCarryingRpcController;
 import org.apache.hadoop.hbase.ipc.PayloadCarryingRpcController;
 import org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.util.SchemaUtil;
 
 import com.google.common.collect.ImmutableList;
 
@@ -36,7 +37,16 @@ class MetadataRpcController extends DelegatingPayloadCarryingRpcController {
 			.add(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME)
 			.add(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME)
 			.add(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME)
-			.add(PhoenixDatabaseMetaData.SYSTEM_FUNCTION_NAME).build();
+			.add(PhoenixDatabaseMetaData.SYSTEM_FUNCTION_NAME)
+            .add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES, true)
+                    .getNameAsString())
+            .add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME_BYTES, true)
+                    .getNameAsString())
+            .add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES, true)
+                    .getNameAsString())
+            .add(SchemaUtil.getPhysicalTableName(PhoenixDatabaseMetaData.SYSTEM_FUNCTION_NAME_BYTES, true)
+                    .getNameAsString())
+            .build();
 
 	public MetadataRpcController(PayloadCarryingRpcController delegate,
 			Configuration conf) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/compile/ColumnResolver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ColumnResolver.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ColumnResolver.java
index 55253ea..6c91123 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ColumnResolver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ColumnResolver.java
@@ -20,7 +20,12 @@ package org.apache.phoenix.compile;
 import java.sql.SQLException;
 import java.util.List;
 
+import org.apache.hadoop.hbase.TableNotFoundException;
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
+import org.apache.phoenix.schema.AmbiguousColumnException;
+import org.apache.phoenix.schema.AmbiguousTableException;
+import org.apache.phoenix.schema.ColumnNotFoundException;
 import org.apache.phoenix.schema.ColumnRef;
 import org.apache.phoenix.schema.TableRef;
 
@@ -77,4 +82,9 @@ public interface ColumnResolver {
     public PFunction resolveFunction(String functionName) throws SQLException;
 
     public boolean hasUDFs();
+
+    public PSchema resolveSchema(String schemaName) throws SQLException;
+
+    public List<PSchema> getSchemas();
+
 }


[04/52] [abbrv] phoenix git commit: PHOENIX-2828 Ordinality should be 1-based in UNNEST WITH ORDINALITY

Posted by sa...@apache.org.
PHOENIX-2828 Ordinality should be 1-based in UNNEST WITH ORDINALITY


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

Branch: refs/heads/encodecolumns
Commit: caea1a514d804c70ceac158ccb33956c7090f81a
Parents: f65d048
Author: maryannxue <ma...@gmail.com>
Authored: Fri Apr 8 11:50:49 2016 -0400
Committer: maryannxue <ma...@gmail.com>
Committed: Fri Apr 8 11:50:49 2016 -0400

----------------------------------------------------------------------
 .../src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java  | 2 +-
 .../test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/caea1a51/phoenix-core/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java
index c8fef3f..8905eef 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java
@@ -170,7 +170,7 @@ public class UnnestArrayPlan extends DelegateQueryPlan {
         @Override
         public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
             byte[] lengthBuf = new byte[PInteger.INSTANCE.getByteSize()];
-            PInteger.INSTANCE.getCodec().encodeInt(index, lengthBuf, 0);
+            PInteger.INSTANCE.getCodec().encodeInt(index + 1, lengthBuf, 0);
             ptr.set(lengthBuf);
             return true;
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/caea1a51/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
index 51b8868..50e2721 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
@@ -143,7 +143,7 @@ public class UnnestArrayPlanTest {
         List<Object[]> ret = Lists.newArrayList();
         for (Object[] array : arrays) {
             for (int i = 0; i < array.length; i++) {
-                ret.add(new Object[] {array[i], i});
+                ret.add(new Object[] {array[i], i + 1});
             }
         }
         return ret;


[32/52] [abbrv] phoenix git commit: PHOENIX-2743 HivePhoenixHandler for big-big join with

Posted by sa...@apache.org.
PHOENIX-2743 HivePhoenixHandler for big-big join with

Signed-off-by: Josh Elser <el...@apache.org>


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

Branch: refs/heads/encodecolumns
Commit: 521b8192806e6df3196fcf1b1eb933e33decbee7
Parents: 87f47b8
Author: Sergey Soldatov <se...@gmail.com>
Authored: Mon Apr 18 23:36:36 2016 -0700
Committer: Josh Elser <el...@apache.org>
Committed: Tue Apr 19 21:18:56 2016 -0400

----------------------------------------------------------------------
 phoenix-hive/pom.xml                            |  158 +++
 .../apache/phoenix/hive/HivePhoenixStoreIT.java |  303 ++++
 .../org/apache/phoenix/hive/HiveTestUtil.java   | 1291 ++++++++++++++++++
 .../apache/phoenix/hive/PhoenixMetaHook.java    |  246 ++++
 .../phoenix/hive/PhoenixRecordUpdater.java      |  336 +++++
 .../org/apache/phoenix/hive/PhoenixRow.java     |   64 +
 .../org/apache/phoenix/hive/PhoenixRowKey.java  |   69 +
 .../org/apache/phoenix/hive/PhoenixSerDe.java   |  159 +++
 .../apache/phoenix/hive/PhoenixSerializer.java  |  169 +++
 .../phoenix/hive/PhoenixStorageHandler.java     |  212 +++
 .../PhoenixStorageHandlerConstants.java         |  108 ++
 .../hive/mapreduce/PhoenixInputFormat.java      |  269 ++++
 .../hive/mapreduce/PhoenixInputSplit.java       |  160 +++
 .../hive/mapreduce/PhoenixOutputFormat.java     |  112 ++
 .../hive/mapreduce/PhoenixRecordReader.java     |  216 +++
 .../hive/mapreduce/PhoenixRecordWriter.java     |  355 +++++
 .../hive/mapreduce/PhoenixResultWritable.java   |  211 +++
 .../AbstractPhoenixObjectInspector.java         |   59 +
 .../PhoenixBinaryObjectInspector.java           |   58 +
 .../PhoenixBooleanObjectInspector.java          |   50 +
 .../PhoenixByteObjectInspector.java             |   54 +
 .../PhoenixCharObjectInspector.java             |   51 +
 .../PhoenixDateObjectInspector.java             |   63 +
 .../PhoenixDecimalObjectInspector.java          |   63 +
 .../PhoenixDoubleObjectInspector.java           |   54 +
 .../PhoenixFloatObjectInspector.java            |   55 +
 .../PhoenixIntObjectInspector.java              |   51 +
 .../PhoenixListObjectInspector.java             |  105 ++
 .../PhoenixLongObjectInspector.java             |   51 +
 .../PhoenixObjectInspectorFactory.java          |  148 ++
 .../PhoenixShortObjectInspector.java            |   51 +
 .../PhoenixStringObjectInspector.java           |   72 +
 .../PhoenixTimestampObjectInspector.java        |   61 +
 .../hive/ppd/PhoenixPredicateDecomposer.java    |   82 ++
 .../ppd/PhoenixPredicateDecomposerManager.java  |   83 ++
 .../hive/ql/index/IndexPredicateAnalyzer.java   |  523 +++++++
 .../hive/ql/index/IndexSearchCondition.java     |  143 ++
 .../hive/ql/index/PredicateAnalyzerFactory.java |   40 +
 .../phoenix/hive/query/PhoenixQueryBuilder.java |  760 +++++++++++
 .../hive/util/PhoenixConnectionUtil.java        |   97 ++
 .../hive/util/PhoenixStorageHandlerUtil.java    |  278 ++++
 .../apache/phoenix/hive/util/PhoenixUtil.java   |  210 +++
 phoenix-server/pom.xml                          |    6 +
 pom.xml                                         |   39 +-
 44 files changed, 7743 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/pom.xml
----------------------------------------------------------------------
diff --git a/phoenix-hive/pom.xml b/phoenix-hive/pom.xml
new file mode 100644
index 0000000..f815b56
--- /dev/null
+++ b/phoenix-hive/pom.xml
@@ -0,0 +1,158 @@
+<?xml version='1.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.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.phoenix</groupId>
+    <artifactId>phoenix</artifactId>
+    <version>4.8.0-HBase-0.98-SNAPSHOT</version>
+  </parent>
+  <artifactId>phoenix-hive</artifactId>
+  <name>Phoenix - Hive</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.phoenix</groupId>
+      <artifactId>phoenix-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hive</groupId>
+      <artifactId>hive-cli</artifactId>
+      <version>${hive.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hive</groupId>
+      <artifactId>hive-exec</artifactId>
+      <version>${hive.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-mapreduce-client-core</artifactId>
+    </dependency>
+
+    <!-- Test dependencies -->
+    <dependency>
+      <groupId>org.apache.phoenix</groupId>
+      <artifactId>phoenix-core</artifactId>
+      <classifier>tests</classifier>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-testing-util</artifactId>
+      <scope>test</scope>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hbase</groupId>
+      <artifactId>hbase-it</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-hdfs</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-hdfs</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-auth</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-mapreduce-client-common</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-minicluster</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-failsafe-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>${maven-dependency-plugin.version}</version>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <configuration>
+          <descriptorRefs>
+            <descriptorRef>jar-with-dependencies</descriptorRef>
+          </descriptorRefs>
+        </configuration>
+        <executions>
+          <execution>
+            <id>make-jar-with-dependencies</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/it/java/org/apache/phoenix/hive/HivePhoenixStoreIT.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/it/java/org/apache/phoenix/hive/HivePhoenixStoreIT.java b/phoenix-hive/src/it/java/org/apache/phoenix/hive/HivePhoenixStoreIT.java
new file mode 100644
index 0000000..a707a06
--- /dev/null
+++ b/phoenix-hive/src/it/java/org/apache/phoenix/hive/HivePhoenixStoreIT.java
@@ -0,0 +1,303 @@
+/*
+ * 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.phoenix.hive;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.phoenix.end2end.NeedsOwnMiniClusterTest;
+import org.apache.phoenix.jdbc.PhoenixDriver;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.StringUtil;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Properties;
+
+import static org.apache.phoenix.query.BaseTest.setUpConfigForMiniCluster;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Test class to run all Hive Phoenix integration tests against a MINI Map-Reduce cluster.
+ */
+@Category(NeedsOwnMiniClusterTest.class)
+public class HivePhoenixStoreIT {
+
+    private static final Log LOG = LogFactory.getLog(HivePhoenixStoreIT.class);
+    private static HBaseTestingUtility hbaseTestUtil;
+    private static String zkQuorum;
+    private static Connection conn;
+    private static Configuration conf;
+    private static HiveTestUtil qt;
+    private static String hiveOutputDir;
+    private static String hiveLogDir;
+
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        String hadoopConfDir = System.getenv("HADOOP_CONF_DIR");
+        if (null != hadoopConfDir && !hadoopConfDir.isEmpty()) {
+          LOG.warn("WARNING: HADOOP_CONF_DIR is set in the environment which may cause "
+              + "issues with test execution via MiniDFSCluster");
+        }
+        hbaseTestUtil = new HBaseTestingUtility();
+        conf = hbaseTestUtil.getConfiguration();
+        setUpConfigForMiniCluster(conf);
+        conf.set(QueryServices.DROP_METADATA_ATTRIB, Boolean.toString(true));
+        hiveOutputDir = new Path(hbaseTestUtil.getDataTestDir(), "hive_output").toString();
+        File outputDir = new File(hiveOutputDir);
+        outputDir.mkdirs();
+        hiveLogDir = new Path(hbaseTestUtil.getDataTestDir(), "hive_log").toString();
+        File logDir = new File(hiveLogDir);
+        logDir.mkdirs();
+        // Setup Hive mini Server
+        Path testRoot = hbaseTestUtil.getDataTestDir();
+        System.setProperty("test.tmp.dir", testRoot.toString());
+        System.setProperty("test.warehouse.dir", (new Path(testRoot, "warehouse")).toString());
+
+        HiveTestUtil.MiniClusterType miniMR = HiveTestUtil.MiniClusterType.mr;
+        try {
+            qt = new HiveTestUtil(hiveOutputDir, hiveLogDir, miniMR, null);
+        } catch (Exception e) {
+            LOG.error("Unexpected exception in setup", e);
+            fail("Unexpected exception in setup");
+        }
+
+        //Start HBase cluster
+        hbaseTestUtil.startMiniCluster(3);
+        MiniDFSCluster x = hbaseTestUtil.getDFSCluster();
+
+        Class.forName(PhoenixDriver.class.getName());
+        zkQuorum = "localhost:" + hbaseTestUtil.getZkCluster().getClientPort();
+        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
+        props.put(QueryServices.DROP_METADATA_ATTRIB, Boolean.toString(true));
+        conn = DriverManager.getConnection(PhoenixRuntime.JDBC_PROTOCOL +
+                PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + zkQuorum, props);
+        // Setup Hive Output Folder
+
+        Statement stmt = conn.createStatement();
+        stmt.execute("create table t(a integer primary key,b varchar)");
+    }
+
+    /**
+     * Create a table with two column, insert 1 row, check that phoenix table is created and
+     * the row is there
+     *
+     * @throws Exception
+     */
+    @Test
+    public void simpleTest() throws Exception {
+        String testName = "simpleTest";
+        // create a dummy outfile under log folder
+        hbaseTestUtil.getTestFileSystem().createNewFile(new Path(hiveLogDir, testName + ".out"));
+        createFile(StringUtil.EMPTY_STRING, new Path(hiveLogDir, testName + ".out").toString());
+        createFile(StringUtil.EMPTY_STRING, new Path(hiveOutputDir, testName + ".out").toString());
+        StringBuilder sb = new StringBuilder();
+        sb.append("CREATE TABLE phoenix_table(ID STRING, SALARY STRING)" + HiveTestUtil.CRLF +
+                " STORED BY  \"org.apache.phoenix.hive.PhoenixStorageHandler\"" + HiveTestUtil
+                .CRLF + " TBLPROPERTIES(" + HiveTestUtil.CRLF +
+                "   'phoenix.table.name'='phoenix_table'," + HiveTestUtil.CRLF +
+                "   'phoenix.zookeeper.znode.parent'='hbase'," + HiveTestUtil.CRLF +
+                "   'phoenix.zookeeper.quorum'='localhost:" + hbaseTestUtil.getZkCluster()
+                .getClientPort() + "', 'phoenix.rowkeys'='id');");
+        sb.append("INSERT INTO TABLE phoenix_table" + HiveTestUtil.CRLF +
+                "VALUES ('10', '1000');" + HiveTestUtil.CRLF);
+        String fullPath = new Path(hbaseTestUtil.getDataTestDir(), testName).toString();
+        createFile(sb.toString(), fullPath);
+        runTest(testName, fullPath);
+
+        String phoenixQuery = "SELECT * FROM phoenix_table";
+        PreparedStatement statement = conn.prepareStatement(phoenixQuery);
+        ResultSet rs = statement.executeQuery();
+        assert (rs.getMetaData().getColumnCount() == 2);
+        assertTrue(rs.next());
+        assert (rs.getString(1).equals("10"));
+        assert (rs.getString(2).equals("1000"));
+
+    }
+
+    /**
+     * Datatype Test
+     *
+     * @throws Exception
+     */
+    @Test
+    public void dataTypeTest() throws Exception {
+        String testName = "dataTypeTest";
+        // create a dummy outfile under log folder
+        hbaseTestUtil.getTestFileSystem().createNewFile(new Path(hiveLogDir, testName + ".out"));
+        createFile(StringUtil.EMPTY_STRING, new Path(hiveLogDir, testName + ".out").toString());
+        createFile(StringUtil.EMPTY_STRING, new Path(hiveOutputDir, testName + ".out").toString());
+        StringBuilder sb = new StringBuilder();
+        sb.append("CREATE TABLE phoenix_datatype(ID int, description STRING, ts TIMESTAMP, db " +
+                "DOUBLE,fl FLOAT, us INT)" + HiveTestUtil.CRLF +
+                " STORED BY  \"org.apache.phoenix.hive.PhoenixStorageHandler\"" + HiveTestUtil
+                .CRLF + " TBLPROPERTIES(" + HiveTestUtil.CRLF +
+                "   'phoenix.hbase.table.name'='phoenix_datatype'," + HiveTestUtil.CRLF +
+                "   'phoenix.zookeeper.znode.parent'='hbase'," + HiveTestUtil.CRLF +
+                "   'phoenix.zookeeper.quorum'='localhost:" + hbaseTestUtil.getZkCluster()
+                .getClientPort() + "'," + HiveTestUtil.CRLF +
+                "   'phoenix.rowkeys'='id');");
+        sb.append("INSERT INTO TABLE phoenix_datatype" + HiveTestUtil.CRLF +
+                "VALUES (10, \"foodesc\",\"2013-01-05 01:01:01\",200,2.0,-1);" + HiveTestUtil.CRLF);
+        String fullPath = new Path(hbaseTestUtil.getDataTestDir(), testName).toString();
+        createFile(sb.toString(), fullPath);
+        runTest(testName, fullPath);
+
+        String phoenixQuery = "SELECT * FROM phoenix_datatype";
+        PreparedStatement statement = conn.prepareStatement(phoenixQuery);
+        ResultSet rs = statement.executeQuery();
+        assert (rs.getMetaData().getColumnCount() == 6);
+        while (rs.next()) {
+            assert (rs.getInt(1) == 10);
+            assert (rs.getString(2).equalsIgnoreCase("foodesc"));
+            /* Need a way how to correctly handle timestamp since Hive's implementation uses
+            time zone information but Phoenix doesn't.
+             */
+            //assert(rs.getTimestamp(3).equals(Timestamp.valueOf("2013-01-05 02:01:01")));
+            assert (rs.getDouble(4) == 200);
+            assert (rs.getFloat(5) == 2.0);
+            assert (rs.getInt(6) == -1);
+        }
+    }
+
+    /**
+     * Datatype Test
+     *
+     * @throws Exception
+     */
+    @Test
+    public void MultiKey() throws Exception {
+        String testName = "MultiKey";
+        // create a dummy outfile under log folder
+        hbaseTestUtil.getTestFileSystem().createNewFile(new Path(hiveLogDir, testName + ".out"));
+        createFile(StringUtil.EMPTY_STRING, new Path(hiveLogDir, testName + ".out").toString());
+        createFile(StringUtil.EMPTY_STRING, new Path(hiveOutputDir, testName + ".out").toString());
+        StringBuilder sb = new StringBuilder();
+        sb.append("CREATE TABLE phoenix_MultiKey(ID int, ID2 String,description STRING, ts " +
+                "TIMESTAMP, db DOUBLE,fl FLOAT, us INT)" + HiveTestUtil.CRLF +
+                " STORED BY  \"org.apache.phoenix.hive.PhoenixStorageHandler\"" + HiveTestUtil
+                .CRLF +
+                " TBLPROPERTIES(" + HiveTestUtil.CRLF +
+                "   'phoenix.hbase.table.name'='phoenix_MultiKey'," + HiveTestUtil.CRLF +
+                "   'phoenix.zookeeper.znode.parent'='hbase'," + HiveTestUtil.CRLF +
+                "   'phoenix.zookeeper.quorum'='localhost:" + hbaseTestUtil.getZkCluster()
+                .getClientPort() + "'," + HiveTestUtil.CRLF +
+                "   'phoenix.rowkeys'='id,id2');");
+        sb.append("INSERT INTO TABLE phoenix_MultiKey" + HiveTestUtil.CRLF +
+                "VALUES (10,  \"part2\",\"foodesc\",\"2013-01-05 01:01:01\",200,2.0,-1);" +
+                HiveTestUtil.CRLF);
+        String fullPath = new Path(hbaseTestUtil.getDataTestDir(), testName).toString();
+        createFile(sb.toString(), fullPath);
+        runTest(testName, fullPath);
+
+        String phoenixQuery = "SELECT * FROM phoenix_MultiKey";
+        PreparedStatement statement = conn.prepareStatement(phoenixQuery);
+        ResultSet rs = statement.executeQuery();
+        assert (rs.getMetaData().getColumnCount() == 7);
+        while (rs.next()) {
+            assert (rs.getInt(1) == 10);
+            assert (rs.getString(2).equalsIgnoreCase("part2"));
+            assert (rs.getString(3).equalsIgnoreCase("foodesc"));
+            //assert(rs.getTimestamp(4).equals(Timestamp.valueOf("2013-01-05 02:01:01")));
+            assert (rs.getDouble(5) == 200);
+            assert (rs.getFloat(6) == 2.0);
+            assert (rs.getInt(7) == -1);
+        }
+    }
+
+
+    private void runTest(String fname, String fpath) throws Exception {
+        long startTime = System.currentTimeMillis();
+        try {
+            LOG.info("Begin query: " + fname);
+            qt.addFile(fpath);
+
+            if (qt.shouldBeSkipped(fname)) {
+                LOG.info("Test " + fname + " skipped");
+                return;
+            }
+
+            qt.cliInit(fname);
+            qt.clearTestSideEffects();
+            int ecode = qt.executeClient(fname);
+            if (ecode != 0) {
+                qt.failed(ecode, fname, null);
+            }
+
+            ecode = qt.checkCliDriverResults(fname);
+            if (ecode != 0) {
+                qt.failedDiff(ecode, fname, null);
+            }
+            qt.clearPostTestEffects();
+
+        } catch (Throwable e) {
+            qt.failed(e, fname, null);
+        }
+
+        long elapsedTime = System.currentTimeMillis() - startTime;
+        LOG.info("Done query: " + fname + " elapsedTime=" + elapsedTime / 1000 + "s");
+        assertTrue("Test passed", true);
+    }
+
+    private void createFile(String content, String fullName) throws IOException {
+        FileUtils.write(new File(fullName), content);
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {
+        if (qt != null) {
+            try {
+                qt.shutdown();
+            } catch (Exception e) {
+                LOG.error("Unexpected exception in setup", e);
+                fail("Unexpected exception in tearDown");
+            }
+        }
+        try {
+            conn.close();
+        } finally {
+            try {
+                PhoenixDriver.INSTANCE.close();
+            } finally {
+                try {
+                    DriverManager.deregisterDriver(PhoenixDriver.INSTANCE);
+                } finally {
+                    hbaseTestUtil.shutdownMiniCluster();
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/it/java/org/apache/phoenix/hive/HiveTestUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/it/java/org/apache/phoenix/hive/HiveTestUtil.java b/phoenix-hive/src/it/java/org/apache/phoenix/hive/HiveTestUtil.java
new file mode 100644
index 0000000..57722f8
--- /dev/null
+++ b/phoenix-hive/src/it/java/org/apache/phoenix/hive/HiveTestUtil.java
@@ -0,0 +1,1291 @@
+/*
+ * 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.phoenix.hive;
+
+import com.google.common.collect.ImmutableList;
+import junit.framework.Assert;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
+import org.apache.hadoop.hive.cli.CliDriver;
+import org.apache.hadoop.hive.cli.CliSessionState;
+import org.apache.hadoop.hive.common.io.CachingPrintStream;
+import org.apache.hadoop.hive.common.io.DigestPrintStream;
+import org.apache.hadoop.hive.common.io.SortAndDigestPrintStream;
+import org.apache.hadoop.hive.common.io.SortPrintStream;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+import org.apache.hadoop.hive.metastore.api.Index;
+import org.apache.hadoop.hive.ql.exec.FunctionRegistry;
+import org.apache.hadoop.hive.ql.exec.Utilities;
+import org.apache.hadoop.hive.ql.lockmgr.zookeeper.ZooKeeperHiveLockManager;
+import org.apache.hadoop.hive.ql.metadata.Hive;
+import org.apache.hadoop.hive.ql.metadata.Table;
+import org.apache.hadoop.hive.ql.parse.ASTNode;
+import org.apache.hadoop.hive.ql.parse.BaseSemanticAnalyzer;
+import org.apache.hadoop.hive.ql.parse.ParseDriver;
+import org.apache.hadoop.hive.ql.parse.SemanticAnalyzer;
+import org.apache.hadoop.hive.ql.parse.SemanticException;
+import org.apache.hadoop.hive.ql.session.SessionState;
+import org.apache.hadoop.hive.shims.HadoopShims;
+import org.apache.hadoop.hive.shims.ShimLoader;
+import org.apache.hadoop.util.Shell;
+import org.apache.hive.common.util.StreamPrinter;
+import org.apache.tools.ant.BuildException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * HiveTestUtil cloned from Hive QTestUtil. Can be outdated and may require update once a problem
+ * found.
+ */
+public class HiveTestUtil {
+
+    public static final String UTF_8 = "UTF-8";
+    private static final Log LOG = LogFactory.getLog("HiveTestUtil");
+    private static final String QTEST_LEAVE_FILES = "QTEST_LEAVE_FILES";
+    public static final String DEFAULT_DATABASE_NAME = "default";
+
+    private String testWarehouse;
+    private final String testFiles;
+    protected final String outDir;
+    protected final String logDir;
+    private final TreeMap<String, String> qMap;
+    private final Set<String> qSkipSet;
+    private final Set<String> qSortSet;
+    private final Set<String> qSortQuerySet;
+    private final Set<String> qHashQuerySet;
+    private final Set<String> qSortNHashQuerySet;
+    private final Set<String> qJavaVersionSpecificOutput;
+    private static final String SORT_SUFFIX = ".sorted";
+    private static MiniClusterType clusterType = MiniClusterType.none;
+    private ParseDriver pd;
+    protected Hive db;
+    protected HiveConf conf;
+    private BaseSemanticAnalyzer sem;
+    protected final boolean overWrite;
+    private CliDriver cliDriver;
+    private HadoopShims.MiniMrShim mr = null;
+    private HadoopShims.MiniDFSShim dfs = null;
+    private String hadoopVer = null;
+    private HiveTestSetup setup = null;
+    private boolean isSessionStateStarted = false;
+    private static final String javaVersion = getJavaVersion();
+
+    private String initScript = "";
+    private String cleanupScript = "";
+
+    public HiveConf getConf() {
+        return conf;
+    }
+
+    public boolean deleteDirectory(File path) {
+        if (path.exists()) {
+            File[] files = path.listFiles();
+            for (File file : files) {
+                if (file.isDirectory()) {
+                    deleteDirectory(file);
+                } else {
+                    file.delete();
+                }
+            }
+        }
+        return (path.delete());
+    }
+
+    public void copyDirectoryToLocal(Path src, Path dest) throws Exception {
+
+        FileSystem srcFs = src.getFileSystem(conf);
+        FileSystem destFs = dest.getFileSystem(conf);
+        if (srcFs.exists(src)) {
+            FileStatus[] files = srcFs.listStatus(src);
+            for (FileStatus file : files) {
+                String name = file.getPath().getName();
+                Path dfs_path = file.getPath();
+                Path local_path = new Path(dest, name);
+
+                if (file.isDir()) {
+                    if (!destFs.exists(local_path)) {
+                        destFs.mkdirs(local_path);
+                    }
+                    copyDirectoryToLocal(dfs_path, local_path);
+                } else {
+                    srcFs.copyToLocalFile(dfs_path, local_path);
+                }
+            }
+        }
+    }
+
+    static Pattern mapTok = Pattern.compile("(\\.?)(.*)_map_(.*)");
+    static Pattern reduceTok = Pattern.compile("(.*)(reduce_[^\\.]*)((\\..*)?)");
+
+    public void normalizeNames(File path) throws Exception {
+        if (path.isDirectory()) {
+            File[] files = path.listFiles();
+            for (File file : files) {
+                normalizeNames(file);
+            }
+        } else {
+            Matcher m = reduceTok.matcher(path.getName());
+            if (m.matches()) {
+                String name = m.group(1) + "reduce" + m.group(3);
+                path.renameTo(new File(path.getParent(), name));
+            } else {
+                m = mapTok.matcher(path.getName());
+                if (m.matches()) {
+                    String name = m.group(1) + "map_" + m.group(3);
+                    path.renameTo(new File(path.getParent(), name));
+                }
+            }
+        }
+    }
+
+    public String getOutputDirectory() {
+        return outDir;
+    }
+
+    public String getLogDirectory() {
+        return logDir;
+    }
+
+    private String getHadoopMainVersion(String input) {
+        if (input == null) {
+            return null;
+        }
+        Pattern p = Pattern.compile("^(\\d+\\.\\d+).*");
+        Matcher m = p.matcher(input);
+        if (m.matches()) {
+            return m.group(1);
+        }
+        return null;
+    }
+
+    public void initConf() throws Exception {
+        // Plug verifying metastore in for testing.
+        conf.setVar(HiveConf.ConfVars.METASTORE_RAW_STORE_IMPL,
+                "org.apache.hadoop.hive.metastore.VerifyingObjectStore");
+
+        if (mr != null) {
+            assert dfs != null;
+
+            mr.setupConfiguration(conf);
+
+            // set fs.default.name to the uri of mini-dfs
+            String dfsUriString = WindowsPathUtil.getHdfsUriString(dfs.getFileSystem().getUri()
+                    .toString());
+            conf.setVar(HiveConf.ConfVars.HADOOPFS, dfsUriString);
+            // hive.metastore.warehouse.dir needs to be set relative to the mini-dfs
+            conf.setVar(HiveConf.ConfVars.METASTOREWAREHOUSE,
+                    (new Path(dfsUriString,
+                            "/build/ql/test/data/warehouse/")).toString());
+        }
+
+        // Windows paths should be converted after MiniMrShim.setupConfiguration()
+        // since setupConfiguration may overwrite configuration values.
+        if (Shell.WINDOWS) {
+            WindowsPathUtil.convertPathsFromWindowsToHdfs(conf);
+        }
+    }
+
+    public enum MiniClusterType {
+        mr,
+        tez,
+        none;
+
+        public static MiniClusterType valueForString(String type) {
+            if (type.equals("miniMR")) {
+                return mr;
+            } else if (type.equals("tez")) {
+                return tez;
+            } else {
+                return none;
+            }
+        }
+    }
+
+    public HiveTestUtil(String outDir, String logDir, MiniClusterType clusterType, String hadoopVer)
+            throws Exception {
+        this(outDir, logDir, clusterType, null, hadoopVer);
+    }
+
+    public HiveTestUtil(String outDir, String logDir, MiniClusterType clusterType, String confDir,
+                        String hadoopVer)
+            throws Exception {
+        this.outDir = outDir;
+        this.logDir = logDir;
+        if (confDir != null && !confDir.isEmpty()) {
+            HiveConf.setHiveSiteLocation(new URL("file://" + new File(confDir).toURI().getPath()
+                    + "/hive-site.xml"));
+            LOG.info("Setting hive-site: " + HiveConf.getHiveSiteLocation());
+        }
+        conf = new HiveConf();
+        String tmpBaseDir = System.getProperty("test.tmp.dir");
+        if (tmpBaseDir == null || tmpBaseDir == "") {
+            tmpBaseDir = System.getProperty("java.io.tmpdir");
+        }
+        String metaStoreURL = "jdbc:derby:" + tmpBaseDir + File.separator + "metastore_dbtest;" +
+                "create=true";
+        conf.set(ConfVars.METASTORECONNECTURLKEY.varname, metaStoreURL);
+        System.setProperty(HiveConf.ConfVars.METASTORECONNECTURLKEY.varname, metaStoreURL);
+
+        //set where derby logs
+        File derbyLogFile = new File(tmpBaseDir + "/derby.log");
+        derbyLogFile.createNewFile();
+        System.setProperty("derby.stream.error.file", derbyLogFile.getPath());
+
+        this.hadoopVer = getHadoopMainVersion(hadoopVer);
+        qMap = new TreeMap<String, String>();
+        qSkipSet = new HashSet<String>();
+        qSortSet = new HashSet<String>();
+        qSortQuerySet = new HashSet<String>();
+        qHashQuerySet = new HashSet<String>();
+        qSortNHashQuerySet = new HashSet<String>();
+        qJavaVersionSpecificOutput = new HashSet<String>();
+        this.clusterType = clusterType;
+
+        HadoopShims shims = ShimLoader.getHadoopShims();
+        int numberOfDataNodes = 4;
+
+        if (clusterType != MiniClusterType.none) {
+            dfs = shims.getMiniDfs(conf, numberOfDataNodes, true, null);
+            FileSystem fs = dfs.getFileSystem();
+            String uriString = WindowsPathUtil.getHdfsUriString(fs.getUri().toString());
+            if (clusterType == MiniClusterType.tez) {
+                mr = shims.getMiniTezCluster(conf, 4, uriString, 1);
+            } else {
+                mr = shims.getMiniMrCluster(conf, 4, uriString, 1);
+            }
+        }
+
+        initConf();
+
+        // Use the current directory if it is not specified
+        String dataDir = conf.get("test.data.files");
+        if (dataDir == null) {
+            dataDir = new File(".").getAbsolutePath() + "/data/files";
+        }
+
+        testFiles = dataDir;
+
+        // Use the current directory if it is not specified
+        String scriptsDir = conf.get("test.data.scripts");
+        if (scriptsDir == null) {
+            scriptsDir = new File(".").getAbsolutePath() + "/data/scripts";
+        }
+        if (!initScript.isEmpty()) {
+            this.initScript = scriptsDir + "/" + initScript;
+        }
+        if (!cleanupScript.isEmpty()) {
+            this.cleanupScript = scriptsDir + "/" + cleanupScript;
+        }
+
+        overWrite = "true".equalsIgnoreCase(System.getProperty("test.output.overwrite"));
+
+        setup = new HiveTestSetup();
+        setup.preTest(conf);
+        init();
+    }
+
+    public void shutdown() throws Exception {
+        cleanUp();
+        setup.tearDown();
+        if (mr != null) {
+            mr.shutdown();
+            mr = null;
+        }
+        FileSystem.closeAll();
+        if (dfs != null) {
+            dfs.shutdown();
+            dfs = null;
+        }
+    }
+
+    public String readEntireFileIntoString(File queryFile) throws IOException {
+        InputStreamReader isr = new InputStreamReader(
+                new BufferedInputStream(new FileInputStream(queryFile)), HiveTestUtil.UTF_8);
+        StringWriter sw = new StringWriter();
+        try {
+            IOUtils.copy(isr, sw);
+        } finally {
+            if (isr != null) {
+                isr.close();
+            }
+        }
+        return sw.toString();
+    }
+
+    public void addFile(String queryFile) throws IOException {
+        addFile(queryFile, false);
+    }
+
+    public void addFile(String queryFile, boolean partial) throws IOException {
+        addFile(new File(queryFile));
+    }
+
+    public void addFile(File qf) throws IOException {
+        addFile(qf, false);
+    }
+
+    public void addFile(File qf, boolean partial) throws IOException {
+        String query = readEntireFileIntoString(qf);
+        qMap.put(qf.getName(), query);
+        if (partial) return;
+
+        if (matches(SORT_BEFORE_DIFF, query)) {
+            qSortSet.add(qf.getName());
+        } else if (matches(SORT_QUERY_RESULTS, query)) {
+            qSortQuerySet.add(qf.getName());
+        } else if (matches(HASH_QUERY_RESULTS, query)) {
+            qHashQuerySet.add(qf.getName());
+        } else if (matches(SORT_AND_HASH_QUERY_RESULTS, query)) {
+            qSortNHashQuerySet.add(qf.getName());
+        }
+    }
+
+    private static final Pattern SORT_BEFORE_DIFF = Pattern.compile("-- SORT_BEFORE_DIFF");
+    private static final Pattern SORT_QUERY_RESULTS = Pattern.compile("-- SORT_QUERY_RESULTS");
+    private static final Pattern HASH_QUERY_RESULTS = Pattern.compile("-- HASH_QUERY_RESULTS");
+    private static final Pattern SORT_AND_HASH_QUERY_RESULTS = Pattern.compile("-- " +
+            "SORT_AND_HASH_QUERY_RESULTS");
+
+    private boolean matches(Pattern pattern, String query) {
+        Matcher matcher = pattern.matcher(query);
+        if (matcher.find()) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get formatted Java version to include minor version, but
+     * exclude patch level.
+     *
+     * @return Java version formatted as major_version.minor_version
+     */
+    private static String getJavaVersion() {
+        String version = System.getProperty("java.version");
+        if (version == null) {
+            throw new NullPointerException("No java version could be determined " +
+                    "from system properties");
+        }
+
+        // "java version" system property is formatted
+        // major_version.minor_version.patch_level.
+        // Find second dot, instead of last dot, to be safe
+        int pos = version.indexOf('.');
+        pos = version.indexOf('.', pos + 1);
+        return version.substring(0, pos);
+    }
+
+    /**
+     * Clear out any side effects of running tests
+     */
+    public void clearPostTestEffects() throws Exception {
+        setup.postTest(conf);
+    }
+
+    /**
+     * Clear out any side effects of running tests
+     */
+    public void clearTablesCreatedDuringTests() throws Exception {
+        if (System.getenv(QTEST_LEAVE_FILES) != null) {
+            return;
+        }
+
+        // Delete any tables other than the source tables
+        // and any databases other than the default database.
+        for (String dbName : db.getAllDatabases()) {
+            SessionState.get().setCurrentDatabase(dbName);
+            for (String tblName : db.getAllTables()) {
+                if (!DEFAULT_DATABASE_NAME.equals(dbName)) {
+                    Table tblObj = db.getTable(tblName);
+                    // dropping index table can not be dropped directly. Dropping the base
+                    // table will automatically drop all its index table
+                    if (tblObj.isIndexTable()) {
+                        continue;
+                    }
+                    db.dropTable(dbName, tblName);
+                } else {
+                    // this table is defined in srcTables, drop all indexes on it
+                    List<Index> indexes = db.getIndexes(dbName, tblName, (short) -1);
+                    if (indexes != null && indexes.size() > 0) {
+                        for (Index index : indexes) {
+                            db.dropIndex(dbName, tblName, index.getIndexName(), true, true);
+                        }
+                    }
+                }
+            }
+            if (!DEFAULT_DATABASE_NAME.equals(dbName)) {
+                // Drop cascade, may need to drop functions
+                db.dropDatabase(dbName, true, true, true);
+            }
+        }
+
+        // delete remaining directories for external tables (can affect stats for following tests)
+        try {
+            Path p = new Path(testWarehouse);
+            FileSystem fileSystem = p.getFileSystem(conf);
+            if (fileSystem.exists(p)) {
+                for (FileStatus status : fileSystem.listStatus(p)) {
+                    if (status.isDir()) {
+                        fileSystem.delete(status.getPath(), true);
+                    }
+                }
+            }
+        } catch (IllegalArgumentException e) {
+            // ignore.. provides invalid url sometimes intentionally
+        }
+        SessionState.get().setCurrentDatabase(DEFAULT_DATABASE_NAME);
+
+        List<String> roleNames = db.getAllRoleNames();
+        for (String roleName : roleNames) {
+            if (!"PUBLIC".equalsIgnoreCase(roleName) && !"ADMIN".equalsIgnoreCase(roleName)) {
+                db.dropRole(roleName);
+            }
+        }
+    }
+
+    /**
+     * Clear out any side effects of running tests
+     */
+    public void clearTestSideEffects() throws Exception {
+        if (System.getenv(QTEST_LEAVE_FILES) != null) {
+            return;
+        }
+
+        clearTablesCreatedDuringTests();
+    }
+
+    public void cleanUp() throws Exception {
+        if (!isSessionStateStarted) {
+            startSessionState();
+        }
+        if (System.getenv(QTEST_LEAVE_FILES) != null) {
+            return;
+        }
+
+        clearTablesCreatedDuringTests();
+
+        SessionState.get().getConf().setBoolean("hive.test.shutdown.phase", true);
+
+        if (cleanupScript != "") {
+            String cleanupCommands = readEntireFileIntoString(new File(cleanupScript));
+            LOG.info("Cleanup (" + cleanupScript + "):\n" + cleanupCommands);
+            if (cliDriver == null) {
+                cliDriver = new CliDriver();
+            }
+            cliDriver.processLine(cleanupCommands);
+        }
+
+        SessionState.get().getConf().setBoolean("hive.test.shutdown.phase", false);
+
+        // delete any contents in the warehouse dir
+        Path p = new Path(testWarehouse);
+        FileSystem fs = p.getFileSystem(conf);
+
+        try {
+            FileStatus[] ls = fs.listStatus(p);
+            for (int i = 0; (ls != null) && (i < ls.length); i++) {
+                fs.delete(ls[i].getPath(), true);
+            }
+        } catch (FileNotFoundException e) {
+            // Best effort
+        }
+
+        FunctionRegistry.unregisterTemporaryUDF("test_udaf");
+        FunctionRegistry.unregisterTemporaryUDF("test_error");
+    }
+
+    public void createSources() throws Exception {
+        if (!isSessionStateStarted) {
+            startSessionState();
+        }
+        conf.setBoolean("hive.test.init.phase", true);
+
+        if (cliDriver == null) {
+            cliDriver = new CliDriver();
+        }
+        cliDriver.processLine("set test.data.dir=" + testFiles + ";");
+
+        conf.setBoolean("hive.test.init.phase", false);
+    }
+
+    public void init() throws Exception {
+        testWarehouse = conf.getVar(HiveConf.ConfVars.METASTOREWAREHOUSE);
+        String execEngine = conf.get("hive.execution.engine");
+        conf.set("hive.execution.engine", "mr");
+        SessionState.start(conf);
+        conf.set("hive.execution.engine", execEngine);
+        db = Hive.get(conf);
+        pd = new ParseDriver();
+        sem = new SemanticAnalyzer(conf);
+    }
+
+    public void init(String tname) throws Exception {
+        cleanUp();
+        createSources();
+        cliDriver.processCmd("set hive.cli.print.header=true;");
+    }
+
+    public void cliInit(String tname) throws Exception {
+        cliInit(tname, true);
+    }
+
+    public String cliInit(String tname, boolean recreate) throws Exception {
+        if (recreate) {
+            cleanUp();
+            createSources();
+        }
+
+        HiveConf.setVar(conf, HiveConf.ConfVars.HIVE_AUTHENTICATOR_MANAGER,
+                "org.apache.hadoop.hive.ql.security.HadoopDefaultAuthenticator");
+        Utilities.clearWorkMap();
+        CliSessionState ss = new CliSessionState(conf);
+        assert ss != null;
+        ss.in = System.in;
+
+        String outFileExtension = getOutFileExtension(tname);
+        String stdoutName = null;
+        if (outDir != null) {
+            File qf = new File(outDir, tname);
+            stdoutName = qf.getName().concat(outFileExtension);
+        } else {
+            stdoutName = tname + outFileExtension;
+        }
+
+        File outf = new File(logDir, stdoutName);
+        OutputStream fo = new BufferedOutputStream(new FileOutputStream(outf));
+        if (qSortQuerySet.contains(tname)) {
+            ss.out = new SortPrintStream(fo, "UTF-8");
+        } else if (qHashQuerySet.contains(tname)) {
+            ss.out = new DigestPrintStream(fo, "UTF-8");
+        } else if (qSortNHashQuerySet.contains(tname)) {
+            ss.out = new SortAndDigestPrintStream(fo, "UTF-8");
+        } else {
+            ss.out = new PrintStream(fo, true, "UTF-8");
+        }
+        ss.err = new CachingPrintStream(fo, true, "UTF-8");
+        ss.setIsSilent(true);
+        SessionState oldSs = SessionState.get();
+
+        if (oldSs != null && clusterType == MiniClusterType.tez) {
+            oldSs.close();
+        }
+
+        if (oldSs != null && oldSs.out != null && oldSs.out != System.out) {
+            oldSs.out.close();
+        }
+        SessionState.start(ss);
+
+        cliDriver = new CliDriver();
+        cliDriver.processInitFiles(ss);
+
+        return outf.getAbsolutePath();
+    }
+
+    private CliSessionState startSessionState()
+            throws IOException {
+
+        HiveConf.setVar(conf, HiveConf.ConfVars.HIVE_AUTHENTICATOR_MANAGER,
+                "org.apache.hadoop.hive.ql.security.HadoopDefaultAuthenticator");
+
+        String execEngine = conf.get("hive.execution.engine");
+        conf.set("hive.execution.engine", "mr");
+        CliSessionState ss = new CliSessionState(conf);
+        assert ss != null;
+        ss.in = System.in;
+        ss.out = System.out;
+        ss.err = System.out;
+
+        SessionState oldSs = SessionState.get();
+        if (oldSs != null && clusterType == MiniClusterType.tez) {
+            oldSs.close();
+        }
+        if (oldSs != null && oldSs.out != null && oldSs.out != System.out) {
+            oldSs.out.close();
+        }
+        SessionState.start(ss);
+
+        isSessionStateStarted = true;
+
+        conf.set("hive.execution.engine", execEngine);
+        return ss;
+    }
+
+    public int executeOne(String tname) {
+        String q = qMap.get(tname);
+
+        if (q.indexOf(";") == -1) {
+            return -1;
+        }
+
+        String q1 = q.substring(0, q.indexOf(";") + 1);
+        String qrest = q.substring(q.indexOf(";") + 1);
+        qMap.put(tname, qrest);
+
+        LOG.info("Executing " + q1);
+        return cliDriver.processLine(q1);
+    }
+
+    public static final String CRLF = System.getProperty("line.separator");
+
+    public int executeClient(String tname1, String tname2) {
+        String commands = getCommands(tname1) + CRLF + getCommands(tname2);
+        return cliDriver.processLine(commands);
+    }
+
+    public int executeClient(String tname) {
+        return cliDriver.processLine(getCommands(tname), false);
+    }
+
+    private String getCommands(String tname) {
+        String commands = qMap.get(tname);
+        StringBuilder newCommands = new StringBuilder(commands.length());
+        int lastMatchEnd = 0;
+        Matcher commentMatcher = Pattern.compile("^--.*$", Pattern.MULTILINE).matcher(commands);
+        while (commentMatcher.find()) {
+            newCommands.append(commands.substring(lastMatchEnd, commentMatcher.start()));
+            newCommands.append(commentMatcher.group().replaceAll("(?<!\\\\);", "\\\\;"));
+            lastMatchEnd = commentMatcher.end();
+        }
+        newCommands.append(commands.substring(lastMatchEnd, commands.length()));
+        commands = newCommands.toString();
+        return commands;
+    }
+
+    public boolean shouldBeSkipped(String tname) {
+        return qSkipSet.contains(tname);
+    }
+
+    private String getOutFileExtension(String fname) {
+        String outFileExtension = ".out";
+        if (qJavaVersionSpecificOutput.contains(fname)) {
+            outFileExtension = ".java" + javaVersion + ".out";
+        }
+
+        return outFileExtension;
+    }
+
+    /**
+     * Given the current configurations (e.g., hadoop version and execution mode), return
+     * the correct file name to compare with the current test run output.
+     *
+     * @param outDir   The directory where the reference log files are stored.
+     * @param testName The test file name (terminated by ".out").
+     * @return The file name appended with the configuration values if it exists.
+     */
+    public String outPath(String outDir, String testName) {
+        String ret = (new File(outDir, testName)).getPath();
+        // List of configurations. Currently the list consists of hadoop version and execution
+        // mode only
+        List<String> configs = new ArrayList<String>();
+        configs.add(this.hadoopVer);
+
+        Deque<String> stack = new LinkedList<String>();
+        StringBuilder sb = new StringBuilder();
+        sb.append(testName);
+        stack.push(sb.toString());
+
+        // example file names are input1.q.out_0.20.0_minimr or input2.q.out_0.17
+        for (String s : configs) {
+            sb.append('_');
+            sb.append(s);
+            stack.push(sb.toString());
+        }
+        while (stack.size() > 0) {
+            String fileName = stack.pop();
+            File f = new File(outDir, fileName);
+            if (f.exists()) {
+                ret = f.getPath();
+                break;
+            }
+        }
+        return ret;
+    }
+
+    private Pattern[] toPattern(String[] patternStrs) {
+        Pattern[] patterns = new Pattern[patternStrs.length];
+        for (int i = 0; i < patternStrs.length; i++) {
+            patterns[i] = Pattern.compile(patternStrs[i]);
+        }
+        return patterns;
+    }
+
+    private void maskPatterns(Pattern[] patterns, String fname) throws Exception {
+        String maskPattern = "#### A masked pattern was here ####";
+
+        String line;
+        BufferedReader in;
+        BufferedWriter out;
+
+        File file = new File(fname);
+        File fileOrig = new File(fname + ".orig");
+        FileUtils.copyFile(file, fileOrig);
+
+        in = new BufferedReader(new InputStreamReader(new FileInputStream(fileOrig), "UTF-8"));
+        out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
+
+        boolean lastWasMasked = false;
+        while (null != (line = in.readLine())) {
+            for (Pattern pattern : patterns) {
+                line = pattern.matcher(line).replaceAll(maskPattern);
+            }
+
+            if (line.equals(maskPattern)) {
+                // We're folding multiple masked lines into one.
+                if (!lastWasMasked) {
+                    out.write(line);
+                    out.write("\n");
+                    lastWasMasked = true;
+                }
+            } else {
+                out.write(line);
+                out.write("\n");
+                lastWasMasked = false;
+            }
+        }
+
+        in.close();
+        out.close();
+    }
+
+    private final Pattern[] planMask = toPattern(new String[]{
+            ".*file:.*",
+            ".*pfile:.*",
+            ".*hdfs:.*",
+            ".*/tmp/.*",
+            ".*invalidscheme:.*",
+            ".*lastUpdateTime.*",
+            ".*lastAccessTime.*",
+            ".*lastModifiedTime.*",
+            ".*[Oo]wner.*",
+            ".*CreateTime.*",
+            ".*LastAccessTime.*",
+            ".*Location.*",
+            ".*LOCATION '.*",
+            ".*transient_lastDdlTime.*",
+            ".*last_modified_.*",
+            ".*at org.*",
+            ".*at sun.*",
+            ".*at java.*",
+            ".*at junit.*",
+            ".*Caused by:.*",
+            ".*LOCK_QUERYID:.*",
+            ".*LOCK_TIME:.*",
+            ".*grantTime.*",
+            ".*[.][.][.] [0-9]* more.*",
+            ".*job_[0-9_]*.*",
+            ".*job_local[0-9_]*.*",
+            ".*USING 'java -cp.*",
+            "^Deleted.*",
+            ".*DagName:.*",
+            ".*Input:.*/data/files/.*",
+            ".*Output:.*/data/files/.*",
+            ".*total number of created files now is.*"
+    });
+
+    public int checkCliDriverResults(String tname) throws Exception {
+        assert (qMap.containsKey(tname));
+
+        String outFileExtension = getOutFileExtension(tname);
+        String outFileName = outPath(outDir, tname + outFileExtension);
+
+        File f = new File(logDir, tname + outFileExtension);
+
+        maskPatterns(planMask, f.getPath());
+        int exitVal = executeDiffCommand(f.getPath(),
+                outFileName, false,
+                qSortSet.contains(tname));
+
+        if (exitVal != 0 && overWrite) {
+            exitVal = overwriteResults(f.getPath(), outFileName);
+        }
+
+        return exitVal;
+    }
+
+
+    public int checkCompareCliDriverResults(String tname, List<String> outputs) throws Exception {
+        assert outputs.size() > 1;
+        maskPatterns(planMask, outputs.get(0));
+        for (int i = 1; i < outputs.size(); ++i) {
+            maskPatterns(planMask, outputs.get(i));
+            int ecode = executeDiffCommand(
+                    outputs.get(i - 1), outputs.get(i), false, qSortSet.contains(tname));
+            if (ecode != 0) {
+                LOG.info("Files don't match: " + outputs.get(i - 1) + " and " + outputs.get(i));
+                return ecode;
+            }
+        }
+        return 0;
+    }
+
+    private static int overwriteResults(String inFileName, String outFileName) throws Exception {
+        // This method can be replaced with Files.copy(source, target, REPLACE_EXISTING)
+        // once Hive uses JAVA 7.
+        LOG.info("Overwriting results " + inFileName + " to " + outFileName);
+        return executeCmd(new String[]{
+                "cp",
+                getQuotedString(inFileName),
+                getQuotedString(outFileName)
+        });
+    }
+
+    private static int executeDiffCommand(String inFileName,
+                                          String outFileName,
+                                          boolean ignoreWhiteSpace,
+                                          boolean sortResults
+    ) throws Exception {
+
+        int result = 0;
+
+        if (sortResults) {
+            // sort will try to open the output file in write mode on windows. We need to
+            // close it first.
+            SessionState ss = SessionState.get();
+            if (ss != null && ss.out != null && ss.out != System.out) {
+                ss.out.close();
+            }
+
+            String inSorted = inFileName + SORT_SUFFIX;
+            String outSorted = outFileName + SORT_SUFFIX;
+
+            result = sortFiles(inFileName, inSorted);
+            result |= sortFiles(outFileName, outSorted);
+            if (result != 0) {
+                LOG.error("ERROR: Could not sort files before comparing");
+                return result;
+            }
+            inFileName = inSorted;
+            outFileName = outSorted;
+        }
+
+        ArrayList<String> diffCommandArgs = new ArrayList<String>();
+        diffCommandArgs.add("diff");
+
+        // Text file comparison
+        diffCommandArgs.add("-a");
+
+        // Ignore changes in the amount of white space
+        if (ignoreWhiteSpace || Shell.WINDOWS) {
+            diffCommandArgs.add("-b");
+        }
+
+        // Files created on Windows machines have different line endings
+        // than files created on Unix/Linux. Windows uses carriage return and line feed
+        // ("\r\n") as a line ending, whereas Unix uses just line feed ("\n").
+        // Also StringBuilder.toString(), Stream to String conversions adds extra
+        // spaces at the end of the line.
+        if (Shell.WINDOWS) {
+            diffCommandArgs.add("--strip-trailing-cr"); // Strip trailing carriage return on input
+            diffCommandArgs.add("-B"); // Ignore changes whose lines are all blank
+        }
+        // Add files to compare to the arguments list
+        diffCommandArgs.add(getQuotedString(inFileName));
+        diffCommandArgs.add(getQuotedString(outFileName));
+
+        result = executeCmd(diffCommandArgs);
+
+        if (sortResults) {
+            new File(inFileName).delete();
+            new File(outFileName).delete();
+        }
+
+        return result;
+    }
+
+    private static int sortFiles(String in, String out) throws Exception {
+        return executeCmd(new String[]{
+                "sort",
+                getQuotedString(in),
+        }, out, null);
+    }
+
+    private static int executeCmd(Collection<String> args) throws Exception {
+        return executeCmd(args, null, null);
+    }
+
+    private static int executeCmd(String[] args) throws Exception {
+        return executeCmd(args, null, null);
+    }
+
+    private static int executeCmd(Collection<String> args, String outFile, String errFile) throws
+            Exception {
+        String[] cmdArray = args.toArray(new String[args.size()]);
+        return executeCmd(cmdArray, outFile, errFile);
+    }
+
+    private static int executeCmd(String[] args, String outFile, String errFile) throws Exception {
+        LOG.info("Running: " + org.apache.commons.lang.StringUtils.join(args, ' '));
+
+        PrintStream out = outFile == null ?
+                SessionState.getConsole().getChildOutStream() :
+                new PrintStream(new FileOutputStream(outFile), true);
+        PrintStream err = errFile == null ?
+                SessionState.getConsole().getChildErrStream() :
+                new PrintStream(new FileOutputStream(errFile), true);
+
+        Process executor = Runtime.getRuntime().exec(args);
+
+        StreamPrinter errPrinter = new StreamPrinter(executor.getErrorStream(), null, err);
+        StreamPrinter outPrinter = new StreamPrinter(executor.getInputStream(), null, out);
+
+        outPrinter.start();
+        errPrinter.start();
+
+        int result = executor.waitFor();
+
+        outPrinter.join();
+        errPrinter.join();
+
+        if (outFile != null) {
+            out.close();
+        }
+
+        if (errFile != null) {
+            err.close();
+        }
+
+        return result;
+    }
+
+    private static String getQuotedString(String str) {
+        return Shell.WINDOWS ? String.format("\"%s\"", str) : str;
+    }
+
+    public ASTNode parseQuery(String tname) throws Exception {
+        return pd.parse(qMap.get(tname));
+    }
+
+    public void resetParser() throws SemanticException {
+        pd = new ParseDriver();
+        sem = new SemanticAnalyzer(conf);
+    }
+
+    public TreeMap<String, String> getQMap() {
+        return qMap;
+    }
+
+    /**
+     * HiveTestSetup defines test fixtures which are reused across testcases,
+     * and are needed before any test can be run
+     */
+    public static class HiveTestSetup {
+        private MiniZooKeeperCluster zooKeeperCluster = null;
+        private int zkPort;
+        private ZooKeeper zooKeeper;
+
+        public HiveTestSetup() {
+        }
+
+        public void preTest(HiveConf conf) throws Exception {
+
+            if (zooKeeperCluster == null) {
+                //create temp dir
+                String tmpBaseDir = System.getProperty("test.tmp.dir");
+                File tmpDir = Utilities.createTempDir(tmpBaseDir);
+
+                zooKeeperCluster = new MiniZooKeeperCluster();
+                zkPort = zooKeeperCluster.startup(tmpDir);
+            }
+
+            if (zooKeeper != null) {
+                zooKeeper.close();
+            }
+
+            int sessionTimeout = (int) conf.getTimeVar(HiveConf.ConfVars
+                    .HIVE_ZOOKEEPER_SESSION_TIMEOUT, TimeUnit.MILLISECONDS);
+            zooKeeper = new ZooKeeper("localhost:" + zkPort, sessionTimeout, new Watcher() {
+                @Override
+                public void process(WatchedEvent arg0) {
+                }
+            });
+
+            String zkServer = "localhost";
+            conf.set("hive.zookeeper.quorum", zkServer);
+            conf.set("hive.zookeeper.client.port", "" + zkPort);
+        }
+
+        public void postTest(HiveConf conf) throws Exception {
+            if (zooKeeperCluster == null) {
+                return;
+            }
+
+            if (zooKeeper != null) {
+                zooKeeper.close();
+            }
+
+            ZooKeeperHiveLockManager.releaseAllLocks(conf);
+        }
+
+        public void tearDown() throws Exception {
+            if (zooKeeperCluster != null) {
+                zooKeeperCluster.shutdown();
+                zooKeeperCluster = null;
+            }
+        }
+    }
+
+    /**
+     * QTRunner: Runnable class for running a a single query file.
+     **/
+    public static class HiveTestRunner implements Runnable {
+        private final HiveTestUtil qt;
+        private final String fname;
+
+        public HiveTestRunner(HiveTestUtil qt, String fname) {
+            this.qt = qt;
+            this.fname = fname;
+        }
+
+        @Override
+        public void run() {
+            try {
+                // assumption is that environment has already been cleaned once globally
+                // hence each thread does not call cleanUp() and createSources() again
+                qt.cliInit(fname, false);
+                qt.executeClient(fname);
+            } catch (Throwable e) {
+                LOG.error("Query file " + fname + " failed with exception ", e);
+                e.printStackTrace();
+                outputTestFailureHelpMessage();
+            }
+        }
+    }
+
+    /**
+     * Setup to execute a set of query files. Uses HiveTestUtil to do so.
+     *
+     * @param qfiles array of input query files containing arbitrary number of hive
+     *               queries
+     * @param resDir output directory
+     * @param logDir log directory
+     * @return one HiveTestUtil for each query file
+     */
+    public static HiveTestUtil[] queryListRunnerSetup(File[] qfiles, String resDir,
+                                                      String logDir) throws Exception {
+        HiveTestUtil[] qt = new HiveTestUtil[qfiles.length];
+        for (int i = 0; i < qfiles.length; i++) {
+            qt[i] = new HiveTestUtil(resDir, logDir, MiniClusterType.mr, null, "0.20");
+            qt[i].addFile(qfiles[i]);
+            qt[i].clearTestSideEffects();
+        }
+
+        return qt;
+    }
+
+    /**
+     * Executes a set of query files in sequence.
+     *
+     * @param qfiles array of input query files containing arbitrary number of hive
+     *               queries
+     * @param qt     array of HiveTestUtils, one per qfile
+     * @return true if all queries passed, false otw
+     */
+    public static boolean queryListRunnerSingleThreaded(File[] qfiles, HiveTestUtil[] qt)
+            throws Exception {
+        boolean failed = false;
+        qt[0].cleanUp();
+        qt[0].createSources();
+        for (int i = 0; i < qfiles.length && !failed; i++) {
+            qt[i].clearTestSideEffects();
+            qt[i].cliInit(qfiles[i].getName(), false);
+            qt[i].executeClient(qfiles[i].getName());
+            int ecode = qt[i].checkCliDriverResults(qfiles[i].getName());
+            if (ecode != 0) {
+                failed = true;
+                LOG.error("Test " + qfiles[i].getName()
+                        + " results check failed with error code " + ecode);
+                outputTestFailureHelpMessage();
+            }
+            qt[i].clearPostTestEffects();
+        }
+        return (!failed);
+    }
+
+    public static void outputTestFailureHelpMessage() {
+        LOG.error("See ./ql/target/tmp/log/hive.log or ./itests/qtest/target/tmp/log/hive.log, "
+                + "or check ./ql/target/surefire-reports or " +
+                "./itests/qtest/target/surefire-reports/ for specific test cases logs.");
+    }
+
+    public static String ensurePathEndsInSlash(String path) {
+        if (path == null) {
+            throw new NullPointerException("Path cannot be null");
+        }
+        if (path.endsWith(File.separator)) {
+            return path;
+        } else {
+            return path + File.separator;
+        }
+    }
+
+    private static String[] cachedQvFileList = null;
+    private static ImmutableList<String> cachedDefaultQvFileList = null;
+    private static Pattern qvSuffix = Pattern.compile("_[0-9]+.qv$", Pattern.CASE_INSENSITIVE);
+
+    public static List<String> getVersionFiles(String queryDir, String tname) {
+        ensureQvFileList(queryDir);
+        List<String> result = getVersionFilesInternal(tname);
+        if (result == null) {
+            result = cachedDefaultQvFileList;
+        }
+        return result;
+    }
+
+    private static void ensureQvFileList(String queryDir) {
+        if (cachedQvFileList != null) return;
+        // Not thread-safe.
+        LOG.info("Getting versions from " + queryDir);
+        cachedQvFileList = (new File(queryDir)).list(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.toLowerCase().endsWith(".qv");
+            }
+        });
+        if (cachedQvFileList == null) return; // no files at all
+        Arrays.sort(cachedQvFileList, String.CASE_INSENSITIVE_ORDER);
+        List<String> defaults = getVersionFilesInternal("default");
+        cachedDefaultQvFileList = (defaults != null)
+                ? ImmutableList.copyOf(defaults) : ImmutableList.<String>of();
+    }
+
+    private static List<String> getVersionFilesInternal(String tname) {
+        if (cachedQvFileList == null) {
+            return new ArrayList<String>();
+        }
+        int pos = Arrays.binarySearch(cachedQvFileList, tname, String.CASE_INSENSITIVE_ORDER);
+        if (pos >= 0) {
+            throw new BuildException("Unexpected file list element: " + cachedQvFileList[pos]);
+        }
+        List<String> result = null;
+        for (pos = (-pos - 1); pos < cachedQvFileList.length; ++pos) {
+            String candidate = cachedQvFileList[pos];
+            if (candidate.length() <= tname.length()
+                    || !tname.equalsIgnoreCase(candidate.substring(0, tname.length()))
+                    || !qvSuffix.matcher(candidate.substring(tname.length())).matches()) {
+                break;
+            }
+            if (result == null) {
+                result = new ArrayList<String>();
+            }
+            result.add(candidate);
+        }
+        return result;
+    }
+
+    public void failed(int ecode, String fname, String debugHint) {
+        String command = SessionState.get() != null ? SessionState.get().getLastCommand() : null;
+        Assert.fail("Client Execution failed with error code = " + ecode +
+                (command != null ? " running " + command : "") + (debugHint != null ? debugHint :
+                ""));
+    }
+
+    // for negative tests, which is succeeded.. no need to print the query string
+    public void failed(String fname, String debugHint) {
+        Assert.fail("Client Execution was expected to fail, but succeeded with error code 0 " +
+                (debugHint != null ? debugHint : ""));
+    }
+
+    public void failedDiff(int ecode, String fname, String debugHint) {
+        Assert.fail("Client Execution results failed with error code = " + ecode +
+                (debugHint != null ? debugHint : ""));
+    }
+
+    public void failed(Throwable e, String fname, String debugHint) {
+        String command = SessionState.get() != null ? SessionState.get().getLastCommand() : null;
+        LOG.error("Exception: ", e);
+        e.printStackTrace();
+        LOG.error("Failed query: " + fname);
+        Assert.fail("Unexpected exception " +
+                org.apache.hadoop.util.StringUtils.stringifyException(e) + "\n" +
+                (command != null ? " running " + command : "") +
+                (debugHint != null ? debugHint : ""));
+    }
+
+    public static class WindowsPathUtil {
+
+        public static void convertPathsFromWindowsToHdfs(HiveConf conf) {
+            // Following local paths are used as HDFS paths in unit tests.
+            // It works well in Unix as the path notation in Unix and HDFS is more or less same.
+            // But when it comes to Windows, drive letter separator ':' & backslash '\" are invalid
+            // characters in HDFS so we need to converts these local paths to HDFS paths before
+            // using them
+            // in unit tests.
+
+            String orgWarehouseDir = conf.getVar(HiveConf.ConfVars.METASTOREWAREHOUSE);
+            conf.setVar(HiveConf.ConfVars.METASTOREWAREHOUSE, getHdfsUriString(orgWarehouseDir));
+
+            String orgTestTempDir = System.getProperty("test.tmp.dir");
+            System.setProperty("test.tmp.dir", getHdfsUriString(orgTestTempDir));
+
+            String orgTestWarehouseDir = System.getProperty("test.warehouse.dir");
+            System.setProperty("test.warehouse.dir", getHdfsUriString(orgTestWarehouseDir));
+
+            String orgScratchDir = conf.getVar(HiveConf.ConfVars.SCRATCHDIR);
+            conf.setVar(HiveConf.ConfVars.SCRATCHDIR, getHdfsUriString(orgScratchDir));
+        }
+
+        public static String getHdfsUriString(String uriStr) {
+            assert uriStr != null;
+            if (Shell.WINDOWS) {
+                // If the URI conversion is from Windows to HDFS then replace the '\' with '/'
+                // and remove the windows single drive letter & colon from absolute path.
+                return uriStr.replace('\\', '/')
+                        .replaceFirst("/[c-zC-Z]:", "/")
+                        .replaceFirst("^[c-zC-Z]:", "");
+            }
+            return uriStr;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixMetaHook.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixMetaHook.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixMetaHook.java
new file mode 100644
index 0000000..d920517
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/PhoenixMetaHook.java
@@ -0,0 +1,246 @@
+/*
+ * 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.phoenix.hive;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hive.metastore.HiveMetaHook;
+import org.apache.hadoop.hive.metastore.TableType;
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.hive.util.PhoenixConnectionUtil;
+import org.apache.phoenix.hive.util.PhoenixStorageHandlerUtil;
+import org.apache.phoenix.hive.util.PhoenixUtil;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation for notification methods which are invoked as part of transactions against the
+ * hive metastore,allowing Phoenix metadata to be kept in sync with Hive'smetastore.
+ */
+public class PhoenixMetaHook implements HiveMetaHook {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixMetaHook.class);
+
+    @Override
+    public void preCreateTable(Table table) throws MetaException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Precreate  table : " + table.getTableName());
+        }
+
+        try (Connection conn = PhoenixConnectionUtil.getConnection(table)) {
+            String tableType = table.getTableType();
+            String tableName = PhoenixStorageHandlerUtil.getTargetTableName(table);
+
+            if (TableType.EXTERNAL_TABLE.name().equals(tableType)) {
+                // Check whether phoenix table exists.
+                if (!PhoenixUtil.existTable(conn, tableName)) {
+                    // Error if phoenix table not exist.
+                    throw new MetaException("Phoenix table " + tableName + " doesn't exist");
+                }
+            } else if (TableType.MANAGED_TABLE.name().equals(tableType)) {
+                // Check whether phoenix table exists.
+                if (PhoenixUtil.existTable(conn, tableName)) {
+                    // Error if phoenix table already exist.
+                    throw new MetaException("Phoenix table " + tableName + " already exist.");
+                }
+
+                PhoenixUtil.createTable(conn, createTableStatement(table));
+            } else {
+                throw new MetaException("Unsupported table Type: " + table.getTableType());
+            }
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Phoenix table " + tableName + " was created");
+            }
+        } catch (SQLException e) {
+            throw new MetaException(e.getMessage());
+        }
+    }
+
+    private String createTableStatement(Table table) throws MetaException {
+        Map<String, String> tableParameterMap = table.getParameters();
+
+        String tableName = PhoenixStorageHandlerUtil.getTargetTableName(table);
+        StringBuilder ddl = new StringBuilder("create table ").append(tableName).append(" (\n");
+
+        String phoenixRowKeys = tableParameterMap.get(PhoenixStorageHandlerConstants
+                .PHOENIX_ROWKEYS);
+        StringBuilder realRowKeys = new StringBuilder();
+        List<String> phoenixRowKeyList = Lists.newArrayList(Splitter.on
+                (PhoenixStorageHandlerConstants.COMMA).trimResults().split(phoenixRowKeys));
+        Map<String, String> columnMappingMap = getColumnMappingMap(tableParameterMap.get
+                (PhoenixStorageHandlerConstants.PHOENIX_COLUMN_MAPPING));
+
+        List<FieldSchema> fieldSchemaList = table.getSd().getCols();
+        for (int i = 0, limit = fieldSchemaList.size(); i < limit; i++) {
+            FieldSchema fieldSchema = fieldSchemaList.get(i);
+            String fieldName = fieldSchema.getName();
+            String fieldType = fieldSchema.getType();
+            String columnType = PhoenixUtil.getPhoenixType(fieldType);
+
+            String rowKeyName = getRowKeyMapping(fieldName, phoenixRowKeyList);
+            if (rowKeyName != null) {
+                // In case of RowKey
+                if ("binary".equals(columnType)) {
+                    // Phoenix must define max length of binary when type definition. Obtaining
+                    // information from the column mapping. ex) phoenix.rowkeys = "r1, r2(100), ..."
+                    List<String> tokenList = Lists.newArrayList(Splitter.on(CharMatcher.is('(')
+                            .or(CharMatcher.is(')'))).trimResults().split(rowKeyName));
+                    columnType = columnType + "(" + tokenList.get(1) + ")";
+                    rowKeyName = tokenList.get(0);
+                }
+
+                ddl.append("  ").append(rowKeyName).append(" ").append(columnType).append(" not " +
+                        "null,\n");
+                realRowKeys.append(rowKeyName).append(",");
+            } else {
+                // In case of Column
+                String columnName = columnMappingMap.get(fieldName);
+
+                if (columnName == null) {
+                    // Use field definition.
+                    columnName = fieldName;
+                }
+
+                if ("binary".equals(columnType)) {
+                    // Phoenix must define max length of binary when type definition. Obtaining
+                    // information from the column mapping. ex) phoenix.column.mapping=c1:c1(100)
+                    List<String> tokenList = Lists.newArrayList(Splitter.on(CharMatcher.is('(')
+                            .or(CharMatcher.is(')'))).trimResults().split(columnName));
+                    columnType = columnType + "(" + tokenList.get(1) + ")";
+                    columnName = tokenList.get(0);
+                }
+
+                ddl.append("  ").append(columnName).append(" ").append(columnType).append(",\n");
+            }
+        }
+        ddl.append("  ").append("constraint pk_").append(tableName).append(" primary key(")
+                .append(realRowKeys.deleteCharAt(realRowKeys.length() - 1)).append(")\n)\n");
+
+        String tableOptions = tableParameterMap.get(PhoenixStorageHandlerConstants
+                .PHOENIX_TABLE_OPTIONS);
+        if (tableOptions != null) {
+            ddl.append(tableOptions);
+        }
+
+        String statement = ddl.toString();
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("DDL : " + statement);
+        }
+
+        return statement;
+    }
+
+    private String getRowKeyMapping(String rowKeyName, List<String> phoenixRowKeyList) {
+        String rowKeyMapping = null;
+
+        for (String phoenixRowKey : phoenixRowKeyList) {
+            if (phoenixRowKey.equals(rowKeyName)) {
+                rowKeyMapping = phoenixRowKey;
+                break;
+            } else if (phoenixRowKey.startsWith(rowKeyName + "(") && phoenixRowKey.endsWith(")")) {
+                rowKeyMapping = phoenixRowKey;
+                break;
+            }
+        }
+
+        return rowKeyMapping;
+    }
+
+    private Map<String, String> getColumnMappingMap(String columnMappings) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Column mappings : " + columnMappings);
+        }
+
+        if (columnMappings == null) {
+            if (LOG.isInfoEnabled()) {
+                LOG.info("phoenix.column.mapping not set. using field definition");
+            }
+
+            return Collections.emptyMap();
+        }
+
+        Map<String, String> columnMappingMap = Splitter.on(PhoenixStorageHandlerConstants.COMMA)
+                .trimResults().withKeyValueSeparator(PhoenixStorageHandlerConstants.COLON).split
+                        (columnMappings);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Column mapping map : " + columnMappingMap);
+        }
+
+        return columnMappingMap;
+    }
+
+    @Override
+    public void rollbackCreateTable(Table table) throws MetaException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Rollback for table : " + table.getTableName());
+        }
+
+        dropTableIfExist(table);
+    }
+
+    @Override
+    public void commitCreateTable(Table table) throws MetaException {
+
+    }
+
+    @Override
+    public void preDropTable(Table table) throws MetaException {
+    }
+
+    @Override
+    public void rollbackDropTable(Table table) throws MetaException {
+    }
+
+    @Override
+    public void commitDropTable(Table table, boolean deleteData) throws MetaException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Commit drop table : " + table.getTableName());
+        }
+
+        dropTableIfExist(table);
+    }
+
+    private void dropTableIfExist(Table table) throws MetaException {
+        try (Connection conn = PhoenixConnectionUtil.getConnection(table)) {
+            String tableType = table.getTableType();
+            String tableName = PhoenixStorageHandlerUtil.getTargetTableName(table);
+
+            if (TableType.MANAGED_TABLE.name().equals(tableType)) {
+                // Drop if phoenix table exist.
+                if (PhoenixUtil.existTable(conn, tableName)) {
+                    PhoenixUtil.dropTable(conn, tableName);
+                }
+            }
+        } catch (SQLException e) {
+            throw new MetaException(e.getMessage());
+        }
+    }
+}


[28/52] [abbrv] phoenix git commit: PHOENIX-2743 HivePhoenixHandler for big-big join with

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixUtil.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixUtil.java
new file mode 100644
index 0000000..e889b63
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixUtil.java
@@ -0,0 +1,210 @@
+/*
+ * 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.phoenix.hive.util;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.phoenix.coprocessor.MetaDataProtocol.MetaDataMutationResult;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.schema.MetaDataClient;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.util.ColumnInfo;
+import org.apache.phoenix.util.PhoenixRuntime;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Misc utils
+ */
+public class PhoenixUtil {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixUtil.class);
+
+    public static String getPhoenixType(String hiveTypeName) {
+        if (hiveTypeName.startsWith("array")) {
+            List<String> tokenList = Lists.newArrayList(Splitter.on(CharMatcher.is('<').or
+                    (CharMatcher.is('>'))).split(hiveTypeName));
+            return getPhoenixType(tokenList.get(1)) + "[]";
+        } else if (hiveTypeName.startsWith("int")) {
+            return "integer";
+        } else if (hiveTypeName.equals("string")) {
+            return "varchar";
+        } else {
+            return hiveTypeName;
+        }
+    }
+
+    public static boolean existTable(Connection conn, String tableName) throws SQLException {
+        boolean exist = false;
+        DatabaseMetaData dbMeta = conn.getMetaData();
+
+        try (ResultSet rs = dbMeta.getTables(null, null, tableName.toUpperCase(), null)) {
+            exist = rs.next();
+
+            if (LOG.isDebugEnabled()) {
+                if (exist) {
+                    LOG.debug(rs.getString("TABLE_NAME") + " table exist. ");
+                } else {
+                    LOG.debug("table " + tableName + " doesn't exist.");
+                }
+            }
+        }
+
+        return exist;
+    }
+
+    public static List<String> getPrimaryKeyColumnList(Connection conn, String tableName) throws
+            SQLException {
+        Map<Short, String> primaryKeyColumnInfoMap = Maps.newHashMap();
+        DatabaseMetaData dbMeta = conn.getMetaData();
+
+        try (ResultSet rs = dbMeta.getPrimaryKeys(null, null, tableName.toUpperCase())) {
+            while (rs.next()) {
+                primaryKeyColumnInfoMap.put(rs.getShort("KEY_SEQ"), rs.getString("COLUMN_NAME"));
+            }
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("PK-columns : " + primaryKeyColumnInfoMap);
+            }
+        }
+
+        return Lists.newArrayList(primaryKeyColumnInfoMap.values());
+    }
+
+    public static List<String> getPrimaryKeyColumnList(Configuration config, String tableName) {
+        List<String> pkColumnNameList = null;
+
+        try (Connection conn = PhoenixConnectionUtil.getInputConnection(config, new Properties())) {
+            pkColumnNameList = getPrimaryKeyColumnList(conn, tableName);
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+
+        return pkColumnNameList;
+    }
+
+    public static void createTable(Connection conn, String createTableStatement) throws
+            SQLException {
+        conn.createStatement().execute(createTableStatement);
+    }
+
+    public static void dropTable(Connection conn, String tableName) throws SQLException {
+        conn.createStatement().execute("drop table " + tableName);
+    }
+
+    public static List<ColumnInfo> getColumnInfoList(Connection conn, String tableName) throws
+            SQLException {
+        List<ColumnInfo> columnInfoList = null;
+
+        try {
+            columnInfoList = PhoenixRuntime.generateColumnInfo(conn, tableName, null);
+        } catch (TableNotFoundException e) {
+            // Exception can be occurred when table create.
+            columnInfoList = Collections.emptyList();
+        }
+
+        return columnInfoList;
+    }
+
+    public static String[] getTableSchema(String tableName) {
+        String[] schemaInfo = new String[2];
+        String[] tokens = tableName.split("\\.");
+
+        if (tokens.length == 2) {
+            schemaInfo = tokens;
+        } else {
+            schemaInfo[1] = tokens[0];
+        }
+
+        return schemaInfo;
+    }
+
+    public static boolean isDisabledWal(MetaDataClient metaDataClient, String tableName) throws
+            SQLException {
+        String[] schemaInfo = getTableSchema(tableName.toUpperCase());
+        MetaDataMutationResult result = metaDataClient.updateCache(schemaInfo[0], schemaInfo[1]);
+        PTable dataTable = result.getTable();
+
+        return dataTable.isWALDisabled();
+    }
+
+    public static void alterTableForWalDisable(Connection conn, String tableName, boolean
+            disableMode) throws SQLException {
+        conn.createStatement().execute("alter table " + tableName + " set disable_wal=" +
+                disableMode);
+    }
+
+    public static void flush(Connection conn, String tableName) throws SQLException {
+        try (HBaseAdmin admin = ((PhoenixConnection) conn).getQueryServices().getAdmin()) {
+            admin.flush(TableName.valueOf(tableName).getName());
+        } catch (IOException e) {
+            throw new SQLException(e);
+        } catch (InterruptedException e) {
+            throw new SQLException(e);
+        }
+    }
+
+    public static String constructDeleteStatement(Connection conn, String tableName) throws
+            SQLException {
+        StringBuilder deleteQuery = new StringBuilder("delete from ").append(tableName).append(" " +
+                "where ");
+
+        List<String> primaryKeyColumnList = getPrimaryKeyColumnList(conn, tableName);
+        for (int i = 0, limit = primaryKeyColumnList.size(); i < limit; i++) {
+            String pkColumn = primaryKeyColumnList.get(i);
+            deleteQuery.append(pkColumn).append(PhoenixStorageHandlerConstants.EQUAL).append
+                    (PhoenixStorageHandlerConstants.QUESTION);
+
+            if ((i + 1) != primaryKeyColumnList.size()) {
+                deleteQuery.append(" and ");
+            }
+        }
+
+        return deleteQuery.toString();
+    }
+
+    public static void closeResource(Statement stmt) throws SQLException {
+        if (stmt != null && !stmt.isClosed()) {
+            stmt.close();
+        }
+    }
+
+    public static void closeResource(Connection conn) throws SQLException {
+        if (conn != null && !conn.isClosed()) {
+            conn.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-server/pom.xml
----------------------------------------------------------------------
diff --git a/phoenix-server/pom.xml b/phoenix-server/pom.xml
index 772239c..4bc1a4c 100644
--- a/phoenix-server/pom.xml
+++ b/phoenix-server/pom.xml
@@ -102,6 +102,12 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-auth</artifactId>
+      <version>2.7.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.hbase</groupId>
       <artifactId>hbase-testing-util</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 16762e9..758eb3a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,6 +30,7 @@
     <module>phoenix-server</module>
     <module>phoenix-pherf</module>
     <module>phoenix-spark</module>
+    <module>phoenix-hive</module>
     <module>phoenix-assembly</module>
     <module>phoenix-tracing-webapp</module>
   </modules>
@@ -62,11 +63,12 @@
 
     <!-- Hadoop Versions -->
     <hbase.version>0.98.17-hadoop2</hbase.version>
-    <hadoop-two.version>2.2.0</hadoop-two.version>
+    <hadoop-two.version>2.7.1</hadoop-two.version>
 
     <!-- Dependency versions -->
     <commons-cli.version>1.2</commons-cli.version>
-    <hadoop.version>1.0.4</hadoop.version>
+    <hive.version>1.2.1</hive.version>
+    <hadoop.version>2.7.1</hadoop.version>
     <pig.version>0.13.0</pig.version>
     <jackson.version>1.9.2</jackson.version>
     <antlr.version>3.5.2</antlr.version>
@@ -576,6 +578,39 @@
         <scope>test</scope>
       </dependency>
 
+      <!-- Required for mini-cluster since hbase built against old version of hadoop -->
+      <dependency>
+        <groupId>org.apache.hadoop</groupId>
+        <artifactId>hadoop-auth</artifactId>
+        <version>${hadoop-two.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.hadoop</groupId>
+        <artifactId>hadoop-mapreduce-client-common</artifactId>
+        <version>${hadoop-two.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.hadoop</groupId>
+        <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
+        <version>${hadoop-two.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.hadoop</groupId>
+        <artifactId>hadoop-hdfs</artifactId>
+        <version>${hadoop-two.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.hadoop</groupId>
+        <artifactId>hadoop-hdfs</artifactId>
+        <version>${hadoop-two.version}</version>
+        <type>test-jar</type>
+        <scope>test</scope>
+      </dependency>
+
       <!-- General Dependencies -->
       <dependency>
         <groupId>org.apache.pig</groupId>


[14/52] [abbrv] phoenix git commit: PHOENIX-2156 Support drop of column from table with views

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
index f1816cc..ea376de 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
@@ -18,11 +18,9 @@
 package org.apache.phoenix.end2end;
 
 import static org.apache.phoenix.exception.SQLExceptionCode.CANNOT_MUTATE_TABLE;
-import static org.apache.phoenix.query.QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT;
-import static org.apache.phoenix.query.QueryConstants.DIVERGED_VIEW_BASE_COLUMN_COUNT;
+import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -32,37 +30,47 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.List;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Map;
-import java.util.Properties;
 
-import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.commons.lang.ArrayUtils;
 import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.coprocessor.PhoenixTransactionalProcessor;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
-import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.query.QueryServices;
-import org.apache.phoenix.schema.PColumn;
-import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PName;
+import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableType;
-import org.apache.phoenix.util.IndexUtil;
-import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.ReadOnlyProps;
-import org.apache.phoenix.util.SchemaUtil;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
-import com.google.common.base.Objects;
 import com.google.common.collect.Maps;
 
+@RunWith(Parameterized.class)
 public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
+    
+    private final boolean isMultiTenant;
+    
+    private final String TENANT_SPECIFIC_URL1 = getUrl() + ';' + TENANT_ID_ATTRIB + "=tenant1";
+    private final String TENANT_SPECIFIC_URL2 = getUrl() + ';' + TENANT_ID_ATTRIB + "=tenant2";
+    
+    public AlterTableWithViewsIT(boolean isMultiTenant) {
+        this.isMultiTenant = isMultiTenant;
+    }
+    
+    @Parameters(name="multiTenant = {0}")
+    public static Collection<Boolean> data() {
+        return Arrays.asList(false, true);
+    }
 	
 	@BeforeClass
     @Shadower(classBeingShadowed = BaseHBaseManagedTimeIT.class)
@@ -71,49 +79,84 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
         props.put(QueryServices.TRANSACTIONS_ENABLED, Boolean.toString(true));
         setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
     }
+	
+    private String generateDDL(String format) {
+        return String.format(format, isMultiTenant ? "TENANT_ID VARCHAR NOT NULL, " : "",
+            isMultiTenant ? "TENANT_ID, " : "", isMultiTenant ? "MULTI_TENANT=true" : "");
+    }
     
     @Test
     public void testAddNewColumnsToBaseTableWithViews() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        try {       
-            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
-                    + " ID char(1) NOT NULL,"
-                    + " COL1 integer NOT NULL,"
-                    + " COL2 bigint NOT NULL,"
-                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
-                    + " )");
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {       
+            String ddlFormat = "CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
+                            + " %s ID char(1) NOT NULL,"
+                            + " COL1 integer NOT NULL,"
+                            + " COL2 bigint NOT NULL,"
+                            + " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+                            + " ) %s";
+            conn.createStatement().execute(generateDDL(ddlFormat));
             assertTableDefinition(conn, "TABLEWITHVIEW", PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
             
-            conn.createStatement().execute("CREATE VIEW VIEWOFTABLE ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM TABLEWITHVIEW");
+            viewConn.createStatement().execute("CREATE VIEW VIEWOFTABLE ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM TABLEWITHVIEW");
             assertTableDefinition(conn, "VIEWOFTABLE", PTableType.VIEW, "TABLEWITHVIEW", 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
             // adding a new pk column and a new regular column
             conn.createStatement().execute("ALTER TABLE TABLEWITHVIEW ADD COL3 varchar(10) PRIMARY KEY, COL4 integer");
             assertTableDefinition(conn, "TABLEWITHVIEW", PTableType.TABLE, null, 1, 5, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3", "COL4");
             assertTableDefinition(conn, "VIEWOFTABLE", PTableType.VIEW, "TABLEWITHVIEW", 1, 7, 5, "ID", "COL1", "COL2", "COL3", "COL4", "VIEW_COL1", "VIEW_COL2");
-        } finally {
-            conn.close();
+        } 
+    }
+    
+    @Test
+    public void testDropColumnsFromBaseTableWithView() throws Exception {
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) { 
+            String ddlFormat = "CREATE TABLE IF NOT EXISTS TABLEWITHVIEW (" + " %s ID char(1) NOT NULL,"
+                            + " COL1 integer NOT NULL," + " COL2 bigint NOT NULL,"
+                            + " COL3 varchar(10)," + " COL4 varchar(10)," + " COL5 varchar(10),"
+                            + " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)" + " ) %s";
+            conn.createStatement().execute(generateDDL(ddlFormat));
+            assertTableDefinition(conn, "TABLEWITHVIEW", PTableType.TABLE, null, 0, 6,
+                QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL3", "COL4",
+                "COL5");
+
+            viewConn.createStatement()
+                    .execute(
+                        "CREATE VIEW VIEWOFTABLE ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM TABLEWITHVIEW");
+            assertTableDefinition(conn, "VIEWOFTABLE", PTableType.VIEW, "TABLEWITHVIEW", 0, 8, 6,
+                "ID", "COL1", "COL2", "COL3", "COL4", "COL5", "VIEW_COL1", "VIEW_COL2");
+
+            // drop two columns from the base table
+            conn.createStatement().execute("ALTER TABLE TABLEWITHVIEW DROP COLUMN COL3, COL5");
+            assertTableDefinition(conn, "TABLEWITHVIEW", PTableType.TABLE, null, 1, 4,
+                QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2", "COL4");
+            assertTableDefinition(conn, "VIEWOFTABLE", PTableType.VIEW, "TABLEWITHVIEW", 1, 6, 4,
+                "ID", "COL1", "COL2", "COL4", "VIEW_COL1", "VIEW_COL2");
         }
     }
     
     @Test
     public void testAddExistingViewColumnToBaseTableWithViews() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        try {       
-            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
-                    + " ID char(10) NOT NULL,"
-                    + " COL1 integer NOT NULL,"
-                    + " COL2 bigint NOT NULL,"
-                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
-                    + " )");
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {
+            conn.setAutoCommit(false);
+            viewConn.setAutoCommit(false);
+            String ddlFormat = "CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
+                            + " %s ID char(10) NOT NULL,"
+                            + " COL1 integer NOT NULL,"
+                            + " COL2 bigint NOT NULL,"
+                            + " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+                            + " ) %s";
+            conn.createStatement().execute(generateDDL(ddlFormat));
             assertTableDefinition(conn, "TABLEWITHVIEW", PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
             
-            conn.createStatement().execute("CREATE VIEW VIEWOFTABLE ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256), VIEW_COL3 VARCHAR, VIEW_COL4 DECIMAL, VIEW_COL5 DECIMAL(10,2), VIEW_COL6 VARCHAR, CONSTRAINT pk PRIMARY KEY (VIEW_COL5, VIEW_COL6) ) AS SELECT * FROM TABLEWITHVIEW");
+            viewConn.createStatement().execute("CREATE VIEW VIEWOFTABLE ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256), VIEW_COL3 VARCHAR, VIEW_COL4 DECIMAL, VIEW_COL5 DECIMAL(10,2), VIEW_COL6 VARCHAR, CONSTRAINT pk PRIMARY KEY (VIEW_COL5, VIEW_COL6) ) AS SELECT * FROM TABLEWITHVIEW");
             assertTableDefinition(conn, "VIEWOFTABLE", PTableType.VIEW, "TABLEWITHVIEW", 0, 9, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2", "VIEW_COL3", "VIEW_COL4", "VIEW_COL5", "VIEW_COL6");
             
             // upsert single row into view
             String dml = "UPSERT INTO VIEWOFTABLE VALUES(?,?,?,?,?, ?, ?, ?, ?)";
-            PreparedStatement stmt = conn.prepareStatement(dml);
+            PreparedStatement stmt = viewConn.prepareStatement(dml);
             stmt.setString(1, "view1");
             stmt.setInt(2, 12);
             stmt.setInt(3, 13);
@@ -124,7 +167,7 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
             stmt.setInt(8, 18);
             stmt.setString(9, "view9");
             stmt.execute();
-            conn.commit();
+            viewConn.commit();
             
             try {
                 // should fail because there is already a view column with same name of different type
@@ -194,36 +237,37 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
             assertEquals(18, rs.getInt("VIEW_COL5"));
             assertEquals("view9", rs.getString("VIEW_COL6"));
             assertFalse(rs.next());
-        } finally {
-            conn.close();
-        }
+        } 
     }
     
     @Test
     public void testAddExistingViewPkColumnToBaseTableWithViews() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        try {       
-            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
-                    + " ID char(10) NOT NULL,"
-                    + " COL1 integer NOT NULL,"
-                    + " COL2 integer NOT NULL,"
-                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
-                    + " )");
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {      
+            conn.setAutoCommit(false);
+            viewConn.setAutoCommit(false);
+            String ddlFormat = "CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
+                            + " %s ID char(10) NOT NULL,"
+                            + " COL1 integer NOT NULL,"
+                            + " COL2 integer NOT NULL,"
+                            + " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+                            + " ) %s";
+            conn.createStatement().execute(generateDDL(ddlFormat));
             assertTableDefinition(conn, "TABLEWITHVIEW", PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
             
-            conn.createStatement().execute("CREATE VIEW VIEWOFTABLE ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM TABLEWITHVIEW");
+            viewConn.createStatement().execute("CREATE VIEW VIEWOFTABLE ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM TABLEWITHVIEW");
             assertTableDefinition(conn, "VIEWOFTABLE", PTableType.VIEW, "TABLEWITHVIEW", 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
             // upsert single row into view
             String dml = "UPSERT INTO VIEWOFTABLE VALUES(?,?,?,?,?)";
-            PreparedStatement stmt = conn.prepareStatement(dml);
+            PreparedStatement stmt = viewConn.prepareStatement(dml);
             stmt.setString(1, "view1");
             stmt.setInt(2, 12);
             stmt.setInt(3, 13);
             stmt.setInt(4, 14);
             stmt.setString(5, "view5");
             stmt.execute();
-            conn.commit();
+            viewConn.commit();
             
             try {
                 // should fail because there we have to add both VIEW_COL1 and VIEW_COL2 to the pk
@@ -303,27 +347,26 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
             assertEquals(14, rs.getInt("VIEW_COL1"));
             assertEquals("view5", rs.getString("VIEW_COL2"));
             assertFalse(rs.next());
-        } finally {
-            conn.close();
-        }
+        } 
     }
     
     @Test
     public void testAddExistingViewPkColumnToBaseTableWithMultipleViews() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        try {       
-            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
-                    + " ID char(10) NOT NULL,"
-                    + " COL1 integer NOT NULL,"
-                    + " COL2 integer NOT NULL,"
-                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
-                    + " )");
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {              
+            String ddlFormat = "CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
+                            + " %s ID char(10) NOT NULL,"
+                            + " COL1 integer NOT NULL,"
+                            + " COL2 integer NOT NULL,"
+                            + " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+                            + " ) %s";
+            conn.createStatement().execute(generateDDL(ddlFormat));
             assertTableDefinition(conn, "TABLEWITHVIEW", PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
             
-            conn.createStatement().execute("CREATE VIEW VIEWOFTABLE1 ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM TABLEWITHVIEW");
+            viewConn.createStatement().execute("CREATE VIEW VIEWOFTABLE1 ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM TABLEWITHVIEW");
             assertTableDefinition(conn, "VIEWOFTABLE1", PTableType.VIEW, "TABLEWITHVIEW", 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
-            conn.createStatement().execute("CREATE VIEW VIEWOFTABLE2 ( VIEW_COL3 VARCHAR(256), VIEW_COL4 DECIMAL(10,2) CONSTRAINT pk PRIMARY KEY (VIEW_COL3, VIEW_COL4)) AS SELECT * FROM TABLEWITHVIEW");
+            viewConn.createStatement().execute("CREATE VIEW VIEWOFTABLE2 ( VIEW_COL3 VARCHAR(256), VIEW_COL4 DECIMAL(10,2) CONSTRAINT pk PRIMARY KEY (VIEW_COL3, VIEW_COL4)) AS SELECT * FROM TABLEWITHVIEW");
             assertTableDefinition(conn, "VIEWOFTABLE2", PTableType.VIEW, "TABLEWITHVIEW", 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL3", "VIEW_COL4");
             
             try {
@@ -361,48 +404,51 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
             catch (SQLException e) {
                 assertEquals("Unexpected exception", CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
             }
-        } finally {
-            conn.close();
-        }
+        } 
     }
     
     @Test
     public void testAddExistingViewPkColumnToBaseTableWithMultipleViewsHavingSamePks() throws Exception {
-        Connection conn = DriverManager.getConnection(getUrl());
-        try {       
-            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
-                    + " ID char(10) NOT NULL,"
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn;
+                Connection viewConn2 = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn) {
+            conn.setAutoCommit(false);
+            viewConn.setAutoCommit(false);
+            viewConn2.setAutoCommit(false);
+            String ddlFormat = "CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
+                    + " %s ID char(10) NOT NULL,"
                     + " COL1 integer NOT NULL,"
                     + " COL2 integer NOT NULL,"
-                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
-                    + " )");
+                    + " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+                    + " ) %s";
+            conn.createStatement().execute(generateDDL(ddlFormat));
             assertTableDefinition(conn, "TABLEWITHVIEW", PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
             
-            conn.createStatement().execute("CREATE VIEW VIEWOFTABLE1 ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM TABLEWITHVIEW");
+            viewConn.createStatement().execute("CREATE VIEW VIEWOFTABLE1 ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM TABLEWITHVIEW");
             assertTableDefinition(conn, "VIEWOFTABLE1", PTableType.VIEW, "TABLEWITHVIEW", 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
-            conn.createStatement().execute("CREATE VIEW VIEWOFTABLE2 ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM TABLEWITHVIEW");
+            viewConn2.createStatement().execute("CREATE VIEW VIEWOFTABLE2 ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR(256) CONSTRAINT pk PRIMARY KEY (VIEW_COL1, VIEW_COL2)) AS SELECT * FROM TABLEWITHVIEW");
             assertTableDefinition(conn, "VIEWOFTABLE2", PTableType.VIEW, "TABLEWITHVIEW", 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
             // upsert single row into both view
             String dml = "UPSERT INTO VIEWOFTABLE1 VALUES(?,?,?,?,?)";
-            PreparedStatement stmt = conn.prepareStatement(dml);
+            PreparedStatement stmt = viewConn.prepareStatement(dml);
             stmt.setString(1, "view1");
             stmt.setInt(2, 12);
             stmt.setInt(3, 13);
             stmt.setInt(4, 14);
             stmt.setString(5, "view5");
             stmt.execute();
-            conn.commit();
+            viewConn.commit();
             dml = "UPSERT INTO VIEWOFTABLE2 VALUES(?,?,?,?,?)";
-            stmt = conn.prepareStatement(dml);
+            stmt = viewConn2.prepareStatement(dml);
             stmt.setString(1, "view1");
             stmt.setInt(2, 12);
             stmt.setInt(3, 13);
             stmt.setInt(4, 14);
             stmt.setString(5, "view5");
             stmt.execute();
-            conn.commit();
+            viewConn2.commit();
             
             try {
                 // should fail because the view have two extra columns in their pk
@@ -447,7 +493,7 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
             assertFalse(rs.next());
 
             // query both views
-            rs = stmt.executeQuery("SELECT * FROM VIEWOFTABLE1");
+            rs = viewConn.createStatement().executeQuery("SELECT * FROM VIEWOFTABLE1");
             assertTrue(rs.next());
             assertEquals("view1", rs.getString("ID"));
             assertEquals(12, rs.getInt("COL1"));
@@ -455,7 +501,7 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
             assertEquals(14, rs.getInt("VIEW_COL1"));
             assertEquals("view5", rs.getString("VIEW_COL2"));
             assertFalse(rs.next());
-            rs = stmt.executeQuery("SELECT * FROM VIEWOFTABLE2");
+            rs = viewConn2.createStatement().executeQuery("SELECT * FROM VIEWOFTABLE2");
             assertTrue(rs.next());
             assertEquals("view1", rs.getString("ID"));
             assertEquals(12, rs.getInt("COL1"));
@@ -463,59 +509,23 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
             assertEquals(14, rs.getInt("VIEW_COL1"));
             assertEquals("view5", rs.getString("VIEW_COL2"));
             assertFalse(rs.next());
-        } finally {
-            conn.close();
         }
     }
     
-    private void assertTableDefinition(Connection conn, String tableName, PTableType tableType, String parentTableName, int sequenceNumber, int columnCount, int baseColumnCount, String... columnName) throws Exception {
-        PreparedStatement p = conn.prepareStatement("SELECT * FROM SYSTEM.CATALOG WHERE TABLE_NAME=? AND TABLE_TYPE=?");
-        p.setString(1, tableName);
-        p.setString(2, tableType.getSerializedValue());
-        ResultSet rs = p.executeQuery();
-        assertTrue(rs.next());
-        assertEquals(getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in BaseColumnCount"), baseColumnCount, rs.getInt("BASE_COLUMN_COUNT"));
-        assertEquals(getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in columnCount"), columnCount, rs.getInt("COLUMN_COUNT"));
-        assertEquals(getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in sequenceNumber"), sequenceNumber, rs.getInt("TABLE_SEQ_NUM"));
-        rs.close();
-
-        ResultSet parentTableColumnsRs = null; 
-        if (parentTableName != null) {
-            parentTableColumnsRs = conn.getMetaData().getColumns(null, null, parentTableName, null);
-            parentTableColumnsRs.next();
+    public void assertTableDefinition(Connection conn, String tableName, PTableType tableType, String parentTableName, int sequenceNumber, int columnCount, int baseColumnCount, String... columnNames) throws Exception {
+        int delta = isMultiTenant ? 1 : 0;
+        String[] cols;
+        if (isMultiTenant) {
+            cols = (String[])ArrayUtils.addAll(new String[]{"TENANT_ID"}, columnNames);
         }
-        
-        ResultSet viewColumnsRs = conn.getMetaData().getColumns(null, null, tableName, null);
-        for (int i = 0; i < columnName.length; i++) {
-            if (columnName[i] != null) {
-                assertTrue(viewColumnsRs.next());
-                assertEquals(getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in columnName: i=" + i), columnName[i], viewColumnsRs.getString(PhoenixDatabaseMetaData.COLUMN_NAME));
-                int viewColOrdinalPos = viewColumnsRs.getInt(PhoenixDatabaseMetaData.ORDINAL_POSITION);
-                assertEquals(getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in ordinalPosition: i=" + i), i+1, viewColOrdinalPos);
-                // validate that all the columns in the base table are present in the view   
-                if (parentTableColumnsRs != null && !parentTableColumnsRs.isAfterLast()) {
-                    ResultSetMetaData parentTableColumnsMetadata = parentTableColumnsRs.getMetaData();
-                    assertEquals(parentTableColumnsMetadata.getColumnCount(), viewColumnsRs.getMetaData().getColumnCount());
-                    int parentTableColOrdinalRs = parentTableColumnsRs.getInt(PhoenixDatabaseMetaData.ORDINAL_POSITION);
-                    assertEquals(getSystemCatalogEntriesForTable(conn, tableName, "Mismatch in ordinalPosition of view and base table for i=" + i), parentTableColOrdinalRs, viewColOrdinalPos);
-                    for (int columnIndex = 1; columnIndex < parentTableColumnsMetadata.getColumnCount(); columnIndex++) {
-                        String viewColumnValue = viewColumnsRs.getString(columnIndex);
-                        String parentTableColumnValue = parentTableColumnsRs.getString(columnIndex);
-                        if (!Objects.equal(viewColumnValue, parentTableColumnValue)) {
-                            if (parentTableColumnsMetadata.getColumnName(columnIndex).equals(PhoenixDatabaseMetaData.TABLE_NAME)) {
-                                assertEquals(parentTableName, parentTableColumnValue);
-                                assertEquals(tableName, viewColumnValue);
-                            } 
-                        }
-                    }
-                    parentTableColumnsRs.next();
-                }
-            }
+        else {
+            cols = columnNames;
         }
-        assertFalse(getSystemCatalogEntriesForTable(conn, tableName, ""), viewColumnsRs.next());
+        AlterMultiTenantTableWithViews.assertTableDefinition(conn, tableName, tableType, parentTableName, sequenceNumber, columnCount + delta,
+            baseColumnCount==QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT ? baseColumnCount : baseColumnCount +delta, cols);
     }
     
-    private String getSystemCatalogEntriesForTable(Connection conn, String tableName, String message) throws Exception {
+    public static String getSystemCatalogEntriesForTable(Connection conn, String tableName, String message) throws Exception {
         StringBuilder sb = new StringBuilder(message);
         sb.append("\n\n\n");
         ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM SYSTEM.CATALOG WHERE TABLE_NAME='"+ tableName +"'");
@@ -532,90 +542,49 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
         return sb.toString();
     }
     
-    @Test
-    public void testCacheInvalidatedAfterAddingColumnToBaseTableWithViews() throws Exception {
-        String baseTable = "testCacheInvalidatedAfterAddingColumnToBaseTableWithViews";
-        String viewName = baseTable + "_view";
-        String tenantId = "tenantId";
-        try (Connection globalConn = DriverManager.getConnection(getUrl())) {
-            String tableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true " ;
-            globalConn.createStatement().execute(tableDDL);
-            Properties tenantProps = new Properties();
-            tenantProps.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
-            // create a tenant specific view
-            try (Connection tenantConn =  DriverManager.getConnection(getUrl(), tenantProps)) {
-                String viewDDL = "CREATE VIEW " + viewName + " AS SELECT * FROM " + baseTable;
-                tenantConn.createStatement().execute(viewDDL);
-                
-                // Add a column to the base table using global connection
-                globalConn.createStatement().execute("ALTER TABLE " + baseTable + " ADD NEW_COL VARCHAR");
-
-                // Check now whether the tenant connection can see the column that was added
-                tenantConn.createStatement().execute("SELECT NEW_COL FROM " + viewName);
-                tenantConn.createStatement().execute("SELECT NEW_COL FROM " + baseTable);
-            }
-        }
-    }
     
-    @Test
-    public void testDropColumnOnTableWithViewsNotAllowed() throws Exception {
-        String baseTable = "testDropColumnOnTableWithViewsNotAllowed";
-        String viewName = baseTable + "_view";
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            String tableDDL = "CREATE TABLE " + baseTable + " (PK1 VARCHAR NOT NULL PRIMARY KEY, V1 VARCHAR, V2 VARCHAR)";
-            conn.createStatement().execute(tableDDL);
-            
-            String viewDDL = "CREATE VIEW " + viewName + " AS SELECT * FROM " + baseTable;
-            conn.createStatement().execute(viewDDL);
-            
-            String dropColumn = "ALTER TABLE " + baseTable + " DROP COLUMN V2";
-            try {
-                conn.createStatement().execute(dropColumn);
-                fail("Dropping column on a base table that has views is not allowed");
-            } catch (SQLException e) {  
-                assertEquals(CANNOT_MUTATE_TABLE.getErrorCode(), e.getErrorCode());
-            }
-        }
-    }
     
     @Test
     public void testAlteringViewThatHasChildViews() throws Exception {
         String baseTable = "testAlteringViewThatHasChildViews";
         String childView = "childView";
         String grandChildView = "grandChildView";
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            String baseTableDDL =
-                    "CREATE TABLE " +  baseTable + " (TENANT_ID VARCHAR NOT NULL, PK2 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK2))";
-            conn.createStatement().execute(baseTableDDL);
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {
+            String ddlFormat = "CREATE TABLE IF NOT EXISTS " + baseTable + "  ("
+                    + " %s PK2 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR "
+                    + " CONSTRAINT NAME_PK PRIMARY KEY (%s PK2)"
+                    + " ) %s";
+            conn.createStatement().execute(generateDDL(ddlFormat));
 
             String childViewDDL = "CREATE VIEW " + childView + " AS SELECT * FROM " + baseTable;
-            conn.createStatement().execute(childViewDDL);
+            viewConn.createStatement().execute(childViewDDL);
 
             String addColumnToChildViewDDL =
                     "ALTER VIEW " + childView + " ADD CHILD_VIEW_COL VARCHAR";
-            conn.createStatement().execute(addColumnToChildViewDDL);
+            viewConn.createStatement().execute(addColumnToChildViewDDL);
 
             String grandChildViewDDL =
                     "CREATE VIEW " + grandChildView + " AS SELECT * FROM " + childView;
-            conn.createStatement().execute(grandChildViewDDL);
+            viewConn.createStatement().execute(grandChildViewDDL);
 
             // dropping base table column from child view should succeed
             String dropColumnFromChildView = "ALTER VIEW " + childView + " DROP COLUMN V2";
-            conn.createStatement().execute(dropColumnFromChildView);
+            viewConn.createStatement().execute(dropColumnFromChildView);
 
             // dropping view specific column from child view should succeed
             dropColumnFromChildView = "ALTER VIEW " + childView + " DROP COLUMN CHILD_VIEW_COL";
-            conn.createStatement().execute(dropColumnFromChildView);
+            viewConn.createStatement().execute(dropColumnFromChildView);
             
             // Adding column to view that has child views is allowed
             String addColumnToChildView = "ALTER VIEW " + childView + " ADD V5 VARCHAR";
-            conn.createStatement().execute(addColumnToChildView);
+            viewConn.createStatement().execute(addColumnToChildView);
             // V5 column should be visible now for childView
-            conn.createStatement().execute("SELECT V5 FROM " + childView);    
+            viewConn.createStatement().execute("SELECT V5 FROM " + childView);    
             
             // However, column V5 shouldn't have propagated to grandChildView. Not till PHOENIX-2054 is fixed.
             try {
-                conn.createStatement().execute("SELECT V5 FROM " + grandChildView);
+                viewConn.createStatement().execute("SELECT V5 FROM " + grandChildView);
             } catch (SQLException e) {
                 assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
             }
@@ -623,11 +592,11 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
             // dropping column from the grand child view, however, should work.
             String dropColumnFromGrandChildView =
                     "ALTER VIEW " + grandChildView + " DROP COLUMN CHILD_VIEW_COL";
-            conn.createStatement().execute(dropColumnFromGrandChildView);
+            viewConn.createStatement().execute(dropColumnFromGrandChildView);
 
             // similarly, dropping column inherited from the base table should work.
             dropColumnFromGrandChildView = "ALTER VIEW " + grandChildView + " DROP COLUMN V2";
-            conn.createStatement().execute(dropColumnFromGrandChildView);
+            viewConn.createStatement().execute(dropColumnFromGrandChildView);
         }
     }
     
@@ -636,19 +605,24 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
         String baseTable = "testDivergedViewsStayDiverged";
         String view1 = baseTable + "_view1";
         String view2 = baseTable + "_view2";
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            String tableDDL = "CREATE TABLE " + baseTable + " (PK1 VARCHAR NOT NULL PRIMARY KEY, V1 VARCHAR, V2 VARCHAR)";
-            conn.createStatement().execute(tableDDL);
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ;
+                Connection viewConn2 = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL2) : conn) {
+            String ddlFormat = "CREATE TABLE IF NOT EXISTS " + baseTable + " ("
+                    + " %s PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR "
+                    + " CONSTRAINT NAME_PK PRIMARY KEY (%s PK1)"
+                    + " ) %s";
+            conn.createStatement().execute(generateDDL(ddlFormat));
             
             String viewDDL = "CREATE VIEW " + view1 + " AS SELECT * FROM " + baseTable;
-            conn.createStatement().execute(viewDDL);
+            viewConn.createStatement().execute(viewDDL);
             
             viewDDL = "CREATE VIEW " + view2 + " AS SELECT * FROM " + baseTable;
-            conn.createStatement().execute(viewDDL);
+            viewConn2.createStatement().execute(viewDDL);
             
             // Drop the column inherited from base table to make it diverged
             String dropColumn = "ALTER VIEW " + view1 + " DROP COLUMN V2";
-            conn.createStatement().execute(dropColumn);
+            viewConn.createStatement().execute(dropColumn);
             
             String alterBaseTable = "ALTER TABLE " + baseTable + " ADD V3 VARCHAR";
             conn.createStatement().execute(alterBaseTable);
@@ -656,508 +630,50 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
             // Column V3 shouldn't have propagated to the diverged view.
             String sql = "SELECT V3 FROM " + view1;
             try {
-                conn.createStatement().execute(sql);
+                viewConn.createStatement().execute(sql);
             } catch (SQLException e) {
                 assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
             }
             
             // However, column V3 should have propagated to the non-diverged view.
             sql = "SELECT V3 FROM " + view2;
-            conn.createStatement().execute(sql);
+            viewConn2.createStatement().execute(sql);
         } 
     }
     
     @Test
-    public void testAddingColumnToBaseTablePropagatesToEntireViewHierarchy() throws Exception {
-        String baseTable = "testViewHierarchy";
-        String view1 = "view1";
-        String view2 = "view2";
-        String view3 = "view3";
-        String view4 = "view4";
-        /*                                     baseTable
-                                 /                  |               \ 
-                         view1(tenant1)    view3(tenant2)          view4(global)
-                          /
-                        view2(tenant1)  
-        */
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
-            conn.createStatement().execute(baseTableDDL);
-            
-            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
-                String view1DDL = "CREATE VIEW " + view1 + " AS SELECT * FROM " + baseTable;
-                tenant1Conn.createStatement().execute(view1DDL);
-                
-                String view2DDL = "CREATE VIEW " + view2 + " AS SELECT * FROM " + view1;
-                tenant1Conn.createStatement().execute(view2DDL);
-            }
-            
-            try (Connection tenant2Conn = getTenantConnection("tenant2")) {
-                String view3DDL = "CREATE VIEW " + view3 + " AS SELECT * FROM " + baseTable;
-                tenant2Conn.createStatement().execute(view3DDL);
-            }
-            
-            String view4DDL = "CREATE VIEW " + view4 + " AS SELECT * FROM " + baseTable;
-            conn.createStatement().execute(view4DDL);
-            
-            String alterBaseTable = "ALTER TABLE " + baseTable + " ADD V3 VARCHAR";
-            conn.createStatement().execute(alterBaseTable);
-            
-            // verify that the column is visible to view4
-            conn.createStatement().execute("SELECT V3 FROM " + view4);
-            
-            // verify that the column is visible to view1 and view2
-            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
-                tenant1Conn.createStatement().execute("SELECT V3 from " + view1);
-                tenant1Conn.createStatement().execute("SELECT V3 from " + view2);
-            }
-            
-            // verify that the column is visible to view3
-            try (Connection tenant2Conn = getTenantConnection("tenant2")) {
-                tenant2Conn.createStatement().execute("SELECT V3 from " + view3);
-            }
-            
-        }
-           
-    }
-    
-    @Test
-    public void testChangingPKOfBaseTableChangesPKForAllViews() throws Exception {
-        String baseTable = "testChangePKOfBaseTable";
-        String view1 = "view1";
-        String view2 = "view2";
-        String view3 = "view3";
-        String view4 = "view4";
-        /*                                     baseTable
-                                 /                  |               \ 
-                         view1(tenant1)    view3(tenant2)          view4(global)
-                          /
-                        view2(tenant1)  
-         */
-        Connection tenant1Conn = null, tenant2Conn = null;
-        try (Connection globalConn = DriverManager.getConnection(getUrl())) {
-            String baseTableDDL = "CREATE TABLE "
-                    + baseTable
-                    + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
-            globalConn.createStatement().execute(baseTableDDL);
-
-            tenant1Conn = getTenantConnection("tenant1");
-            String view1DDL = "CREATE VIEW " + view1 + " AS SELECT * FROM " + baseTable;
-            tenant1Conn.createStatement().execute(view1DDL);
-
-            String view2DDL = "CREATE VIEW " + view2 + " AS SELECT * FROM " + view1;
-            tenant1Conn.createStatement().execute(view2DDL);
-
-            tenant2Conn = getTenantConnection("tenant2");
-            String view3DDL = "CREATE VIEW " + view3 + " AS SELECT * FROM " + baseTable;
-            tenant2Conn.createStatement().execute(view3DDL);
-
-            String view4DDL = "CREATE VIEW " + view4 + " AS SELECT * FROM " + baseTable;
-            globalConn.createStatement().execute(view4DDL);
-
-            String alterBaseTable = "ALTER TABLE " + baseTable + " ADD NEW_PK varchar primary key ";
-            globalConn.createStatement().execute(alterBaseTable);
-            
-            // verify that the new column new_pk is now part of the primary key for the entire hierarchy
-            
-            globalConn.createStatement().execute("SELECT * FROM " + baseTable);
-            assertTrue(checkColumnPartOfPk(globalConn.unwrap(PhoenixConnection.class), "NEW_PK", baseTable));
-            
-            tenant1Conn.createStatement().execute("SELECT * FROM " + view1);
-            assertTrue(checkColumnPartOfPk(tenant1Conn.unwrap(PhoenixConnection.class), "NEW_PK", view1));
-            
-            tenant1Conn.createStatement().execute("SELECT * FROM " + view2);
-            assertTrue(checkColumnPartOfPk(tenant1Conn.unwrap(PhoenixConnection.class), "NEW_PK", view2));
-            
-            tenant2Conn.createStatement().execute("SELECT * FROM " + view3);
-            assertTrue(checkColumnPartOfPk(tenant2Conn.unwrap(PhoenixConnection.class), "NEW_PK", view3));
-            
-            globalConn.createStatement().execute("SELECT * FROM " + view4);
-            assertTrue(checkColumnPartOfPk(globalConn.unwrap(PhoenixConnection.class), "NEW_PK", view4));
-
-        } finally {
-            if (tenant1Conn != null) {
-                try {
-                    tenant1Conn.close();
-                } catch (Throwable ignore) {}
-            }
-            if (tenant2Conn != null) {
-                try {
-                    tenant2Conn.close();
-                } catch (Throwable ignore) {}
-            }
-        }
-
-    }
-    
-    private boolean checkColumnPartOfPk(PhoenixConnection conn, String columnName, String tableName) throws SQLException {
-        String normalizedTableName = SchemaUtil.normalizeIdentifier(tableName);
-        PTable table = conn.getTable(new PTableKey(conn.getTenantId(), normalizedTableName));
-        List<PColumn> pkCols = table.getPKColumns();
-        String normalizedColumnName = SchemaUtil.normalizeIdentifier(columnName);
-        for (PColumn pkCol : pkCols) {
-            if (pkCol.getName().getString().equals(normalizedColumnName)) {
-                return true;
-            }
-        }
-        return false;
-    }
-    
-    private int getIndexOfPkColumn(PhoenixConnection conn, String columnName, String tableName) throws SQLException {
-        String normalizedTableName = SchemaUtil.normalizeIdentifier(tableName);
-        PTable table = conn.getTable(new PTableKey(conn.getTenantId(), normalizedTableName));
-        List<PColumn> pkCols = table.getPKColumns();
-        String normalizedColumnName = SchemaUtil.normalizeIdentifier(columnName);
-        int i = 0;
-        for (PColumn pkCol : pkCols) {
-            if (pkCol.getName().getString().equals(normalizedColumnName)) {
-                return i;
-            }
-            i++;
-        }
-        return -1;
-    }
-    
-    private Connection getTenantConnection(String tenantId) throws Exception {
-        Properties tenantProps = new Properties();
-        tenantProps.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, tenantId);
-        return DriverManager.getConnection(getUrl(), tenantProps);
-    }
-    
-    @Test
-    public void testAddPKColumnToBaseTableWhoseViewsHaveIndices() throws Exception {
-        String baseTable = "testAddPKColumnToBaseTableWhoseViewsHaveIndices";
-        String view1 = "view1";
-        String view2 = "view2";
-        String view3 = "view3";
-        String tenant1 = "tenant1";
-        String tenant2 = "tenant2";
-        String view2Index = view2 + "_idx";
-        String view3Index = view3 + "_idx";
-        /*                          baseTable(mutli-tenant)
-                                 /                           \                
-                         view1(tenant1)                  view3(tenant2, index) 
-                          /
-                        view2(tenant1, index)  
-         */
-        try (Connection globalConn = DriverManager.getConnection(getUrl())) {
-            // make sure that the tables are empty, but reachable
-            globalConn
-            .createStatement()
-            .execute(
-                    "CREATE TABLE "
-                            + baseTable
-                            + " (TENANT_ID VARCHAR NOT NULL, K1 varchar not null, V1 VARCHAR, V2 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, K1)) MULTI_TENANT = true ");
-
-        }
-        try (Connection tenantConn = getTenantConnection(tenant1)) {
-            // create tenant specific view for tenant1 - view1
-            tenantConn.createStatement().execute("CREATE VIEW " + view1 + " AS SELECT * FROM " + baseTable);
-            PhoenixConnection phxConn = tenantConn.unwrap(PhoenixConnection.class);
-            assertEquals(0, getTableSequenceNumber(phxConn, view1));
-            assertEquals(2, getMaxKeySequenceNumber(phxConn, view1));
-
-            // create a view - view2 on view - view1
-            tenantConn.createStatement().execute("CREATE VIEW " + view2 + " AS SELECT * FROM " + view1);
-            assertEquals(0, getTableSequenceNumber(phxConn, view2));
-            assertEquals(2, getMaxKeySequenceNumber(phxConn, view2));
-
-
-            // create an index on view2
-            tenantConn.createStatement().execute("CREATE INDEX " + view2Index + " ON " + view2 + " (v1) include (v2)");
-            assertEquals(0, getTableSequenceNumber(phxConn, view2Index));
-            assertEquals(4, getMaxKeySequenceNumber(phxConn, view2Index));
-        }
-        try (Connection tenantConn = getTenantConnection(tenant2)) {
-            // create tenant specific view for tenant2 - view3
-            tenantConn.createStatement().execute("CREATE VIEW " + view3 + " AS SELECT * FROM " + baseTable);
-            PhoenixConnection phxConn = tenantConn.unwrap(PhoenixConnection.class);
-            assertEquals(0, getTableSequenceNumber(phxConn, view3));
-            assertEquals(2, getMaxKeySequenceNumber(phxConn, view3));
-
-
-            // create an index on view3
-            tenantConn.createStatement().execute("CREATE INDEX " + view3Index + " ON " + view3 + " (v1) include (v2)");
-            assertEquals(0, getTableSequenceNumber(phxConn, view3Index));
-            assertEquals(4, getMaxKeySequenceNumber(phxConn, view3Index));
-
-
-        }
-
-        // alter the base table by adding 1 non-pk and 2 pk columns
-        try (Connection globalConn = DriverManager.getConnection(getUrl())) {
-            globalConn.createStatement().execute("ALTER TABLE " + baseTable + " ADD v3 VARCHAR, k2 VARCHAR PRIMARY KEY, k3 VARCHAR PRIMARY KEY");
-            assertEquals(4, getMaxKeySequenceNumber(globalConn.unwrap(PhoenixConnection.class), baseTable));
-
-            // Upsert records in the base table
-            String upsert = "UPSERT INTO " + baseTable + " (TENANT_ID, K1, K2, K3, V1, V2, V3) VALUES (?, ?, ?, ?, ?, ?, ?)";
-            PreparedStatement stmt = globalConn.prepareStatement(upsert);
-            stmt.setString(1, tenant1);
-            stmt.setString(2, "K1");
-            stmt.setString(3, "K2");
-            stmt.setString(4, "K3");
-            stmt.setString(5, "V1");
-            stmt.setString(6, "V2");
-            stmt.setString(7, "V3");
-            stmt.executeUpdate();
-            stmt.setString(1, tenant2);
-            stmt.setString(2, "K11");
-            stmt.setString(3, "K22");
-            stmt.setString(4, "K33");
-            stmt.setString(5, "V11");
-            stmt.setString(6, "V22");
-            stmt.setString(7, "V33");
-            stmt.executeUpdate();
-            globalConn.commit();
-        }
-
-        // Verify now that the sequence number of data table, indexes and views have changed.
-        // Also verify that the newly added pk columns show up as pk columns of data table, indexes and views.
-        try (Connection tenantConn = getTenantConnection(tenant1)) {
-
-            ResultSet rs = tenantConn.createStatement().executeQuery("SELECT K2, K3, V3 FROM " + view1);
-            PhoenixConnection phxConn = tenantConn.unwrap(PhoenixConnection.class);
-            assertEquals(2, getIndexOfPkColumn(phxConn, "k2", view1));
-            assertEquals(3, getIndexOfPkColumn(phxConn, "k3", view1));
-            assertEquals(1, getTableSequenceNumber(phxConn, view1));
-            assertEquals(4, getMaxKeySequenceNumber(phxConn, view1));
-            verifyNewColumns(rs, "K2", "K3", "V3");
-
-
-            rs = tenantConn.createStatement().executeQuery("SELECT K2, K3, V3 FROM " + view2);
-            assertEquals(2, getIndexOfPkColumn(phxConn, "k2", view2));
-            assertEquals(3, getIndexOfPkColumn(phxConn, "k3", view2));
-            assertEquals(1, getTableSequenceNumber(phxConn, view2));
-            assertEquals(4, getMaxKeySequenceNumber(phxConn, view2));
-            verifyNewColumns(rs, "K2", "K3", "V3");
-
-            assertEquals(4, getIndexOfPkColumn(phxConn, IndexUtil.getIndexColumnName(null, "k2"), view2Index));
-            assertEquals(5, getIndexOfPkColumn(phxConn, IndexUtil.getIndexColumnName(null, "k3"), view2Index));
-            assertEquals(1, getTableSequenceNumber(phxConn, view2Index));
-            assertEquals(6, getMaxKeySequenceNumber(phxConn, view2Index));
-        }
-        try (Connection tenantConn = getTenantConnection(tenant2)) {
-            ResultSet rs = tenantConn.createStatement().executeQuery("SELECT K2, K3, V3 FROM " + view3);
-            PhoenixConnection phxConn = tenantConn.unwrap(PhoenixConnection.class);
-            assertEquals(2, getIndexOfPkColumn(phxConn, "k2", view3));
-            assertEquals(3, getIndexOfPkColumn(phxConn, "k3", view3));
-            assertEquals(1, getTableSequenceNumber(phxConn, view3));
-            verifyNewColumns(rs, "K22", "K33", "V33");
-
-            assertEquals(4, getIndexOfPkColumn(phxConn, IndexUtil.getIndexColumnName(null, "k2"), view3Index));
-            assertEquals(5, getIndexOfPkColumn(phxConn, IndexUtil.getIndexColumnName(null, "k3"), view3Index));
-            assertEquals(1, getTableSequenceNumber(phxConn, view3Index));
-            assertEquals(6, getMaxKeySequenceNumber(phxConn, view3Index));
-        }
-        // Verify that the index is actually being used when using newly added pk col
-        try (Connection tenantConn = getTenantConnection(tenant1)) {
-            String upsert = "UPSERT INTO " + view2 + " (K1, K2, K3, V1, V2, V3) VALUES ('key1', 'key2', 'key3', 'value1', 'value2', 'value3')";
-            tenantConn.createStatement().executeUpdate(upsert);
-            tenantConn.commit();
-            Statement stmt = tenantConn.createStatement();
-            String sql = "SELECT V2 FROM " + view2 + " WHERE V1 = 'value1' AND K3 = 'key3'";
-            QueryPlan plan = stmt.unwrap(PhoenixStatement.class).optimizeQuery(sql);
-            assertTrue(plan.getTableRef().getTable().getName().getString().equals(SchemaUtil.normalizeIdentifier(view2Index)));
-            ResultSet rs = tenantConn.createStatement().executeQuery(sql);
-            verifyNewColumns(rs, "value2");
-        }
-
-    }
-    
-    @Test
-    public void testAddingPkAndKeyValueColumnsToBaseTableWithDivergedView() throws Exception {
-        String baseTable = "testAlteringPkOfBaseTableWithDivergedView".toUpperCase();
-        String view1 = "view1".toUpperCase();
-        String divergedView = "divergedView".toUpperCase();
-        String divergedViewIndex = divergedView + "_IDX";
-        /*                                     baseTable
-                                 /                  |                
-                         view1(tenant1)         divergedView(tenant2)    
-                            
-        */
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
-            conn.createStatement().execute(baseTableDDL);
-            
-            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
-                String view1DDL = "CREATE VIEW " + view1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
-                tenant1Conn.createStatement().execute(view1DDL);
-            }
-            
-            try (Connection tenant2Conn = getTenantConnection("tenant2")) {
-                String divergedViewDDL = "CREATE VIEW " + divergedView + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
-                tenant2Conn.createStatement().execute(divergedViewDDL);
-                // Drop column V2 from the view to have it diverge from the base table
-                tenant2Conn.createStatement().execute("ALTER VIEW " + divergedView + " DROP COLUMN V2");
-                
-                // create an index on the diverged view
-                String indexDDL = "CREATE INDEX " + divergedViewIndex + " ON " + divergedView + " (V1) include (V3)";
-                tenant2Conn.createStatement().execute(indexDDL);
-            }
-            
-            String alterBaseTable = "ALTER TABLE " + baseTable + " ADD KV VARCHAR, PK2 VARCHAR PRIMARY KEY";
-            conn.createStatement().execute(alterBaseTable);
-            
-            
-            // verify that the both columns were added to view1
-            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
-                tenant1Conn.createStatement().execute("SELECT KV from " + view1);
-                tenant1Conn.createStatement().execute("SELECT PK2 from " + view1);
-            }
-            
-            // verify that only the primary key column PK2 was added to diverged view
-            try (Connection tenant2Conn = getTenantConnection("tenant2")) {
-                tenant2Conn.createStatement().execute("SELECT PK2 from " + divergedView);
-                try {
-                    tenant2Conn.createStatement().execute("SELECT KV FROM " + divergedView);
-                } catch (SQLException e) {
-                    assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
-                }
-            }
-            
-            // Upsert records in diverged view. Verify that the PK column was added to the index on it.
-            String upsert = "UPSERT INTO " + divergedView + " (PK1, PK2, V1, V3) VALUES ('PK1', 'PK2', 'V1', 'V3')";
-            try (Connection tenantConn = getTenantConnection("tenant2")) {
-                tenantConn.createStatement().executeUpdate(upsert);
-                tenantConn.commit();
-                Statement stmt = tenantConn.createStatement();
-                String sql = "SELECT V3 FROM " + divergedView + " WHERE V1 = 'V1' AND PK2 = 'PK2'";
-                QueryPlan plan = stmt.unwrap(PhoenixStatement.class).optimizeQuery(sql);
-                assertTrue(plan.getTableRef().getTable().getName().getString().equals(SchemaUtil.normalizeIdentifier(divergedViewIndex)));
-                ResultSet rs = tenantConn.createStatement().executeQuery(sql);
-                verifyNewColumns(rs, "V3");
-            }
-            
-            // For non-diverged view, base table columns will be added at the same position as base table
-            assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 1, 9, 7, "TENANT_ID", "PK1", "V1", "V2", "V3", "KV", "PK2", "VIEW_COL1", "VIEW_COL2");
-            // For a diverged view, only base table's pk column will be added and that too at the end.
-            assertTableDefinition(conn, divergedView, PTableType.VIEW, baseTable, 2, 7, DIVERGED_VIEW_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V3", "VIEW_COL1", "VIEW_COL2", "PK2");
-            
-            // Add existing column VIEW_COL2 to the base table
-            alterBaseTable = "ALTER TABLE " + baseTable + " ADD VIEW_COL2 CHAR(256)";
-            conn.createStatement().execute(alterBaseTable);
-            
-            // For the non-diverged view, adding the column VIEW_COL2 will end up changing its ordinal position in the view.
-            assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 2, 9, 8, "TENANT_ID", "PK1", "V1", "V2", "V3", "KV", "PK2", "VIEW_COL2", "VIEW_COL1");
-            // For the diverged view, adding the column VIEW_COL2 will not change its ordinal position in the view. It also won't change the base column count or the sequence number
-            assertTableDefinition(conn, divergedView, PTableType.VIEW, baseTable, 2, 7, DIVERGED_VIEW_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V3", "VIEW_COL1", "VIEW_COL2", "PK2");
-        }
-    }
-    
-    @Test
-    public void testAlterSaltedBaseTableWithViews() throws Exception {
-        String baseTable = "testAlterSaltedBaseTableWithViews".toUpperCase();
-        String view1 = "view1".toUpperCase();
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
-            conn.createStatement().execute(baseTableDDL);
-
-            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
-                String view1DDL = "CREATE VIEW " + view1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
-                tenant1Conn.createStatement().execute(view1DDL);
-            }
-
-            assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 0, 5, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V2", "V3");
-            assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 0, 7, 5, "TENANT_ID", "PK1", "V1", "V2", "V3", "VIEW_COL1", "VIEW_COL2");
-
-            String alterBaseTable = "ALTER TABLE " + baseTable + " ADD KV VARCHAR, PK2 VARCHAR PRIMARY KEY";
-            conn.createStatement().execute(alterBaseTable);
-
-            assertTableDefinition(conn, baseTable, PTableType.TABLE, null, 1, 7, BASE_TABLE_BASE_COLUMN_COUNT, "TENANT_ID", "PK1", "V1", "V2", "V3", "KV", "PK2");
-            assertTableDefinition(conn, view1, PTableType.VIEW, baseTable, 1, 9, 7, "TENANT_ID", "PK1", "V1", "V2", "V3", "KV", "PK2", "VIEW_COL1", "VIEW_COL2");
-
-            // verify that the both columns were added to view1
-            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
-                tenant1Conn.createStatement().execute("SELECT KV from " + view1);
-                tenant1Conn.createStatement().execute("SELECT PK2 from " + view1);
-            }
-        }
-    }
-    
-    @Test
-    public void testAlteringViewConditionallyModifiesHTableMetadata() throws Exception {
-        String baseTable = "testAlteringViewConditionallyModifiesBaseTable".toUpperCase();
-        String view1 = "view1".toUpperCase();
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            String baseTableDDL = "CREATE TABLE " + baseTable + " (TENANT_ID VARCHAR NOT NULL, PK1 VARCHAR NOT NULL, V1 VARCHAR, V2 VARCHAR, V3 VARCHAR CONSTRAINT NAME_PK PRIMARY KEY(TENANT_ID, PK1)) MULTI_TENANT = true ";
-            conn.createStatement().execute(baseTableDDL);
-            HTableDescriptor tableDesc1 = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin().getTableDescriptor(Bytes.toBytes(baseTable)); 
-            try (Connection tenant1Conn = getTenantConnection("tenant1")) {
-                String view1DDL = "CREATE VIEW " + view1 + " ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 CHAR(256)) AS SELECT * FROM " + baseTable;
-                tenant1Conn.createStatement().execute(view1DDL);
-                // This should not modify the base table
-                String alterView = "ALTER VIEW " + view1 + " ADD NEWCOL1 VARCHAR";
-                tenant1Conn.createStatement().execute(alterView);
-                HTableDescriptor tableDesc2 = tenant1Conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin().getTableDescriptor(Bytes.toBytes(baseTable));
-                assertEquals(tableDesc1, tableDesc2);
-                
-                // Add a new column family that doesn't already exist in the base table
-                alterView = "ALTER VIEW " + view1 + " ADD CF.NEWCOL2 VARCHAR";
-                tenant1Conn.createStatement().execute(alterView);
-                
-                // Verify that the column family now shows up in the base table descriptor
-                tableDesc2 = tenant1Conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin().getTableDescriptor(Bytes.toBytes(baseTable));
-                assertFalse(tableDesc2.equals(tableDesc1));
-                assertNotNull(tableDesc2.getFamily(Bytes.toBytes("CF")));
-                
-                // Add a column with an existing column family. This shouldn't modify the base table.
-                alterView = "ALTER VIEW " + view1 + " ADD CF.NEWCOL3 VARCHAR";
-                tenant1Conn.createStatement().execute(alterView);
-                HTableDescriptor tableDesc3 = tenant1Conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin().getTableDescriptor(Bytes.toBytes(baseTable));
-                assertTrue(tableDesc3.equals(tableDesc2));
-                assertNotNull(tableDesc3.getFamily(Bytes.toBytes("CF")));
-            }
-        }
-    }
-    
-    @Test
     public void testMakeBaseTableTransactional() throws Exception {
-        try (Connection conn = DriverManager.getConnection(getUrl())) {       
-            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS TABLEWITHVIEW ("
-                    + " ID char(1) NOT NULL,"
-                    + " COL1 integer NOT NULL,"
-                    + " COL2 bigint NOT NULL,"
-                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
-                    + " )");
-            assertTableDefinition(conn, "TABLEWITHVIEW", PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
-            
-            conn.createStatement().execute("CREATE VIEW VIEWOFTABLE ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM TABLEWITHVIEW");
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL1) : conn ) {  
+            String baseTableName = "NONTXNTBL_" + (isMultiTenant ? "0":"1");
+            String ddlFormat = "CREATE TABLE IF NOT EXISTS " + baseTableName + " ("
+                            + " %s ID char(1) NOT NULL,"
+                            + " COL1 integer NOT NULL,"
+                            + " COL2 bigint NOT NULL,"
+                            + " CONSTRAINT NAME_PK PRIMARY KEY (%s ID, COL1, COL2)"
+                            + " ) %s";
+            conn.createStatement().execute(generateDDL(ddlFormat));
+            assertTableDefinition(conn, baseTableName, PTableType.TABLE, null, 0, 3, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, "ID", "COL1", "COL2");
+            
+            viewConn.createStatement().execute("CREATE VIEW VIEWOFTABLE ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM "+baseTableName);
             assertTableDefinition(conn, "VIEWOFTABLE", PTableType.VIEW, "TABLEWITHVIEW", 0, 5, 3, "ID", "COL1", "COL2", "VIEW_COL1", "VIEW_COL2");
             
-            HTableInterface htable = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes("TABLEWITHVIEW"));
+            PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null;
+            PhoenixConnection phoenixConn = conn.unwrap(PhoenixConnection.class);
+            HTableInterface htable = phoenixConn.getQueryServices().getTable(Bytes.toBytes(baseTableName));
             assertFalse(htable.getTableDescriptor().getCoprocessors().contains(PhoenixTransactionalProcessor.class.getName()));
-            assertFalse(conn.unwrap(PhoenixConnection.class).getTable(new PTableKey(null, "TABLEWITHVIEW")).isTransactional());
-            assertFalse(conn.unwrap(PhoenixConnection.class).getTable(new PTableKey(null, "VIEWOFTABLE")).isTransactional());
+            assertFalse(phoenixConn.getTable(new PTableKey(null, baseTableName)).isTransactional());
+            assertFalse(viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, "VIEWOFTABLE")).isTransactional());
             
             // make the base table transactional
-            conn.createStatement().execute("ALTER TABLE TABLEWITHVIEW SET TRANSACTIONAL=true");
+            conn.createStatement().execute("ALTER TABLE " + baseTableName + " SET TRANSACTIONAL=true");
             // query the view to force the table cache to be updated
-            conn.createStatement().execute("SELECT * FROM VIEWOFTABLE");
-            htable = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes("TABLEWITHVIEW"));
+            viewConn.createStatement().execute("SELECT * FROM VIEWOFTABLE");
+            htable = phoenixConn.getQueryServices().getTable(Bytes.toBytes(baseTableName));
             assertTrue(htable.getTableDescriptor().getCoprocessors().contains(PhoenixTransactionalProcessor.class.getName()));
-            assertTrue(conn.unwrap(PhoenixConnection.class).getTable(new PTableKey(null, "TABLEWITHVIEW")).isTransactional());
-            assertTrue(conn.unwrap(PhoenixConnection.class).getTable(new PTableKey(null, "VIEWOFTABLE")).isTransactional());
+            assertTrue(phoenixConn.getTable(new PTableKey(null, baseTableName)).isTransactional());
+            assertTrue(viewConn.unwrap(PhoenixConnection.class).getTable(new PTableKey(tenantId, "VIEWOFTABLE")).isTransactional());
         } 
-    
-    }
-    
-    private static long getTableSequenceNumber(PhoenixConnection conn, String tableName) throws SQLException {
-        PTable table = conn.getTable(new PTableKey(conn.getTenantId(), SchemaUtil.normalizeIdentifier(tableName)));
-        return table.getSequenceNumber();
-    }
-    
-    private static short getMaxKeySequenceNumber(PhoenixConnection conn, String tableName) throws SQLException {
-        PTable table = conn.getTable(new PTableKey(conn.getTenantId(), SchemaUtil.normalizeIdentifier(tableName)));
-        return SchemaUtil.getMaxKeySeq(table);
     }
     
-    private static void verifyNewColumns(ResultSet rs, String ... values) throws SQLException {
-        assertTrue(rs.next());
-        int i = 1;
-        for (String value : values) {
-            assertEquals(value, rs.getString(i++));
-        }
-        assertFalse(rs.next());
-        assertEquals(values.length, i - 1);
-    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java
index 327627d..69b3d00 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TenantSpecificTablesDDLIT.java
@@ -307,13 +307,12 @@ public class TenantSpecificTablesDDLIT extends BaseTenantSpecificTablesIT {
                 assertEquals(CANNOT_DROP_PK.getErrorCode(), expected.getErrorCode());
             }
             
-            // try removing a non-PK col
+            // try removing a non-PK col, which is allowed
             try {
                 conn.createStatement().execute("alter table " + PARENT_TABLE_NAME + " drop column user");
-                fail();
             }
             catch (SQLException expected) {
-                assertEquals(CANNOT_MUTATE_TABLE.getErrorCode(), expected.getErrorCode());
+                fail("We should be able to drop a non pk base table column");
             }
         }
         finally {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropMetadataIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropMetadataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropMetadataIT.java
new file mode 100644
index 0000000..4c60ea3
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/DropMetadataIT.java
@@ -0,0 +1,315 @@
+/*
+ * 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.phoenix.end2end.index;
+
+import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
+import static org.apache.phoenix.util.TestUtil.HBASE_NATIVE;
+import static org.apache.phoenix.util.TestUtil.HBASE_NATIVE_SCHEMA_NAME;
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
+import org.apache.phoenix.end2end.Shadower;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.ColumnNotFoundException;
+import org.apache.phoenix.schema.PName;
+import org.apache.phoenix.schema.PNameFactory;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableKey;
+import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.util.IndexUtil;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.SchemaUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+
+public class DropMetadataIT extends BaseHBaseManagedTimeIT {
+    private static final byte[] HBASE_NATIVE_BYTES = SchemaUtil.getTableNameAsBytes(HBASE_NATIVE_SCHEMA_NAME, HBASE_NATIVE);
+    private static final byte[] FAMILY_NAME = Bytes.toBytes(SchemaUtil.normalizeIdentifier("1"));
+    public static final String SCHEMA_NAME = "";
+    public static final String DATA_TABLE_NAME = "T";
+    public static final String INDEX_TABLE_NAME = "I";
+    public static final String DATA_TABLE_FULL_NAME = SchemaUtil.getTableName(SCHEMA_NAME, "T");
+    public static final String INDEX_TABLE_FULL_NAME = SchemaUtil.getTableName(SCHEMA_NAME, "I");
+    private final String TENANT_SPECIFIC_URL = getUrl() + ';' + TENANT_ID_ATTRIB + "=tenant1";
+    
+    @Shadower(classBeingShadowed = BaseHBaseManagedTimeIT.class)
+    @BeforeClass 
+    public static void doSetup() throws Exception {
+        Map<String,String> props = Maps.newHashMapWithExpectedSize(1);
+        // Drop the HBase table metadata for this test
+        props.put(QueryServices.DROP_METADATA_ATTRIB, Boolean.toString(true));
+        // Must update config before starting server
+        setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+    }
+    
+    @Test
+    public void testDropViewKeepsHTable() throws Exception {
+        HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TEST_PROPERTIES).getAdmin();
+        try {
+            try {
+                admin.disableTable(HBASE_NATIVE_BYTES);
+                admin.deleteTable(HBASE_NATIVE_BYTES);
+            } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
+            }
+            @SuppressWarnings("deprecation")
+            HTableDescriptor descriptor = new HTableDescriptor(HBASE_NATIVE_BYTES);
+            HColumnDescriptor columnDescriptor =  new HColumnDescriptor(FAMILY_NAME);
+            columnDescriptor.setKeepDeletedCells(true);
+            descriptor.addFamily(columnDescriptor);
+            admin.createTable(descriptor);
+        } finally {
+            admin.close();
+        }
+        
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.createStatement().execute("create view " + HBASE_NATIVE +
+                "   (uint_key unsigned_int not null," +
+                "    ulong_key unsigned_long not null," +
+                "    string_key varchar not null,\n" +
+                "    \"1\".uint_col unsigned_int," +
+                "    \"1\".ulong_col unsigned_long" +
+                "    CONSTRAINT pk PRIMARY KEY (uint_key, ulong_key, string_key))\n" +
+                     HColumnDescriptor.DATA_BLOCK_ENCODING + "='" + DataBlockEncoding.NONE + "'");
+        conn.createStatement().execute("drop view " + HBASE_NATIVE);
+        
+        admin = driver.getConnectionQueryServices(getUrl(), PropertiesUtil.deepCopy(TEST_PROPERTIES)).getAdmin();
+        try {
+            try {
+                admin.disableTable(HBASE_NATIVE_BYTES);
+                admin.deleteTable(HBASE_NATIVE_BYTES);
+            } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
+                fail(); // The underlying HBase table should still exist
+            }
+        } finally {
+            admin.close();
+        }
+    }
+    
+    @Test
+    public void testDroppingIndexedColDropsIndex() throws Exception {
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        String localIndexTableName1 = "LOCAL_" + INDEX_TABLE_NAME + "_1";
+        String localIndexTableName2 = "LOCAL_" + INDEX_TABLE_NAME + "_2";
+        try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
+            conn.setAutoCommit(false);
+            conn.createStatement().execute(
+                "CREATE TABLE " + DATA_TABLE_FULL_NAME
+                        + " (k VARCHAR NOT NULL PRIMARY KEY, v1 VARCHAR, v2 VARCHAR)");
+            // create one regular and two local indexes
+            conn.createStatement().execute(
+                "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v2) INCLUDE (v1)");
+            conn.createStatement().execute(
+                "CREATE LOCAL INDEX " + localIndexTableName1 + " ON " + DATA_TABLE_FULL_NAME + " (v2) INCLUDE (v1)");
+            conn.createStatement().execute(
+                "CREATE LOCAL INDEX " + localIndexTableName2 + " ON " + DATA_TABLE_FULL_NAME + " (k) INCLUDE (v1)");
+            
+            // upsert a single row
+            PreparedStatement stmt = conn.prepareStatement("UPSERT INTO " + DATA_TABLE_FULL_NAME + " VALUES(?,?,?)");
+            stmt.setString(1, "a");
+            stmt.setString(2, "x");
+            stmt.setString(3, "1");
+            stmt.execute();
+            conn.commit();
+            
+            // verify the indexes were created
+            PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
+            PTable dataTable = pconn.getTable(new PTableKey(null, DATA_TABLE_FULL_NAME));
+            assertEquals("Unexpected number of indexes ", 3, dataTable.getIndexes().size());
+            PTable indexTable = dataTable.getIndexes().get(0);
+            byte[] indexTablePhysicalName = indexTable.getPhysicalName().getBytes();
+            PName localIndexTablePhysicalName = dataTable.getIndexes().get(1).getPhysicalName();
+            
+            // drop v2 which causes the regular index and first local index to be dropped
+            conn.createStatement().execute(
+                "ALTER TABLE " + DATA_TABLE_FULL_NAME + " DROP COLUMN v2 ");
+
+            // verify the both of the indexes' metadata were dropped
+            conn.createStatement().execute("SELECT * FROM "+DATA_TABLE_FULL_NAME);
+            try {
+                conn.createStatement().execute("SELECT * FROM "+INDEX_TABLE_NAME);
+                fail("Index should have been dropped");
+            } catch (TableNotFoundException e) {
+            }
+            pconn = conn.unwrap(PhoenixConnection.class);
+            dataTable = pconn.getTable(new PTableKey(null, DATA_TABLE_FULL_NAME));
+            try {
+                pconn.getTable(new PTableKey(null, INDEX_TABLE_NAME));
+                fail("index should have been dropped");
+            } catch (TableNotFoundException e) {
+            }
+            try {
+                pconn.getTable(new PTableKey(null, localIndexTableName1));
+                fail("index should have been dropped");
+            } catch (TableNotFoundException e) {
+            }
+            assertEquals("Unexpected number of indexes ", 1, dataTable.getIndexes().size());
+            
+            // verify that the regular index physical table was dropped
+            try {
+                conn.unwrap(PhoenixConnection.class).getQueryServices().getTableDescriptor(indexTablePhysicalName);
+                fail("Index table should have been dropped");
+            } catch (TableNotFoundException e) {
+            }
+            
+            // verify that the local index physical table was *not* dropped
+            conn.unwrap(PhoenixConnection.class).getQueryServices().getTableDescriptor(localIndexTablePhysicalName.getBytes());
+            
+            // there should be a single row belonging to localIndexTableName2 
+            Scan scan = new Scan();
+            HTable table = (HTable) conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(localIndexTablePhysicalName.getBytes());
+            ResultScanner results = table.getScanner(scan);
+            Result result = results.next();
+            assertNotNull(result);
+            assertNotNull("localIndexTableName2 row is missing", result.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, 
+                IndexUtil.getIndexColumnName(QueryConstants.DEFAULT_COLUMN_FAMILY, "V1").getBytes()));
+            assertNull(results.next());
+        }
+    }
+    
+    @Test
+    public void testDroppingIndexedColDropsViewIndex() throws Exception {
+        helpTestDroppingIndexedColDropsViewIndex(false);
+    }
+    
+    @Test
+    public void testDroppingIndexedColDropsMultiTenantViewIndex() throws Exception {
+        helpTestDroppingIndexedColDropsViewIndex(true);
+    }
+    
+    public void helpTestDroppingIndexedColDropsViewIndex(boolean isMultiTenant) throws Exception {
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection viewConn = isMultiTenant ? DriverManager.getConnection(TENANT_SPECIFIC_URL) : conn ) {
+            conn.setAutoCommit(false);
+            viewConn.setAutoCommit(false);
+            String ddlFormat = "CREATE TABLE TABLEWITHVIEW (%s k VARCHAR NOT NULL, v1 VARCHAR, v2 VARCHAR, v3 VARCHAR, v4 VARCHAR CONSTRAINT PK PRIMARY KEY(%s k))%s";
+            String ddl = String.format(ddlFormat, isMultiTenant ? "TENANT_ID VARCHAR NOT NULL, " : "",
+                    isMultiTenant ? "TENANT_ID, " : "", isMultiTenant ? "MULTI_TENANT=true" : "");
+            conn.createStatement().execute(ddl);
+            viewConn.createStatement()
+                    .execute(
+                        "CREATE VIEW VIEWOFTABLE ( VIEW_COL1 DECIMAL(10,2), VIEW_COL2 VARCHAR ) AS SELECT * FROM TABLEWITHVIEW");
+            // create an index with the column that will be dropped
+            viewConn.createStatement().execute("CREATE INDEX VIEWINDEX1 ON VIEWOFTABLE(v2) INCLUDE (v4)");
+            // create an index without the column that will be dropped
+            viewConn.createStatement().execute("CREATE INDEX VIEWINDEX2 ON VIEWOFTABLE(v1) INCLUDE (v4)");
+            // verify index was created
+            try {
+                viewConn.createStatement().execute("SELECT * FROM VIEWINDEX1");
+            } catch (TableNotFoundException e) {
+                fail("Index on view was not created");
+            }
+            
+            // upsert a single row
+            PreparedStatement stmt = viewConn.prepareStatement("UPSERT INTO VIEWOFTABLE VALUES(?,?,?,?,?,?,?)");
+            stmt.setString(1, "a");
+            stmt.setString(2, "b");
+            stmt.setString(3, "c");
+            stmt.setString(4, "d");
+            stmt.setString(5, "e");
+            stmt.setInt(6, 1);
+            stmt.setString(7, "g");
+            stmt.execute();
+            viewConn.commit();
+
+            // verify the index was created
+            PhoenixConnection pconn = viewConn.unwrap(PhoenixConnection.class);
+            PName tenantId = isMultiTenant ? PNameFactory.newName("tenant1") : null; 
+            PTable view = pconn.getTable(new PTableKey(tenantId, "VIEWOFTABLE"));
+            PTable viewIndex = pconn.getTable(new PTableKey(tenantId, "VIEWINDEX1"));
+            byte[] viewIndexPhysicalTable = viewIndex.getPhysicalName().getBytes();
+            assertNotNull("Can't find view index", viewIndex);
+            assertEquals("Unexpected number of indexes ", 2, view.getIndexes().size());
+            assertEquals("Unexpected index ", "VIEWINDEX1", view.getIndexes().get(0).getName()
+                    .getString());
+            assertEquals("Unexpected index ", "VIEWINDEX2", view.getIndexes().get(1).getName()
+                .getString());
+            
+            // drop two columns
+            conn.createStatement().execute("ALTER TABLE TABLEWITHVIEW DROP COLUMN v2, v3 ");
+            
+            // verify columns were dropped
+            try {
+                conn.createStatement().execute("SELECT v2 FROM TABLEWITHVIEW");
+                fail("Column should have been dropped");
+            } catch (ColumnNotFoundException e) {
+            }
+            try {
+                conn.createStatement().execute("SELECT v3 FROM TABLEWITHVIEW");
+                fail("Column should have been dropped");
+            } catch (ColumnNotFoundException e) {
+            }
+            
+            // verify index metadata was dropped
+            try {
+                viewConn.createStatement().execute("SELECT * FROM VIEWINDEX1");
+                fail("Index metadata should have been dropped");
+            } catch (TableNotFoundException e) {
+            }
+            
+            pconn = viewConn.unwrap(PhoenixConnection.class);
+            view = pconn.getTable(new PTableKey(tenantId, "VIEWOFTABLE"));
+            try {
+                viewIndex = pconn.getTable(new PTableKey(tenantId, "VIEWINDEX1"));
+                fail("View index should have been dropped");
+            } catch (TableNotFoundException e) {
+            }
+            assertEquals("Unexpected number of indexes ", 1, view.getIndexes().size());
+            assertEquals("Unexpected index ", "VIEWINDEX2", view.getIndexes().get(0).getName().getString());
+            
+            // verify that the physical index view table is *not* dropped
+            conn.unwrap(PhoenixConnection.class).getQueryServices().getTableDescriptor(viewIndexPhysicalTable);
+            
+            // scan the physical table and verify there is a single row for the second local index
+            Scan scan = new Scan();
+            HTable table = (HTable) conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(viewIndexPhysicalTable);
+            ResultScanner results = table.getScanner(scan);
+            Result result = results.next();
+            assertNotNull(result);
+            // there should be a single row belonging to VIEWINDEX2 
+            assertNotNull("VIEWINDEX2 row is missing", result.getValue(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, 
+                IndexUtil.getIndexColumnName(QueryConstants.DEFAULT_COLUMN_FAMILY, "V4").getBytes()));
+            assertNull(results.next());
+        }
+    }
+}
+        


[11/52] [abbrv] phoenix git commit: PHOENIX-2156 Support drop of column from table with views

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 7f3f850..76b2f51 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -111,6 +111,7 @@ import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.Set;
 
@@ -137,6 +138,7 @@ import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
 import org.apache.phoenix.coprocessor.MetaDataProtocol.MetaDataMutationResult;
 import org.apache.phoenix.coprocessor.MetaDataProtocol.MutationCode;
+import org.apache.phoenix.coprocessor.MetaDataProtocol.SharedTableState;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.exception.SQLExceptionInfo;
 import org.apache.phoenix.execute.MutationState;
@@ -204,6 +206,8 @@ import org.apache.phoenix.util.UpgradeUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import co.cask.tephra.TxConstants;
+
 import com.google.common.base.Objects;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.ListMultimap;
@@ -212,8 +216,6 @@ import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.common.primitives.Ints;
 
-import co.cask.tephra.TxConstants;
-
 public class MetaDataClient {
     private static final Logger logger = LoggerFactory.getLogger(MetaDataClient.class);
 
@@ -444,11 +446,11 @@ public class MetaDataClient {
         return currentScn;
     }
     
-    private MetaDataMutationResult updateCache(PName tenantId, String schemaName, String tableName,
+    private MetaDataMutationResult updateCache(PName origTenantId, String schemaName, String tableName,
             boolean alwaysHitServer, Long resolvedTimestamp) throws SQLException { // TODO: pass byte[] herez
         boolean systemTable = SYSTEM_CATALOG_SCHEMA.equals(schemaName);
         // System tables must always have a null tenantId
-        tenantId = systemTable ? null : tenantId;
+        PName tenantId = systemTable ? null : origTenantId;
         PTable table = null;
         PTableRef tableRef = null;
         String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
@@ -535,7 +537,7 @@ public class MetaDataClient {
                     // If table was not found at the current time stamp and we have one cached, remove it.
                     // Otherwise, we're up to date, so there's nothing to do.
                     if (code == MutationCode.TABLE_NOT_FOUND && tryCount + 1 == maxTryCount) {
-                        connection.removeTable(tenantId, fullTableName, table.getParentName() == null ? null : table.getParentName().getString(), table.getTimeStamp());
+                        connection.removeTable(origTenantId, fullTableName, table.getParentName() == null ? null : table.getParentName().getString(), table.getTimeStamp());
                     }
                 }
             }
@@ -3029,12 +3031,18 @@ public class MetaDataClient {
                     List<PColumn> indexColumnsToDrop = Lists.newArrayListWithExpectedSize(columnRefs.size());
                     for(PColumn columnToDrop : tableColumnsToDrop) {
                         ColumnReference columnToDropRef = new ColumnReference(columnToDrop.getFamilyName().getBytes(), columnToDrop.getName().getBytes());
+                        // if the columns being dropped is indexed and the physical index table is not shared
                         if (indexColumns.contains(columnToDropRef)) {
-                            indexesToDrop.add(new TableRef(index));
+                            if (index.getViewIndexId()==null) 
+                                indexesToDrop.add(new TableRef(index));
+                            connection.removeTable(tenantId, SchemaUtil.getTableName(schemaName, index.getName().getString()), index.getParentName() == null ? null : index.getParentName().getString(), index.getTimeStamp());
                         } 
                         else if (coveredColumns.contains(columnToDropRef)) {
                             String indexColumnName = IndexUtil.getIndexColumnName(columnToDrop);
-                            indexColumnsToDrop.add(index.getColumn(indexColumnName));
+                            PColumn indexColumn = index.getColumn(indexColumnName);
+                            indexColumnsToDrop.add(indexColumn);
+                            // add the index column to be dropped so that we actually delete the column values
+                            columnsToDrop.add(new ColumnRef(new TableRef(index), indexColumn.getPosition()));
                         }
                     }
                     if(!indexColumnsToDrop.isEmpty()) {
@@ -3109,11 +3117,53 @@ public class MetaDataClient {
                         // Delete everything in the column. You'll still be able to do queries at earlier timestamps
                         long ts = (scn == null ? result.getMutationTime() : scn);
                         PostDDLCompiler compiler = new PostDDLCompiler(connection);
+                        
                         boolean dropMetaData = connection.getQueryServices().getProps().getBoolean(DROP_METADATA_ATTRIB, DEFAULT_DROP_METADATA);
-                        if(!dropMetaData){
-                            // Drop any index tables that had the dropped column in the PK
-                            connection.getQueryServices().updateData(compiler.compile(indexesToDrop, null, null, Collections.<PColumn>emptyList(), ts));
+                        // if the index is a local index or view index it uses a shared physical table
+                        // so we need to issue deletes markers for all the rows of the index 
+                        final List<TableRef> tableRefsToDrop = Lists.newArrayList();
+                        Map<String, List<TableRef>> tenantIdTableRefMap = Maps.newHashMap();
+                        if (result.getSharedTablesToDelete()!=null) {
+                            for (SharedTableState sharedTableState : result.getSharedTablesToDelete()) { 
+                                PTableImpl viewIndexTable = new PTableImpl(sharedTableState.getTenantId(), 
+                                    sharedTableState.getSchemaName(), sharedTableState.getTableName(), 
+                                    ts, table.getColumnFamilies(), sharedTableState.getColumns(),
+                                    sharedTableState.getPhysicalNames(), sharedTableState.getViewIndexId(), table.isMultiTenant());
+                                TableRef indexTableRef = new TableRef(viewIndexTable);
+                                PName indexTableTenantId = sharedTableState.getTenantId();
+                                if (indexTableTenantId==null) {
+                                    tableRefsToDrop.add(indexTableRef);
+                                }
+                                else {
+                                    if (!tenantIdTableRefMap.containsKey(indexTableTenantId)) {
+                                        tenantIdTableRefMap.put(indexTableTenantId.getString(), Lists.<TableRef>newArrayList());
+                                    }
+                                    tenantIdTableRefMap.get(indexTableTenantId.getString()).add(indexTableRef);
+                                }
+                                
+                            }
+                        }
+                        // if dropMetaData is false delete all rows for the indexes (if it was true
+                        // they would have been dropped in ConnectionQueryServices.dropColumn)
+                        if (!dropMetaData) {
+                            tableRefsToDrop.addAll(indexesToDrop);
+                        }
+                        // Drop any index tables that had the dropped column in the PK
+                        connection.getQueryServices().updateData(compiler.compile(tableRefsToDrop, null, null, Collections.<PColumn>emptyList(), ts));
+                        
+                        // Drop any tenant-specific indexes
+                        if (!tenantIdTableRefMap.isEmpty()) {
+                            for (Entry<String, List<TableRef>> entry : tenantIdTableRefMap.entrySet()) {
+                                String indexTenantId = entry.getKey();
+                                Properties props = new Properties(connection.getClientInfo());
+                                props.setProperty(PhoenixRuntime.TENANT_ID_ATTRIB, indexTenantId);
+                                try (PhoenixConnection tenantConn = DriverManager.getConnection(connection.getURL(), props).unwrap(PhoenixConnection.class)) {
+                                    PostDDLCompiler dropCompiler = new PostDDLCompiler(tenantConn);
+                                    tenantConn.getQueryServices().updateData(dropCompiler.compile(entry.getValue(), null, null, Collections.<PColumn>emptyList(), ts));
+                                }
+                            }
                         }
+                        
                         // Update empty key value column if necessary
                         for (ColumnRef droppedColumnRef : columnsToDrop) {
                             // Painful, but we need a TableRef with a pre-set timestamp to prevent attempts

http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index 8165451..5789263 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -167,6 +167,24 @@ public class PTableImpl implements PTable {
         this.families = families;
         this.physicalNames = Collections.emptyList();
     }
+    
+    public PTableImpl(PName tenantId, PName schemaName, PName tableName, long timestamp, List<PColumnFamily> families, 
+            List<PColumn> columns, List<PName> physicalNames, Short viewIndexId, boolean multiTenant) throws SQLException { // For indexes stored in shared physical tables
+        this.pkColumns = this.allColumns = Collections.emptyList();
+        this.rowKeySchema = RowKeySchema.EMPTY_SCHEMA;
+        this.indexes = Collections.emptyList();
+        this.familyByBytes = Maps.newHashMapWithExpectedSize(families.size());
+        this.familyByString = Maps.newHashMapWithExpectedSize(families.size());
+        for (PColumnFamily family : families) {
+            familyByBytes.put(family.getName().getBytes(), family);
+            familyByString.put(family.getName().getString(), family);
+        }
+        this.families = families;
+        init(tenantId, this.schemaName, this.tableName, PTableType.INDEX, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
+            PTableStats.EMPTY_STATS, this.schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName,
+            null, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
+            isTransactional, updateCacheFrequency, indexDisableTimestamp);
+    }
 
     public PTableImpl(long timeStamp) { // For delete marker
         this(timeStamp, false);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/fccbe56a/phoenix-protocol/src/main/MetaDataService.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/MetaDataService.proto b/phoenix-protocol/src/main/MetaDataService.proto
index a5a3934..d1dcf9a 100644
--- a/phoenix-protocol/src/main/MetaDataService.proto
+++ b/phoenix-protocol/src/main/MetaDataService.proto
@@ -44,6 +44,15 @@ enum MutationCode {
   FUNCTION_NOT_IN_REGION = 13;
 };
 
+message SharedTableState {
+  optional bytes tenantId = 1;
+  required bytes schemaName  = 2;
+  required bytes tableName = 3;
+  repeated PColumn columns = 4;  
+  repeated bytes physicalNames = 5;
+  required int32 viewIndexId = 6;
+}
+
 message MetaDataResponse {
   optional MutationCode returnCode = 1;
   optional int64 mutationTime = 2;
@@ -53,6 +62,7 @@ message MetaDataResponse {
   optional bytes familyName = 6;
   optional bytes functionName = 7;
   repeated PFunction function = 8;
+  repeated SharedTableState sharedTablesToDelete = 9;
 }
 
 message GetTableRequest {


[42/52] [abbrv] phoenix git commit: Store encoded column counters for base tables and make views use them

Posted by sa...@apache.org.
Store encoded column counters for base tables and make views use them


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

Branch: refs/heads/encodecolumns
Commit: d8488efd9401dc5f26ce12e6717776846876336d
Parents: 8a9ffe5
Author: Samarth <sa...@salesforce.com>
Authored: Thu Apr 7 09:54:52 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:31 2016 -0700

----------------------------------------------------------------------
 .../phoenix/end2end/AlterTableWithViewsIT.java  |  221 +++-
 .../apache/phoenix/end2end/CreateTableIT.java   |  108 ++
 .../apache/phoenix/end2end/DynamicColumnIT.java |   59 +-
 .../end2end/index/txn/MutableRollbackIT.java    |    2 +-
 .../apache/phoenix/compile/FromCompiler.java    |    4 +-
 .../apache/phoenix/compile/JoinCompiler.java    |    3 +-
 .../compile/TupleProjectionCompiler.java        |    4 +-
 .../apache/phoenix/compile/UnionCompiler.java   |    2 +-
 .../coprocessor/MetaDataEndpointImpl.java       |  112 +-
 .../coprocessor/generated/PTableProtos.java     | 1143 +++++++++++++++++-
 .../index/PhoenixTransactionalIndexer.java      |   11 +-
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java   |   10 +-
 .../apache/phoenix/query/QueryConstants.java    |    6 +-
 .../apache/phoenix/schema/DelegateTable.java    |    6 +
 .../apache/phoenix/schema/MetaDataClient.java   |  203 +++-
 .../java/org/apache/phoenix/schema/PTable.java  |    4 +-
 .../org/apache/phoenix/schema/PTableImpl.java   |   67 +-
 .../org/apache/phoenix/util/SchemaUtil.java     |   40 +-
 .../phoenix/compile/WhereCompilerTest.java      |    4 +-
 .../phoenix/execute/CorrelatePlanTest.java      |    2 +-
 .../execute/LiteralResultIteratorPlanTest.java  |    2 +-
 .../phoenix/query/ConnectionlessTest.java       |   17 +-
 phoenix-protocol/src/main/PTable.proto          |    6 +
 23 files changed, 1795 insertions(+), 241 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
index ea376de..6deab29 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
@@ -18,6 +18,14 @@
 package org.apache.phoenix.end2end;
 
 import static org.apache.phoenix.exception.SQLExceptionCode.CANNOT_MUTATE_TABLE;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER_COUNTER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM;
+import static org.apache.phoenix.query.QueryConstants.DEFAULT_COLUMN_FAMILY;
 import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -40,10 +48,12 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.coprocessor.PhoenixTransactionalProcessor;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PNameFactory;
+import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.util.ReadOnlyProps;
@@ -71,15 +81,15 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
     public static Collection<Boolean> data() {
         return Arrays.asList(false, true);
     }
-	
-	@BeforeClass
+    
+    @BeforeClass
     @Shadower(classBeingShadowed = BaseHBaseManagedTimeIT.class)
     public static void doSetup() throws Exception {
         Map<String,String> props = Maps.newHashMapWithExpectedSize(1);
         props.put(QueryServices.TRANSACTIONS_ENABLED, Boolean.toString(true));
         setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
     }
-	
+    
     private String generateDDL(String format) {
         return String.format(format, isMultiTenant ? "TENANT_ID VARCHAR NOT NULL, " : "",
             isMultiTenant ? "TENANT_ID, " : "", isMultiTenant ? "MULTI_TENANT=true" : "");
@@ -676,4 +686,207 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
         } 
     }
     
-}
+    @Test
+    public void testClientAndServerMetadataForEncodedColumns() throws Exception {
+        String schemaName = "XYZ";
+        String baseTableName = "TABLEWITHVIEW";
+        String viewName = "VIEW1";
+        String fullTableName = schemaName + "." + baseTableName;
+        String fullViewName = schemaName + "." + viewName;
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
+            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + fullTableName + " ("
+                    + " ID char(1) NOT NULL,"
+                    + " COL1 integer NOT NULL,"
+                    + " COL2 bigint NOT NULL,"
+                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
+                    + " )");
+            PTable baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            long initBaseTableSeqNumber = baseTable.getSequenceNumber(); 
+                    
+            // assert that the client side cache is updated.
+            Map<String, Integer> cqCounters = baseTable.getEncodedCQCounters();
+            assertEquals(1, cqCounters.size());
+            int counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+            assertEquals(1, counter);
+            
+            // assert that the server side metadata is updated correctly.
+            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 1);
+            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber);
+            
+            // now create a view and validate client and server side metadata
+            String viewDDL = "CREATE VIEW " + fullViewName + " ( VIEW_COL1 INTEGER, A.VIEW_COL2 VARCHAR ) AS SELECT * FROM " + fullTableName;
+            conn.createStatement().execute(viewDDL);
+            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            PTable view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
+            
+            // verify that the client side cache is updated. Base table's cq counters should be updated.
+            cqCounters = baseTable.getEncodedCQCounters();
+            counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+            assertEquals(2, counter);
+            counter = cqCounters.get("A");
+            assertEquals(2, counter);
+            cqCounters = view.getEncodedCQCounters();
+            assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
+            
+            // assert that the server side metadata for the base table and the view is also updated correctly.
+            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 2);
+            assertEncodedCQCounter("A", schemaName, baseTableName, 2);
+            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "VIEW_COL1", schemaName, viewName, 1);
+            assertEncodedCQValue("A", "VIEW_COL2", schemaName, viewName, 1);
+            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 1);
+            assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM);
+        }
+    }
+    
+    @Test
+    public void testAddingColumnsToTablesAndViewsWithEncodedColumns() throws Exception {
+        String schemaName = "XYZ";
+        String baseTableName = "testAddingColumnsWithEncodedColumns".toUpperCase();
+        String viewName = "VIEW1";
+        String fullTableName = schemaName + "." + baseTableName;
+        String fullViewName = schemaName + "." + viewName;
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
+            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + fullTableName + " ("
+                    + " ID char(1) NOT NULL,"
+                    + " COL1 integer NOT NULL,"
+                    + " COL2 bigint NOT NULL,"
+                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
+                    + " )");
+            PTable baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            long initBaseTableSeqNumber = baseTable.getSequenceNumber(); 
+
+            // Add a column to the base table and see if the client and server metadata is updated correctly
+            String alterDDL = "ALTER TABLE " + fullTableName + " ADD COL3 VARCHAR PRIMARY KEY, COL4 INTEGER, COL5 VARCHAR, B.COL6 DECIMAL (10, 2)";
+            conn.createStatement().execute(alterDDL);
+
+            // assert that the client side cache is updated.
+            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            Map<String, Integer> cqCounters = baseTable.getEncodedCQCounters();
+            int counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+            assertEquals(3, counter);
+            counter = cqCounters.get("B");
+            assertEquals(2, counter);
+
+            // assert that the server side metadata is updated correctly.
+            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 3);
+            assertEncodedCQCounter("B", schemaName, baseTableName, 2);
+            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "COL4", schemaName, baseTableName, 1);
+            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "COL5", schemaName, baseTableName, 2);
+            assertEncodedCQValue("B", "COL6", schemaName, baseTableName, 1);
+            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 1);
+
+            // Create a view
+            String viewDDL = "CREATE VIEW " + fullViewName + " ( VIEW_COL1 INTEGER, A.VIEW_COL2 VARCHAR ) AS SELECT * FROM " + fullTableName;
+            conn.createStatement().execute(viewDDL);
+            // Creating a view that adds its own columns should increment the base table's sequence number too.
+            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 2);
+
+            // Add column to the view
+            viewDDL = "ALTER VIEW " + fullViewName + " ADD VIEW_COL3 DECIMAL(10, 2), A.VIEW_COL4 VARCHAR, B.VIEW_COL5 INTEGER";
+            conn.createStatement().execute(viewDDL);
+
+            // assert that the client cache for the base table is updated
+            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            cqCounters = baseTable.getEncodedCQCounters();
+            counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+            assertEquals(5, counter);
+            counter = cqCounters.get("B");
+            assertEquals(3, counter);
+            counter = cqCounters.get("A");
+            assertEquals(3, counter);
+
+            // assert client cache for view
+            PTable view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
+            cqCounters = view.getEncodedCQCounters();
+            assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
+
+            // assert that the server side metadata for the base table and the view is also updated correctly.
+            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 5);
+            assertEncodedCQCounter("A", schemaName, baseTableName, 3);
+            assertEncodedCQCounter("B", schemaName, baseTableName, 3);
+            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "VIEW_COL3", schemaName, viewName, 4);
+            assertEncodedCQValue("A", "VIEW_COL4", schemaName, viewName, 2);
+            assertEncodedCQValue("B", "VIEW_COL5", schemaName, viewName, 2);
+            // Adding a column to the should increment the base table's sequence number too since we update the cq counters for column families.
+            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 3);
+            assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM + 1);
+            
+            // Add column to the base table which doesn't already exist in the view.
+            alterDDL = "ALTER TABLE " + fullTableName + " ADD COL10 VARCHAR, A.COL11 INTEGER";
+            conn.createStatement().execute(alterDDL);
+            baseTable = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            
+            // assert that the client cache for the base table is updated 
+            cqCounters = baseTable.getEncodedCQCounters();
+            counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+            assertEquals(6, counter);
+            counter = cqCounters.get("B");
+            assertEquals(3, counter);
+            counter = cqCounters.get("A");
+            assertEquals(4, counter);
+            
+            // assert client cache for view
+            view = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullViewName));
+            cqCounters = view.getEncodedCQCounters();
+            assertTrue("A view should always have the column qualifier counters map empty", cqCounters.isEmpty());
+            
+            // assert that the server side metadata for the base table and the view is also updated correctly.
+            assertEncodedCQCounter(DEFAULT_COLUMN_FAMILY, schemaName, baseTableName, 6);
+            assertEncodedCQCounter("A", schemaName, baseTableName, 4);
+            assertEncodedCQCounter("B", schemaName, baseTableName, 3);
+            assertEncodedCQValue(DEFAULT_COLUMN_FAMILY, "COL10", schemaName, viewName, 5);
+            assertEncodedCQValue("A", "COL11", schemaName, viewName, 3);
+            assertSequenceNumber(schemaName, baseTableName, initBaseTableSeqNumber + 4);
+            assertSequenceNumber(schemaName, viewName, PTable.INITIAL_SEQ_NUM + 2);
+        }
+    }
+    
+    private void assertEncodedCQValue(String columnFamily, String columnName, String schemaName, String tableName, int expectedValue) throws Exception {
+        String query = "SELECT " + ENCODED_COLUMN_QUALIFIER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? " + " AND " + COLUMN_FAMILY + " = ?" + " AND " + COLUMN_NAME  + " = ?";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PreparedStatement stmt = conn.prepareStatement(query);
+            stmt.setString(1, schemaName);
+            stmt.setString(2, tableName);
+            stmt.setString(3, columnFamily);
+            stmt.setString(4, columnName);
+            ResultSet rs = stmt.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(expectedValue, rs.getInt(1));
+            assertFalse(rs.next());
+        }
+    }
+    
+    private void assertEncodedCQCounter(String columnFamily, String schemaName, String tableName, int expectedValue) throws Exception {
+        String query = "SELECT " + ENCODED_COLUMN_QUALIFIER_COUNTER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? " + " AND " + COLUMN_FAMILY + " = ? AND " + ENCODED_COLUMN_QUALIFIER_COUNTER + " IS NOT NULL";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PreparedStatement stmt = conn.prepareStatement(query);
+            stmt.setString(1, schemaName);
+            stmt.setString(2, tableName);
+            stmt.setString(3, columnFamily);
+            ResultSet rs = stmt.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(expectedValue, rs.getInt(1));
+            assertFalse(rs.next());
+        }
+    }
+    
+    private void assertSequenceNumber(String schemaName, String tableName, long expectedSequenceNumber) throws Exception {
+        String query = "SELECT " + TABLE_SEQ_NUM + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? AND " +  TABLE_SEQ_NUM + " IS NOT NULL AND " + COLUMN_NAME + " IS NULL AND "
+                + COLUMN_FAMILY + " IS NULL ";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PreparedStatement stmt = conn.prepareStatement(query);
+            stmt.setString(1, schemaName);
+            stmt.setString(2, tableName);
+            ResultSet rs = stmt.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(expectedSequenceNumber, rs.getInt(1));
+            assertFalse(rs.next());
+        }
+    }
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
index 30bdb41..0ab47f0 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
@@ -18,28 +18,43 @@
 package org.apache.phoenix.end2end;
 
 import static org.apache.hadoop.hbase.HColumnDescriptor.DEFAULT_REPLICATION_SCOPE;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER_COUNTER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM;
+import static org.apache.phoenix.query.QueryConstants.DEFAULT_COLUMN_FAMILY;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.NewerTableAlreadyExistsException;
 import org.apache.phoenix.schema.SchemaNotFoundException;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.TableAlreadyExistsException;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.PropertiesUtil;
@@ -502,4 +517,97 @@ public class CreateTableIT extends BaseClientManagedTimeIT {
             fail();
         }
     }
+    
+    @Test
+    public void testClientAndServerMetadataForEncodedColumns() throws Exception {
+        String schemaName = "XYZ";
+        String tableName = "TABLEWITHVIEW";
+        String fullTableName = schemaName + "." + tableName;
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PhoenixConnection phxConn = conn.unwrap(PhoenixConnection.class);
+            conn.createStatement().execute("CREATE TABLE IF NOT EXISTS " + fullTableName + " ("
+                    + " ID char(1) NOT NULL,"
+                    + " COL1 integer NOT NULL,"
+                    + " COL2 bigint NOT NULL,"
+                    + " CONSTRAINT NAME_PK PRIMARY KEY (ID, COL1, COL2)"
+                    + " )");
+            PTable table = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+            long initialSequenceNumber = table.getSequenceNumber(); 
+
+            // assert that the client side cache is updated.
+            Map<String, Integer> cqCounters = table.getEncodedCQCounters();
+            assertEquals(1, cqCounters.size());
+            int counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+            assertEquals(1, counter);
+
+            // assert that the server side metadata is updated correctly.
+            assertColumnFamilyCounter(DEFAULT_COLUMN_FAMILY, schemaName, tableName, 1);
+            assertSequenceNumber(schemaName, tableName, initialSequenceNumber);
+
+            // now add a column and validate client and server side metadata
+            conn.createStatement().execute("ALTER TABLE " + fullTableName + " ADD COL3 varchar(10) PRIMARY KEY, COL4 integer, COL6 VARCHAR, A.COL5 INTEGER");
+            table = phxConn.getTable(new PTableKey(phxConn.getTenantId(), fullTableName));
+
+            // verify that the client side cache is updated.
+            cqCounters = table.getEncodedCQCounters();
+            counter = cqCounters.get(DEFAULT_COLUMN_FAMILY);
+            assertEquals(3, counter);
+            counter = cqCounters.get("A");
+            assertEquals(2, counter);
+
+            // assert that the server side metadata is also updated correctly.
+            assertColumnFamilyCounter(DEFAULT_COLUMN_FAMILY, schemaName, tableName, 3);
+            assertColumnFamilyCounter("A", schemaName, tableName, 2);
+            assertColumnQualifier(DEFAULT_COLUMN_FAMILY, "COL4", schemaName, tableName, 1);
+            assertColumnQualifier(DEFAULT_COLUMN_FAMILY, "COL6", schemaName, tableName, 2);
+            assertColumnQualifier("A", "COL5", schemaName, tableName, 1);
+            assertSequenceNumber(schemaName, tableName, initialSequenceNumber + 1);
+        }
+    }
+    
+    private void assertColumnQualifier(String columnFamily, String columnName, String schemaName, String tableName, int expectedValue) throws Exception {
+        String query = "SELECT " + ENCODED_COLUMN_QUALIFIER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? " + " AND " + COLUMN_FAMILY + " = ?" + " AND " + COLUMN_NAME  + " = ?";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PreparedStatement stmt = conn.prepareStatement(query);
+            stmt.setString(1, schemaName);
+            stmt.setString(2, tableName);
+            stmt.setString(3, columnFamily);
+            stmt.setString(4, columnName);
+            ResultSet rs = stmt.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(expectedValue, rs.getInt(1));
+            assertFalse(rs.next());
+        }
+    }
+    
+    private void assertColumnFamilyCounter(String columnFamily, String schemaName, String tableName, int expectedValue) throws Exception {
+        String query = "SELECT " + ENCODED_COLUMN_QUALIFIER_COUNTER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? " + " AND " + COLUMN_FAMILY + " = ? AND " + ENCODED_COLUMN_QUALIFIER_COUNTER + " IS NOT NULL";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PreparedStatement stmt = conn.prepareStatement(query);
+            stmt.setString(1, schemaName);
+            stmt.setString(2, tableName);
+            stmt.setString(3, columnFamily);
+            ResultSet rs = stmt.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(expectedValue, rs.getInt(1));
+            assertFalse(rs.next());
+        }
+    }
+    
+    private void assertSequenceNumber(String schemaName, String tableName, long expectedSequenceNumber) throws Exception {
+        String query = "SELECT " + TABLE_SEQ_NUM + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? AND " +  TABLE_SEQ_NUM + " IS NOT NULL AND " + COLUMN_NAME + " IS NULL AND "
+                + COLUMN_FAMILY + " IS NULL ";
+        try (Connection conn = DriverManager.getConnection(getUrl())) {
+            PreparedStatement stmt = conn.prepareStatement(query);
+            stmt.setString(1, schemaName);
+            stmt.setString(2, tableName);
+            ResultSet rs = stmt.executeQuery();
+            assertTrue(rs.next());
+            assertEquals(expectedSequenceNumber, rs.getInt(1));
+            assertFalse(rs.next());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/it/java/org/apache/phoenix/end2end/DynamicColumnIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DynamicColumnIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DynamicColumnIT.java
index fd14abb..4141b7f 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DynamicColumnIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DynamicColumnIT.java
@@ -18,6 +18,7 @@
 
 package org.apache.phoenix.end2end;
 
+import static org.apache.phoenix.query.QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES;
 import static org.apache.phoenix.util.TestUtil.HBASE_DYNAMIC_COLUMNS;
 import static org.apache.phoenix.util.TestUtil.HBASE_DYNAMIC_COLUMNS_SCHEMA_NAME;
 import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
@@ -38,12 +39,18 @@ import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.client.Row;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.query.ConnectionQueryServices;
 import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.ColumnAlreadyExistsException;
 import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
+import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableKey;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.TestUtil;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -81,25 +88,26 @@ public class DynamicColumnIT extends BaseClientManagedTimeIT {
         try {
             // Insert rows using standard HBase mechanism with standard HBase "types"
             List<Row> mutations = new ArrayList<Row>();
-            byte[] dv = Bytes.toBytes("DV");
-            byte[] first = Bytes.toBytes("F");
-            byte[] f1v1 = Bytes.toBytes("F1V1");
-            byte[] f1v2 = Bytes.toBytes("F1V2");
-            byte[] f2v1 = Bytes.toBytes("F2V1");
-            byte[] f2v2 = Bytes.toBytes("F2V2");
-            byte[] key = Bytes.toBytes("entry1");
-
-            Put put = new Put(key);
-            put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, dv, Bytes.toBytes("default"));
-            put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, first, Bytes.toBytes("first"));
-            put.add(FAMILY_NAME, f1v1, Bytes.toBytes("f1value1"));
-            put.add(FAMILY_NAME, f1v2, Bytes.toBytes("f1value2"));
-            put.add(FAMILY_NAME2, f2v1, Bytes.toBytes("f2value1"));
-            put.add(FAMILY_NAME2, f2v2, Bytes.toBytes("f2value2"));
-            mutations.add(put);
-
-            hTable.batch(mutations);
-
+            try (Connection conn = DriverManager.getConnection(url, TestUtil.TEST_PROPERTIES)) {
+                PTable table = conn.unwrap(PhoenixConnection.class).getTable(new PTableKey(null, SchemaUtil.getTableName(HBASE_DYNAMIC_COLUMNS_SCHEMA_NAME,HBASE_DYNAMIC_COLUMNS)));
+                byte[] dv = Bytes.toBytes("DV");
+                byte[] first = EncodedColumnsUtil.getEncodedColumnQualifier(getColumn(table, "F", Bytes.toString(DEFAULT_COLUMN_FAMILY_BYTES)));
+                byte[] f1v1 = EncodedColumnsUtil.getEncodedColumnQualifier(getColumn(table, "F1V1", Bytes.toString(FAMILY_NAME)));
+                byte[] f1v2 = EncodedColumnsUtil.getEncodedColumnQualifier(getColumn(table, "F1V2", Bytes.toString(FAMILY_NAME)));
+                byte[] f2v1 = EncodedColumnsUtil.getEncodedColumnQualifier(getColumn(table, "F2V1", Bytes.toString(FAMILY_NAME2)));
+                byte[] f2v2 = Bytes.toBytes("F2V2");
+                byte[] key = Bytes.toBytes("entry1");
+
+                Put put = new Put(key);
+                put.add(DEFAULT_COLUMN_FAMILY_BYTES, dv, Bytes.toBytes("default"));
+                put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, first, Bytes.toBytes("first"));
+                put.add(FAMILY_NAME, f1v1, Bytes.toBytes("f1value1"));
+                put.add(FAMILY_NAME, f1v2, Bytes.toBytes("f1value2"));
+                put.add(FAMILY_NAME2, f2v1, Bytes.toBytes("f2value1"));
+                put.add(FAMILY_NAME2, f2v2, Bytes.toBytes("f2value2"));
+                mutations.add(put);
+                hTable.batch(mutations);
+            }
         } finally {
             hTable.close();
         }
@@ -107,7 +115,18 @@ public class DynamicColumnIT extends BaseClientManagedTimeIT {
         // The timestamp of the table creation must be later than the timestamp of the data
         ensureTableCreated(getUrl(), HBASE_DYNAMIC_COLUMNS);
     }
-
+    
+    private static PColumn getColumn(PTable table, String columnName, String familyName) {
+        for (PColumn column : table.getColumns()) {
+            if (column.getName().getString().equals(columnName)
+                    && ((familyName == null && column.getFamilyName() == null)
+                            || (familyName == null && column.getFamilyName().getString() == null) || (familyName
+                                .equals(column.getFamilyName().getString())))) {
+                return column;
+            }
+        }
+        throw new IllegalArgumentException("Column " + columnName + " not found in " + table.getName().getString());
+    }
     /**
      * Test a simple select with a dynamic Column
      */

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/txn/MutableRollbackIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/txn/MutableRollbackIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/txn/MutableRollbackIT.java
index e675dda..767c4e0 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/txn/MutableRollbackIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/txn/MutableRollbackIT.java
@@ -278,7 +278,7 @@ public class MutableRollbackIT extends BaseHBaseManagedTimeIT {
             assertFalse(rs.next());
             
             //assert no rows exists in indexName2
-            rs = stmt.executeQuery("select /*+ INDEX(" + indexName1 + ")*/ k, v1 from " + fullTableName2);
+            rs = stmt.executeQuery("select * from " + fullTableName2);
             assertFalse(rs.next());
             
             stmt.executeUpdate("upsert into " + fullTableName1 + " values('x', 'z', 'a')");

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
index ba904e5..eec8c8a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
@@ -776,12 +776,12 @@ public class FromCompiler {
                         null, 0, 0, true, position++, SortOrder.ASC, null, null, false, null, false, false, null);
                 columns.add(column);
             }
-            //TODO: samarth confirm if the storage scheme should be passed as null here. Could it be non-encoded column names?
+            //TODO: samarth confirm if the storage scheme and encode cqcounters should be passed as null here. Could it be non-encoded column names?
             PTable t = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,
                     MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM, null, null, columns, null, null,
                     Collections.<PTable> emptyList(), false, Collections.<PName> emptyList(), null, null, false, false,
                     false, null, null, null, false, false, 0, 0L, SchemaUtil
-                            .isNamespaceMappingEnabled(PTableType.SUBQUERY, connection.getQueryServices().getProps()), null);
+                            .isNamespaceMappingEnabled(PTableType.SUBQUERY, connection.getQueryServices().getProps()), null, null);
 
             String alias = subselectNode.getAlias();
             TableRef tableRef = new TableRef(alias, t, MetaDataProtocol.MIN_TABLE_TIMESTAMP, false);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
index fe07d8d..69b9bfb 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
@@ -1308,7 +1308,8 @@ public class JoinCompiler {
                 left.getBucketNum(), merged,left.getParentSchemaName(), left.getParentTableName(), left.getIndexes(),
                 left.isImmutableRows(), Collections.<PName>emptyList(), null, null, PTable.DEFAULT_DISABLE_WAL,
                 left.isMultiTenant(), left.getStoreNulls(), left.getViewType(), left.getViewIndexId(), left.getIndexType(),
-                left.rowKeyOrderOptimizable(), left.isTransactional(), left.getUpdateCacheFrequency(), left.getIndexDisableTimestamp(), left.isNamespaceMapped(), StorageScheme.NON_ENCODED_COLUMN_NAMES);
+                left.rowKeyOrderOptimizable(), left.isTransactional(), left.getUpdateCacheFrequency(), left.getIndexDisableTimestamp(), left.isNamespaceMapped(), StorageScheme.NON_ENCODED_COLUMN_NAMES, null);
+                //FIXME: samarth
     }
 
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
index b812db5..f9e7f44 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
@@ -154,7 +154,7 @@ public class TupleProjectionCompiler {
                 table.getParentName(), table.getIndexes(), table.isImmutableRows(), Collections.<PName> emptyList(),
                 null, null, table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(),
                 table.getViewIndexId(),
-                table.getIndexType(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
+                table.getIndexType(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme(), table.getEncodedCQCounters());
     }
 
     public static PTable createProjectedTable(TableRef tableRef, List<ColumnRef> sourceColumnRefs, boolean retainPKColumns) throws SQLException {
@@ -182,7 +182,7 @@ public class TupleProjectionCompiler {
                 Collections.<PTable> emptyList(), table.isImmutableRows(), Collections.<PName> emptyList(), null, null,
                 table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(),
                 table.getViewIndexId(), null, table.rowKeyOrderOptimizable(), table.isTransactional(),
-                table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme());
+                table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getStorageScheme(), table.getEncodedCQCounters());
     }
 
     // For extracting column references from single select statement

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
index 7b534ba..9c89817 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
@@ -86,7 +86,7 @@ public class UnionCompiler {
                 scn == null ? HConstants.LATEST_TIMESTAMP : scn, null, null, projectedColumns, null, null, null, true,
                 null, null, null, true, true, true, null, null, null, false, false, 0, 0L,
                 SchemaUtil.isNamespaceMappingEnabled(PTableType.SUBQUERY,
-                        statement.getConnection().getQueryServices().getProps()), null);
+                        statement.getConnection().getQueryServices().getProps()), null, null);
         TableRef tableRef = new TableRef(null, tempTable, 0, false);
         return tableRef;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 8fdb45b..1d2c0d3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -19,14 +19,12 @@ package org.apache.phoenix.coprocessor;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
-import static org.apache.phoenix.schema.PTable.StorageScheme;
 import static org.apache.hadoop.hbase.KeyValue.createFirstOnRow;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ARRAY_SIZE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CLASS_NAME_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME_INDEX;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TYPE_BYTES;
@@ -34,6 +32,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DECIMAL_DIGITS_BYT
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_VALUE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL_BYTES;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.FAMILY_NAME_INDEX;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IMMUTABLE_ROWS_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP_BYTES;
@@ -85,9 +84,11 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-
+import java.util.Map;
+import java.util.Set;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.Coprocessor;
@@ -184,6 +185,7 @@ import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTable.IndexType;
 import org.apache.phoenix.schema.PTable.LinkType;
+import org.apache.phoenix.schema.PTable.StorageScheme;
 import org.apache.phoenix.schema.PTable.ViewType;
 import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableType;
@@ -339,7 +341,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final KeyValue IS_VIEW_REFERENCED_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, IS_VIEW_REFERENCED_BYTES);
     private static final KeyValue COLUMN_DEF_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_DEF_BYTES);
     private static final KeyValue IS_ROW_TIMESTAMP_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, IS_ROW_TIMESTAMP_BYTES);
-    private static final KeyValue COLUMN_QUALIFIER_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_QUALIFIER_BYTES);
+    private static final KeyValue ENCODED_COLUMN_QUALIFIER_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, ENCODED_COLUMN_QUALIFIER_BYTES);
     private static final List<KeyValue> COLUMN_KV_COLUMNS = Arrays.<KeyValue>asList(
             DECIMAL_DIGITS_KV,
             COLUMN_SIZE_KV,
@@ -353,7 +355,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             IS_VIEW_REFERENCED_KV,
             COLUMN_DEF_KV,
             IS_ROW_TIMESTAMP_KV,
-            COLUMN_QUALIFIER_KV
+            ENCODED_COLUMN_QUALIFIER_KV
             );
     static {
         Collections.sort(COLUMN_KV_COLUMNS, KeyValue.COMPARATOR);
@@ -369,10 +371,10 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final int IS_VIEW_REFERENCED_INDEX = COLUMN_KV_COLUMNS.indexOf(IS_VIEW_REFERENCED_KV);
     private static final int COLUMN_DEF_INDEX = COLUMN_KV_COLUMNS.indexOf(COLUMN_DEF_KV);
     private static final int IS_ROW_TIMESTAMP_INDEX = COLUMN_KV_COLUMNS.indexOf(IS_ROW_TIMESTAMP_KV);
-    private static final int COLUMN_QUALIFIER_INDEX = COLUMN_KV_COLUMNS.indexOf(COLUMN_QUALIFIER_KV);
+    private static final int ENCODED_COLUMN_QUALIFIER_INDEX = COLUMN_KV_COLUMNS.indexOf(ENCODED_COLUMN_QUALIFIER_KV);
     
     private static final int LINK_TYPE_INDEX = 0;
-
+    
     private static final KeyValue CLASS_NAME_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, CLASS_NAME_BYTES);
     private static final KeyValue JAR_PATH_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, JAR_PATH_BYTES);
     private static final KeyValue RETURN_TYPE_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, RETURN_TYPE_BYTES);
@@ -708,7 +710,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 isRowTimestampKV == null ? false : Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(
                         isRowTimestampKV.getValueArray(), isRowTimestampKV.getValueOffset(),
                         isRowTimestampKV.getValueLength()));
-        Cell columnQualifierKV = colKeyValues[COLUMN_QUALIFIER_INDEX];
+        Cell columnQualifierKV = colKeyValues[ENCODED_COLUMN_QUALIFIER_INDEX];
         Integer columnQualifier = columnQualifierKV == null ? null :
             PInteger.INSTANCE.getCodec().decodeInt(columnQualifierKV.getValueArray(), columnQualifierKV.getValueOffset(), SortOrder.getDefault());
 
@@ -915,10 +917,12 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                         isNamespaceMappedKv.getValueOffset(), isNamespaceMappedKv.getValueLength()));
         Cell storageSchemeKv = tableKeyValues[STORAGE_SCHEME_INDEX];
         byte v = (byte)PTinyint.INSTANCE.toObject(storageSchemeKv.getValueArray(), storageSchemeKv.getValueOffset(), storageSchemeKv.getValueLength());
-        StorageScheme storageScheme = storageSchemeKv == null ? null : StorageScheme.fromSerializedValue(v);
+        //TODO: change this once we start having other values for storage schemes
+        StorageScheme storageScheme = storageSchemeKv == null ? StorageScheme.NON_ENCODED_COLUMN_NAMES : StorageScheme.fromSerializedValue(v);
         List<PColumn> columns = Lists.newArrayListWithExpectedSize(columnCount);
         List<PTable> indexes = new ArrayList<PTable>();
         List<PName> physicalTables = new ArrayList<PName>();
+        Map<String, Integer> encodedColumnQualifierCounters = new HashMap<>(); //TODO: samarth size properly.
         while (true) {
           results.clear();
           scanner.next(results);
@@ -926,19 +930,36 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
               break;
           }
           Cell colKv = results.get(LINK_TYPE_INDEX);
-          int colKeyLength = colKv.getRowLength();
-          PName colName = newPName(colKv.getRowArray(), colKv.getRowOffset() + offset, colKeyLength-offset);
-          int colKeyOffset = offset + colName.getBytes().length + 1;
-          PName famName = newPName(colKv.getRowArray(), colKv.getRowOffset() + colKeyOffset, colKeyLength-colKeyOffset);
-          if (colName.getString().isEmpty() && famName != null) {
-              LinkType linkType = LinkType.fromSerializedValue(colKv.getValueArray()[colKv.getValueOffset()]);
-              if (linkType == LinkType.INDEX_TABLE) {
-                  addIndexToTable(tenantId, schemaName, famName, tableName, clientTimeStamp, indexes);
-              } else if (linkType == LinkType.PHYSICAL_TABLE) {
-                  physicalTables.add(famName);
+          Cell qualifierCounterKv = null;
+          if (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES) {
+              int index = tableType == PTableType.VIEW ? 1 : 0;
+              qualifierCounterKv = results.get(index);
+          }
+          if (colKv != null) {
+              int colKeyLength = colKv.getRowLength();
+              PName colName = newPName(colKv.getRowArray(), colKv.getRowOffset() + offset, colKeyLength-offset);
+              int colKeyOffset = offset + colName.getBytes().length + 1;
+              PName famName = newPName(colKv.getRowArray(), colKv.getRowOffset() + colKeyOffset, colKeyLength-colKeyOffset);
+              if (colName.getString().isEmpty() && famName != null) {
+                  LinkType linkType = LinkType.fromSerializedValue(colKv.getValueArray()[colKv.getValueOffset()]);
+                  if (linkType == LinkType.INDEX_TABLE) {
+                      addIndexToTable(tenantId, schemaName, famName, tableName, clientTimeStamp, indexes);
+                  } else if (linkType == LinkType.PHYSICAL_TABLE) {
+                      physicalTables.add(famName);
+                  }
+              } else {
+                  addColumnToTable(results, colName, famName, colKeyValues, columns, saltBucketNum != null);
+              }
+          } 
+          if (qualifierCounterKv != null) {
+              int length = qualifierCounterKv.getRowLength();
+              PName colName = newPName(qualifierCounterKv.getRowArray(), qualifierCounterKv.getRowOffset() + offset, length - offset);
+              int colKeyOffset = offset + colName.getBytes().length + 1;
+              PName famName = newPName(qualifierCounterKv.getRowArray(), qualifierCounterKv.getRowOffset() + colKeyOffset, length - colKeyOffset);
+              if (colName.getString().isEmpty() && famName != null) {
+                  Integer counter = (Integer)PInteger.INSTANCE.toObject(qualifierCounterKv.getValueArray(), qualifierCounterKv.getValueOffset(), qualifierCounterKv.getValueLength());
+                  encodedColumnQualifierCounters.put(famName.getString(), counter);
               }
-          } else {
-              addColumnToTable(results, colName, famName, colKeyValues, columns, saltBucketNum != null);
           }
         }
         PName physicalTableName = physicalTables.isEmpty() ? PNameFactory.newName(SchemaUtil.getPhysicalTableName(
@@ -965,7 +986,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 tableType == INDEX ? dataTableName : null, indexes, isImmutableRows, physicalTables, defaultFamilyName,
                 viewStatement, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType,
                 rowKeyOrderOptimizable, transactional, updateCacheFrequency, stats, baseColumnCount,
-                indexDisableTimestamp, isNamespaceMapped, storageScheme);
+                indexDisableTimestamp, isNamespaceMapped, storageScheme, encodedColumnQualifierCounters);
     }
 
     private PSchema getSchema(RegionScanner scanner, long clientTimeStamp) throws IOException, SQLException {
@@ -1866,7 +1887,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                     return result;
                 }
                 region.mutateRowsWithLocks(tableMetadata, Collections.<byte[]> emptySet());
-                // Invalidate from cache
+                // Invalidate from cache. //TODO: samarth should we invalidate the base table from the cache too here.
                 for (ImmutableBytesPtr invalidateKey : invalidateList) {
                     metaDataCache.invalidate(invalidateKey);
                 }
@@ -2039,6 +2060,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 byte[][] rkmd = new byte[5][];
                 int pkCount = getVarChars(m.getRow(), rkmd);
                 if (pkCount > COLUMN_NAME_INDEX
+                        && rkmd[COLUMN_NAME_INDEX] != null && rkmd[COLUMN_NAME_INDEX].length > 0
                         && Bytes.compareTo(schemaName, rkmd[SCHEMA_NAME_INDEX]) == 0
                         && Bytes.compareTo(tableName, rkmd[TABLE_NAME_INDEX]) == 0) {
                     columnPutsForBaseTable.add(new PutWithOrdinalPosition((Put)m, getInteger((Put)m, TABLE_FAMILY_BYTES, ORDINAL_POSITION_BYTES)));
@@ -2201,26 +2223,26 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                     columnsAddedToBaseTable++;
                 }
             }
-            /*
-             * Allow adding a pk columns to base table : 1. if all the view pk columns are exactly the same as the base
-             * table pk columns 2. if we are adding all the existing view pk columns to the base table
-             */ 
-            if (addingExistingPkCol && !viewPkCols.equals(basePhysicalTable.getPKColumns())) {
-                return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION, EnvironmentEdgeManager.currentTimeMillis(), basePhysicalTable);
-            }
-            addViewIndexesHeaderRowMutations(mutationsForAddingColumnsToViews, invalidateList, clientTimeStamp, view,
-                    deltaNumPkColsSoFar);
-            
-            /*
-             * Increment the sequence number by 1 if:
-             * 1) For a diverged view, there were columns (pk columns) added to the view.
-             * 2) For a non-diverged view if the base column count changed.
-             */
-            boolean changeSequenceNumber = (isDivergedView(view) && columnsAddedToView > 0)
-                    || (!isDivergedView(view) && columnsAddedToBaseTable > 0);
-            updateViewHeaderRow(basePhysicalTable, tableMetadata, mutationsForAddingColumnsToViews,
-                invalidateList, clientTimeStamp, columnsAddedToView, columnsAddedToBaseTable,
-                viewKey, view, ordinalPositionList, numCols, changeSequenceNumber);
+           /*
+            * Allow adding a pk columns to base table : 1. if all the view pk columns are exactly the same as the base
+            * table pk columns 2. if we are adding all the existing view pk columns to the base table
+            */ 
+           if (addingExistingPkCol && !viewPkCols.equals(basePhysicalTable.getPKColumns())) {
+               return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION, EnvironmentEdgeManager.currentTimeMillis(), basePhysicalTable);
+           }
+           addViewIndexesHeaderRowMutations(mutationsForAddingColumnsToViews, invalidateList, clientTimeStamp, view,
+                   deltaNumPkColsSoFar);
+           
+           /*
+            * Increment the sequence number by 1 if:
+            * 1) For a diverged view, there were columns (pk columns) added to the view.
+            * 2) For a non-diverged view if the base column count changed.
+            */
+           boolean changeSequenceNumber = (isDivergedView(view) && columnsAddedToView > 0)
+                   || (!isDivergedView(view) && columnsAddedToBaseTable > 0);
+           updateViewHeaderRow(basePhysicalTable, tableMetadata, mutationsForAddingColumnsToViews,
+               invalidateList, clientTimeStamp, columnsAddedToView, columnsAddedToBaseTable,
+               viewKey, view, ordinalPositionList, numCols, changeSequenceNumber);
         }
         return null;
     }
@@ -2445,7 +2467,9 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     
     private MetaDataMutationResult validateColumnForAddToBaseTable(PColumn existingViewColumn, Put columnToBeAdded, PTable basePhysicalTable, boolean isColumnToBeAddPkCol, PTable view) {
         if (existingViewColumn != null) {
-            
+            if (EncodedColumnsUtil.usesEncodedColumnNames(basePhysicalTable) && !SchemaUtil.isPKColumn(existingViewColumn)) {
+                return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION, EnvironmentEdgeManager.currentTimeMillis(), basePhysicalTable);
+            }
             // Validate data type is same
             int baseColumnDataType = getInteger(columnToBeAdded, TABLE_FAMILY_BYTES, DATA_TYPE_BYTES);
             if (baseColumnDataType != existingViewColumn.getDataType().getSqlType()) {


[44/52] [abbrv] phoenix git commit: Revert "Metadata changes to support encoding of column names"

Posted by sa...@apache.org.
Revert "Metadata changes to support encoding of column names"

This reverts commit f7c1d45a17771c1010d1bec37a167ee127b54607.
Reverting the commit.


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

Branch: refs/heads/encodecolumns
Commit: 2fda59a19b11f1f669ff0a3bbd4e655766554dbe
Parents: cd89103
Author: Samarth <sa...@salesforce.com>
Authored: Fri Mar 11 18:09:59 2016 -0800
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:31 2016 -0700

----------------------------------------------------------------------
 .../apache/phoenix/end2end/AlterTableIT.java    |  30 ----
 .../apache/phoenix/compile/FromCompiler.java    |   8 +-
 .../phoenix/compile/ListJarsQueryPlan.java      |   2 +-
 .../apache/phoenix/compile/TraceQueryPlan.java  |   2 +-
 .../apache/phoenix/compile/UnionCompiler.java   |   3 +-
 .../coprocessor/MetaDataEndpointImpl.java       |  11 +-
 .../coprocessor/generated/PTableProtos.java     | 147 ++++---------------
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java   |   2 -
 .../query/ConnectionQueryServicesImpl.java      |   1 -
 .../apache/phoenix/query/QueryConstants.java    |   2 -
 .../apache/phoenix/schema/DelegateColumn.java   |   5 -
 .../apache/phoenix/schema/MetaDataClient.java   |  41 ++----
 .../java/org/apache/phoenix/schema/PColumn.java |   7 +-
 .../org/apache/phoenix/schema/PColumnImpl.java  |  24 +--
 .../apache/phoenix/schema/PMetaDataImpl.java    |   2 +-
 .../org/apache/phoenix/schema/SaltingUtil.java  |   2 +-
 .../org/apache/phoenix/util/SchemaUtil.java     |  13 --
 .../phoenix/execute/CorrelatePlanTest.java      |   2 +-
 .../execute/LiteralResultIteratorPlanTest.java  |   2 +-
 .../phoenix/execute/UnnestArrayPlanTest.java    |   4 +-
 .../expression/ColumnExpressionTest.java        |   8 +-
 .../iterate/AggregateResultScannerTest.java     |   4 -
 phoenix-protocol/src/main/PTable.proto          |   1 -
 23 files changed, 64 insertions(+), 259 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index bad6200..2dc0913 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -44,7 +44,6 @@ import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.KeepDeletedCells;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.client.HTable;
-import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.ResultScanner;
 import org.apache.hadoop.hbase.client.Scan;
@@ -2216,35 +2215,6 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
 			}
 		}
 	}
-	
-	@Test
-    public void testColumnQualifierForUpsertedValues() throws Exception {
-        String schemaName = "A";
-        String tableName = "TEST";
-        String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
-        String ddl = "create table " + fullTableName 
-                + " (" 
-                + " K varchar primary key,"
-                + " CF1.V1 varchar)";
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            conn.createStatement().execute(ddl);
-        }
-        String dml = "UPSERT INTO " + fullTableName + " VALUES (?, ?)";
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            PreparedStatement stmt = conn.prepareStatement(dml);
-            stmt.setString(1, "KEY1");
-            stmt.setString(2, "VALUE1");
-            stmt.executeUpdate();
-            conn.commit();
-        }
-        // Issue a raw hbase scan using the column qualifier 0 for column CF1.V1.
-        try (Connection conn = DriverManager.getConnection(getUrl())) {
-            HTableInterface table = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes(fullTableName));
-            ResultScanner scanner = table.getScanner(new Scan());
-            Result next = scanner.next();
-            assertTrue(next.containsColumn(Bytes.toBytes("CF1"), Bytes.toBytes("V1")));
-        }
-    }
     
 }
  

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
index abcf432..a2fc371 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
@@ -250,7 +250,7 @@ public class FromCompiler {
             Expression sourceExpression = projector.getColumnProjector(column.getPosition()).getExpression();
             PColumnImpl projectedColumn = new PColumnImpl(column.getName(), column.getFamilyName(),
                     sourceExpression.getDataType(), sourceExpression.getMaxLength(), sourceExpression.getScale(), sourceExpression.isNullable(),
-                    column.getPosition(), sourceExpression.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic(), column.getColumnQualifier());
+                    column.getPosition(), sourceExpression.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic());
             projectedColumns.add(projectedColumn);
         }
         PTable t = PTableImpl.makePTable(table, projectedColumns);
@@ -664,9 +664,8 @@ public class FromCompiler {
                         theTable.getColumnFamily(family); // Verifies that column family exists
                         familyName = PNameFactory.newName(family);
                     }
-                    // Dynamic columns don't have a corresponding column qualifier
                     allcolumns.add(new PColumnImpl(name, familyName, dynColumn.getDataType(), dynColumn.getMaxLength(),
-                            dynColumn.getScale(), dynColumn.isNull(), position, dynColumn.getSortOrder(), dynColumn.getArraySize(), null, false, dynColumn.getExpression(), false, true, null));
+                            dynColumn.getScale(), dynColumn.isNull(), position, dynColumn.getSortOrder(), dynColumn.getArraySize(), null, false, dynColumn.getExpression(), false, true));
                     position++;
                 }
                 theTable = PTableImpl.makePTable(theTable, allcolumns);
@@ -768,10 +767,9 @@ public class FromCompiler {
                     // referenced by an outer wild-card select.
                     alias = String.valueOf(position);
                 }
-                //TODO: samarth confirm this is the right change i.e. using null for column qualifier
                 PColumnImpl column = new PColumnImpl(PNameFactory.newName(alias),
                         PNameFactory.newName(QueryConstants.DEFAULT_COLUMN_FAMILY),
-                        null, 0, 0, true, position++, SortOrder.ASC, null, null, false, null, false, false, null);
+                        null, 0, 0, true, position++, SortOrder.ASC, null, null, false, null, false, false);
                 columns.add(column);
             }
             PTable t = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
index cceef9a..1047334 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
@@ -80,7 +80,7 @@ public class ListJarsQueryPlan implements QueryPlan {
         PColumn column =
                 new PColumnImpl(PNameFactory.newName("jar_location"), null,
                         PVarchar.INSTANCE, null, null, false, 0, SortOrder.getDefault(), 0, null,
-                        false, null, false, false, null);
+                        false, null, false, false);
         List<PColumn> columns = new ArrayList<PColumn>();
         columns.add(column);
         Expression expression =

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
index 79d212f..699643b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java
@@ -78,7 +78,7 @@ public class TraceQueryPlan implements QueryPlan {
         PColumn column =
                 new PColumnImpl(PNameFactory.newName(MetricInfo.TRACE.columnName), null,
                         PLong.INSTANCE, null, null, false, 0, SortOrder.getDefault(), 0, null,
-                        false, null, false, false, null);
+                        false, null, false, false);
         List<PColumn> columns = new ArrayList<PColumn>();
         columns.add(column);
         Expression expression =

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
index f720e9d..32fa8fe 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
@@ -74,10 +74,9 @@ public class UnionCompiler {
             ColumnProjector colProj = plan.getProjector().getColumnProjector(i);
             Expression sourceExpression = colProj.getExpression();
             String name = selectNodes == null ? colProj.getName() : selectNodes.get(i).getAlias();
-            //TODO: samarth confirm this is the right change
             PColumnImpl projectedColumn = new PColumnImpl(PNameFactory.newName(name), UNION_FAMILY_NAME,
                     sourceExpression.getDataType(), sourceExpression.getMaxLength(), sourceExpression.getScale(), sourceExpression.isNullable(),
-                    i, sourceExpression.getSortOrder(), 500, null, false, sourceExpression.toString(), false, false, null);
+                    i, sourceExpression.getSortOrder(), 500, null, false, sourceExpression.toString(), false, false);
             projectedColumns.add(projectedColumn);
         }
         Long scn = statement.getConnection().getSCN();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index a9dd9ea..1fd4f44 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -25,7 +25,6 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CLASS_NAME_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME_INDEX;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TYPE_BYTES;
@@ -332,7 +331,6 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final KeyValue IS_VIEW_REFERENCED_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, IS_VIEW_REFERENCED_BYTES);
     private static final KeyValue COLUMN_DEF_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_DEF_BYTES);
     private static final KeyValue IS_ROW_TIMESTAMP_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, IS_ROW_TIMESTAMP_BYTES);
-    private static final KeyValue COLUMN_QUALIFIER_KV = KeyValue.createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_QUALIFIER_BYTES);
     private static final List<KeyValue> COLUMN_KV_COLUMNS = Arrays.<KeyValue>asList(
             DECIMAL_DIGITS_KV,
             COLUMN_SIZE_KV,
@@ -345,8 +343,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
             VIEW_CONSTANT_KV,
             IS_VIEW_REFERENCED_KV,
             COLUMN_DEF_KV,
-            IS_ROW_TIMESTAMP_KV,
-            COLUMN_QUALIFIER_KV
+            IS_ROW_TIMESTAMP_KV
             );
     static {
         Collections.sort(COLUMN_KV_COLUMNS, KeyValue.COMPARATOR);
@@ -362,7 +359,6 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final int IS_VIEW_REFERENCED_INDEX = COLUMN_KV_COLUMNS.indexOf(IS_VIEW_REFERENCED_KV);
     private static final int COLUMN_DEF_INDEX = COLUMN_KV_COLUMNS.indexOf(COLUMN_DEF_KV);
     private static final int IS_ROW_TIMESTAMP_INDEX = COLUMN_KV_COLUMNS.indexOf(IS_ROW_TIMESTAMP_KV);
-    private static final int COLUMN_QUALIFIER_INDEX = COLUMN_KV_COLUMNS.indexOf(COLUMN_QUALIFIER_KV);
     
     private static final int LINK_TYPE_INDEX = 0;
 
@@ -701,11 +697,8 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                 isRowTimestampKV == null ? false : Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(
                         isRowTimestampKV.getValueArray(), isRowTimestampKV.getValueOffset(),
                         isRowTimestampKV.getValueLength()));
-        Cell columnQualifierKV = colKeyValues[COLUMN_QUALIFIER_INDEX];
-        Integer columnQualifier = columnQualifierKV == null ? null :
-            PInteger.INSTANCE.getCodec().decodeInt(columnQualifierKV.getValueArray(), columnQualifierKV.getValueOffset(), SortOrder.getDefault());
 
-        PColumn column = new PColumnImpl(colName, famName, dataType, maxLength, scale, isNullable, position-1, sortOrder, arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, false, columnQualifier);
+        PColumn column = new PColumnImpl(colName, famName, dataType, maxLength, scale, isNullable, position-1, sortOrder, arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, false);
         columns.add(column);
     }
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
index 24bb841..126c0dd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
@@ -269,16 +269,6 @@ public final class PTableProtos {
      * <code>optional bool isDynamic = 14;</code>
      */
     boolean getIsDynamic();
-
-    // optional int32 columnQualifier = 15;
-    /**
-     * <code>optional int32 columnQualifier = 15;</code>
-     */
-    boolean hasColumnQualifier();
-    /**
-     * <code>optional int32 columnQualifier = 15;</code>
-     */
-    int getColumnQualifier();
   }
   /**
    * Protobuf type {@code PColumn}
@@ -401,11 +391,6 @@ public final class PTableProtos {
               isDynamic_ = input.readBool();
               break;
             }
-            case 120: {
-              bitField0_ |= 0x00004000;
-              columnQualifier_ = input.readInt32();
-              break;
-            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -724,22 +709,6 @@ public final class PTableProtos {
       return isDynamic_;
     }
 
-    // optional int32 columnQualifier = 15;
-    public static final int COLUMNQUALIFIER_FIELD_NUMBER = 15;
-    private int columnQualifier_;
-    /**
-     * <code>optional int32 columnQualifier = 15;</code>
-     */
-    public boolean hasColumnQualifier() {
-      return ((bitField0_ & 0x00004000) == 0x00004000);
-    }
-    /**
-     * <code>optional int32 columnQualifier = 15;</code>
-     */
-    public int getColumnQualifier() {
-      return columnQualifier_;
-    }
-
     private void initFields() {
       columnNameBytes_ = com.google.protobuf.ByteString.EMPTY;
       familyNameBytes_ = com.google.protobuf.ByteString.EMPTY;
@@ -755,7 +724,6 @@ public final class PTableProtos {
       expression_ = "";
       isRowTimestamp_ = false;
       isDynamic_ = false;
-      columnQualifier_ = 0;
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -831,9 +799,6 @@ public final class PTableProtos {
       if (((bitField0_ & 0x00002000) == 0x00002000)) {
         output.writeBool(14, isDynamic_);
       }
-      if (((bitField0_ & 0x00004000) == 0x00004000)) {
-        output.writeInt32(15, columnQualifier_);
-      }
       getUnknownFields().writeTo(output);
     }
 
@@ -899,10 +864,6 @@ public final class PTableProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeBoolSize(14, isDynamic_);
       }
-      if (((bitField0_ & 0x00004000) == 0x00004000)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeInt32Size(15, columnQualifier_);
-      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -996,11 +957,6 @@ public final class PTableProtos {
         result = result && (getIsDynamic()
             == other.getIsDynamic());
       }
-      result = result && (hasColumnQualifier() == other.hasColumnQualifier());
-      if (hasColumnQualifier()) {
-        result = result && (getColumnQualifier()
-            == other.getColumnQualifier());
-      }
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -1070,10 +1026,6 @@ public final class PTableProtos {
         hash = (37 * hash) + ISDYNAMIC_FIELD_NUMBER;
         hash = (53 * hash) + hashBoolean(getIsDynamic());
       }
-      if (hasColumnQualifier()) {
-        hash = (37 * hash) + COLUMNQUALIFIER_FIELD_NUMBER;
-        hash = (53 * hash) + getColumnQualifier();
-      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -1211,8 +1163,6 @@ public final class PTableProtos {
         bitField0_ = (bitField0_ & ~0x00001000);
         isDynamic_ = false;
         bitField0_ = (bitField0_ & ~0x00002000);
-        columnQualifier_ = 0;
-        bitField0_ = (bitField0_ & ~0x00004000);
         return this;
       }
 
@@ -1297,10 +1247,6 @@ public final class PTableProtos {
           to_bitField0_ |= 0x00002000;
         }
         result.isDynamic_ = isDynamic_;
-        if (((from_bitField0_ & 0x00004000) == 0x00004000)) {
-          to_bitField0_ |= 0x00004000;
-        }
-        result.columnQualifier_ = columnQualifier_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -1363,9 +1309,6 @@ public final class PTableProtos {
         if (other.hasIsDynamic()) {
           setIsDynamic(other.getIsDynamic());
         }
-        if (other.hasColumnQualifier()) {
-          setColumnQualifier(other.getColumnQualifier());
-        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -1966,39 +1909,6 @@ public final class PTableProtos {
         return this;
       }
 
-      // optional int32 columnQualifier = 15;
-      private int columnQualifier_ ;
-      /**
-       * <code>optional int32 columnQualifier = 15;</code>
-       */
-      public boolean hasColumnQualifier() {
-        return ((bitField0_ & 0x00004000) == 0x00004000);
-      }
-      /**
-       * <code>optional int32 columnQualifier = 15;</code>
-       */
-      public int getColumnQualifier() {
-        return columnQualifier_;
-      }
-      /**
-       * <code>optional int32 columnQualifier = 15;</code>
-       */
-      public Builder setColumnQualifier(int value) {
-        bitField0_ |= 0x00004000;
-        columnQualifier_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>optional int32 columnQualifier = 15;</code>
-       */
-      public Builder clearColumnQualifier() {
-        bitField0_ = (bitField0_ & ~0x00004000);
-        columnQualifier_ = 0;
-        onChanged();
-        return this;
-      }
-
       // @@protoc_insertion_point(builder_scope:PColumn)
     }
 
@@ -7269,7 +7179,7 @@ public final class PTableProtos {
       descriptor;
   static {
     java.lang.String[] descriptorData = {
-      "\n\014PTable.proto\032\021PGuidePosts.proto\"\277\002\n\007PC" +
+      "\n\014PTable.proto\032\021PGuidePosts.proto\"\246\002\n\007PC" +
       "olumn\022\027\n\017columnNameBytes\030\001 \002(\014\022\027\n\017family" +
       "NameBytes\030\002 \001(\014\022\020\n\010dataType\030\003 \002(\t\022\021\n\tmax" +
       "Length\030\004 \001(\005\022\r\n\005scale\030\005 \001(\005\022\020\n\010nullable\030" +
@@ -7277,33 +7187,32 @@ public final class PTableProtos {
       "(\005\022\021\n\tarraySize\030\t \001(\005\022\024\n\014viewConstant\030\n " +
       "\001(\014\022\026\n\016viewReferenced\030\013 \001(\010\022\022\n\nexpressio" +
       "n\030\014 \001(\t\022\026\n\016isRowTimestamp\030\r \001(\010\022\021\n\tisDyn" +
-      "amic\030\016 \001(\010\022\027\n\017columnQualifier\030\017 \001(\005\"\232\001\n\013" +
-      "PTableStats\022\013\n\003key\030\001 \002(\014\022\016\n\006values\030\002 \003(\014",
-      "\022\033\n\023guidePostsByteCount\030\003 \001(\003\022\025\n\rkeyByte" +
-      "sCount\030\004 \001(\003\022\027\n\017guidePostsCount\030\005 \001(\005\022!\n" +
-      "\013pGuidePosts\030\006 \001(\0132\014.PGuidePosts\"\336\005\n\006PTa" +
-      "ble\022\027\n\017schemaNameBytes\030\001 \002(\014\022\026\n\016tableNam" +
-      "eBytes\030\002 \002(\014\022\036\n\ttableType\030\003 \002(\0162\013.PTable" +
-      "Type\022\022\n\nindexState\030\004 \001(\t\022\026\n\016sequenceNumb" +
-      "er\030\005 \002(\003\022\021\n\ttimeStamp\030\006 \002(\003\022\023\n\013pkNameByt" +
-      "es\030\007 \001(\014\022\021\n\tbucketNum\030\010 \002(\005\022\031\n\007columns\030\t" +
-      " \003(\0132\010.PColumn\022\030\n\007indexes\030\n \003(\0132\007.PTable" +
-      "\022\027\n\017isImmutableRows\030\013 \002(\010\022 \n\nguidePosts\030",
-      "\014 \003(\0132\014.PTableStats\022\032\n\022dataTableNameByte" +
-      "s\030\r \001(\014\022\031\n\021defaultFamilyName\030\016 \001(\014\022\022\n\ndi" +
-      "sableWAL\030\017 \002(\010\022\023\n\013multiTenant\030\020 \002(\010\022\020\n\010v" +
-      "iewType\030\021 \001(\014\022\025\n\rviewStatement\030\022 \001(\014\022\025\n\r" +
-      "physicalNames\030\023 \003(\014\022\020\n\010tenantId\030\024 \001(\014\022\023\n" +
-      "\013viewIndexId\030\025 \001(\005\022\021\n\tindexType\030\026 \001(\014\022\026\n" +
-      "\016statsTimeStamp\030\027 \001(\003\022\022\n\nstoreNulls\030\030 \001(" +
-      "\010\022\027\n\017baseColumnCount\030\031 \001(\005\022\036\n\026rowKeyOrde" +
-      "rOptimizable\030\032 \001(\010\022\025\n\rtransactional\030\033 \001(" +
-      "\010\022\034\n\024updateCacheFrequency\030\034 \001(\003\022\035\n\025index",
-      "DisableTimestamp\030\035 \001(\003\022\031\n\021isNamespaceMap" +
-      "ped\030\036 \001(\010*A\n\nPTableType\022\n\n\006SYSTEM\020\000\022\010\n\004U" +
-      "SER\020\001\022\010\n\004VIEW\020\002\022\t\n\005INDEX\020\003\022\010\n\004JOIN\020\004B@\n(" +
-      "org.apache.phoenix.coprocessor.generated" +
-      "B\014PTableProtosH\001\210\001\001\240\001\001"
+      "amic\030\016 \001(\010\"\232\001\n\013PTableStats\022\013\n\003key\030\001 \002(\014\022" +
+      "\016\n\006values\030\002 \003(\014\022\033\n\023guidePostsByteCount\030\003",
+      " \001(\003\022\025\n\rkeyBytesCount\030\004 \001(\003\022\027\n\017guidePost" +
+      "sCount\030\005 \001(\005\022!\n\013pGuidePosts\030\006 \001(\0132\014.PGui" +
+      "dePosts\"\336\005\n\006PTable\022\027\n\017schemaNameBytes\030\001 " +
+      "\002(\014\022\026\n\016tableNameBytes\030\002 \002(\014\022\036\n\ttableType" +
+      "\030\003 \002(\0162\013.PTableType\022\022\n\nindexState\030\004 \001(\t\022" +
+      "\026\n\016sequenceNumber\030\005 \002(\003\022\021\n\ttimeStamp\030\006 \002" +
+      "(\003\022\023\n\013pkNameBytes\030\007 \001(\014\022\021\n\tbucketNum\030\010 \002" +
+      "(\005\022\031\n\007columns\030\t \003(\0132\010.PColumn\022\030\n\007indexes" +
+      "\030\n \003(\0132\007.PTable\022\027\n\017isImmutableRows\030\013 \002(\010" +
+      "\022 \n\nguidePosts\030\014 \003(\0132\014.PTableStats\022\032\n\022da",
+      "taTableNameBytes\030\r \001(\014\022\031\n\021defaultFamilyN" +
+      "ame\030\016 \001(\014\022\022\n\ndisableWAL\030\017 \002(\010\022\023\n\013multiTe" +
+      "nant\030\020 \002(\010\022\020\n\010viewType\030\021 \001(\014\022\025\n\rviewStat" +
+      "ement\030\022 \001(\014\022\025\n\rphysicalNames\030\023 \003(\014\022\020\n\010te" +
+      "nantId\030\024 \001(\014\022\023\n\013viewIndexId\030\025 \001(\005\022\021\n\tind" +
+      "exType\030\026 \001(\014\022\026\n\016statsTimeStamp\030\027 \001(\003\022\022\n\n" +
+      "storeNulls\030\030 \001(\010\022\027\n\017baseColumnCount\030\031 \001(" +
+      "\005\022\036\n\026rowKeyOrderOptimizable\030\032 \001(\010\022\025\n\rtra" +
+      "nsactional\030\033 \001(\010\022\034\n\024updateCacheFrequency" +
+      "\030\034 \001(\003\022\035\n\025indexDisableTimestamp\030\035 \001(\003\022\031\n",
+      "\021isNamespaceMapped\030\036 \001(\010*A\n\nPTableType\022\n" +
+      "\n\006SYSTEM\020\000\022\010\n\004USER\020\001\022\010\n\004VIEW\020\002\022\t\n\005INDEX\020" +
+      "\003\022\010\n\004JOIN\020\004B@\n(org.apache.phoenix.coproc" +
+      "essor.generatedB\014PTableProtosH\001\210\001\001\240\001\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -7315,7 +7224,7 @@ public final class PTableProtos {
           internal_static_PColumn_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_PColumn_descriptor,
-              new java.lang.String[] { "ColumnNameBytes", "FamilyNameBytes", "DataType", "MaxLength", "Scale", "Nullable", "Position", "SortOrder", "ArraySize", "ViewConstant", "ViewReferenced", "Expression", "IsRowTimestamp", "IsDynamic", "ColumnQualifier", });
+              new java.lang.String[] { "ColumnNameBytes", "FamilyNameBytes", "DataType", "MaxLength", "Scale", "Nullable", "Position", "SortOrder", "ArraySize", "ViewConstant", "ViewReferenced", "Expression", "IsRowTimestamp", "IsDynamic", });
           internal_static_PTableStats_descriptor =
             getDescriptor().getMessageTypes().get(1);
           internal_static_PTableStats_fieldAccessorTable = new

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index 92c907e..d98ebe3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -205,8 +205,6 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
     public static final byte[] BASE_COLUMN_COUNT_BYTES = Bytes.toBytes(BASE_COLUMN_COUNT);
     public static final String IS_ROW_TIMESTAMP = "IS_ROW_TIMESTAMP";
     public static final byte[] IS_ROW_TIMESTAMP_BYTES = Bytes.toBytes(IS_ROW_TIMESTAMP);
-    public static final String COLUMN_QUALIFIER = "COLUMN_QUALIFIER";
-    public static final byte[] COLUMN_QUALIFIER_BYTES = Bytes.toBytes(COLUMN_QUALIFIER);
 
     public static final String TABLE_FAMILY = QueryConstants.DEFAULT_COLUMN_FAMILY;
     public static final byte[] TABLE_FAMILY_BYTES = QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index d0c7769..dec11af 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -575,7 +575,6 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         }
     }
     
-    @Override
     public PMetaData updateResolvedTimestamp(PTable table, long resolvedTime) throws SQLException {
     	synchronized (latestMetaDataLock) {
             throwConnectionClosedIfNullMetaData();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
index 057d059..36aa8cd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
@@ -29,7 +29,6 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CURRENT_VALUE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CYCLE_FLAG;
@@ -268,7 +267,6 @@ public interface QueryConstants {
             TRANSACTIONAL + " BOOLEAN," +
             UPDATE_CACHE_FREQUENCY + " BIGINT," +
             IS_NAMESPACE_MAPPED + " BOOLEAN," +
-            COLUMN_QUALIFIER + " INTEGER " +
             "CONSTRAINT " + SYSTEM_TABLE_PK_NAME + " PRIMARY KEY (" + TENANT_ID + ","
             + TABLE_SCHEM + "," + TABLE_NAME + "," + COLUMN_NAME + "," + COLUMN_FAMILY + "))\n" +
             HConstants.VERSIONS + "=" + MetaDataProtocol.DEFAULT_MAX_META_DATA_VERSIONS + ",\n" +

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
index 65e362c..a60229e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
@@ -90,9 +90,4 @@ public class DelegateColumn extends DelegateDatum implements PColumn {
 	public boolean isDynamic() {
 		return getDelegate().isDynamic();
 	}
-
-    @Override
-    public Integer getColumnQualifier() {
-        return getDelegate().getColumnQualifier();
-    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 7eb2336..ac40554 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -33,7 +33,6 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TYPE;
@@ -334,9 +333,8 @@ public class MetaDataClient {
         PK_NAME + "," +  // write this both in the column and table rows for access by metadata APIs
         KEY_SEQ + "," +
         COLUMN_DEF + "," +
-        COLUMN_QUALIFIER + "," +
-        IS_ROW_TIMESTAMP +
-        ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+        IS_ROW_TIMESTAMP + 
+        ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
     private static final String INSERT_COLUMN_ALTER_TABLE =
             "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
             TENANT_ID + "," +
@@ -784,13 +782,8 @@ public class MetaDataClient {
         } else {
             colUpsert.setString(18, column.getExpressionStr());
         }
-        if (column.getColumnQualifier() == null) {
-            colUpsert.setNull(19, Types.INTEGER);
-        } else {
-            colUpsert.setInt(19, column.getColumnQualifier());
-        }
-        if (colUpsert.getParameterMetaData().getParameterCount() > 19) {
-            colUpsert.setBoolean(20, column.isRowTimestamp());
+        if (colUpsert.getParameterMetaData().getParameterCount() > 18) {
+            colUpsert.setBoolean(19, column.isRowTimestamp());
         }
         colUpsert.execute();
     }
@@ -809,7 +802,7 @@ public class MetaDataClient {
         argUpsert.execute();
     }
 
-    private PColumn newColumn(int position, ColumnDef def, PrimaryKeyConstraint pkConstraint, String defaultColumnFamily, boolean addingToPK, Map<String, Integer> columnQualifierTracker) throws SQLException {
+    private PColumn newColumn(int position, ColumnDef def, PrimaryKeyConstraint pkConstraint, String defaultColumnFamily, boolean addingToPK) throws SQLException {
         try {
             ColumnName columnDefName = def.getColumnDefName();
             SortOrder sortOrder = def.getSortOrder();
@@ -857,24 +850,15 @@ public class MetaDataClient {
                 }
                 isNull = false;
             }
-            Integer columnQualifier = null;
-            if (!isPK) {
-                columnQualifier = columnQualifierTracker.get(familyName);
-                if (columnQualifier == null) {
-                    columnQualifier = 0;
-                } else {
-                    columnQualifier++;
-                }
-                columnQualifierTracker.put(familyName.toString(), columnQualifier);
-            }
+
             PColumn column = new PColumnImpl(PNameFactory.newName(columnName), familyName, def.getDataType(),
-                    def.getMaxLength(), def.getScale(), isNull, position, sortOrder, def.getArraySize(), null, false, def.getExpression(), isRowTimestamp, false, columnQualifier);
+                    def.getMaxLength(), def.getScale(), isNull, position, sortOrder, def.getArraySize(), null, false, def.getExpression(), isRowTimestamp, false);
             return column;
         } catch (IllegalArgumentException e) { // Based on precondition check in constructor
             throw new SQLException(e);
         }
     }
-    
+
     public MutationState createTable(CreateTableStatement statement, byte[][] splits, PTable parent, String viewStatement, ViewType viewType, byte[][] viewColumnConstants, BitSet isViewColumnReferenced) throws SQLException {
         PTable table = createTableInternal(statement, splits, parent, viewStatement, viewType, viewColumnConstants, isViewColumnReferenced, null, null, null);
         if (table == null || table.getType() == PTableType.VIEW || table.isTransactional()) {
@@ -1903,7 +1887,7 @@ public class MetaDataClient {
             }
             int pkPositionOffset = pkColumns.size();
             int position = positionOffset;
-            Map<String, Integer> columnQualifierTracker = Maps.newHashMapWithExpectedSize(colDefs.size());
+            
             for (ColumnDef colDef : colDefs) {
                 rowTimeStampColumnAlreadyFound = checkAndValidateRowTimestampCol(colDef, pkConstraint, rowTimeStampColumnAlreadyFound, tableType);
                 if (colDef.isPK()) { // i.e. the column is declared as CREATE TABLE COLNAME DATATYPE PRIMARY KEY...
@@ -1922,7 +1906,7 @@ public class MetaDataClient {
                                 .setColumnName(colDef.getColumnDefName().getColumnName()).build().buildException();
                     }
                 }
-                PColumn column = newColumn(position++, colDef, pkConstraint, defaultFamilyName, false, columnQualifierTracker);
+                PColumn column = newColumn(position++, colDef, pkConstraint, defaultFamilyName, false);
                 if (SchemaUtil.isPKColumn(column)) {
                     // TODO: remove this constraint?
                     if (pkColumnsIterator.hasNext() && !column.getName().getString().equals(pkColumnsIterator.next().getFirst().getColumnName())) {
@@ -2769,7 +2753,6 @@ public class MetaDataClient {
                 List<PColumn> columns = Lists.newArrayListWithExpectedSize(columnDefs.size());
                 Set<String> colFamiliesForPColumnsToBeAdded = new LinkedHashSet<>();
                 Set<String> families = new LinkedHashSet<>();
-                Map<String, Integer> columnQualifiers = SchemaUtil.getNextColumnQualifiers(table);
                 if (columnDefs.size() > 0 ) {
                     try (PreparedStatement colUpsert = connection.prepareStatement(INSERT_COLUMN_ALTER_TABLE)) {
                         short nextKeySeq = SchemaUtil.getMaxKeySeq(table);
@@ -2790,7 +2773,7 @@ public class MetaDataClient {
                                 throw new SQLExceptionInfo.Builder(SQLExceptionCode.ROWTIMESTAMP_CREATE_ONLY)
                                 .setColumnName(colDef.getColumnDefName().getColumnName()).build().buildException();
                             }
-                            PColumn column = newColumn(position++, colDef, PrimaryKeyConstraint.EMPTY, table.getDefaultFamilyName() == null ? null : table.getDefaultFamilyName().getString(), true, columnQualifiers);
+                            PColumn column = newColumn(position++, colDef, PrimaryKeyConstraint.EMPTY, table.getDefaultFamilyName() == null ? null : table.getDefaultFamilyName().getString(), true);
                             columns.add(column);
                             String pkName = null;
                             Short keySeq = null;
@@ -2828,7 +2811,7 @@ public class MetaDataClient {
                                         ColumnName indexColName = ColumnName.caseSensitiveColumnName(IndexUtil.getIndexColumnName(null, colDef.getColumnDefName().getColumnName()));
                                         Expression expression = new RowKeyColumnExpression(columns.get(i), new RowKeyValueAccessor(pkColumns, ++pkSlotPosition));
                                         ColumnDef indexColDef = FACTORY.columnDef(indexColName, indexColDataType.getSqlTypeName(), colDef.isNull(), colDef.getMaxLength(), colDef.getScale(), true, colDef.getSortOrder(), expression.toString(), colDef.isRowTimestamp());
-                                        PColumn indexColumn = newColumn(indexPosition++, indexColDef, PrimaryKeyConstraint.EMPTY, null, true, columnQualifiers);
+                                        PColumn indexColumn = newColumn(indexPosition++, indexColDef, PrimaryKeyConstraint.EMPTY, null, true);
                                         addColumnMutation(schemaName, index.getTableName().getString(), indexColumn, colUpsert, index.getParentTableName().getString(), index.getPKName() == null ? null : index.getPKName().getString(), ++nextIndexKeySeq, index.getBucketNum() != null);
                                     }
                                 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
index b63c97b..0f5fa44 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
@@ -27,7 +27,7 @@ package org.apache.phoenix.schema;
 public interface PColumn extends PDatum {
 
     /**
-     * @return the name of the column
+     * @return the name of the column qualifier
      */
     PName getName();
 
@@ -60,9 +60,4 @@ public interface PColumn extends PDatum {
     boolean isRowTimestamp();
     
     boolean isDynamic();
-    
-    /**
-     * @return name of the HBase column qualifier
-     */
-    Integer getColumnQualifier();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
index 5cf1465..a556f76 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
@@ -40,7 +40,6 @@ public class PColumnImpl implements PColumn {
     private String expressionStr;
     private boolean isRowTimestamp;
     private boolean isDynamic;
-    private Integer columnQualifier;
     
     public PColumnImpl() {
     }
@@ -52,13 +51,13 @@ public class PColumnImpl implements PColumn {
                        Integer scale,
                        boolean nullable,
                        int position,
-                       SortOrder sortOrder, Integer arrSize, byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic, Integer columnQualifier) {
-        init(name, familyName, dataType, maxLength, scale, nullable, position, sortOrder, arrSize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic, columnQualifier);
+                       SortOrder sortOrder, Integer arrSize, byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic) {
+        init(name, familyName, dataType, maxLength, scale, nullable, position, sortOrder, arrSize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic);
     }
 
     public PColumnImpl(PColumn column, int position) {
         this(column.getName(), column.getFamilyName(), column.getDataType(), column.getMaxLength(),
-                column.getScale(), column.isNullable(), position, column.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic(), column.getColumnQualifier());
+                column.getScale(), column.isNullable(), position, column.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic());
     }
 
     private void init(PName name,
@@ -70,7 +69,7 @@ public class PColumnImpl implements PColumn {
             int position,
             SortOrder sortOrder,
             Integer arrSize,
-            byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic, Integer columnQualifier) {
+            byte[] viewConstant, boolean isViewReferenced, String expressionStr, boolean isRowTimestamp, boolean isDynamic) {
     	Preconditions.checkNotNull(sortOrder);
         this.dataType = dataType;
         if (familyName == null) {
@@ -95,7 +94,6 @@ public class PColumnImpl implements PColumn {
         this.expressionStr = expressionStr;
         this.isRowTimestamp = isRowTimestamp;
         this.isDynamic = isDynamic;
-        this.columnQualifier = columnQualifier;
     }
 
     @Override
@@ -207,11 +205,6 @@ public class PColumnImpl implements PColumn {
     public boolean isDynamic() {
         return isDynamic;
     }
-    
-    @Override
-    public Integer getColumnQualifier() {
-        return columnQualifier;
-    }
 
     /**
      * Create a PColumn instance from PBed PColumn instance
@@ -258,12 +251,8 @@ public class PColumnImpl implements PColumn {
         if (column.hasIsDynamic()) {
         	isDynamic = column.getIsDynamic();
         }
-        Integer columnQualifier = null;
-        if (column.hasColumnQualifier()) {
-            columnQualifier = column.getColumnQualifier();
-        }
         return new PColumnImpl(columnName, familyName, dataType, maxLength, scale, nullable, position, sortOrder,
-                arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic, columnQualifier);
+                arraySize, viewConstant, isViewReferenced, expressionStr, isRowTimestamp, isDynamic);
     }
 
     public static PTableProtos.PColumn toProto(PColumn column) {
@@ -294,9 +283,6 @@ public class PColumnImpl implements PColumn {
             builder.setExpression(column.getExpressionStr());
         }
         builder.setIsRowTimestamp(column.isRowTimestamp());
-        if (column.getColumnQualifier() != null) {
-            builder.setColumnQualifier(column.getColumnQualifier());
-        }
         return builder.build();
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
index 1bc65be..67a2714 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
@@ -438,7 +438,7 @@ public class PMetaDataImpl implements PMetaData {
             // Update position of columns that follow removed column
             for (int i = position+1; i < oldColumns.size(); i++) {
                 PColumn oldColumn = oldColumns.get(i);
-                PColumn newColumn = new PColumnImpl(oldColumn.getName(), oldColumn.getFamilyName(), oldColumn.getDataType(), oldColumn.getMaxLength(), oldColumn.getScale(), oldColumn.isNullable(), i-1+positionOffset, oldColumn.getSortOrder(), oldColumn.getArraySize(), oldColumn.getViewConstant(), oldColumn.isViewReferenced(), null, oldColumn.isRowTimestamp(), oldColumn.isDynamic(), oldColumn.getColumnQualifier());
+                PColumn newColumn = new PColumnImpl(oldColumn.getName(), oldColumn.getFamilyName(), oldColumn.getDataType(), oldColumn.getMaxLength(), oldColumn.getScale(), oldColumn.isNullable(), i-1+positionOffset, oldColumn.getSortOrder(), oldColumn.getArraySize(), oldColumn.getViewConstant(), oldColumn.isViewReferenced(), null, oldColumn.isRowTimestamp(), oldColumn.isDynamic());
                 columns.add(newColumn);
             }
             

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
index 23cfd1b..734a9ed 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/SaltingUtil.java
@@ -38,7 +38,7 @@ public class SaltingUtil {
     public static final String SALTING_COLUMN_NAME = "_SALT";
     public static final String SALTED_ROW_KEY_NAME = "_SALTED_KEY";
     public static final PColumnImpl SALTING_COLUMN = new PColumnImpl(
-            PNameFactory.newName(SALTING_COLUMN_NAME), null, PBinary.INSTANCE, 1, 0, false, 0, SortOrder.getDefault(), 0, null, false, null, false, false, null);
+            PNameFactory.newName(SALTING_COLUMN_NAME), null, PBinary.INSTANCE, 1, 0, false, 0, SortOrder.getDefault(), 0, null, false, null, false, false);
     public static final RowKeySchema VAR_BINARY_SALTED_SCHEMA = new RowKeySchemaBuilder(2)
         .addField(SALTING_COLUMN, false, SortOrder.getDefault())
         .addField(SchemaUtil.VAR_BINARY_DATUM, false, SortOrder.getDefault()).build();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
index 4f2e501..7e93263 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
@@ -1017,17 +1017,4 @@ public class SchemaUtil {
                 : physicalTableName;
     }
     
-    
-    /**
-     * Return a map of column family -> next column qualifier number to use.
-     */
-    public static Map<String, Integer> getNextColumnQualifiers(PTable table) {
-        Map<String, Integer> map = Maps.newHashMapWithExpectedSize(table.getColumns().size());
-        for (PColumnFamily f : table.getColumnFamilies()) {
-            final int size = f.getColumns().size();
-            int nextColumnQualifier = size == 0 ? 0 : size;
-            map.put(f.getName().getString(), nextColumnQualifier);
-        }
-        return map;
-    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
index aee3fb5..4660e38 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
@@ -249,7 +249,7 @@ public class CorrelatePlanTest {
             Expression expr = LiteralExpression.newConstant(row[i]);
             columns.add(new PColumnImpl(PNameFactory.newName(name), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY),
                     expr.getDataType(), expr.getMaxLength(), expr.getScale(), expr.isNullable(),
-                    i, expr.getSortOrder(), null, null, false, name, false, false, null));
+                    i, expr.getSortOrder(), null, null, false, name, false, false));
         }
         try {
             PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
index 49dabd0..aba4be4 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/LiteralResultIteratorPlanTest.java
@@ -171,7 +171,7 @@ public class LiteralResultIteratorPlanTest {
             Expression expr = LiteralExpression.newConstant(row[i]);
             columns.add(new PColumnImpl(PNameFactory.newName(name),
                     PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), expr.getDataType(), expr.getMaxLength(),
-                    expr.getScale(), expr.isNullable(), i, expr.getSortOrder(), null, null, false, name, false, false, null));
+                    expr.getScale(), expr.isNullable(), i, expr.getSortOrder(), null, null, false, name, false, false));
         }
         try {
             PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, PTableType.SUBQUERY, null,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
index fe29e52..50e2721 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/UnnestArrayPlanTest.java
@@ -117,8 +117,8 @@ public class UnnestArrayPlanTest {
         LiteralExpression dummy = LiteralExpression.newConstant(null, arrayType);
         RowKeyValueAccessor accessor = new RowKeyValueAccessor(Arrays.asList(dummy), 0);
         UnnestArrayPlan plan = new UnnestArrayPlan(subPlan, new RowKeyColumnExpression(dummy, accessor), withOrdinality);
-        PColumn elemColumn = new PColumnImpl(PNameFactory.newName("ELEM"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), baseType, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false, null);
-        PColumn indexColumn = withOrdinality ? new PColumnImpl(PNameFactory.newName("IDX"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), PInteger.INSTANCE, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false, null) : null;
+        PColumn elemColumn = new PColumnImpl(PNameFactory.newName("ELEM"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), baseType, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false);
+        PColumn indexColumn = withOrdinality ? new PColumnImpl(PNameFactory.newName("IDX"), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), PInteger.INSTANCE, null, null, true, 0, SortOrder.getDefault(), null, null, false, "", false, false) : null;
         List<PColumn> columns = withOrdinality ? Arrays.asList(elemColumn, indexColumn) : Arrays.asList(elemColumn);
         ProjectedColumnExpression elemExpr = new ProjectedColumnExpression(elemColumn, columns, 0, elemColumn.getName().getString());
         ProjectedColumnExpression indexExpr = withOrdinality ? new ProjectedColumnExpression(indexColumn, columns, 1, indexColumn.getName().getString()) : null;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java b/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
index e55068d..7ee579c 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/expression/ColumnExpressionTest.java
@@ -41,7 +41,7 @@ public class ColumnExpressionTest {
         int maxLen = 30;
         int scale = 5;
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PDecimal.INSTANCE, maxLen, scale,
-                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false, null);
+                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false);
         ColumnExpression colExp = new KeyValueColumnExpression(column);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);
@@ -61,7 +61,7 @@ public class ColumnExpressionTest {
     public void testSerializationWithNullScale() throws Exception {
         int maxLen = 30;
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PBinary.INSTANCE, maxLen, null,
-                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false, null);
+                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false);
         ColumnExpression colExp = new KeyValueColumnExpression(column);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);
@@ -81,7 +81,7 @@ public class ColumnExpressionTest {
     public void testSerializationWithNullMaxLength() throws Exception {
         int scale = 5;
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PVarchar.INSTANCE, null, scale,
-                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false, null);
+                true, 20, SortOrder.getDefault(), 0, null, false, null, false, false);
         ColumnExpression colExp = new KeyValueColumnExpression(column);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);
@@ -100,7 +100,7 @@ public class ColumnExpressionTest {
     @Test
     public void testSerializationWithNullScaleAndMaxLength() throws Exception {
         PColumn column = new PColumnImpl(PNameFactory.newName("c1"), PNameFactory.newName("f1"), PDecimal.INSTANCE, null, null, true,
-                20, SortOrder.getDefault(), 0, null, false, null, false, false, null);
+                20, SortOrder.getDefault(), 0, null, false, null, false, false);
         ColumnExpression colExp = new KeyValueColumnExpression(column);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream dOut = new DataOutputStream(baos);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
index 1ab606a..f53e871 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
@@ -137,10 +137,6 @@ public class AggregateResultScannerTest extends BaseConnectionlessQueryTest {
 			public boolean isDynamic() {
 				return false;
 			}
-            @Override
-            public Integer getColumnQualifier() {
-                return null;
-            }
         })), null);
         aggregationManager.setAggregators(new ClientAggregators(Collections.<SingleAggregateFunction>singletonList(func), 1));
         ResultIterators iterators = new ResultIterators() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fda59a1/phoenix-protocol/src/main/PTable.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PTable.proto b/phoenix-protocol/src/main/PTable.proto
index 584bfa1..c86f6b6 100644
--- a/phoenix-protocol/src/main/PTable.proto
+++ b/phoenix-protocol/src/main/PTable.proto
@@ -49,7 +49,6 @@ message PColumn {
   optional string expression = 12;
   optional bool isRowTimestamp = 13;
   optional bool isDynamic = 14;
-  optional int32 columnQualifier = 15;
 }
 
 message PTableStats {


[41/52] [abbrv] phoenix git commit: Store encoded column counters for base tables and make views use them

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
index b6b913c..8d6c575 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
@@ -3448,6 +3448,31 @@ public final class PTableProtos {
      * <code>optional bytes storageScheme = 31;</code>
      */
     com.google.protobuf.ByteString getStorageScheme();
+
+    // repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;
+    /**
+     * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+     */
+    java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter> 
+        getEncodedColumnQualifierCountersList();
+    /**
+     * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+     */
+    org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter getEncodedColumnQualifierCounters(int index);
+    /**
+     * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+     */
+    int getEncodedColumnQualifierCountersCount();
+    /**
+     * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+     */
+    java.util.List<? extends org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounterOrBuilder> 
+        getEncodedColumnQualifierCountersOrBuilderList();
+    /**
+     * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+     */
+    org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounterOrBuilder getEncodedColumnQualifierCountersOrBuilder(
+        int index);
   }
   /**
    * Protobuf type {@code PTable}
@@ -3673,6 +3698,14 @@ public final class PTableProtos {
               storageScheme_ = input.readBytes();
               break;
             }
+            case 258: {
+              if (!((mutable_bitField0_ & 0x80000000) == 0x80000000)) {
+                encodedColumnQualifierCounters_ = new java.util.ArrayList<org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter>();
+                mutable_bitField0_ |= 0x80000000;
+              }
+              encodedColumnQualifierCounters_.add(input.readMessage(org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.PARSER, extensionRegistry));
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -3693,6 +3726,9 @@ public final class PTableProtos {
         if (((mutable_bitField0_ & 0x00040000) == 0x00040000)) {
           physicalNames_ = java.util.Collections.unmodifiableList(physicalNames_);
         }
+        if (((mutable_bitField0_ & 0x80000000) == 0x80000000)) {
+          encodedColumnQualifierCounters_ = java.util.Collections.unmodifiableList(encodedColumnQualifierCounters_);
+        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
@@ -4315,6 +4351,42 @@ public final class PTableProtos {
       return storageScheme_;
     }
 
+    // repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;
+    public static final int ENCODEDCOLUMNQUALIFIERCOUNTERS_FIELD_NUMBER = 32;
+    private java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter> encodedColumnQualifierCounters_;
+    /**
+     * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+     */
+    public java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter> getEncodedColumnQualifierCountersList() {
+      return encodedColumnQualifierCounters_;
+    }
+    /**
+     * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+     */
+    public java.util.List<? extends org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounterOrBuilder> 
+        getEncodedColumnQualifierCountersOrBuilderList() {
+      return encodedColumnQualifierCounters_;
+    }
+    /**
+     * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+     */
+    public int getEncodedColumnQualifierCountersCount() {
+      return encodedColumnQualifierCounters_.size();
+    }
+    /**
+     * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+     */
+    public org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter getEncodedColumnQualifierCounters(int index) {
+      return encodedColumnQualifierCounters_.get(index);
+    }
+    /**
+     * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+     */
+    public org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounterOrBuilder getEncodedColumnQualifierCountersOrBuilder(
+        int index) {
+      return encodedColumnQualifierCounters_.get(index);
+    }
+
     private void initFields() {
       schemaNameBytes_ = com.google.protobuf.ByteString.EMPTY;
       tableNameBytes_ = com.google.protobuf.ByteString.EMPTY;
@@ -4347,6 +4419,7 @@ public final class PTableProtos {
       indexDisableTimestamp_ = 0L;
       isNamespaceMapped_ = false;
       storageScheme_ = com.google.protobuf.ByteString.EMPTY;
+      encodedColumnQualifierCounters_ = java.util.Collections.emptyList();
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -4407,6 +4480,12 @@ public final class PTableProtos {
           return false;
         }
       }
+      for (int i = 0; i < getEncodedColumnQualifierCountersCount(); i++) {
+        if (!getEncodedColumnQualifierCounters(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -4507,6 +4586,9 @@ public final class PTableProtos {
       if (((bitField0_ & 0x04000000) == 0x04000000)) {
         output.writeBytes(31, storageScheme_);
       }
+      for (int i = 0; i < encodedColumnQualifierCounters_.size(); i++) {
+        output.writeMessage(32, encodedColumnQualifierCounters_.get(i));
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -4645,6 +4727,10 @@ public final class PTableProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeBytesSize(31, storageScheme_);
       }
+      for (int i = 0; i < encodedColumnQualifierCounters_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(32, encodedColumnQualifierCounters_.get(i));
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -4811,6 +4897,8 @@ public final class PTableProtos {
         result = result && getStorageScheme()
             .equals(other.getStorageScheme());
       }
+      result = result && getEncodedColumnQualifierCountersList()
+          .equals(other.getEncodedColumnQualifierCountersList());
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -4948,6 +5036,10 @@ public final class PTableProtos {
         hash = (37 * hash) + STORAGESCHEME_FIELD_NUMBER;
         hash = (53 * hash) + getStorageScheme().hashCode();
       }
+      if (getEncodedColumnQualifierCountersCount() > 0) {
+        hash = (37 * hash) + ENCODEDCOLUMNQUALIFIERCOUNTERS_FIELD_NUMBER;
+        hash = (53 * hash) + getEncodedColumnQualifierCountersList().hashCode();
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -5052,6 +5144,7 @@ public final class PTableProtos {
           getColumnsFieldBuilder();
           getIndexesFieldBuilder();
           getGuidePostsFieldBuilder();
+          getEncodedColumnQualifierCountersFieldBuilder();
         }
       }
       private static Builder create() {
@@ -5134,6 +5227,12 @@ public final class PTableProtos {
         bitField0_ = (bitField0_ & ~0x20000000);
         storageScheme_ = com.google.protobuf.ByteString.EMPTY;
         bitField0_ = (bitField0_ & ~0x40000000);
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          encodedColumnQualifierCounters_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x80000000);
+        } else {
+          encodedColumnQualifierCountersBuilder_.clear();
+        }
         return this;
       }
 
@@ -5302,6 +5401,15 @@ public final class PTableProtos {
           to_bitField0_ |= 0x04000000;
         }
         result.storageScheme_ = storageScheme_;
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          if (((bitField0_ & 0x80000000) == 0x80000000)) {
+            encodedColumnQualifierCounters_ = java.util.Collections.unmodifiableList(encodedColumnQualifierCounters_);
+            bitField0_ = (bitField0_ & ~0x80000000);
+          }
+          result.encodedColumnQualifierCounters_ = encodedColumnQualifierCounters_;
+        } else {
+          result.encodedColumnQualifierCounters_ = encodedColumnQualifierCountersBuilder_.build();
+        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -5489,6 +5597,32 @@ public final class PTableProtos {
         if (other.hasStorageScheme()) {
           setStorageScheme(other.getStorageScheme());
         }
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          if (!other.encodedColumnQualifierCounters_.isEmpty()) {
+            if (encodedColumnQualifierCounters_.isEmpty()) {
+              encodedColumnQualifierCounters_ = other.encodedColumnQualifierCounters_;
+              bitField0_ = (bitField0_ & ~0x80000000);
+            } else {
+              ensureEncodedColumnQualifierCountersIsMutable();
+              encodedColumnQualifierCounters_.addAll(other.encodedColumnQualifierCounters_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.encodedColumnQualifierCounters_.isEmpty()) {
+            if (encodedColumnQualifierCountersBuilder_.isEmpty()) {
+              encodedColumnQualifierCountersBuilder_.dispose();
+              encodedColumnQualifierCountersBuilder_ = null;
+              encodedColumnQualifierCounters_ = other.encodedColumnQualifierCounters_;
+              bitField0_ = (bitField0_ & ~0x80000000);
+              encodedColumnQualifierCountersBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getEncodedColumnQualifierCountersFieldBuilder() : null;
+            } else {
+              encodedColumnQualifierCountersBuilder_.addAllMessages(other.encodedColumnQualifierCounters_);
+            }
+          }
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -5548,6 +5682,12 @@ public final class PTableProtos {
             return false;
           }
         }
+        for (int i = 0; i < getEncodedColumnQualifierCountersCount(); i++) {
+          if (!getEncodedColumnQualifierCounters(i).isInitialized()) {
+            
+            return false;
+          }
+        }
         return true;
       }
 
@@ -7327,6 +7467,246 @@ public final class PTableProtos {
         return this;
       }
 
+      // repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;
+      private java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter> encodedColumnQualifierCounters_ =
+        java.util.Collections.emptyList();
+      private void ensureEncodedColumnQualifierCountersIsMutable() {
+        if (!((bitField0_ & 0x80000000) == 0x80000000)) {
+          encodedColumnQualifierCounters_ = new java.util.ArrayList<org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter>(encodedColumnQualifierCounters_);
+          bitField0_ |= 0x80000000;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounterOrBuilder> encodedColumnQualifierCountersBuilder_;
+
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter> getEncodedColumnQualifierCountersList() {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(encodedColumnQualifierCounters_);
+        } else {
+          return encodedColumnQualifierCountersBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public int getEncodedColumnQualifierCountersCount() {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          return encodedColumnQualifierCounters_.size();
+        } else {
+          return encodedColumnQualifierCountersBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter getEncodedColumnQualifierCounters(int index) {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          return encodedColumnQualifierCounters_.get(index);
+        } else {
+          return encodedColumnQualifierCountersBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public Builder setEncodedColumnQualifierCounters(
+          int index, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter value) {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureEncodedColumnQualifierCountersIsMutable();
+          encodedColumnQualifierCounters_.set(index, value);
+          onChanged();
+        } else {
+          encodedColumnQualifierCountersBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public Builder setEncodedColumnQualifierCounters(
+          int index, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder builderForValue) {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          ensureEncodedColumnQualifierCountersIsMutable();
+          encodedColumnQualifierCounters_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          encodedColumnQualifierCountersBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public Builder addEncodedColumnQualifierCounters(org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter value) {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureEncodedColumnQualifierCountersIsMutable();
+          encodedColumnQualifierCounters_.add(value);
+          onChanged();
+        } else {
+          encodedColumnQualifierCountersBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public Builder addEncodedColumnQualifierCounters(
+          int index, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter value) {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureEncodedColumnQualifierCountersIsMutable();
+          encodedColumnQualifierCounters_.add(index, value);
+          onChanged();
+        } else {
+          encodedColumnQualifierCountersBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public Builder addEncodedColumnQualifierCounters(
+          org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder builderForValue) {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          ensureEncodedColumnQualifierCountersIsMutable();
+          encodedColumnQualifierCounters_.add(builderForValue.build());
+          onChanged();
+        } else {
+          encodedColumnQualifierCountersBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public Builder addEncodedColumnQualifierCounters(
+          int index, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder builderForValue) {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          ensureEncodedColumnQualifierCountersIsMutable();
+          encodedColumnQualifierCounters_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          encodedColumnQualifierCountersBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public Builder addAllEncodedColumnQualifierCounters(
+          java.lang.Iterable<? extends org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter> values) {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          ensureEncodedColumnQualifierCountersIsMutable();
+          super.addAll(values, encodedColumnQualifierCounters_);
+          onChanged();
+        } else {
+          encodedColumnQualifierCountersBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public Builder clearEncodedColumnQualifierCounters() {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          encodedColumnQualifierCounters_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x80000000);
+          onChanged();
+        } else {
+          encodedColumnQualifierCountersBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public Builder removeEncodedColumnQualifierCounters(int index) {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          ensureEncodedColumnQualifierCountersIsMutable();
+          encodedColumnQualifierCounters_.remove(index);
+          onChanged();
+        } else {
+          encodedColumnQualifierCountersBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder getEncodedColumnQualifierCountersBuilder(
+          int index) {
+        return getEncodedColumnQualifierCountersFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounterOrBuilder getEncodedColumnQualifierCountersOrBuilder(
+          int index) {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          return encodedColumnQualifierCounters_.get(index);  } else {
+          return encodedColumnQualifierCountersBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public java.util.List<? extends org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounterOrBuilder> 
+           getEncodedColumnQualifierCountersOrBuilderList() {
+        if (encodedColumnQualifierCountersBuilder_ != null) {
+          return encodedColumnQualifierCountersBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(encodedColumnQualifierCounters_);
+        }
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder addEncodedColumnQualifierCountersBuilder() {
+        return getEncodedColumnQualifierCountersFieldBuilder().addBuilder(
+            org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder addEncodedColumnQualifierCountersBuilder(
+          int index) {
+        return getEncodedColumnQualifierCountersFieldBuilder().addBuilder(
+            index, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .EncodedColumnQualifierCounter encodedColumnQualifierCounters = 32;</code>
+       */
+      public java.util.List<org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder> 
+           getEncodedColumnQualifierCountersBuilderList() {
+        return getEncodedColumnQualifierCountersFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounterOrBuilder> 
+          getEncodedColumnQualifierCountersFieldBuilder() {
+        if (encodedColumnQualifierCountersBuilder_ == null) {
+          encodedColumnQualifierCountersBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounterOrBuilder>(
+                  encodedColumnQualifierCounters_,
+                  ((bitField0_ & 0x80000000) == 0x80000000),
+                  getParentForChildren(),
+                  isClean());
+          encodedColumnQualifierCounters_ = null;
+        }
+        return encodedColumnQualifierCountersBuilder_;
+      }
+
       // @@protoc_insertion_point(builder_scope:PTable)
     }
 
@@ -7338,74 +7718,697 @@ public final class PTableProtos {
     // @@protoc_insertion_point(class_scope:PTable)
   }
 
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_PColumn_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_PColumn_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_PTableStats_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_PTableStats_fieldAccessorTable;
-  private static com.google.protobuf.Descriptors.Descriptor
-    internal_static_PTable_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_PTable_fieldAccessorTable;
+  public interface EncodedColumnQualifierCounterOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
 
-  public static com.google.protobuf.Descriptors.FileDescriptor
-      getDescriptor() {
-    return descriptor;
+    // required string familyName = 1;
+    /**
+     * <code>required string familyName = 1;</code>
+     */
+    boolean hasFamilyName();
+    /**
+     * <code>required string familyName = 1;</code>
+     */
+    java.lang.String getFamilyName();
+    /**
+     * <code>required string familyName = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getFamilyNameBytes();
+
+    // required int32 counter = 2;
+    /**
+     * <code>required int32 counter = 2;</code>
+     */
+    boolean hasCounter();
+    /**
+     * <code>required int32 counter = 2;</code>
+     */
+    int getCounter();
   }
-  private static com.google.protobuf.Descriptors.FileDescriptor
-      descriptor;
-  static {
-    java.lang.String[] descriptorData = {
-      "\n\014PTable.proto\032\021PGuidePosts.proto\"\277\002\n\007PC" +
-      "olumn\022\027\n\017columnNameBytes\030\001 \002(\014\022\027\n\017family" +
-      "NameBytes\030\002 \001(\014\022\020\n\010dataType\030\003 \002(\t\022\021\n\tmax" +
-      "Length\030\004 \001(\005\022\r\n\005scale\030\005 \001(\005\022\020\n\010nullable\030" +
-      "\006 \002(\010\022\020\n\010position\030\007 \002(\005\022\021\n\tsortOrder\030\010 \002" +
-      "(\005\022\021\n\tarraySize\030\t \001(\005\022\024\n\014viewConstant\030\n " +
-      "\001(\014\022\026\n\016viewReferenced\030\013 \001(\010\022\022\n\nexpressio" +
-      "n\030\014 \001(\t\022\026\n\016isRowTimestamp\030\r \001(\010\022\021\n\tisDyn" +
-      "amic\030\016 \001(\010\022\027\n\017columnQualifier\030\017 \001(\005\"\232\001\n\013" +
-      "PTableStats\022\013\n\003key\030\001 \002(\014\022\016\n\006values\030\002 \003(\014",
-      "\022\033\n\023guidePostsByteCount\030\003 \001(\003\022\025\n\rkeyByte" +
-      "sCount\030\004 \001(\003\022\027\n\017guidePostsCount\030\005 \001(\005\022!\n" +
-      "\013pGuidePosts\030\006 \001(\0132\014.PGuidePosts\"\365\005\n\006PTa" +
-      "ble\022\027\n\017schemaNameBytes\030\001 \002(\014\022\026\n\016tableNam" +
-      "eBytes\030\002 \002(\014\022\036\n\ttableType\030\003 \002(\0162\013.PTable" +
-      "Type\022\022\n\nindexState\030\004 \001(\t\022\026\n\016sequenceNumb" +
-      "er\030\005 \002(\003\022\021\n\ttimeStamp\030\006 \002(\003\022\023\n\013pkNameByt" +
-      "es\030\007 \001(\014\022\021\n\tbucketNum\030\010 \002(\005\022\031\n\007columns\030\t" +
-      " \003(\0132\010.PColumn\022\030\n\007indexes\030\n \003(\0132\007.PTable" +
-      "\022\027\n\017isImmutableRows\030\013 \002(\010\022 \n\nguidePosts\030",
-      "\014 \003(\0132\014.PTableStats\022\032\n\022dataTableNameByte" +
-      "s\030\r \001(\014\022\031\n\021defaultFamilyName\030\016 \001(\014\022\022\n\ndi" +
-      "sableWAL\030\017 \002(\010\022\023\n\013multiTenant\030\020 \002(\010\022\020\n\010v" +
-      "iewType\030\021 \001(\014\022\025\n\rviewStatement\030\022 \001(\014\022\025\n\r" +
-      "physicalNames\030\023 \003(\014\022\020\n\010tenantId\030\024 \001(\014\022\023\n" +
-      "\013viewIndexId\030\025 \001(\005\022\021\n\tindexType\030\026 \001(\014\022\026\n" +
-      "\016statsTimeStamp\030\027 \001(\003\022\022\n\nstoreNulls\030\030 \001(" +
-      "\010\022\027\n\017baseColumnCount\030\031 \001(\005\022\036\n\026rowKeyOrde" +
-      "rOptimizable\030\032 \001(\010\022\025\n\rtransactional\030\033 \001(" +
-      "\010\022\034\n\024updateCacheFrequency\030\034 \001(\003\022\035\n\025index",
-      "DisableTimestamp\030\035 \001(\003\022\031\n\021isNamespaceMap" +
-      "ped\030\036 \001(\010\022\025\n\rstorageScheme\030\037 \001(\014*A\n\nPTab" +
-      "leType\022\n\n\006SYSTEM\020\000\022\010\n\004USER\020\001\022\010\n\004VIEW\020\002\022\t" +
-      "\n\005INDEX\020\003\022\010\n\004JOIN\020\004B@\n(org.apache.phoeni" +
-      "x.coprocessor.generatedB\014PTableProtosH\001\210" +
-      "\001\001\240\001\001"
-    };
-    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
-      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
-        public com.google.protobuf.ExtensionRegistry assignDescriptors(
-            com.google.protobuf.Descriptors.FileDescriptor root) {
-          descriptor = root;
-          internal_static_PColumn_descriptor =
-            getDescriptor().getMessageTypes().get(0);
+  /**
+   * Protobuf type {@code EncodedColumnQualifierCounter}
+   */
+  public static final class EncodedColumnQualifierCounter extends
+      com.google.protobuf.GeneratedMessage
+      implements EncodedColumnQualifierCounterOrBuilder {
+    // Use EncodedColumnQualifierCounter.newBuilder() to construct.
+    private EncodedColumnQualifierCounter(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private EncodedColumnQualifierCounter(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final EncodedColumnQualifierCounter defaultInstance;
+    public static EncodedColumnQualifierCounter getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public EncodedColumnQualifierCounter getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private EncodedColumnQualifierCounter(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              familyName_ = input.readBytes();
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000002;
+              counter_ = input.readInt32();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.phoenix.coprocessor.generated.PTableProtos.internal_static_EncodedColumnQualifierCounter_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.phoenix.coprocessor.generated.PTableProtos.internal_static_EncodedColumnQualifierCounter_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.class, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<EncodedColumnQualifierCounter> PARSER =
+        new com.google.protobuf.AbstractParser<EncodedColumnQualifierCounter>() {
+      public EncodedColumnQualifierCounter parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new EncodedColumnQualifierCounter(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<EncodedColumnQualifierCounter> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required string familyName = 1;
+    public static final int FAMILYNAME_FIELD_NUMBER = 1;
+    private java.lang.Object familyName_;
+    /**
+     * <code>required string familyName = 1;</code>
+     */
+    public boolean hasFamilyName() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string familyName = 1;</code>
+     */
+    public java.lang.String getFamilyName() {
+      java.lang.Object ref = familyName_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          familyName_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string familyName = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getFamilyNameBytes() {
+      java.lang.Object ref = familyName_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        familyName_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required int32 counter = 2;
+    public static final int COUNTER_FIELD_NUMBER = 2;
+    private int counter_;
+    /**
+     * <code>required int32 counter = 2;</code>
+     */
+    public boolean hasCounter() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required int32 counter = 2;</code>
+     */
+    public int getCounter() {
+      return counter_;
+    }
+
+    private void initFields() {
+      familyName_ = "";
+      counter_ = 0;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasFamilyName()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasCounter()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getFamilyNameBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeInt32(2, counter_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getFamilyNameBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(2, counter_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter)) {
+        return super.equals(obj);
+      }
+      org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter other = (org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter) obj;
+
+      boolean result = true;
+      result = result && (hasFamilyName() == other.hasFamilyName());
+      if (hasFamilyName()) {
+        result = result && getFamilyName()
+            .equals(other.getFamilyName());
+      }
+      result = result && (hasCounter() == other.hasCounter());
+      if (hasCounter()) {
+        result = result && (getCounter()
+            == other.getCounter());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasFamilyName()) {
+        hash = (37 * hash) + FAMILYNAME_FIELD_NUMBER;
+        hash = (53 * hash) + getFamilyName().hashCode();
+      }
+      if (hasCounter()) {
+        hash = (37 * hash) + COUNTER_FIELD_NUMBER;
+        hash = (53 * hash) + getCounter();
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code EncodedColumnQualifierCounter}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounterOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.phoenix.coprocessor.generated.PTableProtos.internal_static_EncodedColumnQualifierCounter_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.phoenix.coprocessor.generated.PTableProtos.internal_static_EncodedColumnQualifierCounter_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.class, org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.Builder.class);
+      }
+
+      // Construct using org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        familyName_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        counter_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.phoenix.coprocessor.generated.PTableProtos.internal_static_EncodedColumnQualifierCounter_descriptor;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter getDefaultInstanceForType() {
+        return org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.getDefaultInstance();
+      }
+
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter build() {
+        org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter buildPartial() {
+        org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter result = new org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.familyName_ = familyName_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.counter_ = counter_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter) {
+          return mergeFrom((org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter other) {
+        if (other == org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter.getDefaultInstance()) return this;
+        if (other.hasFamilyName()) {
+          bitField0_ |= 0x00000001;
+          familyName_ = other.familyName_;
+          onChanged();
+        }
+        if (other.hasCounter()) {
+          setCounter(other.getCounter());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasFamilyName()) {
+          
+          return false;
+        }
+        if (!hasCounter()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.phoenix.coprocessor.generated.PTableProtos.EncodedColumnQualifierCounter) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string familyName = 1;
+      private java.lang.Object familyName_ = "";
+      /**
+       * <code>required string familyName = 1;</code>
+       */
+      public boolean hasFamilyName() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string familyName = 1;</code>
+       */
+      public java.lang.String getFamilyName() {
+        java.lang.Object ref = familyName_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          familyName_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string familyName = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getFamilyNameBytes() {
+        java.lang.Object ref = familyName_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          familyName_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string familyName = 1;</code>
+       */
+      public Builder setFamilyName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        familyName_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string familyName = 1;</code>
+       */
+      public Builder clearFamilyName() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        familyName_ = getDefaultInstance().getFamilyName();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string familyName = 1;</code>
+       */
+      public Builder setFamilyNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        familyName_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required int32 counter = 2;
+      private int counter_ ;
+      /**
+       * <code>required int32 counter = 2;</code>
+       */
+      public boolean hasCounter() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required int32 counter = 2;</code>
+       */
+      public int getCounter() {
+        return counter_;
+      }
+      /**
+       * <code>required int32 counter = 2;</code>
+       */
+      public Builder setCounter(int value) {
+        bitField0_ |= 0x00000002;
+        counter_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 counter = 2;</code>
+       */
+      public Builder clearCounter() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        counter_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:EncodedColumnQualifierCounter)
+    }
+
+    static {
+      defaultInstance = new EncodedColumnQualifierCounter(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:EncodedColumnQualifierCounter)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_PColumn_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_PColumn_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_PTableStats_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_PTableStats_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_PTable_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_PTable_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_EncodedColumnQualifierCounter_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_EncodedColumnQualifierCounter_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\014PTable.proto\032\021PGuidePosts.proto\"\277\002\n\007PC" +
+      "olumn\022\027\n\017columnNameBytes\030\001 \002(\014\022\027\n\017family" +
+      "NameBytes\030\002 \001(\014\022\020\n\010dataType\030\003 \002(\t\022\021\n\tmax" +
+      "Length\030\004 \001(\005\022\r\n\005scale\030\005 \001(\005\022\020\n\010nullable\030" +
+      "\006 \002(\010\022\020\n\010position\030\007 \002(\005\022\021\n\tsortOrder\030\010 \002" +
+      "(\005\022\021\n\tarraySize\030\t \001(\005\022\024\n\014viewConstant\030\n " +
+      "\001(\014\022\026\n\016viewReferenced\030\013 \001(\010\022\022\n\nexpressio" +
+      "n\030\014 \001(\t\022\026\n\016isRowTimestamp\030\r \001(\010\022\021\n\tisDyn" +
+      "amic\030\016 \001(\010\022\027\n\017columnQualifier\030\017 \001(\005\"\232\001\n\013" +
+      "PTableStats\022\013\n\003key\030\001 \002(\014\022\016\n\006values\030\002 \003(\014",
+      "\022\033\n\023guidePostsByteCount\030\003 \001(\003\022\025\n\rkeyByte" +
+      "sCount\030\004 \001(\003\022\027\n\017guidePostsCount\030\005 \001(\005\022!\n" +
+      "\013pGuidePosts\030\006 \001(\0132\014.PGuidePosts\"\275\006\n\006PTa" +
+      "ble\022\027\n\017schemaNameBytes\030\001 \002(\014\022\026\n\016tableNam" +
+      "eBytes\030\002 \002(\014\022\036\n\ttableType\030\003 \002(\0162\013.PTable" +
+      "Type\022\022\n\nindexState\030\004 \001(\t\022\026\n\016sequenceNumb" +
+      "er\030\005 \002(\003\022\021\n\ttimeStamp\030\006 \002(\003\022\023\n\013pkNameByt" +
+      "es\030\007 \001(\014\022\021\n\tbucketNum\030\010 \002(\005\022\031\n\007columns\030\t" +
+      " \003(\0132\010.PColumn\022\030\n\007indexes\030\n \003(\0132\007.PTable" +
+      "\022\027\n\017isImmutableRows\030\013 \002(\010\022 \n\nguidePosts\030",
+      "\014 \003(\0132\014.PTableStats\022\032\n\022dataTableNameByte" +
+      "s\030\r \001(\014\022\031\n\021defaultFamilyName\030\016 \001(\014\022\022\n\ndi" +
+      "sableWAL\030\017 \002(\010\022\023\n\013multiTenant\030\020 \002(\010\022\020\n\010v" +
+      "iewType\030\021 \001(\014\022\025\n\rviewStatement\030\022 \001(\014\022\025\n\r" +
+      "physicalNames\030\023 \003(\014\022\020\n\010tenantId\030\024 \001(\014\022\023\n" +
+      "\013viewIndexId\030\025 \001(\005\022\021\n\tindexType\030\026 \001(\014\022\026\n" +
+      "\016statsTimeStamp\030\027 \001(\003\022\022\n\nstoreNulls\030\030 \001(" +
+      "\010\022\027\n\017baseColumnCount\030\031 \001(\005\022\036\n\026rowKeyOrde" +
+      "rOptimizable\030\032 \001(\010\022\025\n\rtransactional\030\033 \001(" +
+      "\010\022\034\n\024updateCacheFrequency\030\034 \001(\003\022\035\n\025index",
+      "DisableTimestamp\030\035 \001(\003\022\031\n\021isNamespaceMap" +
+      "ped\030\036 \001(\010\022\025\n\rstorageScheme\030\037 \001(\014\022F\n\036enco" +
+      "dedColumnQualifierCounters\030  \003(\0132\036.Encod" +
+      "edColumnQualifierCounter\"D\n\035EncodedColum" +
+      "nQualifierCounter\022\022\n\nfamilyName\030\001 \002(\t\022\017\n" +
+      "\007counter\030\002 \002(\005*A\n\nPTableType\022\n\n\006SYSTEM\020\000" +
+      "\022\010\n\004USER\020\001\022\010\n\004VIEW\020\002\022\t\n\005INDEX\020\003\022\010\n\004JOIN\020" +
+      "\004B@\n(org.apache.phoenix.coprocessor.gene" +
+      "ratedB\014PTableProtosH\001\210\001\001\240\001\001"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_PColumn_descriptor =
+            getDescriptor().getMessageTypes().get(0);
           internal_static_PColumn_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_PColumn_descriptor,
@@ -7421,7 +8424,13 @@ public final class PTableProtos {
           internal_static_PTable_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_PTable_descriptor,
-              new java.lang.String[] { "SchemaNameBytes", "TableNameBytes", "TableType", "IndexState", "SequenceNumber", "TimeStamp", "PkNameBytes", "BucketNum", "Columns", "Indexes", "IsImmutableRows", "GuidePosts", "DataTableNameBytes", "DefaultFamilyName", "DisableWAL", "MultiTenant", "ViewType", "ViewStatement", "PhysicalNames", "TenantId", "ViewIndexId", "IndexType", "StatsTimeStamp", "StoreNulls", "BaseColumnCount", "RowKeyOrderOptimizable", "Transactional", "UpdateCacheFrequency", "IndexDisableTimestamp", "IsNamespaceMapped", "StorageScheme", });
+              new java.lang.String[] { "SchemaNameBytes", "TableNameBytes", "TableType", "IndexState", "SequenceNumber", "TimeStamp", "PkNameBytes", "BucketNum", "Columns", "Indexes", "IsImmutableRows", "GuidePosts", "DataTableNameBytes", "DefaultFamilyName", "DisableWAL", "MultiTenant", "ViewType", "ViewStatement", "PhysicalNames", "TenantId", "ViewIndexId", "IndexType", "StatsTimeStamp", "StoreNulls", "BaseColumnCount", "RowKeyOrderOptimizable", "Transactional", "UpdateCacheFrequency", "IndexDisableTimestamp", "IsNamespaceMapped", "StorageScheme", "EncodedColumnQualifierCounters", });
+          internal_static_EncodedColumnQualifierCounter_descriptor =
+            getDescriptor().getMessageTypes().get(3);
+          internal_static_EncodedColumnQualifierCounter_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_EncodedColumnQualifierCounter_descriptor,
+              new java.lang.String[] { "FamilyName", "Counter", });
           return null;
         }
       };

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
index 0eeb662..13b95b5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
@@ -29,6 +29,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import co.cask.tephra.Transaction;
+import co.cask.tephra.Transaction.VisibilityLevel;
+import co.cask.tephra.TxConstants;
+import co.cask.tephra.hbase98.TransactionAwareHTable;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.Cell;
@@ -61,7 +66,6 @@ import org.apache.phoenix.hbase.index.covered.update.IndexedColumnGroup;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.hbase.index.write.IndexWriter;
 import org.apache.phoenix.query.KeyRange;
-import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.schema.types.PVarbinary;
 import org.apache.phoenix.trace.TracingUtils;
 import org.apache.phoenix.trace.util.NullSpan;
@@ -77,11 +81,6 @@ import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.common.primitives.Longs;
 
-import co.cask.tephra.Transaction;
-import co.cask.tephra.Transaction.VisibilityLevel;
-import co.cask.tephra.TxConstants;
-import co.cask.tephra.hbase98.TransactionAwareHTable;
-
 /**
  * Do all the work of managing index updates for a transactional table from a single coprocessor. Since the transaction
  * manager essentially time orders writes through conflict detection, the logic to maintain a secondary index is quite a

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index f253cc9..b528f0b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -205,9 +205,7 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
     public static final byte[] BASE_COLUMN_COUNT_BYTES = Bytes.toBytes(BASE_COLUMN_COUNT);
     public static final String IS_ROW_TIMESTAMP = "IS_ROW_TIMESTAMP";
     public static final byte[] IS_ROW_TIMESTAMP_BYTES = Bytes.toBytes(IS_ROW_TIMESTAMP);
-    public static final String COLUMN_QUALIFIER = "COLUMN_QUALIFIER";
-    public static final byte[] COLUMN_QUALIFIER_BYTES = Bytes.toBytes(COLUMN_QUALIFIER);
-
+    
     public static final String TABLE_FAMILY = QueryConstants.DEFAULT_COLUMN_FAMILY;
     public static final byte[] TABLE_FAMILY_BYTES = QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES;
 
@@ -297,7 +295,11 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
     public static final String ASYNC_CREATED_DATE = "ASYNC_CREATED_DATE";
     public static final String STORAGE_SCHEME = "STORAGE_SCHEME";
     public static final byte[] STORAGE_SCHEME_BYTES = Bytes.toBytes(STORAGE_SCHEME);
-
+    public static final String ENCODED_COLUMN_QUALIFIER = "COLUMN_QUALIFIER";
+    public static final byte[] ENCODED_COLUMN_QUALIFIER_BYTES = Bytes.toBytes(ENCODED_COLUMN_QUALIFIER);
+    public static final String ENCODED_COLUMN_QUALIFIER_COUNTER = "QUALIFIER_COUNTER";
+    public static final byte[] ENCODED_COLUMN_QUALIFIER_COUNTER_BYTES = Bytes.toBytes(ENCODED_COLUMN_QUALIFIER_COUNTER);
+    
     private final PhoenixConnection connection;
     private final ResultSet emptyResultSet;
     public static final int MAX_LOCAL_SI_VERSION_DISALLOW = VersionUtil.encodeVersion("0", "98", "8");

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
index f8f6672..3733c5b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
@@ -29,7 +29,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CURRENT_VALUE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CYCLE_FLAG;
@@ -39,6 +39,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DECIMAL_DIGITS;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_VALUE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER_COUNTER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.FUNCTION_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POSTS_ROW_COUNT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH;
@@ -277,8 +278,9 @@ public interface QueryConstants {
             TRANSACTIONAL + " BOOLEAN," +
             UPDATE_CACHE_FREQUENCY + " BIGINT," +
             IS_NAMESPACE_MAPPED + " BOOLEAN," +
-            COLUMN_QUALIFIER + " INTEGER," +
+            ENCODED_COLUMN_QUALIFIER + " INTEGER," +
             STORAGE_SCHEME + " TINYINT, " + 
+            ENCODED_COLUMN_QUALIFIER_COUNTER + " INTEGER, " +
             "CONSTRAINT " + SYSTEM_TABLE_PK_NAME + " PRIMARY KEY (" + TENANT_ID + ","
             + TABLE_SCHEM + "," + TABLE_NAME + "," + COLUMN_NAME + "," + COLUMN_FAMILY + "))\n" +
             HConstants.VERSIONS + "=" + MetaDataProtocol.DEFAULT_MAX_META_DATA_VERSIONS + ",\n" +

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d8488efd/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
index 3fd95b6..1690bd3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
@@ -18,6 +18,7 @@
 package org.apache.phoenix.schema;
 
 import java.util.List;
+import java.util.Map;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
@@ -286,4 +287,9 @@ public class DelegateTable implements PTable {
     public PColumn getPColumnForColumnQualifier(byte[] cq) throws ColumnNotFoundException, AmbiguousColumnException {
         return delegate.getPColumnForColumnQualifier(cq);
     }
+
+    @Override
+    public Map<String, Integer> getEncodedCQCounters() {
+        return delegate.getEncodedCQCounters();
+    }
 }


[52/52] [abbrv] phoenix git commit: Fix disabling of indexes on write failures

Posted by sa...@apache.org.
Fix disabling of indexes on write failures


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

Branch: refs/heads/encodecolumns
Commit: 227ba1d69bb0c0643a66c8c44a05a5e6497d2519
Parents: d8488ef
Author: Samarth <sa...@salesforce.com>
Authored: Fri Apr 8 00:18:11 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:32 2016 -0700

----------------------------------------------------------------------
 .../phoenix/end2end/AlterTableWithViewsIT.java  |  8 ++--
 .../apache/phoenix/end2end/CreateTableIT.java   |  6 +--
 .../end2end/index/txn/MutableRollbackIT.java    |  2 +-
 .../coprocessor/MetaDataEndpointImpl.java       | 50 +++++++++-----------
 .../example/CoveredColumnIndexCodec.java        |  1 -
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java   |  4 +-
 .../mapreduce/FormatToKeyValueReducer.java      |  8 +++-
 .../apache/phoenix/query/QueryConstants.java    |  4 +-
 .../apache/phoenix/schema/MetaDataClient.java   | 10 ++--
 9 files changed, 46 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/227ba1d6/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
index 6deab29..9295f51 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableWithViewsIT.java
@@ -21,7 +21,7 @@ import static org.apache.phoenix.exception.SQLExceptionCode.CANNOT_MUTATE_TABLE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER_COUNTER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_COUNTER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM;
@@ -860,8 +860,8 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
     }
     
     private void assertEncodedCQCounter(String columnFamily, String schemaName, String tableName, int expectedValue) throws Exception {
-        String query = "SELECT " + ENCODED_COLUMN_QUALIFIER_COUNTER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
-                + " = ? " + " AND " + COLUMN_FAMILY + " = ? AND " + ENCODED_COLUMN_QUALIFIER_COUNTER + " IS NOT NULL";
+        String query = "SELECT " + COLUMN_QUALIFIER_COUNTER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? " + " AND " + COLUMN_FAMILY + " = ? AND " + COLUMN_QUALIFIER_COUNTER + " IS NOT NULL";
         try (Connection conn = DriverManager.getConnection(getUrl())) {
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, schemaName);
@@ -889,4 +889,4 @@ public class AlterTableWithViewsIT extends BaseHBaseManagedTimeIT {
         }
     }
     
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/227ba1d6/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
index 0ab47f0..6055b1c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CreateTableIT.java
@@ -21,7 +21,7 @@ import static org.apache.hadoop.hbase.HColumnDescriptor.DEFAULT_REPLICATION_SCOP
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER_COUNTER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_COUNTER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM;
@@ -582,8 +582,8 @@ public class CreateTableIT extends BaseClientManagedTimeIT {
     }
     
     private void assertColumnFamilyCounter(String columnFamily, String schemaName, String tableName, int expectedValue) throws Exception {
-        String query = "SELECT " + ENCODED_COLUMN_QUALIFIER_COUNTER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
-                + " = ? " + " AND " + COLUMN_FAMILY + " = ? AND " + ENCODED_COLUMN_QUALIFIER_COUNTER + " IS NOT NULL";
+        String query = "SELECT " + COLUMN_QUALIFIER_COUNTER + " FROM SYSTEM.CATALOG WHERE " + TABLE_SCHEM + " = ? AND " + TABLE_NAME
+                + " = ? " + " AND " + COLUMN_FAMILY + " = ? AND " + COLUMN_QUALIFIER_COUNTER + " IS NOT NULL";
         try (Connection conn = DriverManager.getConnection(getUrl())) {
             PreparedStatement stmt = conn.prepareStatement(query);
             stmt.setString(1, schemaName);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/227ba1d6/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/txn/MutableRollbackIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/txn/MutableRollbackIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/txn/MutableRollbackIT.java
index 767c4e0..e675dda 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/txn/MutableRollbackIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/txn/MutableRollbackIT.java
@@ -278,7 +278,7 @@ public class MutableRollbackIT extends BaseHBaseManagedTimeIT {
             assertFalse(rs.next());
             
             //assert no rows exists in indexName2
-            rs = stmt.executeQuery("select * from " + fullTableName2);
+            rs = stmt.executeQuery("select /*+ INDEX(" + indexName1 + ")*/ k, v1 from " + fullTableName2);
             assertFalse(rs.next());
             
             stmt.executeUpdate("upsert into " + fullTableName1 + " values('x', 'z', 'a')");

http://git-wip-us.apache.org/repos/asf/phoenix/blob/227ba1d6/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 1d2c0d3..36e04b5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -33,6 +33,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAM
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_VALUE_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER_BYTES;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_COUNTER_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.FAMILY_NAME_INDEX;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IMMUTABLE_ROWS_BYTES;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP_BYTES;
@@ -274,6 +275,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
     private static final KeyValue IS_NAMESPACE_MAPPED_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY,
             TABLE_FAMILY_BYTES, IS_NAMESPACE_MAPPED_BYTES);
     private static final KeyValue STORAGE_SCHEME_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, STORAGE_SCHEME_BYTES);
+    private static final KeyValue QUALIIFIER_COUNTER_KV = createFirstOnRow(ByteUtil.EMPTY_BYTE_ARRAY, TABLE_FAMILY_BYTES, COLUMN_QUALIFIER_COUNTER_BYTES);
     
     private static final List<KeyValue> TABLE_KV_COLUMNS = Arrays.<KeyValue>asList(
             EMPTY_KEYVALUE_KV,
@@ -930,37 +932,28 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
               break;
           }
           Cell colKv = results.get(LINK_TYPE_INDEX);
-          Cell qualifierCounterKv = null;
-          if (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES) {
-              int index = tableType == PTableType.VIEW ? 1 : 0;
-              qualifierCounterKv = results.get(index);
-          }
           if (colKv != null) {
               int colKeyLength = colKv.getRowLength();
               PName colName = newPName(colKv.getRowArray(), colKv.getRowOffset() + offset, colKeyLength-offset);
               int colKeyOffset = offset + colName.getBytes().length + 1;
               PName famName = newPName(colKv.getRowArray(), colKv.getRowOffset() + colKeyOffset, colKeyLength-colKeyOffset);
-              if (colName.getString().isEmpty() && famName != null) {
-                  LinkType linkType = LinkType.fromSerializedValue(colKv.getValueArray()[colKv.getValueOffset()]);
-                  if (linkType == LinkType.INDEX_TABLE) {
-                      addIndexToTable(tenantId, schemaName, famName, tableName, clientTimeStamp, indexes);
-                  } else if (linkType == LinkType.PHYSICAL_TABLE) {
-                      physicalTables.add(famName);
-                  }
-              } else {
+                if (colName.getString().isEmpty() && famName != null) {
+                    if (isQualifierCounterKv(colKv)) {
+                        Integer counter = (Integer)PInteger.INSTANCE.toObject(colKv.getValueArray(),
+                                colKv.getValueOffset(), colKv.getValueLength());
+                        encodedColumnQualifierCounters.put(famName.getString(), counter);
+                    } else {
+                        LinkType linkType = LinkType.fromSerializedValue(colKv.getValueArray()[colKv.getValueOffset()]);
+                        if (linkType == LinkType.INDEX_TABLE) {
+                            addIndexToTable(tenantId, schemaName, famName, tableName, clientTimeStamp, indexes);
+                        } else if (linkType == LinkType.PHYSICAL_TABLE) {
+                            physicalTables.add(famName);
+                        }
+                    }
+                } else {
                   addColumnToTable(results, colName, famName, colKeyValues, columns, saltBucketNum != null);
               }
           } 
-          if (qualifierCounterKv != null) {
-              int length = qualifierCounterKv.getRowLength();
-              PName colName = newPName(qualifierCounterKv.getRowArray(), qualifierCounterKv.getRowOffset() + offset, length - offset);
-              int colKeyOffset = offset + colName.getBytes().length + 1;
-              PName famName = newPName(qualifierCounterKv.getRowArray(), qualifierCounterKv.getRowOffset() + colKeyOffset, length - colKeyOffset);
-              if (colName.getString().isEmpty() && famName != null) {
-                  Integer counter = (Integer)PInteger.INSTANCE.toObject(qualifierCounterKv.getValueArray(), qualifierCounterKv.getValueOffset(), qualifierCounterKv.getValueLength());
-                  encodedColumnQualifierCounters.put(famName.getString(), counter);
-              }
-          }
         }
         PName physicalTableName = physicalTables.isEmpty() ? PNameFactory.newName(SchemaUtil.getPhysicalTableName(
                 Bytes.toBytes(SchemaUtil.getTableName(schemaName.getBytes(), tableName.getBytes())), isNamespaceMapped)
@@ -1008,6 +1001,12 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
         return new PSchema(schemaName.getString(), timeStamp);
     }
 
+    private static boolean isQualifierCounterKv(Cell colKv) {
+        return Bytes.compareTo(colKv.getQualifierArray(), colKv.getQualifierOffset(),
+                colKv.getQualifierLength(), QUALIIFIER_COUNTER_KV.getQualifierArray(),
+                QUALIIFIER_COUNTER_KV.getQualifierOffset(), QUALIIFIER_COUNTER_KV.getQualifierLength()) == 0;
+    }
+
     private PFunction getFunction(RegionScanner scanner, final boolean isReplace, long clientTimeStamp, List<Mutation> deleteMutationsForReplace)
             throws IOException, SQLException {
         List<Cell> results = Lists.newArrayList();
@@ -3244,10 +3243,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                         tableMetadata = new ArrayList<Mutation>(tableMetadata);
                         // insert an empty KV to trigger time stamp update on data table row
                         Put p = new Put(dataTableKey);
-                        // Decide on what column qualifier to use for empty key value.
-                        PTable currentTable = doGetTable(key, HConstants.LATEST_TIMESTAMP, rowLock);
-                        Pair<byte[], byte[]> emptyKeyValuePair = EncodedColumnsUtil.getEmptyKeyValueInfo(currentTable);
-                        p.add(TABLE_FAMILY_BYTES, emptyKeyValuePair.getFirst(), timeStamp, emptyKeyValuePair.getSecond());
+                        p.add(TABLE_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, timeStamp, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
                         tableMetadata.add(p);
                     }
                     boolean setRowKeyOrderOptimizableCell = newState == PIndexState.BUILDING && !rowKeyOrderOptimizable;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/227ba1d6/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/example/CoveredColumnIndexCodec.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/example/CoveredColumnIndexCodec.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/example/CoveredColumnIndexCodec.java
index 6f9caa6..0f960e4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/example/CoveredColumnIndexCodec.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/example/CoveredColumnIndexCodec.java
@@ -32,7 +32,6 @@ import org.apache.phoenix.hbase.index.covered.TableState;
 import org.apache.phoenix.hbase.index.scanner.Scanner;
 
 import com.google.common.collect.Lists;
-import com.google.common.collect.Lists;
 
 /**
  *

http://git-wip-us.apache.org/repos/asf/phoenix/blob/227ba1d6/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index b528f0b..1c9bc51 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -297,8 +297,8 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
     public static final byte[] STORAGE_SCHEME_BYTES = Bytes.toBytes(STORAGE_SCHEME);
     public static final String ENCODED_COLUMN_QUALIFIER = "COLUMN_QUALIFIER";
     public static final byte[] ENCODED_COLUMN_QUALIFIER_BYTES = Bytes.toBytes(ENCODED_COLUMN_QUALIFIER);
-    public static final String ENCODED_COLUMN_QUALIFIER_COUNTER = "QUALIFIER_COUNTER";
-    public static final byte[] ENCODED_COLUMN_QUALIFIER_COUNTER_BYTES = Bytes.toBytes(ENCODED_COLUMN_QUALIFIER_COUNTER);
+    public static final String COLUMN_QUALIFIER_COUNTER = "QUALIFIER_COUNTER";
+    public static final byte[] COLUMN_QUALIFIER_COUNTER_BYTES = Bytes.toBytes(COLUMN_QUALIFIER_COUNTER);
     
     private final PhoenixConnection connection;
     private final ResultSet emptyResultSet;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/227ba1d6/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
index ddf6120..89d59a4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
@@ -66,6 +66,7 @@ public class FormatToKeyValueReducer
     protected KeyValueBuilder builder;
     List<List<Pair<byte[], byte[]>>> columnIndexes;
     List<ImmutableBytesPtr> emptyFamilyName;
+    List<Pair<byte[], byte[]>> emptyKeyValueQualifier;
 
 
     @Override
@@ -87,7 +88,8 @@ public class FormatToKeyValueReducer
             logicalNames = TargetTableRefFunctions.NAMES_FROM_JSON.apply(logicalNamesConf);
 
             columnIndexes = new ArrayList<>(tableNames.size());
-            emptyFamilyName = new ArrayList<>();
+            emptyFamilyName = new ArrayList<>(logicalNames.size());
+            emptyKeyValueQualifier = new ArrayList<>(logicalNames.size()); 
             initColumnsMap(conn);
         } catch (SQLException | ClassNotFoundException e) {
             throw new RuntimeException(e);
@@ -98,6 +100,7 @@ public class FormatToKeyValueReducer
         for (String tableName : logicalNames) {
             PTable table = PhoenixRuntime.getTable(conn, tableName);
             emptyFamilyName.add(SchemaUtil.getEmptyColumnFamilyPtr(table));
+            emptyKeyValueQualifier.add(EncodedColumnsUtil.getEmptyKeyValueInfo(table));
             List<PColumn> cls = table.getColumns();
             List<Pair<byte[], byte[]>> list = new ArrayList<>(cls.size());
             for (int i = 0; i < cls.size(); i++) {
@@ -153,10 +156,11 @@ public class FormatToKeyValueReducer
                 }
                 map.add(kv);
             }
+            Pair<byte[], byte[]> emptyKeyValue = emptyKeyValueQualifier.get(tableIndex);
             //FIXME: samarth need to supply the right empty column qualifier here.
             KeyValue empty = builder.buildPut(key.getRowkey(),
                     emptyFamilyName.get(tableIndex),
-                    QueryConstants.EMPTY_COLUMN_BYTES_PTR, ByteUtil.EMPTY_BYTE_ARRAY_PTR);
+                    new ImmutableBytesPtr(emptyKeyValue.getFirst()), new ImmutableBytesPtr(emptyKeyValue.getSecond()));
             map.add(empty);
             Closeables.closeQuietly(input);
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/227ba1d6/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
index 3733c5b..f57043b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
@@ -39,7 +39,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DECIMAL_DIGITS;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_VALUE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER_COUNTER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_COUNTER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.FUNCTION_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POSTS_ROW_COUNT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH;
@@ -280,7 +280,7 @@ public interface QueryConstants {
             IS_NAMESPACE_MAPPED + " BOOLEAN," +
             ENCODED_COLUMN_QUALIFIER + " INTEGER," +
             STORAGE_SCHEME + " TINYINT, " + 
-            ENCODED_COLUMN_QUALIFIER_COUNTER + " INTEGER, " +
+            COLUMN_QUALIFIER_COUNTER + " INTEGER, " +
             "CONSTRAINT " + SYSTEM_TABLE_PK_NAME + " PRIMARY KEY (" + TENANT_ID + ","
             + TABLE_SCHEM + "," + TABLE_NAME + "," + COLUMN_NAME + "," + COLUMN_FAMILY + "))\n" +
             HConstants.VERSIONS + "=" + MetaDataProtocol.DEFAULT_MAX_META_DATA_VERSIONS + ",\n" +

http://git-wip-us.apache.org/repos/asf/phoenix/blob/227ba1d6/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index a612e42..70a1d6e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -41,7 +41,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DECIMAL_DIGITS;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_VALUE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODED_COLUMN_QUALIFIER_COUNTER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_COUNTER;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.FUNCTION_NAME;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IMMUTABLE_ROWS;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP;
@@ -294,7 +294,7 @@ public class MetaDataClient {
             TABLE_SCHEM + "," +
             TABLE_NAME + "," +
             COLUMN_FAMILY + "," +
-            ENCODED_COLUMN_QUALIFIER_COUNTER + 
+            COLUMN_QUALIFIER_COUNTER + 
             ") VALUES (?, ?, ?, ?)";
     private static final String INCREMENT_SEQ_NUM =
             "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
@@ -1966,12 +1966,12 @@ public class MetaDataClient {
                  * the column qualifiers that were used when populating the hbase table.
                  */
                 byte[] tableNameBytes = SchemaUtil.getTableNameAsBytes(schemaName, tableName);
-                boolean hbaseTableAlreadyExists = true;
+                boolean tableExists = true;
                 try (HBaseAdmin admin = connection.getQueryServices().getAdmin()) {
                     try {
                         admin.getTableDescriptor(tableNameBytes);
                     } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
-                        hbaseTableAlreadyExists = false;
+                        tableExists = false;
                     }
                 } catch (IOException e) {
                     throw new RuntimeException(e);
@@ -1980,7 +1980,7 @@ public class MetaDataClient {
                 }
                 if (parent != null) {
                     storageScheme = parent.getStorageScheme();
-                } else if (hbaseTableAlreadyExists) {
+                } else if (tableExists) {
                     storageScheme = StorageScheme.NON_ENCODED_COLUMN_NAMES;
                 } else {
                     storageScheme = StorageScheme.ENCODED_COLUMN_NAMES;


[29/52] [abbrv] phoenix git commit: PHOENIX-2743 HivePhoenixHandler for big-big join with

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/IndexPredicateAnalyzer.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/IndexPredicateAnalyzer.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/IndexPredicateAnalyzer.java
new file mode 100644
index 0000000..659983a
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/IndexPredicateAnalyzer.java
@@ -0,0 +1,523 @@
+/*
+ * 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.phoenix.hive.ql.index;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hive.ql.exec.FunctionRegistry;
+import org.apache.hadoop.hive.ql.lib.DefaultGraphWalker;
+import org.apache.hadoop.hive.ql.lib.DefaultRuleDispatcher;
+import org.apache.hadoop.hive.ql.lib.Dispatcher;
+import org.apache.hadoop.hive.ql.lib.GraphWalker;
+import org.apache.hadoop.hive.ql.lib.Node;
+import org.apache.hadoop.hive.ql.lib.NodeProcessor;
+import org.apache.hadoop.hive.ql.lib.NodeProcessorCtx;
+import org.apache.hadoop.hive.ql.lib.Rule;
+import org.apache.hadoop.hive.ql.parse.SemanticException;
+import org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeDescUtils;
+import org.apache.hadoop.hive.ql.plan.ExprNodeFieldDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFBaseCompare;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFBetween;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFBridge;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFIn;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNot;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNotNull;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNull;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFToBinary;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFToChar;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFToDate;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFToDecimal;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFToUnixTimeStamp;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFToUtcTimestamp;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDFToVarchar;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+/**
+ * Clone of org.apache.hadoop.hive.ql.index.IndexPredicateAnalyzer with modifying
+ * analyzePredicate method.
+ *
+ *
+ */
+public class IndexPredicateAnalyzer {
+
+    private static final Log LOG = LogFactory.getLog(IndexPredicateAnalyzer.class);
+
+    private final Set<String> udfNames;
+    private final Map<String, Set<String>> columnToUDFs;
+    private FieldValidator fieldValidator;
+
+    private boolean acceptsFields;
+
+    public IndexPredicateAnalyzer() {
+        udfNames = new HashSet<String>();
+        columnToUDFs = new HashMap<String, Set<String>>();
+    }
+
+    public void setFieldValidator(FieldValidator fieldValidator) {
+        this.fieldValidator = fieldValidator;
+    }
+
+    /**
+     * Registers a comparison operator as one which can be satisfied by an index
+     * search. Unless this is called, analyzePredicate will never find any
+     * indexable conditions.
+     *
+     * @param udfName name of comparison operator as returned by either
+     *                {@link GenericUDFBridge#getUdfName} (for simple UDF's) or
+     *                udf.getClass().getName() (for generic UDF's).
+     */
+    public void addComparisonOp(String udfName) {
+        udfNames.add(udfName);
+    }
+
+    /**
+     * Clears the set of column names allowed in comparisons. (Initially, all
+     * column names are allowed.)
+     */
+    public void clearAllowedColumnNames() {
+        columnToUDFs.clear();
+    }
+
+    /**
+     * Adds a column name to the set of column names allowed.
+     *
+     * @param columnName name of column to be allowed
+     */
+    public void allowColumnName(String columnName) {
+        columnToUDFs.put(columnName, udfNames);
+    }
+
+    /**
+     * add allowed functions per column
+     *
+     * @param columnName
+     * @param udfs
+     */
+    public void addComparisonOp(String columnName, String... udfs) {
+        Set<String> allowed = columnToUDFs.get(columnName);
+        if (allowed == null || allowed == udfNames) {
+            // override
+            columnToUDFs.put(columnName, new HashSet<String>(Arrays.asList(udfs)));
+        } else {
+            allowed.addAll(Arrays.asList(udfs));
+        }
+    }
+
+    /**
+     * Analyzes a predicate.
+     *
+     * @param predicate        predicate to be analyzed
+     * @param searchConditions receives conditions produced by analysis
+     * @return residual predicate which could not be translated to
+     * searchConditions
+     */
+    public ExprNodeDesc analyzePredicate(ExprNodeDesc predicate, final List<IndexSearchCondition>
+            searchConditions) {
+
+        Map<Rule, NodeProcessor> opRules = new LinkedHashMap<Rule, NodeProcessor>();
+        NodeProcessor nodeProcessor = new NodeProcessor() {
+            @Override
+            public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx, Object...
+                    nodeOutputs) throws SemanticException {
+
+                // We can only push down stuff which appears as part of
+                // a pure conjunction: reject OR, CASE, etc.
+                for (Node ancestor : stack) {
+                    if (nd == ancestor) {
+                        break;
+                    }
+                    if (!FunctionRegistry.isOpAnd((ExprNodeDesc) ancestor)) {
+                        return nd;
+                    }
+                }
+
+                return analyzeExpr((ExprNodeGenericFuncDesc) nd, searchConditions, nodeOutputs);
+            }
+        };
+
+        Dispatcher disp = new DefaultRuleDispatcher(nodeProcessor, opRules, null);
+        GraphWalker ogw = new DefaultGraphWalker(disp);
+        ArrayList<Node> topNodes = new ArrayList<Node>();
+        topNodes.add(predicate);
+        HashMap<Node, Object> nodeOutput = new HashMap<Node, Object>();
+
+        try {
+            ogw.startWalking(topNodes, nodeOutput);
+        } catch (SemanticException ex) {
+            throw new RuntimeException(ex);
+        }
+
+        ExprNodeDesc residualPredicate = (ExprNodeDesc) nodeOutput.get(predicate);
+        return residualPredicate;
+    }
+
+    // Check if ExprNodeColumnDesc is wrapped in expr.
+    // If so, peel off. Otherwise return itself.
+    private ExprNodeDesc getColumnExpr(ExprNodeDesc expr) {
+        if (expr instanceof ExprNodeColumnDesc) {
+            return expr;
+        }
+        ExprNodeGenericFuncDesc funcDesc = null;
+        if (expr instanceof ExprNodeGenericFuncDesc) {
+            funcDesc = (ExprNodeGenericFuncDesc) expr;
+        }
+        if (null == funcDesc) {
+            return expr;
+        }
+        GenericUDF udf = funcDesc.getGenericUDF();
+        // check if its a simple cast expression.
+        if ((udf instanceof GenericUDFBridge || udf instanceof GenericUDFToBinary || udf
+                instanceof GenericUDFToChar
+                || udf instanceof GenericUDFToVarchar || udf instanceof GenericUDFToDecimal
+                || udf instanceof GenericUDFToDate || udf instanceof GenericUDFToUnixTimeStamp
+                || udf instanceof GenericUDFToUtcTimestamp) && funcDesc.getChildren().size() == 1
+                && funcDesc.getChildren().get(0) instanceof ExprNodeColumnDesc) {
+            return expr.getChildren().get(0);
+        }
+        return expr;
+    }
+
+    private void processingBetweenOperator(ExprNodeGenericFuncDesc expr,
+                                           List<IndexSearchCondition> searchConditions, Object...
+                                                   nodeOutputs) {
+        ExprNodeColumnDesc columnDesc = null;
+        String[] fields = null;
+
+        if (nodeOutputs[1] instanceof ExprNodeFieldDesc) {
+            // rowKey field
+            ExprNodeFieldDesc fieldDesc = (ExprNodeFieldDesc) nodeOutputs[1];
+            fields = ExprNodeDescUtils.extractFields(fieldDesc);
+
+            ExprNodeDesc[] extracted = ExprNodeDescUtils.extractComparePair((ExprNodeDesc)
+                    nodeOutputs[1], (ExprNodeDesc) nodeOutputs[2]);
+            columnDesc = (ExprNodeColumnDesc) extracted[0];
+        } else if (nodeOutputs[0] instanceof ExprNodeGenericFuncDesc) {
+            columnDesc = (ExprNodeColumnDesc) ((ExprNodeGenericFuncDesc) nodeOutputs[1])
+                    .getChildren().get(0);
+        } else {
+            columnDesc = (ExprNodeColumnDesc) nodeOutputs[1];
+        }
+
+        String udfName = expr.getGenericUDF().getUdfName();
+        ExprNodeConstantDesc[] betweenConstants = new ExprNodeConstantDesc[]{
+                (ExprNodeConstantDesc) nodeOutputs[2], (ExprNodeConstantDesc) nodeOutputs[3]};
+        boolean isNot = (Boolean) ((ExprNodeConstantDesc) nodeOutputs[0]).getValue();
+
+        searchConditions.add(new IndexSearchCondition(columnDesc, udfName, betweenConstants,
+                expr, fields, isNot));
+    }
+
+    private void processingInOperator(ExprNodeGenericFuncDesc expr, List<IndexSearchCondition>
+            searchConditions, boolean isNot, Object... nodeOutputs) {
+        ExprNodeColumnDesc columnDesc = null;
+        String[] fields = null;
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Processing In Operator. nodeOutputs : " + Lists.newArrayList(nodeOutputs));
+        }
+
+        if (nodeOutputs[0] instanceof ExprNodeFieldDesc) {
+            // rowKey field
+            ExprNodeFieldDesc fieldDesc = (ExprNodeFieldDesc) nodeOutputs[0];
+            fields = ExprNodeDescUtils.extractFields(fieldDesc);
+
+            ExprNodeDesc[] extracted = ExprNodeDescUtils.extractComparePair((ExprNodeDesc)
+                    nodeOutputs[0], (ExprNodeDesc) nodeOutputs[1]);
+
+            if (extracted == null) {    // adding for tez
+                return;
+            }
+
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("nodeOutputs[0] : " + nodeOutputs[0] + ", nodeOutputs[1] : " +
+                        nodeOutputs[1] + " => " + Lists.newArrayList(extracted));
+            }
+
+            columnDesc = (ExprNodeColumnDesc) extracted[0];
+        } else if (nodeOutputs[0] instanceof ExprNodeGenericFuncDesc) {
+            columnDesc = (ExprNodeColumnDesc) ((ExprNodeGenericFuncDesc) nodeOutputs[0])
+                    .getChildren().get(0);
+        } else {
+            columnDesc = (ExprNodeColumnDesc) nodeOutputs[0];
+        }
+
+        String udfName = expr.getGenericUDF().getUdfName();
+        ExprNodeConstantDesc[] inConstantDescs = new ExprNodeConstantDesc[nodeOutputs.length - 1];
+
+        for (int i = 0, limit = inConstantDescs.length; i < limit; i++) {
+            if (!(nodeOutputs[i + 1] instanceof ExprNodeConstantDesc)) {    // adding for tez
+                return;
+            }
+
+            inConstantDescs[i] = (ExprNodeConstantDesc) nodeOutputs[i + 1];
+        }
+
+        searchConditions.add(new IndexSearchCondition(columnDesc, udfName, inConstantDescs, expr,
+                fields, isNot));
+    }
+
+    private void processingNullOperator(ExprNodeGenericFuncDesc expr, List<IndexSearchCondition>
+            searchConditions, Object... nodeOutputs) {
+        ExprNodeColumnDesc columnDesc = null;
+        String[] fields = null;
+
+        if (nodeOutputs[0] instanceof ExprNodeFieldDesc) {
+            // rowKey field
+            ExprNodeFieldDesc fieldDesc = (ExprNodeFieldDesc) nodeOutputs[0];
+            fields = ExprNodeDescUtils.extractFields(fieldDesc);
+
+            ExprNodeDesc[] extracted = ExprNodeDescUtils.extractComparePair((ExprNodeDesc)
+                    nodeOutputs[0], new ExprNodeConstantDesc());
+            columnDesc = (ExprNodeColumnDesc) extracted[0];
+        } else if (nodeOutputs[0] instanceof ExprNodeGenericFuncDesc) {
+            columnDesc = (ExprNodeColumnDesc) ((ExprNodeGenericFuncDesc) nodeOutputs[0])
+                    .getChildren().get(0);
+        } else {
+            columnDesc = (ExprNodeColumnDesc) nodeOutputs[0];
+        }
+
+        String udfName = expr.getGenericUDF().getUdfName();
+
+        searchConditions.add(new IndexSearchCondition(columnDesc, udfName, null, expr, fields,
+                false));
+    }
+
+    private void processingNotNullOperator(ExprNodeGenericFuncDesc expr,
+                                           List<IndexSearchCondition> searchConditions, Object...
+                                                   nodeOutputs) {
+        ExprNodeColumnDesc columnDesc = null;
+        String[] fields = null;
+
+        if (nodeOutputs[0] instanceof ExprNodeFieldDesc) {
+            // rowKey field
+            ExprNodeFieldDesc fieldDesc = (ExprNodeFieldDesc) nodeOutputs[0];
+            fields = ExprNodeDescUtils.extractFields(fieldDesc);
+
+            ExprNodeDesc[] extracted = ExprNodeDescUtils.extractComparePair((ExprNodeDesc)
+                    nodeOutputs[0], new ExprNodeConstantDesc());
+            columnDesc = (ExprNodeColumnDesc) extracted[0];
+        } else if (nodeOutputs[0] instanceof ExprNodeGenericFuncDesc) {
+            columnDesc = (ExprNodeColumnDesc) ((ExprNodeGenericFuncDesc) nodeOutputs[0])
+                    .getChildren().get(0);
+        } else {
+            columnDesc = (ExprNodeColumnDesc) nodeOutputs[0];
+        }
+
+        String udfName = expr.getGenericUDF().getUdfName();
+
+        searchConditions.add(new IndexSearchCondition(columnDesc, udfName, null, expr, fields,
+                true));
+    }
+
+    private ExprNodeDesc analyzeExpr(ExprNodeGenericFuncDesc expr, List<IndexSearchCondition>
+            searchConditions, Object... nodeOutputs) throws SemanticException {
+
+        if (FunctionRegistry.isOpAnd(expr)) {
+            assert (nodeOutputs.length == 2);
+            ExprNodeDesc residual1 = (ExprNodeDesc) nodeOutputs[0];
+            ExprNodeDesc residual2 = (ExprNodeDesc) nodeOutputs[1];
+            if (residual1 == null) {
+                return residual2;
+            }
+            if (residual2 == null) {
+                return residual1;
+            }
+            List<ExprNodeDesc> residuals = new ArrayList<ExprNodeDesc>();
+            residuals.add(residual1);
+            residuals.add(residual2);
+            return new ExprNodeGenericFuncDesc(TypeInfoFactory.booleanTypeInfo, FunctionRegistry
+                    .getGenericUDFForAnd(), residuals);
+        }
+
+        GenericUDF genericUDF = expr.getGenericUDF();
+        if (!(genericUDF instanceof GenericUDFBaseCompare)) {
+            // 2015-10-22 Added by JeongMin Ju : Processing Between/In Operator
+            if (genericUDF instanceof GenericUDFBetween) {
+                // In case of not between, The value of first element of nodeOutputs is true.
+                // otherwise false.
+                processingBetweenOperator(expr, searchConditions, nodeOutputs);
+                return expr;
+            } else if (genericUDF instanceof GenericUDFIn) {
+                // In case of not in operator, in operator exist as child of not operator.
+                processingInOperator(expr, searchConditions, false, nodeOutputs);
+                return expr;
+            } else if (genericUDF instanceof GenericUDFOPNot &&
+                    ((ExprNodeGenericFuncDesc) expr.getChildren().get(0)).getGenericUDF()
+                            instanceof GenericUDFIn) {
+                // In case of not in operator, in operator exist as child of not operator.
+                processingInOperator((ExprNodeGenericFuncDesc) expr.getChildren().get(0),
+                        searchConditions, true, ((ExprNodeGenericFuncDesc) nodeOutputs[0])
+                                .getChildren().toArray());
+                return expr;
+            } else if (genericUDF instanceof GenericUDFOPNull) {
+                processingNullOperator(expr, searchConditions, nodeOutputs);
+                return expr;
+            } else if (genericUDF instanceof GenericUDFOPNotNull) {
+                processingNotNullOperator(expr, searchConditions, nodeOutputs);
+                return expr;
+            } else {
+                return expr;
+            }
+        }
+        ExprNodeDesc expr1 = (ExprNodeDesc) nodeOutputs[0];
+        ExprNodeDesc expr2 = (ExprNodeDesc) nodeOutputs[1];
+        // We may need to peel off the GenericUDFBridge that is added by CBO or
+        // user
+        if (expr1.getTypeInfo().equals(expr2.getTypeInfo())) {
+            expr1 = getColumnExpr(expr1);
+            expr2 = getColumnExpr(expr2);
+        }
+
+        ExprNodeDesc[] extracted = ExprNodeDescUtils.extractComparePair(expr1, expr2);
+        if (extracted == null || (extracted.length > 2 && !acceptsFields)) {
+            return expr;
+        }
+
+        ExprNodeColumnDesc columnDesc;
+        ExprNodeConstantDesc constantDesc;
+        if (extracted[0] instanceof ExprNodeConstantDesc) {
+            genericUDF = genericUDF.flip();
+            columnDesc = (ExprNodeColumnDesc) extracted[1];
+            constantDesc = (ExprNodeConstantDesc) extracted[0];
+        } else {
+            columnDesc = (ExprNodeColumnDesc) extracted[0];
+            constantDesc = (ExprNodeConstantDesc) extracted[1];
+        }
+
+        Set<String> allowed = columnToUDFs.get(columnDesc.getColumn());
+        if (allowed == null) {
+            return expr;
+        }
+
+        String udfName = genericUDF.getUdfName();
+        if (!allowed.contains(genericUDF.getUdfName())) {
+            return expr;
+        }
+
+        String[] fields = null;
+        if (extracted.length > 2) {
+            ExprNodeFieldDesc fieldDesc = (ExprNodeFieldDesc) extracted[2];
+            if (!isValidField(fieldDesc)) {
+                return expr;
+            }
+            fields = ExprNodeDescUtils.extractFields(fieldDesc);
+        }
+
+        // We also need to update the expr so that the index query can be
+        // generated.
+        // Note that, hive does not support UDFToDouble etc in the query text.
+        List<ExprNodeDesc> list = new ArrayList<ExprNodeDesc>();
+        list.add(expr1);
+        list.add(expr2);
+        expr = new ExprNodeGenericFuncDesc(expr.getTypeInfo(), expr.getGenericUDF(), list);
+
+        searchConditions.add(new IndexSearchCondition(columnDesc, udfName, constantDesc, expr,
+                fields));
+
+        // we converted the expression to a search condition, so
+        // remove it from the residual predicate
+        return fields == null ? null : expr;
+    }
+
+    private boolean isValidField(ExprNodeFieldDesc field) {
+        return fieldValidator == null || fieldValidator.validate(field);
+    }
+
+    /**
+     * Translates search conditions back to ExprNodeDesc form (as a left-deep
+     * conjunction).
+     *
+     * @param searchConditions (typically produced by analyzePredicate)
+     * @return ExprNodeGenericFuncDesc form of search conditions
+     */
+    public ExprNodeGenericFuncDesc translateSearchConditions(List<IndexSearchCondition>
+                                                                     searchConditions) {
+
+        ExprNodeGenericFuncDesc expr = null;
+
+        for (IndexSearchCondition searchCondition : searchConditions) {
+            if (expr == null) {
+                expr = searchCondition.getComparisonExpr();
+                continue;
+            }
+
+            List<ExprNodeDesc> children = new ArrayList<ExprNodeDesc>();
+            children.add(expr);
+            children.add(searchCondition.getComparisonExpr());
+            expr = new ExprNodeGenericFuncDesc(TypeInfoFactory.booleanTypeInfo, FunctionRegistry
+                    .getGenericUDFForAnd(), children);
+        }
+
+        return expr;
+    }
+
+    public void setAcceptsFields(boolean acceptsFields) {
+        this.acceptsFields = acceptsFields;
+    }
+
+    public static interface FieldValidator {
+        boolean validate(ExprNodeFieldDesc exprNodeDesc);
+    }
+
+    public static IndexPredicateAnalyzer createAnalyzer(boolean equalOnly) {
+        IndexPredicateAnalyzer analyzer = new IndexPredicateAnalyzer();
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPEqual");
+
+        if (equalOnly) {
+            return analyzer;
+        }
+
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic" +
+                ".GenericUDFOPEqualOrGreaterThan");
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic" +
+                ".GenericUDFOPEqualOrLessThan");
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPLessThan");
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPGreaterThan");
+
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNotEqual");
+        // apply !=
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic.GenericUDFBetween");
+        // apply (Not) Between
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic.GenericUDFIn");        //
+        // apply (Not) In
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic.GenericUDFIn");        //
+        // apply In
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNull");
+        // apply Null
+        analyzer.addComparisonOp("org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNotNull");
+        // apply Not Null
+
+        return analyzer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/IndexSearchCondition.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/IndexSearchCondition.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/IndexSearchCondition.java
new file mode 100644
index 0000000..ebd978c
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/IndexSearchCondition.java
@@ -0,0 +1,143 @@
+/*
+ * 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.phoenix.hive.ql.index;
+
+import org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc;
+
+/**
+ * IndexSearchCondition represents an individual search condition found by
+ * {@link IndexPredicateAnalyzer}.
+ *
+ */
+public class IndexSearchCondition {
+    private ExprNodeColumnDesc columnDesc;
+    private String comparisonOp;
+    private ExprNodeConstantDesc constantDesc;
+    private ExprNodeGenericFuncDesc comparisonExpr;
+
+    private String[] fields;
+
+    // Support (Not) Between/(Not) In Operator
+    private ExprNodeConstantDesc[] multiConstants;
+    private boolean isNot;
+
+    public IndexSearchCondition(ExprNodeColumnDesc columnDesc, String comparisonOp,
+                                ExprNodeConstantDesc[] multiConstants, ExprNodeGenericFuncDesc
+                                        comparisonExpr, boolean isNot) {
+        this(columnDesc, comparisonOp, multiConstants, comparisonExpr, null, isNot);
+    }
+
+    public IndexSearchCondition(ExprNodeColumnDesc columnDesc, String comparisonOp,
+                                ExprNodeConstantDesc[] multiConstants, ExprNodeGenericFuncDesc
+                                        comparisonExpr, String[] fields, boolean isNot) {
+        this.columnDesc = columnDesc;
+        this.comparisonOp = comparisonOp;
+        this.multiConstants = multiConstants;
+        this.comparisonExpr = comparisonExpr;
+        this.fields = fields;
+        this.isNot = isNot;
+    }
+
+    public ExprNodeConstantDesc[] getConstantDescs() {
+        return multiConstants;
+    }
+
+    public ExprNodeConstantDesc getConstantDesc(int index) {
+        return multiConstants[index];
+    }
+
+    public boolean isNot() {
+        return isNot;
+    }
+    //////////////////////////////////////////////////////////////////////////////
+
+    public IndexSearchCondition(ExprNodeColumnDesc columnDesc, String comparisonOp,
+                                ExprNodeConstantDesc constantDesc, ExprNodeGenericFuncDesc
+                                        comparisonExpr) {
+        this(columnDesc, comparisonOp, constantDesc, comparisonExpr, null);
+    }
+
+    /**
+     * Constructs a search condition, which takes the form
+     * <p>
+     * <pre>
+     * column-ref comparison-op constant-value
+     * </pre>
+     * <p>
+     * .
+     *
+     * @param columnDesc     column being compared
+     * @param comparisonOp   comparison operator, e.g. "=" (taken from
+     *                       GenericUDFBridge.getUdfName())
+     * @param constantDesc   constant value to search for
+     * @param comparisonExpr the original comparison expression
+     */
+    public IndexSearchCondition(ExprNodeColumnDesc columnDesc, String comparisonOp,
+                                ExprNodeConstantDesc constantDesc, ExprNodeGenericFuncDesc
+                                        comparisonExpr, String[] fields) {
+
+        this.columnDesc = columnDesc;
+        this.comparisonOp = comparisonOp;
+        this.constantDesc = constantDesc;
+        this.comparisonExpr = comparisonExpr;
+        this.fields = fields;
+    }
+
+    public void setColumnDesc(ExprNodeColumnDesc columnDesc) {
+        this.columnDesc = columnDesc;
+    }
+
+    public ExprNodeColumnDesc getColumnDesc() {
+        return columnDesc;
+    }
+
+    public void setComparisonOp(String comparisonOp) {
+        this.comparisonOp = comparisonOp;
+    }
+
+    public String getComparisonOp() {
+        return comparisonOp;
+    }
+
+    public void setConstantDesc(ExprNodeConstantDesc constantDesc) {
+        this.constantDesc = constantDesc;
+    }
+
+    public ExprNodeConstantDesc getConstantDesc() {
+        return constantDesc;
+    }
+
+    public void setComparisonExpr(ExprNodeGenericFuncDesc comparisonExpr) {
+        this.comparisonExpr = comparisonExpr;
+    }
+
+    public ExprNodeGenericFuncDesc getComparisonExpr() {
+        return comparisonExpr;
+    }
+
+    public String[] getFields() {
+        return fields;
+    }
+
+    @Override
+    public String toString() {
+        return comparisonExpr.getExprString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/PredicateAnalyzerFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/PredicateAnalyzerFactory.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/PredicateAnalyzerFactory.java
new file mode 100644
index 0000000..b6903b9
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/ql/index/PredicateAnalyzerFactory.java
@@ -0,0 +1,40 @@
+/*
+ * 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.phoenix.hive.ql.index;
+
+import org.apache.phoenix.hive.ql.index.IndexPredicateAnalyzer.FieldValidator;
+
+import java.util.List;
+
+public class PredicateAnalyzerFactory {
+    public static IndexPredicateAnalyzer createPredicateAnalyzer(List<String> ppdColumnList,
+                                                                 FieldValidator fieldValdator) {
+        // Create analyzer for conditions  =, <, <=, >, >=
+        IndexPredicateAnalyzer analyzer = IndexPredicateAnalyzer.createAnalyzer(false);
+
+        for (String columnName : ppdColumnList) {
+            analyzer.allowColumnName(columnName);
+        }
+
+        analyzer.setAcceptsFields(true);
+        analyzer.setFieldValidator(fieldValdator);
+
+        return analyzer;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/query/PhoenixQueryBuilder.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/query/PhoenixQueryBuilder.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/query/PhoenixQueryBuilder.java
new file mode 100644
index 0000000..8e3a972
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/query/PhoenixQueryBuilder.java
@@ -0,0 +1,760 @@
+/*
+ * 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.phoenix.hive.query;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hive.serde.serdeConstants;
+import org.apache.hadoop.mapred.JobConf;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.hive.ql.index.IndexSearchCondition;
+import org.apache.phoenix.hive.util.PhoenixStorageHandlerUtil;
+import org.apache.phoenix.hive.util.PhoenixUtil;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Query builder. Produces a query depending on the colummn list and conditions
+ */
+
+public class PhoenixQueryBuilder {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixQueryBuilder.class);
+
+    private static final String QUERY_TEMPLATE = "select $HINT$ $COLUMN_LIST$ from $TABLE_NAME$";
+
+    private static final PhoenixQueryBuilder QUERY_BUILDER = new PhoenixQueryBuilder();
+
+    private PhoenixQueryBuilder() {
+        if (LOG.isInfoEnabled()) {
+            LOG.info("PhoenixQueryBuilder created");
+        }
+    }
+
+    public static PhoenixQueryBuilder getInstance() {
+        return QUERY_BUILDER;
+    }
+
+    private void addConditionColumnToReadColumn(List<String> readColumnList, List<String>
+            conditionColumnList) {
+        if (readColumnList.isEmpty()) {
+            return;
+        }
+
+        for (String conditionColumn : conditionColumnList) {
+            if (!readColumnList.contains(conditionColumn)) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Condition column " + conditionColumn + " does not exist in " +
+                            "read-columns.");
+                }
+
+                readColumnList.add(conditionColumn);
+            }
+        }
+    }
+
+    private String makeQueryString(JobConf jobConf, String tableName, List<String>
+            readColumnList, String whereClause, String queryTemplate, String hints, Map<String,
+            String> columnTypeMap) throws IOException {
+        StringBuilder sql = new StringBuilder();
+        List<String> conditionColumnList = buildWhereClause(jobConf, sql, whereClause,
+                columnTypeMap);
+
+        if (conditionColumnList.size() > 0) {
+            addConditionColumnToReadColumn(readColumnList, conditionColumnList);
+            sql.insert(0, queryTemplate.replace("$HINT$", hints).replace("$COLUMN_LIST$",
+                    getSelectColumns(jobConf, tableName, readColumnList)).replace("$TABLE_NAME$",
+                    tableName));
+        } else {
+            sql.append(queryTemplate.replace("$HINT$", hints).replace("$COLUMN_LIST$",
+                    getSelectColumns(jobConf, tableName, readColumnList)).replace("$TABLE_NAME$",
+                    tableName));
+        }
+
+        if (LOG.isInfoEnabled()) {
+            LOG.info("Input query : " + sql.toString());
+        }
+
+        return sql.toString();
+    }
+
+    private String makeQueryString(JobConf jobConf, String tableName, List<String>
+            readColumnList, List<IndexSearchCondition> searchConditions, String queryTemplate,
+                                   String hints) throws IOException {
+        StringBuilder sql = new StringBuilder();
+        List<String> conditionColumnList = buildWhereClause(jobConf, sql, searchConditions);
+
+        if (conditionColumnList.size() > 0) {
+            addConditionColumnToReadColumn(readColumnList, conditionColumnList);
+            sql.insert(0, queryTemplate.replace("$HINT$", hints).replace("$COLUMN_LIST$",
+                    getSelectColumns(jobConf, tableName, readColumnList)).replace("$TABLE_NAME$",
+                    tableName));
+        } else {
+            sql.append(queryTemplate.replace("$HINT$", hints).replace("$COLUMN_LIST$",
+                    getSelectColumns(jobConf, tableName, readColumnList)).replace("$TABLE_NAME$",
+                    tableName));
+        }
+
+        if (LOG.isInfoEnabled()) {
+            LOG.info("Input query : " + sql.toString());
+        }
+
+        return sql.toString();
+    }
+
+    private String getSelectColumns(JobConf jobConf, String tableName, List<String>
+            readColumnList) throws IOException {
+        String selectColumns = Joiner.on(PhoenixStorageHandlerConstants.COMMA).join(readColumnList);
+
+        if (PhoenixStorageHandlerConstants.EMPTY_STRING.equals(selectColumns)) {
+            selectColumns = "*";
+        } else {
+            if (PhoenixStorageHandlerUtil.isTransactionalTable(jobConf)) {
+                List<String> pkColumnList = PhoenixUtil.getPrimaryKeyColumnList(jobConf, tableName);
+                StringBuilder pkColumns = new StringBuilder();
+
+                for (String pkColumn : pkColumnList) {
+                    String pkColumnName = pkColumn.toLowerCase();
+
+                    if (!readColumnList.contains(pkColumnName)) {
+                        pkColumns.append(pkColumnName).append(PhoenixStorageHandlerConstants.COMMA);
+                    }
+                }
+
+                selectColumns = pkColumns.toString() + selectColumns;
+            }
+        }
+
+        return selectColumns;
+    }
+
+    public String buildQuery(JobConf jobConf, String tableName, List<String> readColumnList,
+                             String whereClause, Map<String, String> columnTypeMap) throws
+            IOException {
+        String hints = getHint(jobConf, tableName);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Building query with columns : " + readColumnList + " table name : " +
+                    tableName + "  with where conditions : " + whereClause + "  hints : " + hints);
+        }
+
+        return makeQueryString(jobConf, tableName, Lists.newArrayList(readColumnList),
+                whereClause, QUERY_TEMPLATE, hints, columnTypeMap);
+    }
+
+    public String buildQuery(JobConf jobConf, String tableName, List<String> readColumnList,
+                             List<IndexSearchCondition> searchConditions) throws IOException {
+        String hints = getHint(jobConf, tableName);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Building query with columns : " + readColumnList + "  table name : " +
+                    tableName + " search conditions : " + searchConditions + "  hints : " + hints);
+        }
+
+        return makeQueryString(jobConf, tableName, Lists.newArrayList(readColumnList),
+                searchConditions, QUERY_TEMPLATE, hints);
+    }
+
+    private String getHint(JobConf jobConf, String tableName) {
+        StringBuilder hints = new StringBuilder("/*+ ");
+        if (!jobConf.getBoolean(PhoenixStorageHandlerConstants.HBASE_SCAN_CACHEBLOCKS, Boolean
+                .FALSE)) {
+            hints.append("NO_CACHE ");
+        }
+
+        String queryHint = jobConf.get(tableName + PhoenixStorageHandlerConstants
+                .PHOENIX_TABLE_QUERY_HINT);
+        if (queryHint != null) {
+            hints.append(queryHint);
+        }
+        hints.append(" */");
+
+        return hints.toString();
+    }
+
+    private List<String> buildWhereClause(JobConf jobConf, StringBuilder sql, String whereClause,
+                                          Map<String, String> columnTypeMap) throws IOException {
+        if (whereClause == null || whereClause.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        List<String> conditionColumnList = Lists.newArrayList();
+        sql.append(" where ");
+
+        whereClause = StringUtils.replaceEach(whereClause, new String[]{"UDFToString"}, new
+                String[]{"to_char"});
+
+        for (String columnName : columnTypeMap.keySet()) {
+            if (whereClause.contains(columnName)) {
+                conditionColumnList.add(columnName);
+
+                if (PhoenixStorageHandlerConstants.DATE_TYPE.equals(columnTypeMap.get(columnName)
+                )) {
+                    whereClause = applyDateFunctionUsingRegex(whereClause, columnName);
+                } else if (PhoenixStorageHandlerConstants.TIMESTAMP_TYPE.equals(columnTypeMap.get
+                        (columnName))) {
+                    whereClause = applyTimestampFunctionUsingRegex(whereClause, columnName);
+                }
+            }
+        }
+
+        sql.append(whereClause);
+
+        return conditionColumnList;
+    }
+
+    private String applyDateFunctionUsingRegex(String whereClause, String columnName) {
+        whereClause = applyFunctionForCommonOperator(whereClause, columnName, true);
+        whereClause = applyFunctionForBetweenOperator(whereClause, columnName, true);
+        whereClause = applyFunctionForInOperator(whereClause, columnName, true);
+
+        return whereClause;
+    }
+
+    private String applyTimestampFunctionUsingRegex(String whereClause, String columnName) {
+        whereClause = applyFunctionForCommonOperator(whereClause, columnName, false);
+        whereClause = applyFunctionForBetweenOperator(whereClause, columnName, false);
+        whereClause = applyFunctionForInOperator(whereClause, columnName, false);
+
+        return whereClause;
+    }
+
+    private String applyFunctionForCommonOperator(String whereClause, String columnName, boolean
+            isDate) {
+        String targetPattern = isDate ? PhoenixStorageHandlerConstants.DATE_PATTERN :
+                PhoenixStorageHandlerConstants.TIMESTAMP_PATTERN;
+        String pattern = StringUtils.replaceEach(PhoenixStorageHandlerConstants
+                        .COMMON_OPERATOR_PATTERN,
+                new String[]{PhoenixStorageHandlerConstants.COLUMNE_MARKER,
+                        PhoenixStorageHandlerConstants.PATERN_MARKER}, new String[]{columnName,
+                        targetPattern});
+
+        Matcher matcher = Pattern.compile(pattern).matcher(whereClause);
+
+        while (matcher.find()) {
+            String token = matcher.group(1);
+            String datePart = matcher.group(3);
+
+            String convertString = token.replace(datePart, applyFunction(isDate ?
+                    PhoenixStorageHandlerConstants.DATE_FUNCTION_TEMPLETE :
+                    PhoenixStorageHandlerConstants.TIMESTAMP_FUNCTION_TEMPLATE, datePart));
+            whereClause = whereClause.replaceAll(StringUtils.replaceEach(token, new String[]{"(",
+                    ")"}, new String[]{"\\(", "\\)"}), convertString);
+        }
+
+        return whereClause;
+    }
+
+    private String applyFunctionForBetweenOperator(String whereClause, String columnName, boolean
+            isDate) {
+        String targetPattern = isDate ? PhoenixStorageHandlerConstants.DATE_PATTERN :
+                PhoenixStorageHandlerConstants.TIMESTAMP_PATTERN;
+        String pattern = StringUtils.replaceEach(PhoenixStorageHandlerConstants
+                        .BETWEEN_OPERATOR_PATTERN,
+                new String[]{PhoenixStorageHandlerConstants.COLUMNE_MARKER,
+                        PhoenixStorageHandlerConstants.PATERN_MARKER}, new String[]{columnName,
+                        targetPattern});
+
+        Matcher matcher = Pattern.compile(pattern).matcher(whereClause);
+
+        while (matcher.find()) {
+            String token = matcher.group(1);
+            boolean isNot = matcher.group(2) == null ? false : true;
+            String fromDate = matcher.group(3);
+            String toDate = matcher.group(4);
+
+            String convertString = StringUtils.replaceEach(token, new String[]{fromDate, toDate},
+                    new String[]{applyFunction(isDate ? PhoenixStorageHandlerConstants
+                            .DATE_FUNCTION_TEMPLETE : PhoenixStorageHandlerConstants
+                            .TIMESTAMP_FUNCTION_TEMPLATE, fromDate),
+                            applyFunction(isDate ? PhoenixStorageHandlerConstants
+                                    .DATE_FUNCTION_TEMPLETE : PhoenixStorageHandlerConstants
+                                    .TIMESTAMP_FUNCTION_TEMPLATE, toDate)});
+
+            whereClause = whereClause.replaceAll(pattern, convertString);
+        }
+
+        return whereClause;
+    }
+
+    private String applyFunctionForInOperator(String whereClause, String columnName, boolean
+            isDate) {
+        String targetPattern = isDate ? PhoenixStorageHandlerConstants.DATE_PATTERN :
+                PhoenixStorageHandlerConstants.TIMESTAMP_PATTERN;
+        String pattern = StringUtils.replaceEach(PhoenixStorageHandlerConstants.IN_OPERATOR_PATTERN,
+                new String[]{PhoenixStorageHandlerConstants.COLUMNE_MARKER,
+                        PhoenixStorageHandlerConstants.PATERN_MARKER}, new String[]{columnName,
+                        targetPattern});
+        String itemPattern = "(" + targetPattern + ")";
+
+        Matcher matcher = Pattern.compile(pattern).matcher(whereClause);
+
+        while (matcher.find()) {
+            String token = matcher.group(1);
+            Matcher itemMatcher = Pattern.compile(itemPattern).matcher(token);
+            while (itemMatcher.find()) {
+                String item = itemMatcher.group(1);
+
+                token = token.replace(item, applyFunction(isDate ? PhoenixStorageHandlerConstants
+                        .DATE_FUNCTION_TEMPLETE : PhoenixStorageHandlerConstants
+                        .TIMESTAMP_FUNCTION_TEMPLATE, item));
+            }
+
+            whereClause = whereClause.replaceAll(pattern, token);
+        }
+
+        return whereClause;
+    }
+
+    /**
+     * replace value to specific part of pattern.
+     * if pattern is to_date($value$) and value is '2016-01-15'. then return to_date('2016-01-15').
+     * if pattern is cast($value$ as date) and value is '2016-01-15'. then return cast
+     * ('2016-01-15' as date).
+     */
+    private String applyFunction(String pattern, String value) {
+        if (!value.startsWith(PhoenixStorageHandlerConstants.QUOTATION_MARK)) {
+            value = PhoenixStorageHandlerConstants.QUOTATION_MARK + value +
+                    PhoenixStorageHandlerConstants.QUOTATION_MARK;
+        }
+
+        return pattern.replace(PhoenixStorageHandlerConstants.FUNCTION_VALUE_MARKER, value);
+    }
+
+    private String getCompareValueForDateAndTimestampFunction(String compareValue) {
+        if (compareValue.startsWith(PhoenixStorageHandlerConstants.QUOTATION_MARK)) {
+            return compareValue;
+        } else {
+            return PhoenixStorageHandlerConstants.QUOTATION_MARK + compareValue +
+                    PhoenixStorageHandlerConstants.QUOTATION_MARK;
+        }
+    }
+
+    private String applyDateFunction(String whereClause, String columnName) {
+        StringBuilder whereCondition = new StringBuilder();
+        for (Iterator<String> iterator = Splitter.on(CharMatcher.WHITESPACE).omitEmptyStrings()
+                .split(whereClause).iterator(); iterator.hasNext(); whereCondition.append
+                (PhoenixStorageHandlerConstants.SPACE)) {
+            String token = iterator.next();
+            if (isMyCondition(columnName, token)) {
+                whereCondition.append(token);
+
+                String comparator = iterator.next();
+                whereCondition.append(PhoenixStorageHandlerConstants.SPACE);
+                whereCondition.append(comparator).append(PhoenixStorageHandlerConstants.SPACE);
+                if (PhoenixStorageHandlerConstants.BETWEEN_COMPARATOR.equalsIgnoreCase
+                        (comparator)) {
+                    whereCondition.append("to_date(").append
+                            (getCompareValueForDateAndTimestampFunction(iterator.next())).append
+                            (") ").append(iterator.next()).append(PhoenixStorageHandlerConstants
+                            .SPACE)
+                            .append("to_date(");
+
+                    String toCompareValue = iterator.next();
+                    if (toCompareValue.endsWith(PhoenixStorageHandlerConstants
+                            .RIGHT_ROUND_BRACKET)) {
+                        int rightBracketIndex = toCompareValue.indexOf
+                                (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET);
+                        whereCondition.append(getCompareValueForDateAndTimestampFunction
+                                (toCompareValue.substring(0, rightBracketIndex))).append
+                                (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET).append
+                                (toCompareValue.substring(rightBracketIndex));
+                    } else {
+                        whereCondition.append(getCompareValueForDateAndTimestampFunction
+                                (toCompareValue)).append(PhoenixStorageHandlerConstants
+                                .RIGHT_ROUND_BRACKET);
+                    }
+                } else if (PhoenixStorageHandlerConstants.IN_COMPARATOR.equalsIgnoreCase
+                        (comparator)) {
+                    while (iterator.hasNext()) {
+                        String aToken = iterator.next();
+                        if (aToken.equals(PhoenixStorageHandlerConstants.LEFT_ROUND_BRACKET) ||
+                                aToken.equals(PhoenixStorageHandlerConstants.COMMA)) {
+                            whereCondition.append(aToken);
+                        } else if (aToken.equals(PhoenixStorageHandlerConstants
+                                .RIGHT_ROUND_BRACKET)) {
+                            whereCondition.append(aToken);
+                            break;
+                        } else if (aToken.endsWith(PhoenixStorageHandlerConstants
+                                .RIGHT_ROUND_BRACKET)) {
+                            int bracketIndex = aToken.indexOf(PhoenixStorageHandlerConstants
+                                    .RIGHT_ROUND_BRACKET);
+                            whereCondition.append("to_date(").append
+                                    (getCompareValueForDateAndTimestampFunction(aToken.substring
+                                            (0, bracketIndex))).append
+                                    (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET).append
+                                    (aToken.substring(bracketIndex));
+                            break;
+                        } else if (aToken.endsWith(PhoenixStorageHandlerConstants.COMMA)) {
+                            if (aToken.startsWith(PhoenixStorageHandlerConstants
+                                    .LEFT_ROUND_BRACKET)) {
+                                int bracketIndex = aToken.lastIndexOf
+                                        (PhoenixStorageHandlerConstants.LEFT_ROUND_BRACKET);
+                                whereCondition.append(aToken.substring(0, bracketIndex + 1))
+                                        .append("to_date(").append
+                                        (getCompareValueForDateAndTimestampFunction(aToken
+                                                .substring(bracketIndex + 1, aToken.length() - 1)
+                                        )).append("),");
+                            } else {
+                                whereCondition.append("to_date(").append
+                                        (getCompareValueForDateAndTimestampFunction(aToken
+                                                .substring(0, aToken.length() - 1))).append("),");
+                            }
+                        }
+
+                        whereCondition.append(PhoenixStorageHandlerConstants.SPACE);
+                    }
+                } else if (PhoenixStorageHandlerConstants.COMMON_COMPARATOR.contains(comparator)) {
+                    String compareValue = getCompareValueForDateAndTimestampFunction(iterator
+                            .next());
+                    whereCondition.append("to_date(");
+                    if (compareValue.endsWith(PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET)) {
+                        int rightBracketIndex = compareValue.indexOf
+                                (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET);
+                        whereCondition.append(getCompareValueForDateAndTimestampFunction
+                                (compareValue.substring(0, rightBracketIndex))).append
+                                (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET).append
+                                (compareValue.substring(rightBracketIndex));
+                    } else {
+                        whereCondition.append(getCompareValueForDateAndTimestampFunction
+                                (compareValue)).append(PhoenixStorageHandlerConstants
+                                .RIGHT_ROUND_BRACKET);
+                    }
+                }
+            } else {
+                whereCondition.append(token);
+            }
+        }
+
+        return whereCondition.toString();
+    }
+
+    // Assume timestamp value is yyyy-MM-dd HH:mm:ss.SSS
+    private String applyTimestampFunction(String whereClause, String columnName) {
+        StringBuilder whereCondition = new StringBuilder();
+        for (Iterator<String> iterator = Splitter.on(CharMatcher.WHITESPACE).omitEmptyStrings()
+                .split(whereClause).iterator(); iterator.hasNext(); whereCondition.append
+                (PhoenixStorageHandlerConstants.SPACE)) {
+            String token = iterator.next();
+            if (isMyCondition(columnName, token)) {
+                whereCondition.append(token);
+
+                String comparator = iterator.next();
+                whereCondition.append(PhoenixStorageHandlerConstants.SPACE);
+                whereCondition.append(comparator).append(PhoenixStorageHandlerConstants.SPACE);
+                if (PhoenixStorageHandlerConstants.BETWEEN_COMPARATOR.equalsIgnoreCase
+                        (comparator)) {
+                    String fromCompareValue = iterator.next() + PhoenixStorageHandlerConstants
+                            .SPACE + iterator.next();
+                    whereCondition.append("to_timestamp(").append
+                            (getCompareValueForDateAndTimestampFunction(fromCompareValue)).append
+                            (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET);
+                    whereCondition.append(PhoenixStorageHandlerConstants.SPACE).append(iterator
+                            .next()).append(PhoenixStorageHandlerConstants.SPACE);
+                    whereCondition.append("to_timestamp(");
+
+                    String toCompareValue = iterator.next() + PhoenixStorageHandlerConstants
+                            .SPACE + iterator.next();
+                    if (toCompareValue.endsWith(PhoenixStorageHandlerConstants
+                            .RIGHT_ROUND_BRACKET)) {
+                        int rightBracketIndex = toCompareValue.indexOf
+                                (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET);
+                        whereCondition.append(getCompareValueForDateAndTimestampFunction
+                                (toCompareValue.substring(0, rightBracketIndex))).append
+                                (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET).append
+                                (toCompareValue.substring(rightBracketIndex));
+                    } else {
+                        whereCondition.append(getCompareValueForDateAndTimestampFunction
+                                (toCompareValue)).append(PhoenixStorageHandlerConstants
+                                .RIGHT_ROUND_BRACKET);
+                    }
+                } else if (PhoenixStorageHandlerConstants.IN_COMPARATOR.equalsIgnoreCase
+                        (comparator)) {
+                    while (iterator.hasNext()) {
+                        String aToken = iterator.next();
+                        if (aToken.equals(PhoenixStorageHandlerConstants.LEFT_ROUND_BRACKET) ||
+                                aToken.equals(PhoenixStorageHandlerConstants.COMMA)) {
+                            whereCondition.append(aToken);
+                        } else if (aToken.equals(PhoenixStorageHandlerConstants
+                                .RIGHT_ROUND_BRACKET)) {
+                            whereCondition.append(aToken);
+                            break;
+                        } else {
+                            String compareValue = aToken + PhoenixStorageHandlerConstants.SPACE +
+                                    iterator.next();
+
+                            if (compareValue.startsWith(PhoenixStorageHandlerConstants
+                                    .LEFT_ROUND_BRACKET)) {
+                                int leftBracketIndex = compareValue.lastIndexOf
+                                        (PhoenixStorageHandlerConstants.LEFT_ROUND_BRACKET);
+                                whereCondition.append(compareValue.substring(0, leftBracketIndex
+                                        + 1)).append("to_timestamp(");
+
+                                if (compareValue.endsWith(PhoenixStorageHandlerConstants
+                                        .RIGHT_ROUND_BRACKET)) {
+                                    int rightBracketIndex = compareValue.indexOf
+                                            (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET);
+                                    whereCondition.append
+                                            (getCompareValueForDateAndTimestampFunction
+                                                    (compareValue.substring(leftBracketIndex + 1,
+                                                            rightBracketIndex)))
+                                            .append(PhoenixStorageHandlerConstants
+                                                    .RIGHT_ROUND_BRACKET).append(compareValue
+                                            .substring(rightBracketIndex));
+                                } else if (compareValue.endsWith(PhoenixStorageHandlerConstants
+                                        .COMMA)) {
+                                    whereCondition.append
+                                            (getCompareValueForDateAndTimestampFunction
+                                                    (compareValue.substring(leftBracketIndex + 1,
+                                                            compareValue.length() - 1)))
+                                            .append(PhoenixStorageHandlerConstants
+                                                    .RIGHT_ROUND_BRACKET).append
+                                            (PhoenixStorageHandlerConstants.COMMA);
+                                } else {
+                                    whereCondition.append
+                                            (getCompareValueForDateAndTimestampFunction
+                                                    (compareValue.substring(leftBracketIndex + 1)
+                                                    )).append(PhoenixStorageHandlerConstants
+                                            .RIGHT_ROUND_BRACKET);
+                                }
+                            } else if (compareValue.endsWith(PhoenixStorageHandlerConstants
+                                    .RIGHT_ROUND_BRACKET)) {
+                                int rightBracketIndex = compareValue.indexOf
+                                        (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET);
+                                whereCondition.append("to_timestamp(").append
+                                        (getCompareValueForDateAndTimestampFunction(compareValue
+                                                .substring(0, rightBracketIndex)))
+                                        .append(PhoenixStorageHandlerConstants
+                                                .RIGHT_ROUND_BRACKET).append(compareValue
+                                        .substring(rightBracketIndex));
+                                break;
+                            } else if (compareValue.endsWith(PhoenixStorageHandlerConstants
+                                    .COMMA)) {
+                                whereCondition.append("to_timestamp(").append
+                                        (getCompareValueForDateAndTimestampFunction(compareValue
+                                                .substring(0, compareValue.length() - 1))).append
+                                        ("),");
+                            }
+                        }
+
+                        whereCondition.append(PhoenixStorageHandlerConstants.SPACE);
+                    }
+                } else if (PhoenixStorageHandlerConstants.COMMON_COMPARATOR.contains(comparator)) {
+                    String timestampValue = iterator.next() + PhoenixStorageHandlerConstants
+                            .SPACE + iterator.next();
+                    whereCondition.append("to_timestamp(");
+                    if (timestampValue.endsWith(PhoenixStorageHandlerConstants
+                            .RIGHT_ROUND_BRACKET)) {
+                        int rightBracketIndex = timestampValue.indexOf
+                                (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET);
+                        whereCondition.append(getCompareValueForDateAndTimestampFunction
+                                (timestampValue.substring(0, rightBracketIndex))).append
+                                (PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET).append
+                                (timestampValue.substring(rightBracketIndex));
+                    } else {
+                        whereCondition.append(getCompareValueForDateAndTimestampFunction
+                                (timestampValue)).append(PhoenixStorageHandlerConstants
+                                .RIGHT_ROUND_BRACKET);
+                    }
+                }
+            } else {
+                whereCondition.append(token);
+            }
+        }
+
+        return whereCondition.toString();
+    }
+
+    private boolean isMyCondition(String columnName, String token) {
+        boolean itsMine = false;
+
+        if (columnName.equals(token)) {
+            itsMine = true;
+        } else if (token.startsWith(PhoenixStorageHandlerConstants.LEFT_ROUND_BRACKET) && token
+                .substring(token.lastIndexOf(PhoenixStorageHandlerConstants.LEFT_ROUND_BRACKET) +
+                        1).equals(columnName)) {
+            itsMine = true;
+        } else if (token.startsWith(PhoenixStorageHandlerConstants.LEFT_ROUND_BRACKET) && token
+                .endsWith(PhoenixStorageHandlerConstants.RIGHT_ROUND_BRACKET)
+                && token.substring(token.lastIndexOf(PhoenixStorageHandlerConstants
+                .LEFT_ROUND_BRACKET) + 1, token.indexOf(PhoenixStorageHandlerConstants
+                .RIGHT_ROUND_BRACKET)).equals(columnName)) {
+            itsMine = true;
+        }
+
+        return itsMine;
+    }
+
+    protected List<String> buildWhereClause(JobConf jobConf, StringBuilder sql,
+                                            List<IndexSearchCondition> searchConditions) throws
+            IOException {
+        if (searchConditions == null || searchConditions.size() == 0) {
+            return Collections.emptyList();
+        }
+
+        List<String> conditionColumnList = Lists.newArrayList();
+        sql.append(" where ");
+
+        boolean firstCondition = true;
+        for (IndexSearchCondition condition : searchConditions) {
+            String comparisonOp = condition.getComparisonOp();
+
+            if (comparisonOp.endsWith("GenericUDFBetween") || comparisonOp.endsWith
+                    ("GenericUDFIn")) {
+                if (condition.getConstantDescs() == null) {
+                    continue;
+                }
+            } else if (comparisonOp.endsWith("GenericUDFOPNull") || comparisonOp.endsWith
+                    ("GenericUDFOPNotNull")) {
+                // keep going
+            } else if (comparisonOp.endsWith("GenericUDFOPEqual")) {
+                // keep going
+            } else {
+                if (condition.getConstantDesc().getValue() == null) {
+                    continue;
+                }
+            }
+
+            if (!firstCondition) {
+                sql.append(" and ");
+            } else {
+                firstCondition = false;
+            }
+
+            String columnName = condition.getColumnDesc().getColumn();
+            String typeName = condition.getColumnDesc().getTypeString();
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug(columnName + " has condition: " + condition);
+            }
+
+            conditionColumnList.add(columnName);
+            sql.append(columnName);
+
+            String[] constantValues = PhoenixStorageHandlerUtil.getConstantValues(condition,
+                    comparisonOp);
+
+            if (comparisonOp.endsWith("UDFOPEqual")) {        // column = 1
+                appendCondition(sql, " = ", typeName, constantValues[0]);
+            } else if (comparisonOp.endsWith("UDFOPEqualOrGreaterThan")) {    // column >= 1
+                appendCondition(sql, " >= ", typeName, constantValues[0]);
+            } else if (comparisonOp.endsWith("UDFOPGreaterThan")) {        // column > 1
+                appendCondition(sql, " > ", typeName, constantValues[0]);
+            } else if (comparisonOp.endsWith("UDFOPEqualOrLessThan")) {    // column <= 1
+                appendCondition(sql, " <= ", typeName, constantValues[0]);
+            } else if (comparisonOp.endsWith("UDFOPLessThan")) {    // column < 1
+                appendCondition(sql, " < ", typeName, constantValues[0]);
+            } else if (comparisonOp.endsWith("UDFOPNotEqual")) {    // column != 1
+                appendCondition(sql, " != ", typeName, constantValues[0]);
+            } else if (comparisonOp.endsWith("GenericUDFBetween")) {
+                appendBetweenCondition(jobConf, sql, condition.isNot(), typeName, constantValues);
+            } else if (comparisonOp.endsWith("GenericUDFIn")) {
+                appendInCondition(sql, condition.isNot(), typeName, constantValues);
+            } else if (comparisonOp.endsWith("GenericUDFOPNull")) {
+                sql.append(" is null ");
+            } else if (comparisonOp.endsWith("GenericUDFOPNotNull")) {
+                sql.append(" is not null ");
+            }
+        }
+
+        return conditionColumnList;
+    }
+
+    protected void appendCondition(StringBuilder sql, String comparisonOp, String typeName,
+                                   String conditionValue) {
+        if (serdeConstants.STRING_TYPE_NAME.equals(typeName)) {
+            sql.append(comparisonOp).append("'").append(conditionValue).append("'");
+        } else if (serdeConstants.DATE_TYPE_NAME.equals(typeName)) {
+            sql.append(comparisonOp).append("to_date('").append(conditionValue).append("')");
+        } else if (serdeConstants.TIMESTAMP_TYPE_NAME.equals(typeName)) {
+            sql.append(comparisonOp).append("to_timestamp('").append(conditionValue).append("')");
+        } else {
+            sql.append(comparisonOp).append(conditionValue);
+        }
+    }
+
+    protected void appendBetweenCondition(JobConf jobConf, StringBuilder sql, boolean isNot,
+                                          String typeName, String[] conditionValues) throws
+            IOException {
+        if (isNot) {
+            sql.append(" not between ");
+        } else {
+            sql.append(" between ");
+        }
+
+        try {
+            Arrays.sort(PhoenixStorageHandlerUtil.toTypedValues(jobConf, typeName,
+                    conditionValues));
+
+            if (serdeConstants.STRING_TYPE_NAME.equals(typeName)) {
+                sql.append("'").append(conditionValues[0]).append("'").append(" and ").append
+                        ("'").append(conditionValues[1]).append("'");
+            } else if (serdeConstants.DATE_TYPE_NAME.equals(typeName)) {
+                sql.append("to_date('").append(conditionValues[0]).append("')").append(" and ")
+                        .append("to_date('").append(conditionValues[1]).append("')");
+            } else if (serdeConstants.TIMESTAMP_TYPE_NAME.equals(typeName)) {
+                sql.append("to_timestamp('").append(conditionValues[0]).append("')").append(" and" +
+                        " ").append("to_timestamp('").append(conditionValues[1]).append("')");
+            } else {
+                sql.append(conditionValues[0]).append(" and ").append(conditionValues[1]);
+            }
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+    }
+
+    protected void appendInCondition(StringBuilder sql, boolean isNot, String typeName, String[]
+            conditionValues) {
+        if (isNot) {
+            sql.append(" not in (");
+        } else {
+            sql.append(" in (");
+        }
+
+        for (String conditionValue : conditionValues) {
+            if (serdeConstants.STRING_TYPE_NAME.equals(typeName)) {
+                sql.append("'").append(conditionValue).append("'");
+            } else if (serdeConstants.DATE_TYPE_NAME.equals(typeName)) {
+                sql.append("to_date('").append(conditionValue).append("')");
+            } else if (serdeConstants.TIMESTAMP_TYPE_NAME.equals(typeName)) {
+                sql.append("to_timestamp('").append(conditionValue).append("')");
+            } else {
+                sql.append(conditionValue);
+            }
+
+            sql.append(", ");
+        }
+
+        sql.delete(sql.length() - 2, sql.length());
+
+        sql.append(")");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixConnectionUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixConnectionUtil.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixConnectionUtil.java
new file mode 100644
index 0000000..51f6c7e
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixConnectionUtil.java
@@ -0,0 +1,97 @@
+/*
+ * 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.phoenix.hive.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.QueryUtil;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Set of methods to obtain Connection depending on configuration
+ */
+
+public class PhoenixConnectionUtil {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixConnectionUtil.class);
+
+    public static Connection getInputConnection(final Configuration conf, final Properties props)
+            throws SQLException {
+        String quorum = conf.get(PhoenixStorageHandlerConstants.ZOOKEEPER_QUORUM);
+        quorum = quorum == null ? props.getProperty(PhoenixStorageHandlerConstants
+                .ZOOKEEPER_QUORUM, PhoenixStorageHandlerConstants.DEFAULT_ZOOKEEPER_QUORUM) :
+                quorum;
+
+        int zooKeeperClientPort = conf.getInt(PhoenixStorageHandlerConstants.ZOOKEEPER_PORT, 0);
+        zooKeeperClientPort = zooKeeperClientPort == 0 ?
+                Integer.parseInt(props.getProperty(PhoenixStorageHandlerConstants.ZOOKEEPER_PORT,
+                        String.valueOf(PhoenixStorageHandlerConstants.DEFAULT_ZOOKEEPER_PORT))) :
+                zooKeeperClientPort;
+
+        String zNodeParent = conf.get(PhoenixStorageHandlerConstants.ZOOKEEPER_PARENT);
+        zNodeParent = zNodeParent == null ? props.getProperty(PhoenixStorageHandlerConstants
+                .ZOOKEEPER_PARENT, PhoenixStorageHandlerConstants.DEFAULT_ZOOKEEPER_PARENT) :
+                zNodeParent;
+
+        return getConnection(quorum, zooKeeperClientPort, zNodeParent, PropertiesUtil
+                .extractProperties(props, conf));
+    }
+
+    public static Connection getConnection(final Table table) throws SQLException {
+        Map<String, String> tableParameterMap = table.getParameters();
+
+        String zookeeperQuorum = tableParameterMap.get(PhoenixStorageHandlerConstants
+                .ZOOKEEPER_QUORUM);
+        zookeeperQuorum = zookeeperQuorum == null ? PhoenixStorageHandlerConstants
+                .DEFAULT_ZOOKEEPER_QUORUM : zookeeperQuorum;
+
+        String clientPortString = tableParameterMap.get(PhoenixStorageHandlerConstants
+                .ZOOKEEPER_PORT);
+        int clientPort = clientPortString == null ? PhoenixStorageHandlerConstants
+                .DEFAULT_ZOOKEEPER_PORT : Integer.parseInt(clientPortString);
+
+        String zNodeParent = tableParameterMap.get(PhoenixStorageHandlerConstants.ZOOKEEPER_PARENT);
+        zNodeParent = zNodeParent == null ? PhoenixStorageHandlerConstants
+                .DEFAULT_ZOOKEEPER_PARENT : zNodeParent;
+
+        return DriverManager.getConnection(QueryUtil.getUrl(zookeeperQuorum, clientPort,
+                zNodeParent));
+    }
+
+    private static Connection getConnection(final String quorum, final Integer clientPort, String
+            zNodeParent, Properties props) throws SQLException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Connection attrs [quorum, port, znode] : " + quorum + ", " + clientPort +
+                    ", " +
+                    zNodeParent);
+        }
+
+        return DriverManager.getConnection(clientPort != null ? QueryUtil.getUrl(quorum,
+                clientPort, zNodeParent) : QueryUtil.getUrl(quorum), props);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixStorageHandlerUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixStorageHandlerUtil.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixStorageHandlerUtil.java
new file mode 100644
index 0000000..eb5fd24
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/util/PhoenixStorageHandlerUtil.java
@@ -0,0 +1,278 @@
+/*
+ * 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.phoenix.hive.util;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Maps;
+import org.apache.commons.logging.Log;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HRegionLocation;
+import org.apache.hadoop.hbase.util.Strings;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
+import org.apache.hadoop.hive.ql.io.AcidOutputFormat.Options;
+import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc;
+import org.apache.hadoop.hive.ql.session.SessionState;
+import org.apache.hadoop.hive.serde.serdeConstants;
+import org.apache.hadoop.mapred.JobConf;
+import org.apache.hadoop.net.DNS;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.hive.ql.index.IndexSearchCondition;
+
+import javax.naming.NamingException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+/**
+ * Misc utils for PhoenixStorageHandler
+ */
+
+public class PhoenixStorageHandlerUtil {
+
+    public static String getTargetTableName(Table table) {
+        Map<String, String> tableParameterMap = table.getParameters();
+        String tableName = tableParameterMap.get(PhoenixStorageHandlerConstants
+                .PHOENIX_TABLE_NAME);
+        if (tableName == null) {
+            tableName = table.getTableName();
+            tableParameterMap.put(PhoenixStorageHandlerConstants.PHOENIX_TABLE_NAME, tableName);
+        }
+
+        return tableName;
+    }
+
+
+    public static Object[] toTypedValues(JobConf jobConf, String typeName, String[] values) throws
+            Exception {
+        Object[] results = new Object[values.length];
+        DateFormat df = null;
+
+        for (int i = 0, limit = values.length; i < limit; i++) {
+            if (serdeConstants.STRING_TYPE_NAME.equals(typeName)) {
+                results[i] = values[i];
+            } else if (serdeConstants.INT_TYPE_NAME.equals(typeName)) {
+                results[i] = new Integer(values[i]);
+            } else if (serdeConstants.BIGINT_TYPE_NAME.equals(typeName)) {
+                results[i] = new Long(values[i]);
+            } else if (serdeConstants.DOUBLE_TYPE_NAME.equals(typeName)) {
+                results[i] = new Double(values[i]);
+            } else if (serdeConstants.FLOAT_TYPE_NAME.equals(typeName)) {
+                results[i] = new Float(values[i]);
+            } else if (serdeConstants.SMALLINT_TYPE_NAME.equals(typeName)) {
+                results[i] = new Short(values[i]);
+            } else if (serdeConstants.TINYINT_TYPE_NAME.equals(typeName)) {
+                results[i] = new Byte(values[i]);
+            } else if (serdeConstants.DATE_TYPE_NAME.equals(typeName)) {
+                String dateFormat = jobConf.get(PhoenixStorageHandlerConstants.HBASE_DATE_FORMAT,
+                        PhoenixStorageHandlerConstants.DEFAULT_DATE_FORMAT);
+                df = new SimpleDateFormat(dateFormat);
+                results[i] = new Long(df.parse(values[i]).getTime());
+            } else if (serdeConstants.TIMESTAMP_TYPE_NAME.equals(typeName)) {
+                String timestampFormat = jobConf.get(PhoenixStorageHandlerConstants
+                        .HBASE_TIMESTAMP_FORMAT, PhoenixStorageHandlerConstants
+                        .DEFAULT_TIMESTAMP_FORMAT);
+                df = new SimpleDateFormat(timestampFormat);
+                results[i] = new Long(df.parse(values[i]).getTime());
+            } else if (typeName.contains(serdeConstants.DECIMAL_TYPE_NAME)) {
+                results[i] = new BigDecimal(values[i]);
+            }
+        }
+
+        return results;
+    }
+
+    public static String[] getConstantValues(IndexSearchCondition condition, String comparisonOp) {
+        String[] constantValues = null;
+
+        if (comparisonOp.endsWith("UDFOPEqual") || comparisonOp.endsWith("UDFOPNotEqual")) {
+            constantValues = new String[]{String.valueOf(condition.getConstantDesc().getValue())};
+        } else if (comparisonOp.endsWith("UDFOPEqualOrGreaterThan")) {    // key >= 1
+            constantValues = new String[]{String.valueOf(condition.getConstantDesc().getValue())};
+        } else if (comparisonOp.endsWith("UDFOPGreaterThan")) {        // key > 1
+            constantValues = new String[]{String.valueOf(condition.getConstantDesc().getValue())};
+        } else if (comparisonOp.endsWith("UDFOPEqualOrLessThan")) {    // key <= 1
+            constantValues = new String[]{String.valueOf(condition.getConstantDesc().getValue())};
+        } else if (comparisonOp.endsWith("UDFOPLessThan")) {    // key < 1
+            constantValues = new String[]{String.valueOf(condition.getConstantDesc().getValue())};
+        } else if (comparisonOp.endsWith("GenericUDFBetween")) {
+            constantValues = new String[]{String.valueOf(condition.getConstantDesc(0).getValue()),
+                    String.valueOf(condition.getConstantDesc(1).getValue())};
+        } else if (comparisonOp.endsWith("GenericUDFIn")) {
+            ExprNodeConstantDesc[] constantDescs = condition.getConstantDescs();
+            constantValues = new String[constantDescs.length];
+            for (int i = 0, limit = constantDescs.length; i < limit; i++) {
+                constantValues[i] = String.valueOf(condition.getConstantDesc(i).getValue());
+            }
+        }
+
+        return constantValues;
+    }
+
+    public static String getRegionLocation(HRegionLocation location, Log log) throws IOException {
+        InetSocketAddress isa = new InetSocketAddress(location.getHostname(), location.getPort());
+        if (isa.isUnresolved()) {
+            log.warn("Failed resolve " + isa);
+        }
+        InetAddress regionAddress = isa.getAddress();
+        String regionLocation = null;
+        try {
+            regionLocation = reverseDNS(regionAddress);
+        } catch (NamingException e) {
+            log.warn("Cannot resolve the host name for " + regionAddress + " because of " + e);
+            regionLocation = location.getHostname();
+        }
+
+        return regionLocation;
+    }
+
+    // Copy from org.apache.hadoop.hbase.mapreduce.TableInputFormatBase.reverseDNS
+    private static final Map<InetAddress, String> reverseDNSCacheMap = Maps.newConcurrentMap();
+
+    private static String reverseDNS(InetAddress ipAddress) throws NamingException,
+            UnknownHostException {
+        String hostName = reverseDNSCacheMap.get(ipAddress);
+
+        if (hostName == null) {
+            String ipAddressString = null;
+            try {
+                ipAddressString = DNS.reverseDns(ipAddress, null);
+            } catch (Exception e) {
+                // We can use InetAddress in case the jndi failed to pull up the reverse DNS entry
+                // from the name service. Also, in case of ipv6, we need to use the InetAddress
+                // since resolving reverse DNS using jndi doesn't work well with ipv6 addresses.
+                ipAddressString = InetAddress.getByName(ipAddress.getHostAddress()).getHostName();
+            }
+
+            if (ipAddressString == null) {
+                throw new UnknownHostException("No host found for " + ipAddress);
+            }
+
+            hostName = Strings.domainNamePointerToHostName(ipAddressString);
+            reverseDNSCacheMap.put(ipAddress, hostName);
+        }
+
+        return hostName;
+    }
+
+    public static String getTableKeyOfSession(JobConf jobConf, String tableName) {
+        SessionState sessionState = SessionState.get();
+
+        String sessionId = sessionState.getSessionId();
+
+        return new StringBuilder("[").append(sessionId).append("]-").append(tableName).toString();
+    }
+
+    public static Map<String, String> createColumnTypeMap(JobConf jobConf) {
+        Map<String, String> columnTypeMap = Maps.newHashMap();
+
+        String[] columnNames = jobConf.get(serdeConstants.LIST_COLUMNS).split
+                (PhoenixStorageHandlerConstants.COMMA);
+        String[] columnTypes = jobConf.get(serdeConstants.LIST_COLUMN_TYPES).split
+                (PhoenixStorageHandlerConstants.COMMA);
+
+        for (int i = 0, limit = columnNames.length; i < limit; i++) {
+            columnTypeMap.put(columnNames[i], columnTypes[i]);
+        }
+
+        return columnTypeMap;
+    }
+
+    public static boolean isTransactionalTable(Properties tableProperties) {
+        String tableIsTransactional = tableProperties.getProperty(hive_metastoreConstants
+                .TABLE_IS_TRANSACTIONAL);
+
+        return tableIsTransactional != null && tableIsTransactional.equalsIgnoreCase("true");
+    }
+
+    public static boolean isTransactionalTable(Configuration config) {
+        String tableIsTransactional = config.get(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL);
+
+        return tableIsTransactional != null && tableIsTransactional.equalsIgnoreCase("true");
+    }
+
+    public static void printConfiguration(Configuration config) {
+        if (Boolean.getBoolean("dev")) {
+            for (Iterator<Entry<String, String>> iterator = config.iterator(); iterator.hasNext();
+                    ) {
+                Entry<String, String> entry = iterator.next();
+
+                System.out.println(entry.getKey() + "=" + entry.getValue());
+            }
+        }
+    }
+
+    public static String toString(Object obj) {
+        String content = null;
+
+        if (obj instanceof Array) {
+            Object[] values = (Object[]) obj;
+
+            content = Joiner.on(PhoenixStorageHandlerConstants.COMMA).join(values);
+        } else {
+            content = obj.toString();
+        }
+
+        return content;
+    }
+
+    public static Map<?, ?> toMap(byte[] serialized) {
+        Map<?, ?> resultMap = null;
+        ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
+
+        try (ObjectInputStream ois = new ObjectInputStream(bais)) {
+            resultMap = (Map<?, ?>) ois.readObject();
+        } catch (ClassNotFoundException | IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        return resultMap;
+    }
+
+    public static String getOptionsValue(Options options) {
+        StringBuilder content = new StringBuilder();
+
+        int bucket = options.getBucket();
+        String inspectorInfo = options.getInspector().getCategory() + ":" + options.getInspector()
+                .getTypeName();
+        long maxTxnId = options.getMaximumTransactionId();
+        long minTxnId = options.getMinimumTransactionId();
+        int recordIdColumn = options.getRecordIdColumn();
+        boolean isCompresses = options.isCompressed();
+        boolean isWritingBase = options.isWritingBase();
+
+        content.append("bucket : ").append(bucket).append(", inspectorInfo : ").append
+                (inspectorInfo).append(", minTxnId : ").append(minTxnId).append(", maxTxnId : ")
+                .append(maxTxnId).append(", recordIdColumn : ").append(recordIdColumn);
+        content.append(", isCompressed : ").append(isCompresses).append(", isWritingBase : ")
+                .append(isWritingBase);
+
+        return content.toString();
+    }
+}


[30/52] [abbrv] phoenix git commit: PHOENIX-2743 HivePhoenixHandler for big-big join with

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixRecordWriter.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixRecordWriter.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixRecordWriter.java
new file mode 100644
index 0000000..c6884df
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixRecordWriter.java
@@ -0,0 +1,355 @@
+/*
+ * 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.phoenix.hive.mapreduce;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hive.ql.io.AcidOutputFormat;
+import org.apache.hadoop.hive.ql.io.RecordUpdater;
+import org.apache.hadoop.hive.serde2.SerDeException;
+import org.apache.hadoop.hive.serde2.SerDeStats;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.mapred.RecordWriter;
+import org.apache.hadoop.mapred.Reporter;
+import org.apache.hadoop.mapreduce.lib.db.DBWritable;
+import org.apache.phoenix.hive.PhoenixSerializer;
+import org.apache.phoenix.hive.PhoenixSerializer.DmlType;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.hive.util.PhoenixConnectionUtil;
+import org.apache.phoenix.hive.util.PhoenixStorageHandlerUtil;
+import org.apache.phoenix.hive.util.PhoenixUtil;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
+import org.apache.phoenix.schema.ConcurrentTableMutationException;
+import org.apache.phoenix.schema.MetaDataClient;
+import org.apache.phoenix.util.QueryUtil;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Properties;
+
+/**
+ *
+ * RecordWriter implementation. Writes records to the output
+ * WARNING : There is possibility that WAL disable setting not working properly due concurrent
+ * enabling/disabling WAL.
+ *
+ */
+public class PhoenixRecordWriter<T extends DBWritable> implements RecordWriter<NullWritable, T>,
+        org.apache.hadoop.hive.ql.exec.FileSinkOperator.RecordWriter, RecordUpdater {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixRecordWriter.class);
+
+    private Connection conn;
+    private PreparedStatement pstmt;
+    private long batchSize;
+    private long numRecords = 0;
+
+    private Configuration config;
+    private String tableName;
+    private MetaDataClient metaDataClient;
+    private boolean restoreWalMode;
+
+    // For RecordUpdater
+    private long rowCountDelta = 0;
+    private PhoenixSerializer phoenixSerializer;
+    private ObjectInspector objInspector;
+    private PreparedStatement pstmtForDelete;
+
+    // For RecordUpdater
+    public PhoenixRecordWriter(Path path, AcidOutputFormat.Options options) throws IOException {
+        Configuration config = options.getConfiguration();
+        Properties props = new Properties();
+
+        try {
+            initialize(config, props);
+        } catch (SQLException e) {
+            throw new IOException(e);
+        }
+
+        this.objInspector = options.getInspector();
+        try {
+            phoenixSerializer = new PhoenixSerializer(config, options.getTableProperties());
+        } catch (SerDeException e) {
+            throw new IOException(e);
+        }
+    }
+
+    public PhoenixRecordWriter(final Configuration configuration, final Properties props) throws
+            SQLException {
+        initialize(configuration, props);
+    }
+
+    private void initialize(Configuration config, Properties properties) throws SQLException {
+        this.config = config;
+        tableName = config.get(PhoenixStorageHandlerConstants.PHOENIX_TABLE_NAME);
+
+        // Disable WAL
+        String walConfigName = tableName.toLowerCase() + PhoenixStorageHandlerConstants.DISABLE_WAL;
+        boolean disableWal = config.getBoolean(walConfigName, false);
+        if (disableWal) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Property " + walConfigName + " is true. batch.mode will be set true. ");
+            }
+
+            properties.setProperty(PhoenixStorageHandlerConstants.BATCH_MODE, "true");
+        }
+
+        this.conn = PhoenixConnectionUtil.getInputConnection(config, properties);
+
+        if (disableWal) {
+            metaDataClient = new MetaDataClient((PhoenixConnection) conn);
+
+            if (!PhoenixUtil.isDisabledWal(metaDataClient, tableName)) {
+                // execute alter tablel statement if disable_wal is not true.
+                try {
+                    PhoenixUtil.alterTableForWalDisable(conn, tableName, true);
+                } catch (ConcurrentTableMutationException e) {
+                    if (LOG.isWarnEnabled()) {
+                        LOG.warn("Another mapper or task processing wal disable");
+                    }
+                }
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug(tableName + "s wal disabled.");
+                }
+
+                // restore original value of disable_wal at the end.
+                restoreWalMode = true;
+            }
+        }
+
+        this.batchSize = PhoenixConfigurationUtil.getBatchSize(config);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Batch-size : " + batchSize);
+        }
+
+        String upsertQuery = QueryUtil.constructUpsertStatement(tableName, PhoenixUtil
+                .getColumnInfoList(conn, tableName));
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Upsert-query : " + upsertQuery);
+        }
+        this.pstmt = this.conn.prepareStatement(upsertQuery);
+    }
+
+    @Override
+    public void write(NullWritable key, T record) throws IOException {
+        try {
+            record.write(pstmt);
+            numRecords++;
+            pstmt.executeUpdate();
+
+            if (numRecords % batchSize == 0) {
+                LOG.debug("Commit called on a batch of size : " + batchSize);
+                conn.commit();
+            }
+        } catch (SQLException e) {
+            throw new IOException("Exception while writing to table.", e);
+        }
+    }
+
+    @Override
+    public void close(Reporter reporter) throws IOException {
+        try {
+            conn.commit();
+
+            if (LOG.isInfoEnabled()) {
+                LOG.info("Wrote row : " + numRecords);
+            }
+        } catch (SQLException e) {
+            LOG.error("SQLException while performing the commit for the task.");
+            throw new IOException(e);
+        } finally {
+            try {
+                if (restoreWalMode && PhoenixUtil.isDisabledWal(metaDataClient, tableName)) {
+                    try {
+                        PhoenixUtil.alterTableForWalDisable(conn, tableName, false);
+                    } catch (ConcurrentTableMutationException e) {
+                        if (LOG.isWarnEnabled()) {
+                            LOG.warn("Another mapper or task processing wal enable");
+                        }
+                    }
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug(tableName + "s wal enabled.");
+                    }
+                }
+
+                // flush if [table-name].auto.flush is true.
+                String autoFlushConfigName = tableName.toLowerCase() +
+                        PhoenixStorageHandlerConstants.AUTO_FLUSH;
+                boolean autoFlush = config.getBoolean(autoFlushConfigName, false);
+                if (autoFlush) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("autoFlush is true.");
+                    }
+
+                    PhoenixUtil.flush(conn, tableName);
+                }
+
+                PhoenixUtil.closeResource(pstmt);
+                PhoenixUtil.closeResource(pstmtForDelete);
+                PhoenixUtil.closeResource(conn);
+            } catch (SQLException ex) {
+                LOG.error("SQLException while closing the connection for the task.");
+                throw new IOException(ex);
+            }
+        }
+    }
+
+    // For Testing
+    public boolean isRestoreWalMode() {
+        return restoreWalMode;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void write(Writable w) throws IOException {
+        PhoenixResultWritable row = (PhoenixResultWritable) w;
+
+        write(NullWritable.get(), (T) row);
+    }
+
+    @Override
+    public void close(boolean abort) throws IOException {
+        close(Reporter.NULL);
+    }
+
+    @Override
+    public void insert(long currentTransaction, Object row) throws IOException {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("insert transaction : " + currentTransaction + ", row : " +
+                    PhoenixStorageHandlerUtil.toString(row));
+        }
+
+        PhoenixResultWritable pResultWritable = (PhoenixResultWritable) phoenixSerializer
+                .serialize(row, objInspector, DmlType.INSERT);
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Data : " + pResultWritable.getValueList());
+        }
+
+        write(pResultWritable);
+        rowCountDelta++;
+    }
+
+    @Override
+    public void update(long currentTransaction, Object row) throws IOException {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("update transaction : " + currentTransaction + ", row : " +
+                    PhoenixStorageHandlerUtil
+                            .toString(row));
+        }
+
+        PhoenixResultWritable pResultWritable = (PhoenixResultWritable) phoenixSerializer
+                .serialize(row, objInspector, DmlType.UPDATE);
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Data : " + pResultWritable.getValueList());
+        }
+
+        write(pResultWritable);
+    }
+
+    @Override
+    public void delete(long currentTransaction, Object row) throws IOException {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("delete transaction : " + currentTransaction + ", row : " +
+                    PhoenixStorageHandlerUtil.toString(row));
+        }
+
+        PhoenixResultWritable pResultWritable = (PhoenixResultWritable) phoenixSerializer
+                .serialize(row, objInspector, DmlType.DELETE);
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Data : " + pResultWritable.getValueList());
+        }
+
+        if (pstmtForDelete == null) {
+            try {
+                String deleteQuery = PhoenixUtil.constructDeleteStatement(conn, tableName);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Delete query : " + deleteQuery);
+                }
+
+                pstmtForDelete = conn.prepareStatement(deleteQuery);
+            } catch (SQLException e) {
+                throw new IOException(e);
+            }
+        }
+
+        delete(pResultWritable);
+
+        rowCountDelta--;
+    }
+
+    private void delete(PhoenixResultWritable pResultWritable) throws IOException {
+        try {
+            pResultWritable.delete(pstmtForDelete);
+            numRecords++;
+            pstmtForDelete.executeUpdate();
+
+            if (numRecords % batchSize == 0) {
+                LOG.debug("Commit called on a batch of size : " + batchSize);
+                conn.commit();
+            }
+        } catch (SQLException e) {
+            throw new IOException("Exception while deleting to table.", e);
+        }
+    }
+
+    @Override
+    public void flush() throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Flush called");
+        }
+
+        try {
+            conn.commit();
+
+            if (LOG.isInfoEnabled()) {
+                LOG.info("Written row : " + numRecords);
+            }
+        } catch (SQLException e) {
+            LOG.error("SQLException while performing the commit for the task.");
+            throw new IOException(e);
+        }
+    }
+
+    @Override
+    public SerDeStats getStats() {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("getStats called");
+        }
+
+        SerDeStats stats = new SerDeStats();
+        stats.setRowCount(rowCountDelta);
+        // Don't worry about setting raw data size diff.  There is no reasonable way  to calculate
+        // that without finding the row we are updating or deleting, which would be a mess.
+        return stats;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixResultWritable.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixResultWritable.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixResultWritable.java
new file mode 100644
index 0000000..18ded89
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/mapreduce/PhoenixResultWritable.java
@@ -0,0 +1,211 @@
+/*
+ * 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.phoenix.hive.mapreduce;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.mapreduce.lib.db.DBWritable;
+import org.apache.phoenix.hive.PhoenixRowKey;
+import org.apache.phoenix.hive.constants.PhoenixStorageHandlerConstants;
+import org.apache.phoenix.hive.util.PhoenixStorageHandlerUtil;
+import org.apache.phoenix.hive.util.PhoenixUtil;
+import org.apache.phoenix.util.ColumnInfo;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Serialized class for SerDe
+ *
+ */
+public class PhoenixResultWritable implements Writable, DBWritable, Configurable {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixResultWritable.class);
+
+    private List<ColumnInfo> columnMetadataList;
+    private List<Object> valueList;    // for output
+    private Map<String, Object> rowMap = Maps.newHashMap();  // for input
+
+    private int columnCount = -1;
+
+    private Configuration config;
+    private boolean isTransactional;
+    private Map<String, Object> rowKeyMap = Maps.newLinkedHashMap();
+    private List<String> primaryKeyColumnList;
+
+    public PhoenixResultWritable() {
+    }
+
+    public PhoenixResultWritable(Configuration config) throws IOException {
+        setConf(config);
+    }
+
+    public PhoenixResultWritable(Configuration config, List<ColumnInfo> columnMetadataList)
+            throws IOException {
+        this(config);
+        this.columnMetadataList = columnMetadataList;
+
+        valueList = Lists.newArrayListWithExpectedSize(columnMetadataList.size());
+    }
+
+    @Override
+    public void write(DataOutput out) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void readFields(DataInput in) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    // for write
+    public void clear() {
+        valueList.clear();
+    }
+
+    // for write
+    public void add(Object value) {
+        valueList.add(value);
+    }
+
+    @Override
+    public void write(PreparedStatement statement) throws SQLException {
+        ColumnInfo columnInfo = null;
+        Object value = null;
+
+        try {
+            for (int i = 0, limit = columnMetadataList.size(); i < limit; i++) {
+                columnInfo = columnMetadataList.get(i);
+
+                if (valueList.size() > i) {
+                    value = valueList.get(i);
+                } else {
+                    value = null;
+                }
+
+                if (value == null) {
+                    statement.setNull(i + 1, columnInfo.getSqlType());
+                } else {
+                    statement.setObject(i + 1, value, columnInfo.getSqlType());
+                }
+            }
+        } catch (SQLException | RuntimeException e) {
+            LOG.error("[column-info, value] : " + columnInfo + ", " + value);
+            throw e;
+        }
+    }
+
+    public void delete(PreparedStatement statement) throws SQLException {
+        ColumnInfo columnInfo = null;
+        Object value = null;
+
+        try {
+            for (int i = 0, limit = primaryKeyColumnList.size(); i < limit; i++) {
+                columnInfo = columnMetadataList.get(i);
+
+                if (valueList.size() > i) {
+                    value = valueList.get(i);
+                } else {
+                    value = null;
+                }
+
+                if (value == null) {
+                    statement.setNull(i + 1, columnInfo.getSqlType());
+                } else {
+                    statement.setObject(i + 1, value, columnInfo.getSqlType());
+                }
+            }
+        } catch (SQLException | RuntimeException e) {
+            LOG.error("[column-info, value] : " + columnInfo + ", " + value);
+            throw e;
+        }
+    }
+
+    @Override
+    public void readFields(ResultSet resultSet) throws SQLException {
+        ResultSetMetaData rsmd = resultSet.getMetaData();
+        if (columnCount == -1) {
+            this.columnCount = rsmd.getColumnCount();
+        }
+        rowMap.clear();
+
+        for (int i = 0; i < columnCount; i++) {
+            Object value = resultSet.getObject(i + 1);
+
+            rowMap.put(rsmd.getColumnName(i + 1), value);
+        }
+
+        // Adding row__id column.
+        if (isTransactional) {
+            rowKeyMap.clear();
+
+            for (String pkColumn : primaryKeyColumnList) {
+                rowKeyMap.put(pkColumn, rowMap.get(pkColumn));
+            }
+        }
+    }
+
+    public void readPrimaryKey(PhoenixRowKey rowKey) {
+        rowKey.setRowKeyMap(rowKeyMap);
+    }
+
+    public List<ColumnInfo> getColumnMetadataList() {
+        return columnMetadataList;
+    }
+
+    public void setColumnMetadataList(List<ColumnInfo> columnMetadataList) {
+        this.columnMetadataList = columnMetadataList;
+    }
+
+    public Map<String, Object> getResultMap() {
+        return rowMap;
+    }
+
+    public List<Object> getValueList() {
+        return valueList;
+    }
+
+    @Override
+    public void setConf(Configuration conf) {
+        config = conf;
+
+        isTransactional = PhoenixStorageHandlerUtil.isTransactionalTable(config);
+
+        if (isTransactional) {
+            primaryKeyColumnList = PhoenixUtil.getPrimaryKeyColumnList(config, config.get
+                    (PhoenixStorageHandlerConstants.PHOENIX_TABLE_NAME));
+        }
+    }
+
+    @Override
+    public Configuration getConf() {
+        return config;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/AbstractPhoenixObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/AbstractPhoenixObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/AbstractPhoenixObjectInspector.java
new file mode 100644
index 0000000..1de1cc7
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/AbstractPhoenixObjectInspector.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.phoenix.hive.objectinspector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hive.serde2.lazy.objectinspector.primitive
+        .AbstractPrimitiveLazyObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo;
+import org.apache.hadoop.io.Writable;
+
+/**
+ * AbstractPhoenixObjectInspector for a LazyPrimitive object
+ */
+public abstract class AbstractPhoenixObjectInspector<T extends Writable>
+        extends AbstractPrimitiveLazyObjectInspector<T> {
+
+    private final Log log;
+
+    public AbstractPhoenixObjectInspector() {
+        super();
+
+        log = LogFactory.getLog(getClass());
+    }
+
+    protected AbstractPhoenixObjectInspector(PrimitiveTypeInfo typeInfo) {
+        super(typeInfo);
+
+        log = LogFactory.getLog(getClass());
+    }
+
+    @Override
+    public Object getPrimitiveJavaObject(Object o) {
+        return o == null ? null : o;
+    }
+
+    public void logExceptionMessage(Object value, String dataType) {
+        if (log.isDebugEnabled()) {
+            log.debug("Data not in the " + dataType + " data type range so converted to null. " +
+                    "Given data is :"
+                    + value.toString(), new Exception("For debugging purposes"));
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixBinaryObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixBinaryObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixBinaryObjectInspector.java
new file mode 100644
index 0000000..2c642d2
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixBinaryObjectInspector.java
@@ -0,0 +1,58 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.BinaryObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+import org.apache.hadoop.io.BytesWritable;
+
+/**
+ * ObjectInspector for Binary type
+ */
+
+public class PhoenixBinaryObjectInspector extends AbstractPhoenixObjectInspector<BytesWritable>
+        implements BinaryObjectInspector {
+
+    public PhoenixBinaryObjectInspector() {
+        super(TypeInfoFactory.binaryTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        byte[] clone = null;
+
+        if (o != null) {
+            byte[] source = (byte[]) o;
+            clone = new byte[source.length];
+            System.arraycopy(source, 0, clone, 0, source.length);
+        }
+
+        return clone;
+    }
+
+    @Override
+    public byte[] getPrimitiveJavaObject(Object o) {
+        return (byte[]) o;
+    }
+
+    @Override
+    public BytesWritable getPrimitiveWritableObject(Object o) {
+        return new BytesWritable((byte[]) o);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixBooleanObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixBooleanObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixBooleanObjectInspector.java
new file mode 100644
index 0000000..0795e14
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixBooleanObjectInspector.java
@@ -0,0 +1,50 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.BooleanObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+import org.apache.hadoop.io.BooleanWritable;
+
+public class PhoenixBooleanObjectInspector extends AbstractPhoenixObjectInspector<BooleanWritable>
+        implements BooleanObjectInspector {
+
+    public PhoenixBooleanObjectInspector() {
+        super(TypeInfoFactory.booleanTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new Boolean((Boolean) o);
+    }
+
+    @Override
+    public boolean get(Object o) {
+        Boolean value = null;
+
+        if (o != null) {
+            try {
+                value = (Boolean) o;
+            } catch (Exception e) {
+                logExceptionMessage(o, "BOOLEAN");
+            }
+        }
+
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixByteObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixByteObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixByteObjectInspector.java
new file mode 100644
index 0000000..c6c5e95
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixByteObjectInspector.java
@@ -0,0 +1,54 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.ByteObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+import org.apache.hadoop.io.ByteWritable;
+
+/**
+ * ObjectInspector for byte type
+ */
+public class PhoenixByteObjectInspector extends AbstractPhoenixObjectInspector<ByteWritable>
+        implements ByteObjectInspector {
+
+    public PhoenixByteObjectInspector() {
+        super(TypeInfoFactory.byteTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new Byte((Byte) o);
+    }
+
+    @Override
+    public byte get(Object o) {
+        Byte value = null;
+
+        if (o != null) {
+            try {
+                value = (Byte) o;
+            } catch (Exception e) {
+                logExceptionMessage(o, "BYTE");
+            }
+        }
+
+        return value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixCharObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixCharObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixCharObjectInspector.java
new file mode 100644
index 0000000..8d6aa8c
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixCharObjectInspector.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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.common.type.HiveChar;
+import org.apache.hadoop.hive.serde2.io.HiveCharWritable;
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.HiveCharObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+
+/**
+ * ObjectInspector for char type
+ */
+public class PhoenixCharObjectInspector extends AbstractPhoenixObjectInspector<HiveCharWritable>
+        implements HiveCharObjectInspector {
+
+    public PhoenixCharObjectInspector() {
+        super(TypeInfoFactory.charTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new String((String) o);
+    }
+
+    @Override
+    public HiveCharWritable getPrimitiveWritableObject(Object o) {
+        return new HiveCharWritable(getPrimitiveJavaObject(o));
+    }
+
+    @Override
+    public HiveChar getPrimitiveJavaObject(Object o) {
+        String value = (String) o;
+        return new HiveChar(value, value.length());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDateObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDateObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDateObjectInspector.java
new file mode 100644
index 0000000..d97993e
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDateObjectInspector.java
@@ -0,0 +1,63 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.io.DateWritable;
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.DateObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+
+import java.sql.Date;
+
+/**
+ * ObjectInspector for date type
+ */
+
+public class PhoenixDateObjectInspector extends AbstractPhoenixObjectInspector<DateWritable>
+        implements DateObjectInspector {
+
+    public PhoenixDateObjectInspector() {
+        super(TypeInfoFactory.dateTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new Date(((Date) o).getTime());
+    }
+
+    @Override
+    public DateWritable getPrimitiveWritableObject(Object o) {
+        DateWritable value = null;
+
+        if (o != null) {
+            try {
+                value = new DateWritable((Date) o);
+            } catch (Exception e) {
+                logExceptionMessage(o, "DATE");
+                value = new DateWritable();
+            }
+        }
+
+        return value;
+    }
+
+    @Override
+    public Date getPrimitiveJavaObject(Object o) {
+        return (Date) o;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDecimalObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDecimalObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDecimalObjectInspector.java
new file mode 100644
index 0000000..388863a
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDecimalObjectInspector.java
@@ -0,0 +1,63 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.common.type.HiveDecimal;
+import org.apache.hadoop.hive.metastore.api.Decimal;
+import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable;
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.HiveDecimalObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+
+import java.math.BigDecimal;
+
+public class PhoenixDecimalObjectInspector extends
+        AbstractPhoenixObjectInspector<HiveDecimalWritable>
+        implements HiveDecimalObjectInspector {
+
+    public PhoenixDecimalObjectInspector() {
+        super(TypeInfoFactory.decimalTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new Decimal((Decimal) o);
+    }
+
+    @Override
+    public HiveDecimal getPrimitiveJavaObject(Object o) {
+        return HiveDecimal.create((BigDecimal) o);
+    }
+
+    @Override
+    public HiveDecimalWritable getPrimitiveWritableObject(Object o) {
+        HiveDecimalWritable value = null;
+
+        if (o != null) {
+            try {
+                value = new HiveDecimalWritable((HiveDecimalWritable) o);
+            } catch (Exception e) {
+                logExceptionMessage(o, "DECIMAL");
+            }
+        }
+
+        return value;
+
+//		return super.getPrimitiveWritableObject(o);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDoubleObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDoubleObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDoubleObjectInspector.java
new file mode 100644
index 0000000..25ae793
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixDoubleObjectInspector.java
@@ -0,0 +1,54 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.DoubleObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+import org.apache.hadoop.io.DoubleWritable;
+
+/**
+ * ObjectInspector for double type
+ */
+public class PhoenixDoubleObjectInspector extends AbstractPhoenixObjectInspector<DoubleWritable>
+        implements DoubleObjectInspector {
+
+    public PhoenixDoubleObjectInspector() {
+        super(TypeInfoFactory.doubleTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new Double((Double) o);
+    }
+
+    @Override
+    public double get(Object o) {
+        Double value = null;
+
+        if (o != null) {
+            try {
+                value = ((Double) o).doubleValue();
+            } catch (Exception e) {
+                logExceptionMessage(o, "LONG");
+            }
+        }
+
+        return value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixFloatObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixFloatObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixFloatObjectInspector.java
new file mode 100644
index 0000000..83ad2b0
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixFloatObjectInspector.java
@@ -0,0 +1,55 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.FloatObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+import org.apache.hadoop.io.FloatWritable;
+
+/**
+ * ObjectInspector for float type
+ */
+
+public class PhoenixFloatObjectInspector extends AbstractPhoenixObjectInspector<FloatWritable>
+        implements FloatObjectInspector {
+
+    public PhoenixFloatObjectInspector() {
+        super(TypeInfoFactory.floatTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new Float((Float) o);
+    }
+
+    @Override
+    public float get(Object o) {
+        Float value = null;
+
+        if (o != null) {
+            try {
+                value = ((Float) o).floatValue();
+            } catch (Exception e) {
+                logExceptionMessage(o, "LONG");
+            }
+        }
+
+        return value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixIntObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixIntObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixIntObjectInspector.java
new file mode 100644
index 0000000..fc9e7d0
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixIntObjectInspector.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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.IntObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+import org.apache.hadoop.io.IntWritable;
+
+public class PhoenixIntObjectInspector extends AbstractPhoenixObjectInspector<IntWritable>
+        implements IntObjectInspector {
+
+    public PhoenixIntObjectInspector() {
+        super(TypeInfoFactory.intTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new Integer((Integer) o);
+    }
+
+    @Override
+    public int get(Object o) {
+        Integer value = null;
+
+        if (o != null) {
+            try {
+                value = ((Integer) o).intValue();
+            } catch (Exception e) {
+                logExceptionMessage(o, "INT");
+            }
+        }
+
+        return value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixListObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixListObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixListObjectInspector.java
new file mode 100644
index 0000000..c4f2d51
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixListObjectInspector.java
@@ -0,0 +1,105 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import com.google.common.collect.Lists;
+import org.apache.hadoop.hive.serde2.lazy.objectinspector.primitive.LazyObjectInspectorParameters;
+import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+import org.apache.phoenix.schema.types.PhoenixArray;
+
+import java.util.List;
+
+/**
+ * ObjectInspector for list objects.
+ */
+public class PhoenixListObjectInspector implements ListObjectInspector {
+
+    private ObjectInspector listElementObjectInspector;
+    private byte separator;
+    private LazyObjectInspectorParameters lazyParams;
+
+    public PhoenixListObjectInspector(ObjectInspector listElementObjectInspector,
+                                      byte separator, LazyObjectInspectorParameters lazyParams) {
+        this.listElementObjectInspector = listElementObjectInspector;
+        this.separator = separator;
+        this.lazyParams = lazyParams;
+    }
+
+    @Override
+    public String getTypeName() {
+        return org.apache.hadoop.hive.serde.serdeConstants.LIST_TYPE_NAME + "<" +
+                listElementObjectInspector.getTypeName() + ">";
+    }
+
+    @Override
+    public Category getCategory() {
+        return Category.LIST;
+    }
+
+    @Override
+    public ObjectInspector getListElementObjectInspector() {
+        return listElementObjectInspector;
+    }
+
+    @Override
+    public Object getListElement(Object data, int index) {
+        if (data == null) {
+            return null;
+        }
+
+        PhoenixArray array = (PhoenixArray) data;
+
+        return array.getElement(index);
+    }
+
+    @Override
+    public int getListLength(Object data) {
+        if (data == null) {
+            return -1;
+        }
+
+        PhoenixArray array = (PhoenixArray) data;
+        return array.getDimensions();
+    }
+
+    @Override
+    public List<?> getList(Object data) {
+        if (data == null) {
+            return null;
+        }
+
+        PhoenixArray array = (PhoenixArray) data;
+        int valueLength = array.getDimensions();
+        List<Object> valueList = Lists.newArrayListWithExpectedSize(valueLength);
+
+        for (int i = 0; i < valueLength; i++) {
+            valueList.add(array.getElement(i));
+        }
+
+        return valueList;
+    }
+
+    public byte getSeparator() {
+        return separator;
+    }
+
+    public LazyObjectInspectorParameters getLazyParams() {
+        return lazyParams;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixLongObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixLongObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixLongObjectInspector.java
new file mode 100644
index 0000000..ad5cd05
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixLongObjectInspector.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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.LongObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+import org.apache.hadoop.io.LongWritable;
+
+public class PhoenixLongObjectInspector extends AbstractPhoenixObjectInspector<LongWritable>
+        implements LongObjectInspector {
+
+    public PhoenixLongObjectInspector() {
+        super(TypeInfoFactory.longTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new Long((Long) o);
+    }
+
+    @Override
+    public long get(Object o) {
+        Long value = null;
+
+        if (o != null) {
+            try {
+                value = ((Long) o).longValue();
+            } catch (Exception e) {
+                logExceptionMessage(o, "LONG");
+            }
+        }
+
+        return value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixObjectInspectorFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixObjectInspectorFactory.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixObjectInspectorFactory.java
new file mode 100644
index 0000000..928dede
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixObjectInspectorFactory.java
@@ -0,0 +1,148 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hive.serde2.lazy.LazySerDeParameters;
+import org.apache.hadoop.hive.serde2.lazy.objectinspector.LazyObjectInspectorFactory;
+import org.apache.hadoop.hive.serde2.lazy.objectinspector.LazySimpleStructObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory.ObjectInspectorOptions;
+import org.apache.hadoop.hive.serde2.typeinfo.ListTypeInfo;
+import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo;
+import org.apache.hadoop.hive.serde2.typeinfo.StructTypeInfo;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Factory for object inspectors. Matches hive type to the corresponding Phoenix object inspector.
+ */
+
+public class PhoenixObjectInspectorFactory {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixObjectInspectorFactory.class);
+
+    private PhoenixObjectInspectorFactory() {
+
+    }
+
+    public static LazySimpleStructObjectInspector createStructObjectInspector(TypeInfo type,
+                                                                              LazySerDeParameters
+                                                                                      serdeParams) {
+        StructTypeInfo structTypeInfo = (StructTypeInfo) type;
+        List<String> fieldNames = structTypeInfo.getAllStructFieldNames();
+        List<TypeInfo> fieldTypeInfos = structTypeInfo.getAllStructFieldTypeInfos();
+        List<ObjectInspector> fieldObjectInspectors = new ArrayList<ObjectInspector>
+                (fieldTypeInfos.size());
+
+        for (int i = 0; i < fieldTypeInfos.size(); i++) {
+            fieldObjectInspectors.add(createObjectInspector(fieldTypeInfos.get(i), serdeParams));
+        }
+
+        return LazyObjectInspectorFactory.getLazySimpleStructObjectInspector(
+                fieldNames, fieldObjectInspectors, null,
+                serdeParams.getSeparators()[1],
+                serdeParams, ObjectInspectorOptions.JAVA);
+    }
+
+    public static ObjectInspector createObjectInspector(TypeInfo type, LazySerDeParameters
+            serdeParams) {
+        ObjectInspector oi = null;
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Type : " + type);
+        }
+
+        switch (type.getCategory()) {
+            case PRIMITIVE:
+                switch (((PrimitiveTypeInfo) type).getPrimitiveCategory()) {
+                    case BOOLEAN:
+                        oi = new PhoenixBooleanObjectInspector();
+                        break;
+                    case BYTE:
+                        oi = new PhoenixByteObjectInspector();
+                        break;
+                    case SHORT:
+                        oi = new PhoenixShortObjectInspector();
+                        break;
+                    case INT:
+                        oi = new PhoenixIntObjectInspector();
+                        break;
+                    case LONG:
+                        oi = new PhoenixLongObjectInspector();
+                        break;
+                    case FLOAT:
+                        oi = new PhoenixFloatObjectInspector();
+                        break;
+                    case DOUBLE:
+                        oi = new PhoenixDoubleObjectInspector();
+                        break;
+                    case VARCHAR:
+                        // same string
+                    case STRING:
+                        oi = new PhoenixStringObjectInspector(serdeParams.isEscaped(),
+                                serdeParams.getEscapeChar());
+                        break;
+                    case CHAR:
+                        oi = new PhoenixCharObjectInspector();
+                        break;
+                    case DATE:
+                        oi = new PhoenixDateObjectInspector();
+                        break;
+                    case TIMESTAMP:
+                        oi = new PhoenixTimestampObjectInspector();
+                        break;
+                    case DECIMAL:
+                        oi = new PhoenixDecimalObjectInspector();
+                        break;
+                    case BINARY:
+                        oi = new PhoenixBinaryObjectInspector();
+                        break;
+                    default:
+                        throw new RuntimeException("Hive internal error. not supported data type " +
+                                ": " + type);
+                }
+
+                break;
+            case LIST:
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("List type started");
+                }
+
+                ObjectInspector listElementObjectInspector = createObjectInspector((
+                        (ListTypeInfo) type).getListElementTypeInfo(), serdeParams);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("List type ended");
+                }
+
+                oi = new PhoenixListObjectInspector(listElementObjectInspector, serdeParams
+                        .getSeparators()[0], serdeParams);
+
+                break;
+            default:
+                throw new RuntimeException("Hive internal error. not supported data type : " +
+                        type);
+        }
+
+        return oi;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixShortObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixShortObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixShortObjectInspector.java
new file mode 100644
index 0000000..1b7ec13
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixShortObjectInspector.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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.ShortObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+import org.apache.hadoop.io.ShortWritable;
+
+public class PhoenixShortObjectInspector extends AbstractPhoenixObjectInspector<ShortWritable>
+        implements ShortObjectInspector {
+
+    public PhoenixShortObjectInspector() {
+        super(TypeInfoFactory.shortTypeInfo);
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new Short((Short) o);
+    }
+
+    @Override
+    public short get(Object o) {
+        Short value = null;
+
+        if (o != null) {
+            try {
+                value = ((Short) o).shortValue();
+            } catch (Exception e) {
+                logExceptionMessage(o, "SHORT");
+            }
+        }
+
+        return value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixStringObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixStringObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixStringObjectInspector.java
new file mode 100644
index 0000000..e409e1d
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixStringObjectInspector.java
@@ -0,0 +1,72 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+import org.apache.hadoop.io.Text;
+
+/**
+ * ObjectInspector for string type
+ */
+public class PhoenixStringObjectInspector extends AbstractPhoenixObjectInspector<Text>
+        implements StringObjectInspector {
+
+    private boolean escaped;
+    private byte escapeChar;
+
+    public PhoenixStringObjectInspector(boolean escaped, byte escapeChar) {
+        super(TypeInfoFactory.stringTypeInfo);
+        this.escaped = escaped;
+        this.escapeChar = escapeChar;
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new String((String) o);
+    }
+
+    @Override
+    public String getPrimitiveJavaObject(Object o) {
+        return (String) o;
+    }
+
+    @Override
+    public Text getPrimitiveWritableObject(Object o) {
+        Text value = null;
+
+        if (o != null) {
+            try {
+                value = new Text((String) o);
+            } catch (Exception e) {
+                logExceptionMessage(o, "STRING");
+            }
+        }
+
+        return value;
+    }
+
+    public boolean isEscaped() {
+        return escaped;
+    }
+
+    public byte getEscapeChar() {
+        return escapeChar;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixTimestampObjectInspector.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixTimestampObjectInspector.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixTimestampObjectInspector.java
new file mode 100644
index 0000000..7b13f2b
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/objectinspector/PhoenixTimestampObjectInspector.java
@@ -0,0 +1,61 @@
+/*
+ * 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.phoenix.hive.objectinspector;
+
+import org.apache.hadoop.hive.serde2.io.TimestampWritable;
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.TimestampObjectInspector;
+import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
+
+import java.sql.Timestamp;
+
+/**
+ * ObjectInspector for timestamp type
+ */
+public class PhoenixTimestampObjectInspector extends
+        AbstractPhoenixObjectInspector<TimestampWritable>
+        implements TimestampObjectInspector {
+
+    public PhoenixTimestampObjectInspector() {
+        super(TypeInfoFactory.timestampTypeInfo);
+    }
+
+    @Override
+    public Timestamp getPrimitiveJavaObject(Object o) {
+        return (Timestamp) o;
+    }
+
+    @Override
+    public Object copyObject(Object o) {
+        return o == null ? null : new Timestamp(((Timestamp) o).getTime());
+    }
+
+    @Override
+    public TimestampWritable getPrimitiveWritableObject(Object o) {
+        TimestampWritable value = null;
+
+        if (o != null) {
+            try {
+                value = new TimestampWritable((Timestamp) o);
+            } catch (Exception e) {
+                logExceptionMessage(o, "TIMESTAMP");
+            }
+        }
+
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/ppd/PhoenixPredicateDecomposer.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/ppd/PhoenixPredicateDecomposer.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/ppd/PhoenixPredicateDecomposer.java
new file mode 100644
index 0000000..b94e4df
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/ppd/PhoenixPredicateDecomposer.java
@@ -0,0 +1,82 @@
+/*
+ * 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.phoenix.hive.ppd;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hive.ql.metadata.HiveStoragePredicateHandler.DecomposedPredicate;
+import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
+import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc;
+import org.apache.phoenix.hive.ql.index.IndexPredicateAnalyzer;
+import org.apache.phoenix.hive.ql.index.IndexSearchCondition;
+import org.apache.phoenix.hive.ql.index.PredicateAnalyzerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Supporting class that generate DecomposedPredicate companion to PhoenixHiveStorageHandler
+ * basing on search conditions.
+ */
+public class PhoenixPredicateDecomposer {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixPredicateDecomposer.class);
+
+    private List<String> columnNameList;
+    private boolean calledPPD;
+
+    private List<IndexSearchCondition> searchConditionList;
+
+    public PhoenixPredicateDecomposer(List<String> columnNameList) {
+        this.columnNameList = columnNameList;
+    }
+
+    public DecomposedPredicate decomposePredicate(ExprNodeDesc predicate) {
+        IndexPredicateAnalyzer analyzer = PredicateAnalyzerFactory.createPredicateAnalyzer
+                (columnNameList, getFieldValidator());
+        DecomposedPredicate decomposed = new DecomposedPredicate();
+
+        List<IndexSearchCondition> conditions = new ArrayList<IndexSearchCondition>();
+        decomposed.residualPredicate = (ExprNodeGenericFuncDesc) analyzer.analyzePredicate
+                (predicate, conditions);
+        if (!conditions.isEmpty()) {
+            decomposed.pushedPredicate = analyzer.translateSearchConditions(conditions);
+            try {
+                searchConditionList = conditions;
+                calledPPD = true;
+            } catch (Exception e) {
+                LOG.warn("Failed to decompose predicates", e);
+                return null;
+            }
+        }
+
+        return decomposed;
+    }
+
+    public List<IndexSearchCondition> getSearchConditionList() {
+        return searchConditionList;
+    }
+
+    public boolean isCalledPPD() {
+        return calledPPD;
+    }
+
+    protected IndexPredicateAnalyzer.FieldValidator getFieldValidator() {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/521b8192/phoenix-hive/src/main/java/org/apache/phoenix/hive/ppd/PhoenixPredicateDecomposerManager.java
----------------------------------------------------------------------
diff --git a/phoenix-hive/src/main/java/org/apache/phoenix/hive/ppd/PhoenixPredicateDecomposerManager.java b/phoenix-hive/src/main/java/org/apache/phoenix/hive/ppd/PhoenixPredicateDecomposerManager.java
new file mode 100644
index 0000000..2faef73
--- /dev/null
+++ b/phoenix-hive/src/main/java/org/apache/phoenix/hive/ppd/PhoenixPredicateDecomposerManager.java
@@ -0,0 +1,83 @@
+/*
+ * 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.phoenix.hive.ppd;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Support class that produces PredicateDecomposer for PhoenixStorageHandler
+ */
+
+public class PhoenixPredicateDecomposerManager {
+
+    private static final Log LOG = LogFactory.getLog(PhoenixPredicateDecomposerManager.class);
+
+    // In case of absence of WHERE clause, PhoenixPredicateDecomposer is not created because
+    // it's not called method of StorageHandler.decomposePredicate.
+
+    private static final Map<String, List<PhoenixPredicateDecomposer>> PREDICATE_DECOMPOSER_MAP =
+            Maps.newConcurrentMap();
+
+    public static PhoenixPredicateDecomposer createPredicateDecomposer(String predicateKey,
+                                                                       List<String>
+                                                                               columnNameList) {
+        List<PhoenixPredicateDecomposer> predicateDecomposerList = PREDICATE_DECOMPOSER_MAP.get
+                (predicateKey);
+        if (predicateDecomposerList == null) {
+            predicateDecomposerList = Lists.newArrayList();
+            PREDICATE_DECOMPOSER_MAP.put(predicateKey, predicateDecomposerList);
+        }
+
+        PhoenixPredicateDecomposer predicateDecomposer = new PhoenixPredicateDecomposer
+                (columnNameList);
+        predicateDecomposerList.add(predicateDecomposer);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Predicate-decomposer : " + PREDICATE_DECOMPOSER_MAP + " [" +
+                    predicateKey + "] : " + predicateDecomposer);
+        }
+
+        return predicateDecomposer;
+    }
+
+    public static PhoenixPredicateDecomposer getPredicateDecomposer(String predicateKey) {
+        List<PhoenixPredicateDecomposer> predicateDecomposerList = PREDICATE_DECOMPOSER_MAP.get
+                (predicateKey);
+
+        PhoenixPredicateDecomposer predicateDecomposer = null;
+        if (predicateDecomposerList != null && predicateDecomposerList.size() > 0) {
+            predicateDecomposer = predicateDecomposerList.remove(0);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Predicate-decomposer : " + PREDICATE_DECOMPOSER_MAP + " [" + predicateKey
+                    + "] : " + predicateDecomposer);
+        }
+
+        return predicateDecomposer;
+    }
+
+    private PhoenixPredicateDecomposerManager() {
+    }
+}


[35/52] [abbrv] phoenix git commit: PHOENIX-2855 Workaround Increment TimeRange not being serialized for HBase 1.2

Posted by sa...@apache.org.
PHOENIX-2855 Workaround Increment TimeRange not being serialized for HBase 1.2


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

Branch: refs/heads/encodecolumns
Commit: 559dfa76bcd622701d789a0f20bd11da11da7412
Parents: 4d5c412
Author: James Taylor <ja...@apache.org>
Authored: Fri Apr 22 18:26:34 2016 -0700
Committer: James Taylor <ja...@apache.org>
Committed: Fri Apr 22 18:56:32 2016 -0700

----------------------------------------------------------------------
 .../coprocessor/SequenceRegionObserver.java     |  7 +++++++
 .../org/apache/phoenix/schema/Sequence.java     | 20 ++++++++++++++++----
 2 files changed, 23 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/559dfa76/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java
index 4bc1ef5..2e2d580 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java
@@ -132,6 +132,13 @@ public class SequenceRegionObserver extends BaseRegionObserver {
                     for (Cell cq : entry.getValue()) {
                     	long value = Bytes.toLong(cq.getValueArray(), cq.getValueOffset());
                         get.addColumn(cf, CellUtil.cloneQualifier(cq));
+                        long cellTimestamp = cq.getTimestamp();
+                        // Workaround HBASE-15698 by using the lowest of the timestamps found
+                        // on the Increment or any of its Cells.
+                        if (cellTimestamp > 0 && cellTimestamp < maxTimestamp) {
+                            maxTimestamp = cellTimestamp;
+                            get.setTimeRange(MetaDataProtocol.MIN_TABLE_TIMESTAMP, maxTimestamp);
+                        }
                         validateOnly &= (Sequence.ValueOp.VALIDATE_SEQUENCE.ordinal() == value);
                     }
                 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/559dfa76/phoenix-core/src/main/java/org/apache/phoenix/schema/Sequence.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/Sequence.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/Sequence.java
index 9c1a74b..9598ace 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/Sequence.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/Sequence.java
@@ -350,9 +350,10 @@ public class Sequence {
     }
 
 
-    @SuppressWarnings("deprecation")
     public Increment newIncrement(long timestamp, Sequence.ValueOp action, long numToAllocate) {
-        Increment inc = new Increment(key.getKey());
+        byte[] incKey = key.getKey();
+        byte[] incValue = Bytes.toBytes((long)action.ordinal());
+        Increment inc = new Increment(incKey);
         // It doesn't matter what we set the amount too - we always use the values we get
         // from the Get we do to prevent any race conditions. All columns that get added
         // are returned with their current value
@@ -363,8 +364,19 @@ public class Sequence {
             throw new RuntimeException(e); // Impossible
         }
         for (KeyValue kv : SEQUENCE_KV_COLUMNS) {
-            // We don't care about the amount, as we'll add what gets looked up on the server-side
-            inc.addColumn(kv.getFamily(), kv.getQualifier(), action.ordinal());
+            try {
+                // Store the timestamp on the cell as well as HBase 1.2 seems to not
+                // be serializing over the time range (see HBASE-15698).
+                Cell cell = new KeyValue(incKey, 0, incKey.length, 
+                        kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength(),
+                        kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength(),
+                        timestamp,
+                        KeyValue.Type.Put,
+                        incValue, 0, incValue.length);
+                inc.add(cell);
+            } catch (IOException e) {
+                throw new RuntimeException(e); // Impossible
+            }
         }
         return inc;
     }


[39/52] [abbrv] phoenix git commit: Fix generation of next column qualifiers

Posted by sa...@apache.org.
Fix generation of next column qualifiers


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

Branch: refs/heads/encodecolumns
Commit: 8a9ffe5c8ca23ec72a3c0be43eeccc65a8753f14
Parents: d89c5cb
Author: Samarth <sa...@salesforce.com>
Authored: Fri Mar 25 10:05:33 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:31 2016 -0700

----------------------------------------------------------------------
 .../phoenix/end2end/index/IndexTestUtil.java    |  3 +-
 .../phoenix/compile/ExpressionCompiler.java     |  3 +-
 .../apache/phoenix/compile/FromCompiler.java    |  4 +-
 .../apache/phoenix/compile/JoinCompiler.java    |  3 +-
 .../apache/phoenix/compile/PostDDLCompiler.java |  6 +-
 .../phoenix/compile/ProjectionCompiler.java     |  3 +-
 .../compile/TupleProjectionCompiler.java        |  3 +-
 .../apache/phoenix/compile/WhereCompiler.java   |  3 +-
 .../coprocessor/MetaDataEndpointImpl.java       |  3 +-
 .../apache/phoenix/execute/BaseQueryPlan.java   |  4 +-
 .../expression/KeyValueColumnExpression.java    |  3 +-
 .../phoenix/filter/ColumnProjectionFilter.java  |  6 +-
 .../apache/phoenix/index/IndexMaintainer.java   |  9 ++-
 .../phoenix/iterate/BaseResultIterators.java    |  5 +-
 .../mapreduce/FormatToBytesWritableMapper.java  |  4 +-
 .../mapreduce/FormatToKeyValueReducer.java      |  3 +-
 .../org/apache/phoenix/schema/ColumnRef.java    |  3 +-
 .../apache/phoenix/schema/DelegateColumn.java   |  4 +-
 .../apache/phoenix/schema/MetaDataClient.java   | 14 ++--
 .../java/org/apache/phoenix/schema/PColumn.java |  2 +-
 .../phoenix/schema/PColumnFamilyImpl.java       | 21 +++---
 .../org/apache/phoenix/schema/PColumnImpl.java  |  8 +-
 .../apache/phoenix/schema/PMetaDataImpl.java    |  2 +-
 .../org/apache/phoenix/schema/PTableImpl.java   | 40 ++++------
 .../apache/phoenix/util/EncodedColumnsUtil.java | 77 ++++++++++++++++++++
 .../java/org/apache/phoenix/util/IndexUtil.java |  2 +-
 .../org/apache/phoenix/util/SchemaUtil.java     | 30 +++++---
 .../iterate/AggregateResultScannerTest.java     |  2 +-
 28 files changed, 178 insertions(+), 92 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexTestUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexTestUtil.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexTestUtil.java
index 42c0264..a2888cf 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexTestUtil.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexTestUtil.java
@@ -47,6 +47,7 @@ import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.RowKeySchema;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.MetaDataUtil;
 import org.apache.phoenix.util.SchemaUtil;
@@ -134,7 +135,7 @@ public class IndexTestUtil {
                     for (Cell kv : entry.getValue()) {
                         @SuppressWarnings("deprecation")
                         byte[] cq = kv.getQualifier();
-                        byte[] emptyKVQualifier = SchemaUtil.getEmptyKeyValueInfo(dataTable).getFirst();
+                        byte[] emptyKVQualifier = EncodedColumnsUtil.getEmptyKeyValueInfo(dataTable).getFirst();
                         if (Bytes.compareTo(emptyKVQualifier, cq) != 0) {
                             try {
                                 PColumn dataColumn = family.getPColumnForColumnQualifier(cq);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
index 31a2f82..1623cab 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
@@ -133,6 +133,7 @@ import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.schema.types.PUnsignedTimestamp;
 import org.apache.phoenix.schema.types.PVarbinary;
 import org.apache.phoenix.schema.types.PhoenixArray;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.ExpressionUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.SchemaUtil;
@@ -407,7 +408,7 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
             return LiteralExpression.newConstant(column.getDataType().toObject(ptr), column.getDataType());
         }
         if (tableRef.equals(context.getCurrentTable()) && !SchemaUtil.isPKColumn(column)) { // project only kv columns
-            context.getScan().addColumn(column.getFamilyName().getBytes(), SchemaUtil.getColumnQualifier(column, tableRef.getTable()));
+            context.getScan().addColumn(column.getFamilyName().getBytes(), EncodedColumnsUtil.getColumnQualifier(column, tableRef.getTable()));
         }
         Expression expression = ref.newColumnExpression(node.isTableNameCaseSensitive(), node.isCaseSensitive());
         Expression wrappedExpression = wrapGroupByExpression(expression);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
index d420036..ba904e5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
@@ -252,7 +252,7 @@ public class FromCompiler {
             Expression sourceExpression = projector.getColumnProjector(column.getPosition()).getExpression();
             PColumnImpl projectedColumn = new PColumnImpl(column.getName(), column.getFamilyName(),
                     sourceExpression.getDataType(), sourceExpression.getMaxLength(), sourceExpression.getScale(), sourceExpression.isNullable(),
-                    column.getPosition(), sourceExpression.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic(), column.getColumnQualifier());
+                    column.getPosition(), sourceExpression.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic(), column.getEncodedColumnQualifier());
             projectedColumns.add(projectedColumn);
         }
         PTable t = PTableImpl.makePTable(table, projectedColumns);
@@ -666,7 +666,7 @@ public class FromCompiler {
                         theTable.getColumnFamily(family); // Verifies that column family exists
                         familyName = PNameFactory.newName(family);
                     }
-                    // Dynamic columns don't have a corresponding column qualifier
+                    // Dynamic columns don't have an encoded column name
                     allcolumns.add(new PColumnImpl(name, familyName, dynColumn.getDataType(), dynColumn.getMaxLength(),
                             dynColumn.getScale(), dynColumn.isNull(), position, dynColumn.getSortOrder(), dynColumn.getArraySize(), null, false, dynColumn.getExpression(), false, true, null));
                     position++;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
index a753b04..fe07d8d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
@@ -91,6 +91,7 @@ import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.schema.types.PTinyint;
 import org.apache.phoenix.schema.types.PVarbinary;
 import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.SchemaUtil;
 
@@ -717,7 +718,7 @@ public class JoinCompiler {
                 if (columnRef.getTableRef().equals(tableRef)
                         && !SchemaUtil.isPKColumn(columnRef.getColumn())
                         && !(columnRef instanceof LocalIndexColumnRef)) {
-                    scan.addColumn(columnRef.getColumn().getFamilyName().getBytes(), SchemaUtil.getColumnQualifier(columnRef.getColumn(), tableRef.getTable()));
+                    scan.addColumn(columnRef.getColumn().getFamilyName().getBytes(), EncodedColumnsUtil.getColumnQualifier(columnRef.getColumn(), tableRef.getTable()));
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
index f7cd2b1..7269cde 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
@@ -50,8 +50,8 @@ import org.apache.phoenix.schema.TableNotFoundException;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.ScanUtil;
-import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.TransactionUtil;
 
 import com.google.common.collect.Lists;
@@ -214,7 +214,7 @@ public class PostDDLCompiler {
                         ScanUtil.setTimeRange(scan, ts);
                         if (emptyCF != null) {
                             scan.setAttribute(BaseScannerRegionObserver.EMPTY_CF, emptyCF);
-                            scan.setAttribute(BaseScannerRegionObserver.EMPTY_COLUMN_QUALIFIER, SchemaUtil.getEmptyKeyValueInfo(tableRef.getTable()).getFirst());
+                            scan.setAttribute(BaseScannerRegionObserver.EMPTY_COLUMN_QUALIFIER, EncodedColumnsUtil.getEmptyKeyValueInfo(tableRef.getTable()).getFirst());
                         }
                         ServerCache cache = null;
                         try {
@@ -238,7 +238,7 @@ public class PostDDLCompiler {
                                     // data empty column family to stay the same, while the index empty column family
                                     // changes.
                                     PColumn column = deleteList.get(0);
-                                    byte[] cq = SchemaUtil.getColumnQualifier(column, tableRef.getTable());
+                                    byte[] cq = EncodedColumnsUtil.getColumnQualifier(column, tableRef.getTable());
                                     if (emptyCF == null) {
                                         scan.addColumn(column.getFamilyName().getBytes(), cq);
                                     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
index b9bfff3..2f0c377 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
@@ -88,6 +88,7 @@ import org.apache.phoenix.schema.ValueBitSet;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.SizedUtil;
@@ -703,7 +704,7 @@ public class ProjectionCompiler {
                          if (expression.getDataType().isArrayType()) {
                              indexProjectedColumns.add(expression);
                              PColumn col = expression.getColumn();
-                             KeyValueColumnExpression keyValueColumnExpression = new KeyValueColumnExpression(col, SchemaUtil.hasEncodedColumnName(col));
+                             KeyValueColumnExpression keyValueColumnExpression = new KeyValueColumnExpression(col, EncodedColumnsUtil.hasEncodedColumnName(col));
                              indexKVs.add(keyValueColumnExpression);
                              copyOfChildren.set(0, keyValueColumnExpression);
                              Integer count = arrayExpressionCounts.get(expression);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
index 51d4cf9..b812db5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
@@ -48,6 +48,7 @@ import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.ProjectedColumn;
 import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.SchemaUtil;
 
@@ -136,7 +137,7 @@ public class TupleProjectionCompiler {
             projectedColumns.add(column);
             // Wildcard or FamilyWildcard will be handled by ProjectionCompiler.
             if (!isWildcard && !families.contains(sourceColumn.getFamilyName())) {
-                context.getScan().addColumn(sourceColumn.getFamilyName().getBytes(), SchemaUtil.getColumnQualifier(column, table));
+                context.getScan().addColumn(sourceColumn.getFamilyName().getBytes(), EncodedColumnsUtil.getColumnQualifier(column, table));
             }
         }
         // add LocalIndexDataColumnRef

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
index c2e42f2..5e64209 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
@@ -56,6 +56,7 @@ import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.TypeMismatchException;
 import org.apache.phoenix.schema.types.PBoolean;
 import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.ScanUtil;
 import org.apache.phoenix.util.SchemaUtil;
 
@@ -170,7 +171,7 @@ public class WhereCompiler {
             TableRef tableRef = ref.getTableRef();
             if (tableRef.equals(context.getCurrentTable()) && !SchemaUtil.isPKColumn(ref.getColumn())) {
                 // track the where condition columns. Later we need to ensure the Scan in HRS scans these column CFs
-                byte[] cq = SchemaUtil.getColumnQualifier(ref.getColumn(), tableRef.getTable());
+                byte[] cq = EncodedColumnsUtil.getColumnQualifier(ref.getColumn(), tableRef.getTable());
                 context.addWhereCoditionColumn(ref.getColumn().getFamilyName().getBytes(), cq);
             }
             return ref.newColumnExpression(node.isTableNameCaseSensitive(), node.isCaseSensitive());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 20b5e89..8fdb45b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -204,6 +204,7 @@ import org.apache.phoenix.schema.types.PVarbinary;
 import org.apache.phoenix.schema.types.PVarchar;
 import org.apache.phoenix.trace.util.Tracing;
 import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.EnvironmentEdgeManager;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.KeyValueUtil;
@@ -3221,7 +3222,7 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
                         Put p = new Put(dataTableKey);
                         // Decide on what column qualifier to use for empty key value.
                         PTable currentTable = doGetTable(key, HConstants.LATEST_TIMESTAMP, rowLock);
-                        Pair<byte[], byte[]> emptyKeyValuePair = SchemaUtil.getEmptyKeyValueInfo(currentTable);
+                        Pair<byte[], byte[]> emptyKeyValuePair = EncodedColumnsUtil.getEmptyKeyValueInfo(currentTable);
                         p.add(TABLE_FAMILY_BYTES, emptyKeyValuePair.getFirst(), timeStamp, emptyKeyValuePair.getSecond());
                         tableMetadata.add(p);
                     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
index 302c3d1..0559f40 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
@@ -69,12 +69,12 @@ import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.trace.TracingIterator;
 import org.apache.phoenix.trace.util.Tracing;
 import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.LogUtil;
 import org.apache.phoenix.util.SQLCloseable;
 import org.apache.phoenix.util.SQLCloseables;
 import org.apache.phoenix.util.ScanUtil;
-import org.apache.phoenix.util.SchemaUtil;
 import org.cloudera.htrace.TraceScope;
 
 import com.google.common.collect.ImmutableSet;
@@ -413,7 +413,7 @@ public abstract class BaseQueryPlan implements QueryPlan {
             WritableUtils.writeVInt(output, dataColumns.size());
             for (PColumn column : dataColumns) {
                 Bytes.writeByteArray(output, column.getFamilyName().getBytes());
-                Bytes.writeByteArray(output, SchemaUtil.getColumnQualifier(column, dataTable));
+                Bytes.writeByteArray(output, EncodedColumnsUtil.getColumnQualifier(column, dataTable));
             }
             scan.setAttribute(BaseScannerRegionObserver.DATA_TABLE_COLUMNS_TO_JOIN, stream.toByteArray());
         } catch (IOException e) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
index 3787d6e..35862c4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
@@ -28,6 +28,7 @@ import org.apache.phoenix.expression.visitor.ExpressionVisitor;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PDatum;
 import org.apache.phoenix.schema.tuple.Tuple;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.SchemaUtil;
 
 
@@ -59,7 +60,7 @@ public class KeyValueColumnExpression extends ColumnExpression {
     public KeyValueColumnExpression(PColumn column, String displayName, boolean encodedColumnName) {
         super(column);
         this.cf = column.getFamilyName().getBytes();
-        this.cq = SchemaUtil.getColumnQualifier(column, encodedColumnName);
+        this.cq = EncodedColumnsUtil.getColumnQualifier(column, encodedColumnName);
         this.displayName = displayName;
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java b/phoenix-core/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java
index 4767090..d1f6211 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java
@@ -40,7 +40,7 @@ import org.apache.hadoop.hbase.util.Writables;
 import org.apache.hadoop.io.Writable;
 import org.apache.hadoop.io.WritableUtils;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
-import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 
 /**
  * When selecting specific columns in a SELECT query, this filter passes only selected columns
@@ -67,7 +67,7 @@ public class ColumnProjectionFilter extends FilterBase implements Writable {
         this.columnsTracker = columnsTracker;
         this.conditionOnlyCfs = conditionOnlyCfs;
         this.usesEncodedColumnNames = usesEncodedColumnNames;
-        this.emptyKVQualifier = SchemaUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst();
+        this.emptyKVQualifier = EncodedColumnsUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst();
     }
 
     @Override
@@ -92,7 +92,7 @@ public class ColumnProjectionFilter extends FilterBase implements Writable {
         }
         int conditionOnlyCfsSize = WritableUtils.readVInt(input);
         usesEncodedColumnNames = conditionOnlyCfsSize > 0;
-        emptyKVQualifier = SchemaUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst();
+        emptyKVQualifier = EncodedColumnsUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst();
         conditionOnlyCfsSize = Math.abs(conditionOnlyCfsSize) - 1; // restore to the actual value.
         this.conditionOnlyCfs = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
         while (conditionOnlyCfsSize > 0) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
index 7ea39fd..124af0d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
@@ -87,6 +87,7 @@ import org.apache.phoenix.schema.tuple.ValueGetterTuple;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.util.BitSet;
 import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.MetaDataUtil;
 import org.apache.phoenix.util.SchemaUtil;
@@ -323,7 +324,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
          * that is serialized in it. Because of this we are forced to have the indexes inherit the
          * storage scheme of the parent data tables. 
          */
-        this.usesEncodedColumnNames = SchemaUtil.usesEncodedColumnNames(dataTable);
+        this.usesEncodedColumnNames = EncodedColumnsUtil.usesEncodedColumnNames(dataTable);
         byte[] indexTableName = index.getPhysicalName().getBytes();
         // Use this for the nDataSaltBuckets as we need this for local indexes
         // TODO: persist nDataSaltBuckets separately, but maintain b/w compat.
@@ -440,8 +441,8 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
             PColumnFamily family = index.getColumnFamilies().get(i);
             for (PColumn indexColumn : family.getColumns()) {
                 PColumn dataColumn = IndexUtil.getDataColumn(dataTable, indexColumn.getName().getString());
-                byte[] dataColumnCq = SchemaUtil.getColumnQualifier(dataColumn, dataTable);
-                byte[] indexColumnCq = SchemaUtil.getColumnQualifier(indexColumn, index);
+                byte[] dataColumnCq = EncodedColumnsUtil.getColumnQualifier(dataColumn, dataTable);
+                byte[] indexColumnCq = EncodedColumnsUtil.getColumnQualifier(indexColumn, index);
                 this.coveredColumns.add(new ColumnReference(dataColumn.getFamilyName().getBytes(), dataColumnCq));
                 this.coveredColumnsMap.put(new ColumnReference(dataColumn.getFamilyName().getBytes(), dataColumnCq), 
                         new ColumnReference(indexColumn.getFamilyName().getBytes(), indexColumnCq));
@@ -1237,7 +1238,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
      * Init calculated state reading/creating
      */
     private void initCachedState() {
-        byte[] emptyKvQualifier = SchemaUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst();
+        byte[] emptyKvQualifier = EncodedColumnsUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst();
         dataEmptyKeyValueRef = new ColumnReference(emptyKeyValueCFPtr.copyBytesIfNecessary(), emptyKvQualifier);
         emptyKeyValueQualifierPtr = new ImmutableBytesPtr(emptyKvQualifier);
         this.allColumns = Sets.newLinkedHashSetWithExpectedSize(indexedExpressions.size() + coveredColumns.size());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
index 959e9f6..b749766 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
@@ -84,6 +84,7 @@ import org.apache.phoenix.schema.stats.GuidePostsInfo;
 import org.apache.phoenix.schema.stats.PTableStats;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.Closeables;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.LogUtil;
 import org.apache.phoenix.util.PrefixByteCodec;
 import org.apache.phoenix.util.PrefixByteDecoder;
@@ -205,7 +206,7 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
                             // Project empty key value unless the column family containing it has
                             // been projected in its entirety.
                             if (!familyMap.containsKey(ecf) || familyMap.get(ecf) != null) {
-                                scan.addColumn(ecf, SchemaUtil.getEmptyKeyValueInfo(table).getFirst());
+                                scan.addColumn(ecf, EncodedColumnsUtil.getEmptyKeyValueInfo(table).getFirst());
                             }
                         }
                     }
@@ -326,7 +327,7 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
             // the ExplicitColumnTracker not to be used, though.
             if (!statement.isAggregate() && filteredColumnNotInProjection) {
                 ScanUtil.andFilterAtEnd(scan, new ColumnProjectionFilter(SchemaUtil.getEmptyColumnFamily(table),
-                        columnsTracker, conditionOnlyCfs, SchemaUtil.usesEncodedColumnNames(table)));
+                        columnsTracker, conditionOnlyCfs, EncodedColumnsUtil.usesEncodedColumnNames(table)));
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java
index 0a28f38..1420e2f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java
@@ -48,9 +48,9 @@ import org.apache.phoenix.mapreduce.util.PhoenixConfigurationUtil;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.util.ColumnInfo;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.QueryUtil;
-import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.UpsertExecutor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -138,7 +138,7 @@ public abstract class FormatToBytesWritableMapper<RECORD> extends Mapper<LongWri
             List<String> logicalTableNames = TargetTableRefFunctions.NAMES_FROM_JSON.apply(logicalNamesConf);
             for (String logicalTableName : logicalTableNames) {
                 PTable table = PhoenixRuntime.getTable(conn, logicalTableName);
-                logicalTables.add(new Pair<>(logicalTableName, SchemaUtil.getEmptyKeyValueInfo(table).getFirst()));
+                logicalTables.add(new Pair<>(logicalTableName, EncodedColumnsUtil.getEmptyKeyValueInfo(table).getFirst()));
             }
             columnIndexes = initColumnIndexes();
         } catch (SQLException | ClassNotFoundException e) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
index cc1559a..ddf6120 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
@@ -44,6 +44,7 @@ import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.Closeables;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.SchemaUtil;
@@ -106,7 +107,7 @@ public class FormatToKeyValueReducer
                     continue;
                 }
                 byte[] family = c.getFamilyName().getBytes();
-                byte[] name = SchemaUtil.getColumnQualifier(c, table);
+                byte[] name = EncodedColumnsUtil.getColumnQualifier(c, table);
                 list.add(new Pair<>(family, name));
             }
             columnIndexes.add(list);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
index d7c6456..544fb20 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
@@ -22,6 +22,7 @@ import org.apache.phoenix.expression.ColumnExpression;
 import org.apache.phoenix.expression.KeyValueColumnExpression;
 import org.apache.phoenix.expression.ProjectedColumnExpression;
 import org.apache.phoenix.expression.RowKeyColumnExpression;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.SchemaUtil;
 
 
@@ -109,7 +110,7 @@ public class ColumnRef {
         	return new ProjectedColumnExpression(column, table, displayName);
         }
        
-        return new KeyValueColumnExpression(column, displayName, SchemaUtil.usesEncodedColumnNames(table));
+        return new KeyValueColumnExpression(column, displayName, EncodedColumnsUtil.usesEncodedColumnNames(table));
     }
 
     public ColumnRef cloneAtTimestamp(long timestamp) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
index 65e362c..4ac8f46 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateColumn.java
@@ -92,7 +92,7 @@ public class DelegateColumn extends DelegateDatum implements PColumn {
 	}
 
     @Override
-    public Integer getColumnQualifier() {
-        return getDelegate().getColumnQualifier();
+    public Integer getEncodedColumnQualifier() {
+        return getDelegate().getEncodedColumnQualifier();
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 3113a98..7ddefed 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -201,6 +201,7 @@ import org.apache.phoenix.schema.types.PUnsignedLong;
 import org.apache.phoenix.schema.types.PVarbinary;
 import org.apache.phoenix.schema.types.PVarchar;
 import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.IndexUtil;
 import org.apache.phoenix.util.LogUtil;
 import org.apache.phoenix.util.MetaDataUtil;
@@ -788,10 +789,10 @@ public class MetaDataClient {
         } else {
             colUpsert.setString(18, column.getExpressionStr());
         }
-        if (column.getColumnQualifier() == null) {
+        if (column.getEncodedColumnQualifier() == null) {
             colUpsert.setNull(19, Types.INTEGER);
         } else {
-            colUpsert.setInt(19, column.getColumnQualifier());
+            colUpsert.setInt(19, column.getEncodedColumnQualifier());
         }
         if (colUpsert.getParameterMetaData().getParameterCount() > 19) {
             colUpsert.setBoolean(20, column.isRowTimestamp());
@@ -1908,7 +1909,7 @@ public class MetaDataClient {
             int position = positionOffset;
             
             StorageScheme storageScheme = null;
-            Map<String, Integer> nextColumnQualifiers = null; // this would be null for tables created before phoenix 4.8.
+            Map<String, Integer> nextColumnQualifiers = null; // this would be null for tables created for columns with storage scheme != ENCODED_COLUMN_NAMES
             if (SchemaUtil.isSystemTable(Bytes.toBytes(SchemaUtil.getTableName(schemaName, tableName)))) {
                 // System tables have hard-coded column qualifiers. So we can't use column encoding for them.
                 storageScheme = StorageScheme.NON_ENCODED_COLUMN_NAMES;
@@ -1922,7 +1923,7 @@ public class MetaDataClient {
                     // HTable.
                     storageScheme = parent.getStorageScheme();
                     if (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES) {
-                        nextColumnQualifiers  = SchemaUtil.getNextColumnQualifiers(parent);
+                        nextColumnQualifiers  = SchemaUtil.getNextEncodedColumnQualifiers(parent);
                     }
                 }
             } else {
@@ -2804,7 +2805,7 @@ public class MetaDataClient {
                 List<PColumn> columns = Lists.newArrayListWithExpectedSize(columnDefs.size());
                 Set<String> colFamiliesForPColumnsToBeAdded = new LinkedHashSet<>();
                 Set<String> families = new LinkedHashSet<>();
-                Map<String, Integer> nextColumnQualifiers = SchemaUtil.getNextColumnQualifiers(table);
+                Map<String, Integer> nextColumnQualifiers = SchemaUtil.getNextEncodedColumnQualifiers(table);
                 if (columnDefs.size() > 0 ) {
                     try (PreparedStatement colUpsert = connection.prepareStatement(INSERT_COLUMN_ALTER_TABLE)) {
                         short nextKeySeq = SchemaUtil.getMaxKeySeq(table);
@@ -3133,8 +3134,7 @@ public class MetaDataClient {
                     Set<ColumnReference> coveredColumns = indexMaintainer.getCoverededColumns();
                     List<PColumn> indexColumnsToDrop = Lists.newArrayListWithExpectedSize(columnRefs.size());
                     for(PColumn columnToDrop : tableColumnsToDrop) {
-                        // if the columns being dropped is indexed and the physical index table is not shared
-                        ColumnReference columnToDropRef = new ColumnReference(columnToDrop.getFamilyName().getBytes(), SchemaUtil.getColumnQualifier(columnToDrop, index));
+                        ColumnReference columnToDropRef = new ColumnReference(columnToDrop.getFamilyName().getBytes(), EncodedColumnsUtil.getColumnQualifier(columnToDrop, index));
                         if (indexColumns.contains(columnToDropRef)) {
                             if (index.getViewIndexId()==null) 
                                 indexesToDrop.add(new TableRef(index));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
index 8f61d6d..a2fadac 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
@@ -66,5 +66,5 @@ public interface PColumn extends PDatum {
      * TODO: samarth I think we should should change this to return byte[] array.
      * Then we won't have to worry about calling SchemaUtil... everywhere 
      */
-    Integer getColumnQualifier();
+    Integer getEncodedColumnQualifier();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
index a3d855b..c175aa2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
@@ -21,7 +21,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.SizedUtil;
 
 import com.google.common.base.Preconditions;
@@ -34,7 +34,7 @@ public class PColumnFamilyImpl implements PColumnFamily {
     private final List<PColumn> columns;
     private final Map<String, PColumn> columnNamesByStrings;
     private final Map<byte[], PColumn> columnNamesByBytes;
-    private final Map<byte[], PColumn> columnQualifiersByBytes;
+    private final Map<byte[], PColumn> encodedColumnQualifersByBytes;
     private final int estimatedSize;
 
     @Override
@@ -51,19 +51,18 @@ public class PColumnFamilyImpl implements PColumnFamily {
         this.columns = ImmutableList.copyOf(columns);
         ImmutableMap.Builder<String, PColumn> columnNamesByStringBuilder = ImmutableMap.builder();
         ImmutableSortedMap.Builder<byte[], PColumn> columnNamesByBytesBuilder = ImmutableSortedMap.orderedBy(Bytes.BYTES_COMPARATOR);
-        ImmutableSortedMap.Builder<byte[], PColumn> columnQualifiersByBytesBuilder = ImmutableSortedMap.orderedBy(Bytes.BYTES_COMPARATOR);
+        ImmutableSortedMap.Builder<byte[], PColumn> encodedColumnQualifiersByBytesBuilder = ImmutableSortedMap.orderedBy(Bytes.BYTES_COMPARATOR);
         for (PColumn column : columns) {
             estimatedSize += column.getEstimatedSize();
             columnNamesByBytesBuilder.put(column.getName().getBytes(), column);
             columnNamesByStringBuilder.put(column.getName().getString(), column);
-            // TODO: samarth fix this. projected columns have column family for pk columns which messes up with checks.
-            if (!useEncodedColumnNames || (useEncodedColumnNames && !(column.getColumnQualifier() == null))) {
-                columnQualifiersByBytesBuilder.put(SchemaUtil.getColumnQualifier(column, useEncodedColumnNames), column);
+            if (useEncodedColumnNames && column.getEncodedColumnQualifier() != null) {
+                encodedColumnQualifiersByBytesBuilder.put(EncodedColumnsUtil.getEncodedColumnQualifier(column), column);
             }
         }
         this.columnNamesByBytes = columnNamesByBytesBuilder.build();
         this.columnNamesByStrings = columnNamesByStringBuilder.build();
-        this.columnQualifiersByBytes = useEncodedColumnNames ? columnQualifiersByBytesBuilder.build() : columnNamesByBytes;
+        this.encodedColumnQualifersByBytes =  encodedColumnQualifiersByBytesBuilder.build();
         this.estimatedSize = (int)estimatedSize;
     }
     
@@ -97,9 +96,13 @@ public class PColumnFamilyImpl implements PColumnFamily {
     
     @Override
     public PColumn getPColumnForColumnQualifier(byte[] cq) throws ColumnNotFoundException {
-        PColumn column = columnQualifiersByBytes.get(cq);
+        Preconditions.checkNotNull(cq);
+        PColumn column = encodedColumnQualifersByBytes.get(cq);
         if (column == null) {
-            throw new ColumnNotFoundException(Bytes.toString(cq));
+            // For tables with non-encoded column names, column qualifiers are
+            // column name bytes. Also dynamic columns don't have encoded column
+            // qualifiers. So they could be found in the column name by bytes map.
+            return getPColumnForColumnNameBytes(cq);
         }
         return column;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
index 5cf1465..d7d2e0c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnImpl.java
@@ -58,7 +58,7 @@ public class PColumnImpl implements PColumn {
 
     public PColumnImpl(PColumn column, int position) {
         this(column.getName(), column.getFamilyName(), column.getDataType(), column.getMaxLength(),
-                column.getScale(), column.isNullable(), position, column.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic(), column.getColumnQualifier());
+                column.getScale(), column.isNullable(), position, column.getSortOrder(), column.getArraySize(), column.getViewConstant(), column.isViewReferenced(), column.getExpressionStr(), column.isRowTimestamp(), column.isDynamic(), column.getEncodedColumnQualifier());
     }
 
     private void init(PName name,
@@ -209,7 +209,7 @@ public class PColumnImpl implements PColumn {
     }
     
     @Override
-    public Integer getColumnQualifier() {
+    public Integer getEncodedColumnQualifier() {
         return columnQualifier;
     }
 
@@ -294,8 +294,8 @@ public class PColumnImpl implements PColumn {
             builder.setExpression(column.getExpressionStr());
         }
         builder.setIsRowTimestamp(column.isRowTimestamp());
-        if (column.getColumnQualifier() != null) {
-            builder.setColumnQualifier(column.getColumnQualifier());
+        if (column.getEncodedColumnQualifier() != null) {
+            builder.setColumnQualifier(column.getEncodedColumnQualifier());
         }
         return builder.build();
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
index 4c42d69..46a5305 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java
@@ -438,7 +438,7 @@ public class PMetaDataImpl implements PMetaData {
             // Update position of columns that follow removed column
             for (int i = position+1; i < oldColumns.size(); i++) {
                 PColumn oldColumn = oldColumns.get(i);
-                PColumn newColumn = new PColumnImpl(oldColumn.getName(), oldColumn.getFamilyName(), oldColumn.getDataType(), oldColumn.getMaxLength(), oldColumn.getScale(), oldColumn.isNullable(), i-1+positionOffset, oldColumn.getSortOrder(), oldColumn.getArraySize(), oldColumn.getViewConstant(), oldColumn.isViewReferenced(), null, oldColumn.isRowTimestamp(), oldColumn.isDynamic(), oldColumn.getColumnQualifier());
+                PColumn newColumn = new PColumnImpl(oldColumn.getName(), oldColumn.getFamilyName(), oldColumn.getDataType(), oldColumn.getMaxLength(), oldColumn.getScale(), oldColumn.isNullable(), i-1+positionOffset, oldColumn.getSortOrder(), oldColumn.getArraySize(), oldColumn.getViewConstant(), oldColumn.isViewReferenced(), null, oldColumn.isRowTimestamp(), oldColumn.isDynamic(), oldColumn.getEncodedColumnQualifier());
                 columns.add(newColumn);
             }
             

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index ec6f6f3..577d1c5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -17,7 +17,6 @@
  */
 package org.apache.phoenix.schema;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static org.apache.phoenix.hbase.index.util.KeyValueBuilder.addQuietly;
 import static org.apache.phoenix.hbase.index.util.KeyValueBuilder.deleteQuietly;
 import static org.apache.phoenix.schema.SaltingUtil.SALTING_COLUMN;
@@ -66,6 +65,7 @@ import org.apache.phoenix.schema.types.PFloat;
 import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PVarchar;
 import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.EncodedColumnsUtil;
 import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.SizedUtil;
 import org.apache.phoenix.util.StringUtil;
@@ -114,7 +114,7 @@ public class PTableImpl implements PTable {
     private Map<byte[], PColumnFamily> familyByBytes;
     private Map<String, PColumnFamily> familyByString;
     private ListMultimap<String, PColumn> columnsByName;
-    private ListMultimap<Integer, PColumn> kvColumnsByColumnQualifiers;
+    private ListMultimap<Integer, PColumn> kvColumnsByEncodedColumnNames;
     private PName pkName;
     private Integer bucketNum;
     private RowKeySchema rowKeySchema;
@@ -414,7 +414,7 @@ public class PTableImpl implements PTable {
         PColumn[] allColumns;
         
         this.columnsByName = ArrayListMultimap.create(columns.size(), 1);
-        this.kvColumnsByColumnQualifiers = (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES ? ArrayListMultimap.<Integer, PColumn>create(columns.size(), 1) : null);
+        this.kvColumnsByEncodedColumnNames = (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES ? ArrayListMultimap.<Integer, PColumn>create(columns.size(), 1) : null);
         int numPKColumns = 0;
         if (bucketNum != null) {
             // Add salt column to allColumns and pkColumns, but don't add to
@@ -446,12 +446,12 @@ public class PTableImpl implements PTable {
                     }
                 }
             }
-            Integer cq = column.getColumnQualifier();
+            Integer cq = column.getEncodedColumnQualifier();
             //TODO: samarth understand the implication of this.
-            if (kvColumnsByColumnQualifiers != null && cq != null) {
-                if (kvColumnsByColumnQualifiers.put(cq, column)) {
+            if (kvColumnsByEncodedColumnNames != null && cq != null) {
+                if (kvColumnsByEncodedColumnNames.put(cq, column)) {
                     int count = 0;
-                    for (PColumn dupColumn : kvColumnsByColumnQualifiers.get(cq)) {
+                    for (PColumn dupColumn : kvColumnsByEncodedColumnNames.get(cq)) {
                         if (Objects.equal(familyName, dupColumn.getFamilyName())) {
                             count++;
                             if (count > 1) {
@@ -729,12 +729,13 @@ public class PTableImpl implements PTable {
     
     @Override
     public PColumn getPColumnForColumnQualifier(byte[] cq) throws ColumnNotFoundException, AmbiguousColumnException {
-        if (SchemaUtil.usesEncodedColumnNames(this)) {
+        Preconditions.checkNotNull(cq);
+        if (!EncodedColumnsUtil.usesEncodedColumnNames(this)) {
             String columnName = (String)PVarchar.INSTANCE.toObject(cq);
             return getPColumnForColumnName(columnName);
         } else {
             Integer qualifier = (Integer)PInteger.INSTANCE.toObject(cq);
-            List<PColumn> columns = kvColumnsByColumnQualifiers.get(qualifier);
+            List<PColumn> columns = kvColumnsByEncodedColumnNames.get(qualifier);
             int size = columns.size();
             if (size == 0) {
                 //TODO: samarth should we have a column qualifier not found exception?
@@ -810,7 +811,7 @@ public class PTableImpl implements PTable {
                 // Because we cannot enforce a not null constraint on a KV column (since we don't know if the row exists when
                 // we upsert it), se instead add a KV that is always emtpy. This allows us to imitate SQL semantics given the
                 // way HBase works.
-                Pair<byte[], byte[]> emptyKvInfo = SchemaUtil.getEmptyKeyValueInfo(PTableImpl.this);
+                Pair<byte[], byte[]> emptyKvInfo = EncodedColumnsUtil.getEmptyKeyValueInfo(PTableImpl.this);
                 addQuietly(setValues, kvBuilder, kvBuilder.buildPut(keyPtr,
                     SchemaUtil.getEmptyColumnFamilyPtr(PTableImpl.this),
                     new ImmutableBytesPtr(emptyKvInfo.getFirst()), ts,
@@ -849,7 +850,7 @@ public class PTableImpl implements PTable {
             deleteRow = null;
             byte[] family = column.getFamilyName().getBytes();
             byte[] qualifier = getColumnQualifier(column);
-            ImmutableBytesPtr qualifierPtr = getColumnQualifierPtr(column);
+            ImmutableBytesPtr qualifierPtr = new ImmutableBytesPtr(qualifier);
             PDataType type = column.getDataType();
             // Check null, since some types have no byte representation for null
             boolean isNull = type.isNull(byteValue);
@@ -904,24 +905,9 @@ public class PTableImpl implements PTable {
         }
         
         private byte[] getColumnQualifier(PColumn column) {
-            //return column.getName().getBytes();
-            checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
-            boolean tableUsesEncodedColumnNames = SchemaUtil.usesEncodedColumnNames(PTableImpl.this);
-            if (!tableUsesEncodedColumnNames) {
-                return column.getName().getBytes();
-            }
-            return PInteger.INSTANCE.toBytes(column.getColumnQualifier());
+            return EncodedColumnsUtil.getColumnQualifier(column, PTableImpl.this);
         }
         
-        private ImmutableBytesPtr getColumnQualifierPtr(PColumn column) {
-//            return column.getName().getBytesPtr();
-            checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
-            boolean tableUsesEncodedColumnNames = SchemaUtil.usesEncodedColumnNames(PTableImpl.this);
-            if (!tableUsesEncodedColumnNames) {
-                return column.getName().getBytesPtr();
-            }
-            return new ImmutableBytesPtr(PInteger.INSTANCE.toBytes(column.getColumnQualifier()));
-        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java
new file mode 100644
index 0000000..bfbfc54
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java
@@ -0,0 +1,77 @@
+/*
+ * 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.phoenix.util;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTable.StorageScheme;
+import org.apache.phoenix.schema.types.PInteger;
+
+public class EncodedColumnsUtil {
+
+    public static boolean usesEncodedColumnNames(PTable table) {
+        return table.getStorageScheme() != null && table.getStorageScheme() == StorageScheme.ENCODED_COLUMN_NAMES;
+    }
+
+    public static byte[] getEncodedColumnQualifier(PColumn column) {
+        checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
+        checkArgument(!column.isDynamic(), "No encoded column qualifiers for dynamic columns");
+        return PInteger.INSTANCE.toBytes(column.getEncodedColumnQualifier());
+    }
+
+    public static byte[] getColumnQualifier(PColumn column, PTable table) {
+      return EncodedColumnsUtil.getColumnQualifier(column, usesEncodedColumnNames(table));
+    }
+
+    public static byte[] getColumnQualifier(PColumn column, boolean encodedColumnName) {
+        checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
+        if (column.isDynamic()) { // Dynamic column names don't have encoded column names
+            return column.getName().getBytes();
+        }
+        return encodedColumnName ? PInteger.INSTANCE.toBytes(column.getEncodedColumnQualifier()) : column.getName().getBytes(); 
+    }
+
+    /**
+     * @return pair of byte arrays. The first part of the pair is the empty key value's column qualifier, and the second
+     *         part is the value to use for it.
+     */
+    public static Pair<byte[], byte[]> getEmptyKeyValueInfo(PTable table) {
+        return usesEncodedColumnNames(table) ? new Pair<>(QueryConstants.ENCODED_EMPTY_COLUMN_BYTES,
+                QueryConstants.ENCODED_EMPTY_COLUMN_VALUE_BYTES) : new Pair<>(QueryConstants.EMPTY_COLUMN_BYTES,
+                QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+    }
+
+    /**
+     * @return pair of byte arrays. The first part of the pair is the empty key value's column qualifier, and the second
+     *         part is the value to use for it.
+     */
+    public static Pair<byte[], byte[]> getEmptyKeyValueInfo(boolean usesEncodedColumnNames) {
+        return usesEncodedColumnNames ? new Pair<>(QueryConstants.ENCODED_EMPTY_COLUMN_BYTES,
+                QueryConstants.ENCODED_EMPTY_COLUMN_VALUE_BYTES) : new Pair<>(QueryConstants.EMPTY_COLUMN_BYTES,
+                QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+    }
+
+    public static boolean hasEncodedColumnName(PColumn column){
+        return !SchemaUtil.isPKColumn(column) && !column.isDynamic() && column.getEncodedColumnQualifier() != null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
index 15fc605..49ac1f4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
@@ -198,7 +198,7 @@ public class IndexUtil {
 
     private static boolean isEmptyKeyValue(PTable table, ColumnReference ref) {
         byte[] emptyKeyValueCF = SchemaUtil.getEmptyColumnFamily(table);
-        byte[] emptyKeyValueQualifier = SchemaUtil.getEmptyKeyValueInfo(table).getFirst();
+        byte[] emptyKeyValueQualifier = EncodedColumnsUtil.getEmptyKeyValueInfo(table).getFirst();
         return (Bytes.compareTo(emptyKeyValueCF, 0, emptyKeyValueCF.length, ref.getFamilyWritable()
                 .get(), ref.getFamilyWritable().getOffset(), ref.getFamilyWritable().getLength()) == 0 && Bytes
                 .compareTo(emptyKeyValueQualifier, 0,

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
index d7d7d8b..216cf34 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
@@ -157,7 +157,7 @@ public class SchemaUtil {
     			rowSize += KeyValue.getKeyValueDataStructureSize(keyLength, column.getFamilyName().getBytes().length, column.getName().getBytes().length, valueLength);
     		}
     	}
-    	byte[] emptyKeyValueKV = SchemaUtil.getEmptyKeyValueInfo(table).getFirst();
+    	byte[] emptyKeyValueKV = EncodedColumnsUtil.getEmptyKeyValueInfo(table).getFirst();
     	// Empty key value
     	rowSize += KeyValue.getKeyValueDataStructureSize(keyLength, getEmptyColumnFamily(table).length, emptyKeyValueKV.length, 0);
     	return rowSize;
@@ -1024,14 +1024,22 @@ public class SchemaUtil {
     /**
      * Return a map of column family -> next column qualifier number to use.
      */
-    public static Map<String, Integer> getNextColumnQualifiers(PTable table) {
-        Map<String, Integer> map = Maps.newHashMapWithExpectedSize(table.getColumns().size());
-        for (PColumnFamily f : table.getColumnFamilies()) {
-            final int size = f.getColumns().size();
-            // column qualifiers start with 1.
-            map.put(f.getName().getString(), size + 1);
+    public static Map<String, Integer> getNextEncodedColumnQualifiers(PTable table) {
+        if (EncodedColumnsUtil.usesEncodedColumnNames(table)) {
+            Map<String, Integer> map = Maps.newHashMapWithExpectedSize(table.getColumns().size());
+            int max = 0; 
+            for (PColumnFamily f : table.getColumnFamilies()) {
+                for (PColumn column : f.getColumns()) {
+                    if (column.getEncodedColumnQualifier() > max) {
+                        max = column.getEncodedColumnQualifier();
+                    }
+                }
+                // column qualifiers start with 1.
+                map.put(f.getName().getString(), max + 1);
+            }
+            return map;
         }
-        return map;
+        return null;
     }
     
     public static boolean usesEncodedColumnNames(PTable table) {
@@ -1040,12 +1048,12 @@ public class SchemaUtil {
     
     public static byte[] getColumnQualifier(PColumn column, PTable table) {
       checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
-      return usesEncodedColumnNames(table) ? PInteger.INSTANCE.toBytes(column.getColumnQualifier()) : column.getName().getBytes();
+      return usesEncodedColumnNames(table) ? PInteger.INSTANCE.toBytes(column.getEncodedColumnQualifier()) : column.getName().getBytes();
     }
     
     public static byte[] getColumnQualifier(PColumn column, boolean encodedColumnName) {
         checkArgument(!SchemaUtil.isPKColumn(column), "No column qualifiers for PK columns");
-        return encodedColumnName ? PInteger.INSTANCE.toBytes(column.getColumnQualifier()) : column.getName().getBytes(); 
+        return encodedColumnName ? PInteger.INSTANCE.toBytes(column.getEncodedColumnQualifier()) : column.getName().getBytes(); 
     }
     
     /**
@@ -1069,7 +1077,7 @@ public class SchemaUtil {
     }
     
     public static boolean hasEncodedColumnName(PColumn column){
-        return !SchemaUtil.isPKColumn(column) && column.getColumnQualifier() != null;
+        return !SchemaUtil.isPKColumn(column) && column.getEncodedColumnQualifier() != null;
     }
     
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/8a9ffe5c/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
index cb9c640..70156a1 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/iterate/AggregateResultScannerTest.java
@@ -138,7 +138,7 @@ public class AggregateResultScannerTest extends BaseConnectionlessQueryTest {
 				return false;
 			}
             @Override
-            public Integer getColumnQualifier() {
+            public Integer getEncodedColumnQualifier() {
                 return null;
             }
         }, false)), null);


[48/52] [abbrv] phoenix git commit: Changes to fix index tests

Posted by sa...@apache.org.
Changes to fix index tests


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

Branch: refs/heads/encodecolumns
Commit: 13a900f63aa02e724ae9a62d4a5032ca8a3cbb6c
Parents: 55c5a72
Author: Samarth <sa...@salesforce.com>
Authored: Wed Mar 23 12:53:12 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Apr 25 11:51:31 2016 -0700

----------------------------------------------------------------------
 .../phoenix/compile/ProjectionCompiler.java     |  2 +-
 .../apache/phoenix/compile/UnionCompiler.java   |  2 +-
 .../UngroupedAggregateRegionObserver.java       |  2 +-
 .../apache/phoenix/execute/BaseQueryPlan.java   | 16 +++--
 .../expression/KeyValueColumnExpression.java    |  2 +-
 .../apache/phoenix/index/IndexMaintainer.java   | 69 ++++++++++++--------
 .../index/PhoenixTransactionalIndexer.java      |  1 -
 .../phoenix/iterate/BaseResultIterators.java    |  1 -
 .../mapreduce/FormatToKeyValueReducer.java      |  1 +
 .../apache/phoenix/schema/MetaDataClient.java   | 15 ++---
 .../java/org/apache/phoenix/schema/PColumn.java |  2 +
 .../java/org/apache/phoenix/schema/PTable.java  |  1 -
 .../org/apache/phoenix/schema/PTableImpl.java   |  6 +-
 .../java/org/apache/phoenix/util/IndexUtil.java |  4 --
 14 files changed, 68 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
index b6a6771..e07b350 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
@@ -702,7 +702,7 @@ public class ProjectionCompiler {
                      public Void visit(ProjectedColumnExpression expression) {
                          if (expression.getDataType().isArrayType()) {
                              indexProjectedColumns.add(expression);
-                             //TODO: samarth confirm this change that column names 
+                             //TODO: samarth confirm this change is to have encodedColumnNames as false. 
                              KeyValueColumnExpression keyValueColumnExpression = new KeyValueColumnExpression(expression.getColumn(), false);
                              indexKVs.add(keyValueColumnExpression);
                              copyOfChildren.set(0, keyValueColumnExpression);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
index 9c79bfb..7b534ba 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UnionCompiler.java
@@ -74,7 +74,7 @@ public class UnionCompiler {
             ColumnProjector colProj = plan.getProjector().getColumnProjector(i);
             Expression sourceExpression = colProj.getExpression();
             String name = selectNodes == null ? colProj.getName() : selectNodes.get(i).getAlias();
-            //TODO: samarth confirm this is the right change
+            //TODO: samarth confirm that column qualifier can be null here.
             PColumnImpl projectedColumn = new PColumnImpl(PNameFactory.newName(name), UNION_FAMILY_NAME,
                     sourceExpression.getDataType(), sourceExpression.getMaxLength(), sourceExpression.getScale(), sourceExpression.isNullable(),
                     i, sourceExpression.getSortOrder(), 500, null, false, sourceExpression.toString(), false, false, null);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
index 3bdcee3..950817f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
@@ -246,7 +246,7 @@ public class UngroupedAggregateRegionObserver extends BaseScannerRegionObserver
                 deleteCQ = scan.getAttribute(BaseScannerRegionObserver.DELETE_CQ);
             }
             emptyCF = scan.getAttribute(BaseScannerRegionObserver.EMPTY_CF);
-            emptyKVQualifier = scan.getAttribute(BaseScannerRegionObserver.EMPTY_COLUMN_QUALIFIER);
+            emptyKVQualifier = scan.getAttribute(BaseScannerRegionObserver.EMPTY_COLUMN_QUALIFIER);//TODO: samarth check this
         }
         TupleProjector tupleProjector = null;
         HRegion dataRegion = null;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
index e08dae1..302c3d1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
@@ -74,6 +74,7 @@ import org.apache.phoenix.util.LogUtil;
 import org.apache.phoenix.util.SQLCloseable;
 import org.apache.phoenix.util.SQLCloseables;
 import org.apache.phoenix.util.ScanUtil;
+import org.apache.phoenix.util.SchemaUtil;
 import org.cloudera.htrace.TraceScope;
 
 import com.google.common.collect.ImmutableSet;
@@ -287,11 +288,6 @@ public abstract class BaseQueryPlan implements QueryPlan {
             // TODO: can have an hint to skip joining back to data table, in that case if any column to
             // project is not present in the index then we need to skip this plan.
             if (!dataColumns.isEmpty()) {
-                // Set data columns to be join back from data table.
-                serializeDataTableColumnsToJoin(scan, dataColumns);
-                KeyValueSchema schema = ProjectedColumnExpression.buildSchema(dataColumns);
-                // Set key value schema of the data columns.
-                serializeSchemaIntoScan(scan, schema);
                 PTable parentTable = context.getCurrentTable().getTable();
                 String parentSchemaName = parentTable.getParentSchemaName().getString();
                 String parentTableName = parentTable.getParentTableName().getString();
@@ -302,6 +298,12 @@ public abstract class BaseQueryPlan implements QueryPlan {
                             FACTORY.namedTable(null, TableName.create(parentSchemaName, parentTableName)),
                             context.getConnection()).resolveTable(parentSchemaName, parentTableName);
                 PTable dataTable = dataTableRef.getTable();
+                // Set data columns to be join back from data table.
+                serializeDataTableColumnsToJoin(scan, dataColumns, dataTable);
+                KeyValueSchema schema = ProjectedColumnExpression.buildSchema(dataColumns);
+                // Set key value schema of the data columns.
+                serializeSchemaIntoScan(scan, schema);
+                
                 // Set index maintainer of the local index.
                 serializeIndexMaintainerIntoScan(scan, dataTable);
                 // Set view constants if exists.
@@ -404,14 +406,14 @@ public abstract class BaseQueryPlan implements QueryPlan {
         }
     }
 
-    private void serializeDataTableColumnsToJoin(Scan scan, Set<PColumn> dataColumns) {
+    private void serializeDataTableColumnsToJoin(Scan scan, Set<PColumn> dataColumns, PTable dataTable) {
         ByteArrayOutputStream stream = new ByteArrayOutputStream();
         try {
             DataOutputStream output = new DataOutputStream(stream);
             WritableUtils.writeVInt(output, dataColumns.size());
             for (PColumn column : dataColumns) {
                 Bytes.writeByteArray(output, column.getFamilyName().getBytes());
-                Bytes.writeByteArray(output, column.getName().getBytes());
+                Bytes.writeByteArray(output, SchemaUtil.getColumnQualifier(column, dataTable));
             }
             scan.setAttribute(BaseScannerRegionObserver.DATA_TABLE_COLUMNS_TO_JOIN, stream.toByteArray());
         } catch (IOException e) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
index 163cc72..3787d6e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java
@@ -41,7 +41,7 @@ import org.apache.phoenix.util.SchemaUtil;
 public class KeyValueColumnExpression extends ColumnExpression {
     private byte[] cf;
     private byte[] cq;
-    private String displayName; // client-side only
+    private String displayName; // client-side only. TODO: samarth see what can you do for encoded column names.
 
     public KeyValueColumnExpression() {
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
index 9dfc5d3..7ea39fd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
@@ -32,8 +32,11 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
+import co.cask.tephra.TxConstants;
+
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.HConstants;
@@ -95,8 +98,6 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
-import co.cask.tephra.TxConstants;
-
 /**
  * 
  * Class that builds index row key from data row key and current state of
@@ -292,7 +293,6 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
     private final boolean isDataTableSalted;
     private final RowKeySchema dataRowKeySchema;
     
-    private List<ImmutableBytesPtr> indexQualifiers;
     private int estimatedIndexRowKeyBytes;
     private int estimatedExpressionSize;
     private int[] dataPkPosition;
@@ -301,6 +301,9 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
     private boolean rowKeyOrderOptimizable;
     private boolean usesEncodedColumnNames;
     private ImmutableBytesPtr emptyKeyValueQualifierPtr;
+    // Map of covered columns where the key part is the column reference for column in data table
+    // and value is the column reference for column in the index table.
+    private Map<ColumnReference, ColumnReference> coveredColumnsMap;
     
     private IndexMaintainer(RowKeySchema dataRowKeySchema, boolean isDataTableSalted) {
         this.dataRowKeySchema = dataRowKeySchema;
@@ -320,7 +323,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
          * that is serialized in it. Because of this we are forced to have the indexes inherit the
          * storage scheme of the parent data tables. 
          */
-        this.usesEncodedColumnNames = SchemaUtil.usesEncodedColumnNames(index);
+        this.usesEncodedColumnNames = SchemaUtil.usesEncodedColumnNames(dataTable);
         byte[] indexTableName = index.getPhysicalName().getBytes();
         // Use this for the nDataSaltBuckets as we need this for local indexes
         // TODO: persist nDataSaltBuckets separately, but maintain b/w compat.
@@ -370,6 +373,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
         this.indexedColumnTypes = Lists.<PDataType>newArrayListWithExpectedSize(nIndexPKColumns-nDataPKColumns);
         this.indexedExpressions = Lists.newArrayListWithExpectedSize(nIndexPKColumns-nDataPKColumns);
         this.coveredColumns = Sets.newLinkedHashSetWithExpectedSize(nIndexColumns-nIndexPKColumns);
+        this.coveredColumnsMap = Maps.newHashMapWithExpectedSize(nIndexColumns - nIndexPKColumns);
         this.nIndexSaltBuckets  = nIndexSaltBuckets == null ? 0 : nIndexSaltBuckets;
         this.dataEmptyKeyValueCF = SchemaUtil.getEmptyColumnFamily(dataTable);
         this.emptyKeyValueCFPtr = SchemaUtil.getEmptyColumnFamilyPtr(index);
@@ -435,9 +439,12 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
         for (int i = 0; i < index.getColumnFamilies().size(); i++) {
             PColumnFamily family = index.getColumnFamilies().get(i);
             for (PColumn indexColumn : family.getColumns()) {
-                PColumn column = IndexUtil.getDataColumn(dataTable, indexColumn.getName().getString());
-                byte[] cq = SchemaUtil.getColumnQualifier(column, index);
-                this.coveredColumns.add(new ColumnReference(column.getFamilyName().getBytes(), cq));
+                PColumn dataColumn = IndexUtil.getDataColumn(dataTable, indexColumn.getName().getString());
+                byte[] dataColumnCq = SchemaUtil.getColumnQualifier(dataColumn, dataTable);
+                byte[] indexColumnCq = SchemaUtil.getColumnQualifier(indexColumn, index);
+                this.coveredColumns.add(new ColumnReference(dataColumn.getFamilyName().getBytes(), dataColumnCq));
+                this.coveredColumnsMap.put(new ColumnReference(dataColumn.getFamilyName().getBytes(), dataColumnCq), 
+                        new ColumnReference(indexColumn.getFamilyName().getBytes(), indexColumnCq));
             }
         }
         this.estimatedIndexRowKeyBytes = estimateIndexRowKeyByteSize(indexColByteSize);
@@ -856,9 +863,9 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
                 emptyKeyValueQualifierPtr));
             put.setDurability(!indexWALDisabled ? Durability.USE_DEFAULT : Durability.SKIP_WAL);
         }
-        int i = 0;
         for (ColumnReference ref : this.getCoverededColumns()) {
-            ImmutableBytesPtr cq = this.indexQualifiers.get(i++);
+            //FIXME: samarth figure out a backward compatible way to handle this as coveredcolumnsmap won't be availble for older phoenix clients.
+            ImmutableBytesPtr cq = this.coveredColumnsMap.get(ref).getQualifierWritable();
             ImmutableBytesWritable value = valueGetter.getLatestValue(ref);
             byte[] indexRowKey = this.buildRowKey(valueGetter, dataRowKeyPtr, regionStartKey, regionEndKey);
             ImmutableBytesPtr rowKey = new ImmutableBytesPtr(indexRowKey);
@@ -978,11 +985,15 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
                         delete = new Delete(indexRowKey);                    
                         delete.setDurability(!indexWALDisabled ? Durability.USE_DEFAULT : Durability.SKIP_WAL);
                     }
+                    ColumnReference indexColumn = coveredColumnsMap.get(ref);
                     // If point delete for data table, then use point delete for index as well
-                    if (kv.getTypeByte() == KeyValue.Type.Delete.getCode()) {
-                        delete.deleteColumn(ref.getFamily(), IndexUtil.getIndexColumnName(ref.getFamily(), ref.getQualifier()), ts);
+                    if (kv.getTypeByte() == KeyValue.Type.Delete.getCode()) { 
+                        //FIXME: samarth change this. Index column qualifiers are not derivable from data table cqs.
+                        // Figure out a backward compatible way of going this since coveredColumnsMap won't be available
+                        // for older clients.
+                        delete.deleteColumn(indexColumn.getFamily(), indexColumn.getQualifier(), ts);
                     } else {
-                        delete.deleteColumns(ref.getFamily(), IndexUtil.getIndexColumnName(ref.getFamily(), ref.getQualifier()), ts);
+                        delete.deleteColumns(indexColumn.getFamily(), indexColumn.getQualifier(), ts);
                     }
                 }
             }
@@ -1037,10 +1048,16 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
         isLocalIndex = encodedCoveredolumnsAndLocalIndex < 0;
         int nCoveredColumns = Math.abs(encodedCoveredolumnsAndLocalIndex) - 1;
         coveredColumns = Sets.newLinkedHashSetWithExpectedSize(nCoveredColumns);
+        coveredColumnsMap = Maps.newHashMapWithExpectedSize(nCoveredColumns);
         for (int i = 0; i < nCoveredColumns; i++) {
-            byte[] cf = Bytes.readByteArray(input);
-            byte[] cq = Bytes.readByteArray(input);
-            coveredColumns.add(new ColumnReference(cf,cq));
+            byte[] dataTableCf = Bytes.readByteArray(input);
+            byte[] dataTableCq = Bytes.readByteArray(input);
+            byte[] indexTableCf = Bytes.readByteArray(input);
+            byte[] indexTableCq = Bytes.readByteArray(input);
+            ColumnReference dataColumn = new ColumnReference(dataTableCf, dataTableCq); 
+            coveredColumns.add(dataColumn);
+            ColumnReference indexColumn = new ColumnReference(indexTableCf, indexTableCq);
+            coveredColumnsMap.put(dataColumn, indexColumn);
         }
         // Hack to serialize whether the index row key is optimizable
         int len = WritableUtils.readVInt(input);
@@ -1144,9 +1161,13 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
         }
         // Encode coveredColumns.size() and whether or not this is a local index
         WritableUtils.writeVInt(output, (coveredColumns.size() + 1) * (isLocalIndex ? -1 : 1));
-        for (ColumnReference ref : coveredColumns) {
-            Bytes.writeByteArray(output, ref.getFamily());
-            Bytes.writeByteArray(output, ref.getQualifier());
+        for (Entry<ColumnReference, ColumnReference> ref : coveredColumnsMap.entrySet()) {
+            ColumnReference dataColumn = ref.getKey();
+            ColumnReference indexColumn = ref.getValue();
+            Bytes.writeByteArray(output, dataColumn.getFamily());
+            Bytes.writeByteArray(output, dataColumn.getQualifier());
+            Bytes.writeByteArray(output, indexColumn.getFamily());
+            Bytes.writeByteArray(output, indexColumn.getQualifier());
         }
         // TODO: remove when rowKeyOrderOptimizable hack no longer needed
         WritableUtils.writeVInt(output,indexTableName.length * (rowKeyOrderOptimizable ? 1 : -1));
@@ -1216,15 +1237,9 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
      * Init calculated state reading/creating
      */
     private void initCachedState() {
-        dataEmptyKeyValueRef = new ColumnReference(emptyKeyValueCFPtr.copyBytesIfNecessary(), SchemaUtil
-                .getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst());
-        emptyKeyValueQualifierPtr = new ImmutableBytesPtr(SchemaUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst());
-        indexQualifiers = Lists.newArrayListWithExpectedSize(this.coveredColumns.size());
-        for (ColumnReference ref : coveredColumns) {
-            indexQualifiers.add(new ImmutableBytesPtr(IndexUtil.getIndexColumnName(
-                ref.getFamily(), ref.getQualifier())));
-        }
-
+        byte[] emptyKvQualifier = SchemaUtil.getEmptyKeyValueInfo(usesEncodedColumnNames).getFirst();
+        dataEmptyKeyValueRef = new ColumnReference(emptyKeyValueCFPtr.copyBytesIfNecessary(), emptyKvQualifier);
+        emptyKeyValueQualifierPtr = new ImmutableBytesPtr(emptyKvQualifier);
         this.allColumns = Sets.newLinkedHashSetWithExpectedSize(indexedExpressions.size() + coveredColumns.size());
         // columns that are required to evaluate all expressions in indexedExpressions (not including columns in data row key)
         this.indexedColumns = Sets.newLinkedHashSetWithExpectedSize(indexedExpressions.size());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
index 6ee981a..0eeb662 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
@@ -221,7 +221,6 @@ public class PhoenixTransactionalIndexer extends BaseRegionObserver {
                 Scan scan = new Scan();
                 // Project all mutable columns
                 for (ColumnReference ref : mutableColumns) {
-                    //TODO: samarth confirm this is ok
                     scan.addColumn(ref.getFamily(), ref.getQualifier());
                 }
                 // Indexes inherit the storage scheme of the data table which means all the indexes have the same

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
index e743dc7..959e9f6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
@@ -302,7 +302,6 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
                         if (whereCol.getSecond() == null) {
                             scan.addFamily(family);                            
                         } else {
-                            //TODO: samarth confirm this
                             scan.addColumn(family, whereCol.getSecond());
                         }
                     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
index 04fe959..cc1559a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java
@@ -152,6 +152,7 @@ public class FormatToKeyValueReducer
                 }
                 map.add(kv);
             }
+            //FIXME: samarth need to supply the right empty column qualifier here.
             KeyValue empty = builder.buildPut(key.getRowkey(),
                     emptyFamilyName.get(tableIndex),
                     QueryConstants.EMPTY_COLUMN_BYTES_PTR, ByteUtil.EMPTY_BYTE_ARRAY_PTR);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 4893a79..3113a98 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -1925,19 +1925,16 @@ public class MetaDataClient {
                         nextColumnQualifiers  = SchemaUtil.getNextColumnQualifiers(parent);
                     }
                 }
-            } else if (parent != null && tableType == PTableType.INDEX) {
+            } else {
                 // New indexes on existing tables can have encoded column names. But unfortunately, due to 
                 // backward compatibility reasons, we aren't able to change IndexMaintainer and the state
                 // that is serialized in it. Because of this we are forced to have the indexes inherit the
-                // storage scheme of the parent data tables.
-                storageScheme = parent.getStorageScheme();
+                // storage scheme of the parent data tables. Otherwise, we always attempt to create tables 
+                // with encoded column names.
+                storageScheme = parent != null ? parent.getStorageScheme() : StorageScheme.ENCODED_COLUMN_NAMES;
                 if (storageScheme == StorageScheme.ENCODED_COLUMN_NAMES) {
-                    nextColumnQualifiers  = SchemaUtil.getNextColumnQualifiers(parent);
+                    nextColumnQualifiers  = Maps.newHashMapWithExpectedSize(colDefs.size() - pkColumns.size());
                 }
-            } else {
-                // we always attempt to create tables with encoded column names.
-                storageScheme = StorageScheme.ENCODED_COLUMN_NAMES;
-                nextColumnQualifiers = Maps.newHashMapWithExpectedSize(colDefs.size() - pkColumns.size());
             }
             
             for (ColumnDef colDef : colDefs) {
@@ -3136,8 +3133,8 @@ public class MetaDataClient {
                     Set<ColumnReference> coveredColumns = indexMaintainer.getCoverededColumns();
                     List<PColumn> indexColumnsToDrop = Lists.newArrayListWithExpectedSize(columnRefs.size());
                     for(PColumn columnToDrop : tableColumnsToDrop) {
-                        ColumnReference columnToDropRef = new ColumnReference(columnToDrop.getFamilyName().getBytes(), columnToDrop.getName().getBytes());
                         // if the columns being dropped is indexed and the physical index table is not shared
+                        ColumnReference columnToDropRef = new ColumnReference(columnToDrop.getFamilyName().getBytes(), SchemaUtil.getColumnQualifier(columnToDrop, index));
                         if (indexColumns.contains(columnToDropRef)) {
                             if (index.getViewIndexId()==null) 
                                 indexesToDrop.add(new TableRef(index));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
index b63c97b..3ffb845 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumn.java
@@ -63,6 +63,8 @@ public interface PColumn extends PDatum {
     
     /**
      * @return name of the HBase column qualifier
+     * TODO: samarth I think we should should change this to return byte[] array.
+     * Then we won't have to worry about calling SchemaUtil... everywhere. I think.
      */
     Integer getColumnQualifier();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
index 567050c..e32477e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
@@ -237,7 +237,6 @@ public interface PTable extends PMetaDataEntity {
      * can be found
      * @throws AmbiguousColumnException if multiple columns are found with the given name
      */
-    //TODO: samarth inspect all the callers of this method.
     PColumn getPColumnForColumnName(String name) throws ColumnNotFoundException, AmbiguousColumnException;
     
     /**

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index c5a56ab..ec6f6f3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.ByteStringer;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.coprocessor.generated.PGuidePostsProtos;
 import org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts;
 import org.apache.phoenix.coprocessor.generated.PTableProtos;
@@ -809,10 +810,11 @@ public class PTableImpl implements PTable {
                 // Because we cannot enforce a not null constraint on a KV column (since we don't know if the row exists when
                 // we upsert it), se instead add a KV that is always emtpy. This allows us to imitate SQL semantics given the
                 // way HBase works.
+                Pair<byte[], byte[]> emptyKvInfo = SchemaUtil.getEmptyKeyValueInfo(PTableImpl.this);
                 addQuietly(setValues, kvBuilder, kvBuilder.buildPut(keyPtr,
                     SchemaUtil.getEmptyColumnFamilyPtr(PTableImpl.this),
-                    QueryConstants.EMPTY_COLUMN_BYTES_PTR, ts,
-                    QueryConstants.EMPTY_COLUMN_VALUE_BYTES_PTR));
+                    new ImmutableBytesPtr(emptyKvInfo.getFirst()), ts,
+                    new ImmutableBytesPtr(emptyKvInfo.getSecond())));
                 mutations.add(setValues);
                 if (!unsetValues.isEmpty()) {
                     mutations.add(unsetValues);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/13a900f6/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
index 9947e0c..bdc546f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
@@ -148,10 +148,6 @@ public class IndexUtil {
         return (dataColumnFamilyName == null ? "" : dataColumnFamilyName) + INDEX_COLUMN_NAME_SEP + dataColumnName;
     }
     
-    public static byte[] getIndexColumnName(byte[] dataColumnFamilyName, byte[] dataColumnName) {
-        return ByteUtil.concat(dataColumnFamilyName == null ?  ByteUtil.EMPTY_BYTE_ARRAY : dataColumnFamilyName, INDEX_COLUMN_NAME_SEP_BYTES, dataColumnName);
-    }
-    
     public static String getIndexColumnName(PColumn dataColumn) {
         String dataColumnFamilyName = SchemaUtil.isPKColumn(dataColumn) ? null : dataColumn.getFamilyName().getString();
         return getIndexColumnName(dataColumnFamilyName, dataColumn.getName().getString());


[26/52] [abbrv] phoenix git commit: PHOENIX-2838 Support case sensitive identifier for drop schema and use schema constructs

Posted by sa...@apache.org.
PHOENIX-2838 Support case sensitive identifier for drop schema and use schema constructs


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

Branch: refs/heads/encodecolumns
Commit: 6d6c8c452d19cd8f31992b7a0543ffb25d426b2c
Parents: 7e432be
Author: Ankit Singhal <an...@gmail.com>
Authored: Tue Apr 19 20:45:35 2016 +0530
Committer: Ankit Singhal <an...@gmail.com>
Committed: Tue Apr 19 20:45:35 2016 +0530

----------------------------------------------------------------------
 .../apache/phoenix/end2end/DropSchemaIT.java    | 37 ++++++++++++++------
 .../end2end/QueryDatabaseMetaDataIT.java        |  3 ++
 .../org/apache/phoenix/end2end/UseSchemaIT.java | 23 ++++++++----
 .../apache/phoenix/jdbc/PhoenixConnection.java  |  5 ++-
 .../apache/phoenix/schema/MetaDataClient.java   |  7 ++--
 5 files changed, 54 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/6d6c8c45/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropSchemaIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropSchemaIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropSchemaIT.java
index 665c0a8..c3c1d65 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropSchemaIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DropSchemaIT.java
@@ -24,6 +24,8 @@ import static org.junit.Assert.fail;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Properties;
 
 import org.apache.hadoop.hbase.NamespaceDescriptor;
@@ -34,17 +36,33 @@ import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.SchemaNotFoundException;
 import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.TestUtil;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
+@RunWith(Parameterized.class)
 public class DropSchemaIT extends BaseClientManagedTimeIT {
+    private String schema;
+
+    public DropSchemaIT(String schema) {
+        this.schema = schema;
+    }
+
+    @Parameters(name = "schema = {0}")
+    public static Collection<String> data() {
+        return Arrays.asList("TEST_SCHEMA", "\"test_schema\"");
+    }
 
     @Test
     public void testDropSchema() throws Exception {
         long ts = nextTimestamp();
-        String schema = "TEST_SCHEMA";
+
         String tableName = "TEST";
         Properties props = new Properties();
+        String normalizeSchemaIdentifier = SchemaUtil.normalizeIdentifier(schema);
         String ddl = "DROP SCHEMA " + schema;
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts));
         props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
@@ -66,7 +84,7 @@ public class DropSchemaIT extends BaseClientManagedTimeIT {
                 e.printStackTrace();
                 assertEquals(e.getErrorCode(), SQLExceptionCode.CANNOT_MUTATE_SCHEMA.getErrorCode());
             }
-            assertNotNull(admin.getNamespaceDescriptor(schema));
+            assertNotNull(admin.getNamespaceDescriptor(normalizeSchemaIdentifier));
         }
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts - 20));
         try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
@@ -75,20 +93,20 @@ public class DropSchemaIT extends BaseClientManagedTimeIT {
         } catch (SchemaNotFoundException e) {
             // expected
         }
-        assertNotNull(admin.getNamespaceDescriptor(schema));
+        assertNotNull(admin.getNamespaceDescriptor(normalizeSchemaIdentifier));
 
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 40));
         try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
             conn.createStatement().execute("DROP TABLE " + schema + "." + tableName);
-            //Dropping table manually because Drop_meta_attrib is not working
-            admin.disableTable(TableName.valueOf(schema, tableName));
-            admin.deleteTable(TableName.valueOf(schema, tableName));
+            // Dropping table manually because Drop_meta_attrib is not working
+            admin.disableTable(TableName.valueOf(normalizeSchemaIdentifier, tableName));
+            admin.deleteTable(TableName.valueOf(normalizeSchemaIdentifier, tableName));
         }
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 50));
         try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
             conn.createStatement().execute(ddl);
             try {
-                admin.getNamespaceDescriptor(schema);
+                admin.getNamespaceDescriptor(normalizeSchemaIdentifier);
                 fail();
             } catch (NamespaceNotFoundException ne) {
                 // expected
@@ -100,11 +118,10 @@ public class DropSchemaIT extends BaseClientManagedTimeIT {
         }
         props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(ts + 70));
         try (Connection conn = DriverManager.getConnection(getUrl(), props);) {
-            admin.createNamespace(NamespaceDescriptor.create(schema).build());
+            admin.createNamespace(NamespaceDescriptor.create(normalizeSchemaIdentifier).build());
             conn.createStatement().execute("DROP SCHEMA IF EXISTS " + schema);
-            assertNotNull(admin.getNamespaceDescriptor(schema));
+            assertNotNull(admin.getNamespaceDescriptor(normalizeSchemaIdentifier));
         }
         admin.close();
     }
-
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/6d6c8c45/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
index f62bf0f..62b7306 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryDatabaseMetaDataIT.java
@@ -175,9 +175,12 @@ public class QueryDatabaseMetaDataIT extends BaseClientManagedTimeIT {
     @Test
     public void testSchemaMetadataScan() throws SQLException {
         Properties props = new Properties();
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(1));
         props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.createStatement().execute("CREATE SCHEMA " + CUSTOM_ENTITY_DATA_SCHEMA_NAME);
+        props.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(2));
+        conn = DriverManager.getConnection(getUrl(), props);
         DatabaseMetaData dbmd = conn.getMetaData();
         ResultSet rs;
         rs = dbmd.getSchemas(null, CUSTOM_ENTITY_DATA_SCHEMA_NAME);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/6d6c8c45/phoenix-core/src/it/java/org/apache/phoenix/end2end/UseSchemaIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UseSchemaIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UseSchemaIT.java
index 793d165..7e61fb3 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UseSchemaIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UseSchemaIT.java
@@ -44,16 +44,25 @@ import org.junit.Test;
 public class UseSchemaIT extends BaseHBaseManagedTimeIT {
 
     @Test
-    public void testUseSchema() throws Exception {
+    public void testUseSchemaCaseInsensitive() throws Exception {
+        testUseSchema("TEST_SCHEMA");
+    }
+
+    @Test
+    public void testUseSchemaCaseSensitive() throws Exception {
+        testUseSchema("\"test_schema\"");
+    }
+
+    public void testUseSchema(String schema) throws Exception {
         Properties props = new Properties();
         props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(true));
         Connection conn = DriverManager.getConnection(getUrl(), props);
-        String ddl = "CREATE SCHEMA IF NOT EXISTS TEST_SCHEMA";
+        String ddl = "CREATE SCHEMA IF NOT EXISTS "+schema;
         conn.createStatement().execute(ddl);
-        ddl = "create table test_schema.test(id varchar primary key)";
+        ddl = "create table "+schema+".TEST(id varchar primary key)";
         conn.createStatement().execute(ddl);
-        conn.createStatement().execute("use test_schema");
-        String query = "select count(*) from test";
+        conn.createStatement().execute("use "+schema);
+        String query = "select count(*) from TEST";
         ResultSet rs = conn.createStatement().executeQuery(query);
         assertTrue(rs.next());
         assertEquals(0, rs.getInt(1));
@@ -64,11 +73,11 @@ public class UseSchemaIT extends BaseHBaseManagedTimeIT {
             assertEquals(SQLExceptionCode.SCHEMA_NOT_FOUND.getErrorCode(), e.getErrorCode());
         }
         conn.createStatement().execute("use default");
-        ddl = "create table IF NOT EXISTS test(schema_name varchar primary key)";
+        ddl = "create table IF NOT EXISTS TEST(schema_name varchar primary key)";
         conn.createStatement().execute(ddl);
         conn.createStatement().executeUpdate("upsert into test values('"+SchemaUtil.SCHEMA_FOR_DEFAULT_NAMESPACE+"')");
         conn.commit();
-        rs = conn.createStatement().executeQuery("select schema_name from test");
+        rs = conn.createStatement().executeQuery("select schema_name from TEST");
         assertTrue(rs.next());
         assertEquals(SchemaUtil.SCHEMA_FOR_DEFAULT_NAMESPACE, rs.getString(1));
         conn.close();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/6d6c8c45/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index 5c8786d..80179ae 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -110,6 +110,7 @@ import org.apache.phoenix.util.SQLCloseable;
 import org.apache.phoenix.util.SQLCloseables;
 import org.cloudera.htrace.Sampler;
 import org.cloudera.htrace.TraceScope;
+import org.apache.phoenix.util.SchemaUtil;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Objects;
@@ -120,6 +121,8 @@ import com.google.common.collect.Lists;
 
 import co.cask.tephra.TransactionContext;
 
+import co.cask.tephra.TransactionContext;
+
 
 /**
  * 
@@ -856,7 +859,7 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
 
     @Override
     public String getSchema() throws SQLException {
-        return this.schema;
+        return SchemaUtil.normalizeIdentifier(this.schema);
     }
 
     public PSchema getSchema(PTableKey key) throws SchemaNotFoundException {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/6d6c8c45/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index ad161fa..ac40554 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -3464,7 +3464,8 @@ public class MetaDataClient {
         connection.rollback();
         boolean wasAutoCommit = connection.getAutoCommit();
         try {
-            String schemaName = executableDropSchemaStatement.getSchemaName();
+            PSchema schema = new PSchema(executableDropSchemaStatement.getSchemaName());
+            String schemaName = schema.getSchemaName();
             boolean ifExists = executableDropSchemaStatement.ifExists();
             byte[] key = SchemaUtil.getSchemaKey(schemaName);
 
@@ -3475,7 +3476,7 @@ public class MetaDataClient {
             schemaMetaData.add(schemaDelete);
             MetaDataMutationResult result = connection.getQueryServices().dropSchema(schemaMetaData, schemaName);
             MutationCode code = result.getMutationCode();
-            PSchema schema = result.getSchema();
+            schema = result.getSchema();
             switch (code) {
             case SCHEMA_NOT_FOUND:
                 if (!ifExists) { throw new SchemaNotFoundException(schemaName); }
@@ -3503,7 +3504,7 @@ public class MetaDataClient {
         } else {
             PSchema schema = FromCompiler.getResolverForSchema(useSchemaStatement, connection)
                     .resolveSchema(useSchemaStatement.getSchemaName());
-            connection.setSchema(schema.getSchemaName());
+            connection.setSchema(useSchemaStatement.getSchemaName());
         }
         return new MutationState(0, connection);
     }


[20/52] [abbrv] phoenix git commit: PHOENIX-1311 HBase namespaces surfaced in phoenix

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
index ae4b7ac..0620eaa 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
@@ -46,6 +46,8 @@ import org.apache.phoenix.schema.stats.PTableStats;
 
 import co.cask.tephra.TransactionSystemClient;
 
+import co.cask.tephra.TransactionSystemClient;
+
 
 public interface ConnectionQueryServices extends QueryServices, MetaDataMutated {
     public static final int INITIAL_META_DATA_TABLE_CAPACITY = 100;
@@ -76,7 +78,10 @@ public interface ConnectionQueryServices extends QueryServices, MetaDataMutated
 
     public MetaDataMutationResult getTable(PName tenantId, byte[] schemaName, byte[] tableName, long tableTimestamp, long clientTimetamp) throws SQLException;
     public MetaDataMutationResult getFunctions(PName tenantId, List<Pair<byte[], Long>> functionNameAndTimeStampPairs, long clientTimestamp) throws SQLException;
-    public MetaDataMutationResult createTable(List<Mutation> tableMetaData, byte[] tableName, PTableType tableType, Map<String,Object> tableProps, List<Pair<byte[],Map<String,Object>>> families, byte[][] splits) throws SQLException;
+
+    public MetaDataMutationResult createTable(List<Mutation> tableMetaData, byte[] tableName, PTableType tableType,
+            Map<String, Object> tableProps, List<Pair<byte[], Map<String, Object>>> families, byte[][] splits,
+            boolean isNamespaceMapped) throws SQLException;
     public MetaDataMutationResult dropTable(List<Mutation> tableMetadata, PTableType tableType, boolean cascade) throws SQLException;
     public MetaDataMutationResult dropFunction(List<Mutation> tableMetadata, boolean ifExists) throws SQLException;
     public MetaDataMutationResult addColumn(List<Mutation> tableMetaData, PTable table, Map<String, List<Pair<String,Object>>> properties, Set<String> colFamiliesForPColumnsToBeAdded) throws SQLException;
@@ -123,4 +128,11 @@ public interface ConnectionQueryServices extends QueryServices, MetaDataMutated
     TransactionSystemClient getTransactionSystemClient();
     public long getRenewLeaseThresholdMilliSeconds();
     public boolean isRenewingLeasesEnabled();
+
+    public MetaDataMutationResult createSchema(List<Mutation> schemaMutations, String schemaName) throws SQLException;
+
+    MetaDataMutationResult getSchema(String schemaName, long clientTimestamp) throws SQLException;
+
+    public MetaDataMutationResult dropSchema(List<Mutation> schemaMetaData, String schemaName) throws SQLException;
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index ebc62de..dec11af 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -34,6 +34,7 @@ import java.io.IOException;
 import java.lang.ref.WeakReference;
 import java.sql.SQLException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -64,6 +65,7 @@ import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
 import org.apache.hadoop.hbase.TableExistsException;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.Append;
@@ -107,11 +109,14 @@ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearCacheRespons
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearTableFromCacheRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearTableFromCacheResponse;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest;
+import org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateSchemaRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropColumnRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropFunctionRequest;
+import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropSchemaRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropTableRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetFunctionsRequest;
+import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetTableRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetVersionRequest;
 import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetVersionResponse;
@@ -137,6 +142,7 @@ import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver.ConnectionInfo;
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.protobuf.ProtobufUtil;
 import org.apache.phoenix.schema.ColumnAlreadyExistsException;
 import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
@@ -155,6 +161,7 @@ import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.ReadOnlyTableException;
 import org.apache.phoenix.schema.SaltingUtil;
+import org.apache.phoenix.schema.SchemaAlreadyExistsException;
 import org.apache.phoenix.schema.Sequence;
 import org.apache.phoenix.schema.SequenceAllocation;
 import org.apache.phoenix.schema.SequenceKey;
@@ -208,7 +215,6 @@ import co.cask.tephra.distributed.PooledClientProvider;
 import co.cask.tephra.distributed.TransactionServiceClient;
 import co.cask.tephra.zookeeper.TephraZKClientService;
 
-
 public class ConnectionQueryServicesImpl extends DelegateQueryServices implements ConnectionQueryServices {
     private static final Logger logger = LoggerFactory.getLogger(ConnectionQueryServicesImpl.class);
     private static final int INITIAL_CHILD_SERVICES_CAPACITY = 100;
@@ -634,15 +640,19 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         }
      }
 
-    @Override
-    public PMetaData addColumn(final PName tenantId, final String tableName, final List<PColumn> columns, final long tableTimeStamp, 
-            final long tableSeqNum, final boolean isImmutableRows, final boolean isWalDisabled, final boolean isMultitenant, 
-            final boolean storeNulls, final boolean isTransactional, final long updateCacheFrequency, final long resolvedTime) throws SQLException {
-        return metaDataMutated(tenantId, tableName, tableSeqNum, new Mutator() {
+	@Override
+    public PMetaData addColumn(final PName tenantId, final String tableName, final List<PColumn> columns,
+            final long tableTimeStamp, final long tableSeqNum, final boolean isImmutableRows,
+            final boolean isWalDisabled, final boolean isMultitenant, final boolean storeNulls,
+            final boolean isTransactional, final long updateCacheFrequency, final boolean isNamespaceMapped,
+            final long resolvedTime) throws SQLException {
+	    return metaDataMutated(tenantId, tableName, tableSeqNum, new Mutator() {
             @Override
             public PMetaData mutate(PMetaData metaData) throws SQLException {
                 try {
-                    return metaData.addColumn(tenantId, tableName, columns, tableTimeStamp, tableSeqNum, isImmutableRows, isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency, resolvedTime);
+                    return metaData.addColumn(tenantId, tableName, columns, tableTimeStamp, tableSeqNum,
+                            isImmutableRows, isWalDisabled, isMultitenant, storeNulls, isTransactional,
+                            updateCacheFrequency, isNamespaceMapped, resolvedTime);
                 } catch (TableNotFoundException e) {
                     // The DROP TABLE may have been processed first, so just ignore.
                     return metaData;
@@ -738,10 +748,13 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         }
     }
     
-    private HTableDescriptor generateTableDescriptor(byte[] tableName, HTableDescriptor existingDesc, PTableType tableType, Map<String,Object> tableProps, List<Pair<byte[],Map<String,Object>>> families, byte[][] splits) throws SQLException {
+    private HTableDescriptor generateTableDescriptor(byte[] tableName, HTableDescriptor existingDesc,
+            PTableType tableType, Map<String, Object> tableProps, List<Pair<byte[], Map<String, Object>>> families,
+            byte[][] splits, boolean isNamespaceMapped) throws SQLException {
         String defaultFamilyName = (String)tableProps.remove(PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME);
-        HTableDescriptor tableDescriptor = (existingDesc != null) ? new HTableDescriptor(existingDesc) :
-          new HTableDescriptor(TableName.valueOf(tableName));
+        HTableDescriptor tableDescriptor = (existingDesc != null) ? new HTableDescriptor(existingDesc)
+                : new HTableDescriptor(
+                        SchemaUtil.getPhysicalHBaseTableName(tableName, isNamespaceMapped, tableType).getBytes());
         for (Entry<String,Object> entry : tableProps.entrySet()) {
             String key = entry.getKey();
             if (!TableProperty.isPhoenixTableProperty(key)) {
@@ -959,6 +972,23 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                 QueryServicesOptions.DEFAULT_ALLOW_ONLINE_TABLE_SCHEMA_UPDATE);
     }
 
+    private NamespaceDescriptor ensureNamespaceCreated(String schemaName) throws SQLException {
+        SQLException sqlE = null;
+        try (HBaseAdmin admin = getAdmin()) {
+            NamespaceDescriptor namespaceDescriptor = null;
+            try {
+                namespaceDescriptor = NamespaceDescriptor.create(schemaName).build();
+                admin.createNamespace(namespaceDescriptor);
+            } catch (org.apache.hadoop.hbase.NamespaceExistException e) {}
+            return namespaceDescriptor;
+        } catch (IOException e) {
+            sqlE = ServerUtil.parseServerException(e);
+        } finally {
+            if (sqlE != null) { throw sqlE; }
+        }
+        return null; // will never make it here
+    }
+
     /**
      *
      * @param tableName
@@ -967,17 +997,20 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
      * @return true if table was created and false if it already exists
      * @throws SQLException
      */
-    private HTableDescriptor ensureTableCreated(byte[] tableName, PTableType tableType , Map<String,Object> props, List<Pair<byte[],Map<String,Object>>> families, byte[][] splits, boolean modifyExistingMetaData) throws SQLException {
+    private HTableDescriptor ensureTableCreated(byte[] tableName, PTableType tableType, Map<String, Object> props,
+            List<Pair<byte[], Map<String, Object>>> families, byte[][] splits, boolean modifyExistingMetaData,
+            boolean isNamespaceMapped) throws SQLException {
         SQLException sqlE = null;
         HTableDescriptor existingDesc = null;
         boolean isMetaTable = SchemaUtil.isMetaTable(tableName);
+        byte[] physicalTable = SchemaUtil.getPhysicalHBaseTableName(tableName, isNamespaceMapped, tableType).getBytes(); 
         boolean tableExist = true;
         try (HBaseAdmin admin = getAdmin()) {
             final String quorum = ZKConfig.getZKQuorumServersString(config);
             final String znode = this.props.get(HConstants.ZOOKEEPER_ZNODE_PARENT);
             logger.debug("Found quorum: " + quorum + ":" + znode);
             try {
-                existingDesc = admin.getTableDescriptor(tableName);
+                existingDesc = admin.getTableDescriptor(physicalTable);
             } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
                 tableExist = false;
                 if (tableType == PTableType.VIEW) {
@@ -989,7 +1022,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                 }
             }
 
-            HTableDescriptor newDesc = generateTableDescriptor(tableName, existingDesc, tableType , props, families, splits);
+            HTableDescriptor newDesc = generateTableDescriptor(tableName, existingDesc, tableType, props, families,
+                    splits, isNamespaceMapped);
 
             if (!tableExist) {
                 if (newDesc.getValue(MetaDataUtil.IS_LOCAL_INDEX_TABLE_PROP_BYTES) != null && Boolean.TRUE.equals(
@@ -1021,11 +1055,11 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                     newDesc.setValue(HTableDescriptor.SPLIT_POLICY, MetaDataSplitPolicy.class.getName());
                     if (allowOnlineTableSchemaUpdate()) {
                         // No need to wait/poll for this update
-                        admin.modifyTable(tableName, newDesc);
+                        admin.modifyTable(physicalTable, newDesc);
                     } else {
-                        admin.disableTable(tableName);
-                        admin.modifyTable(tableName, newDesc);
-                        admin.enableTable(tableName);
+                        admin.disableTable(physicalTable);
+                        admin.modifyTable(physicalTable, newDesc);
+                        admin.enableTable(physicalTable);
                     }
                 }
                 return null;
@@ -1056,7 +1090,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                     return null; // Indicate that no metadata was changed
                 }
 
-                modifyTable(tableName, newDesc, true);
+                modifyTable(physicalTable, newDesc, true);
                 return newDesc;
             }
 
@@ -1111,7 +1145,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         boolean isIncompatible = false;
         int minHBaseVersion = Integer.MAX_VALUE;
         try {
-            List<HRegionLocation> locations = this.getAllTableRegions(SYSTEM_CATALOG_NAME_BYTES);
+            List<HRegionLocation> locations = this
+                    .getAllTableRegions(SchemaUtil.getPhysicalName(SYSTEM_CATALOG_NAME_BYTES, this.getProps()).getName());
             Set<HRegionLocation> serverMap = Sets.newHashSetWithExpectedSize(locations.size());
             TreeMap<byte[], HRegionLocation> regionMap = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
             List<byte[]> regionKeys = Lists.newArrayListWithExpectedSize(locations.size());
@@ -1123,7 +1158,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                 }
             }
 
-            HTableInterface ht = this.getTable(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES);
+            HTableInterface ht = this
+                    .getTable(SchemaUtil.getPhysicalName(SYSTEM_CATALOG_NAME_BYTES, this.getProps()).getName());
             final Map<byte[], Long> results =
                     ht.coprocessorService(MetaDataService.class, null, null, new Batch.Call<MetaDataService,Long>() {
                         @Override
@@ -1187,12 +1223,10 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
             boolean retried = false;
             while (true) {
                 if (retried) {
-                    connection.relocateRegion(
-                        TableName.valueOf(tableName),
-                        tableKey);
+                    connection.relocateRegion(SchemaUtil.getPhysicalName(tableName, this.getProps()), tableKey);
                 }
 
-                HTableInterface ht = this.getTable(tableName);
+                HTableInterface ht = this.getTable(SchemaUtil.getPhysicalName(tableName, this.getProps()).getName());
                 try {
                     final Map<byte[], MetaDataResponse> results =
                             ht.coprocessorService(MetaDataService.class, tableKey, tableKey, callable);
@@ -1220,7 +1254,9 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
     // Our property values are translated using toString, so we need to "string-ify" this.
     private static final String TRUE_BYTES_AS_STRING = Bytes.toString(PDataType.TRUE_BYTES);
 
-    private void ensureViewIndexTableCreated(byte[] physicalTableName, Map<String,Object> tableProps, List<Pair<byte[],Map<String,Object>>> families, byte[][] splits, long timestamp) throws SQLException {
+    private void ensureViewIndexTableCreated(byte[] physicalTableName, Map<String, Object> tableProps,
+            List<Pair<byte[], Map<String, Object>>> families, byte[][] splits, long timestamp,
+            boolean isNamespaceMapped) throws SQLException {
         Long maxFileSize = (Long)tableProps.get(HTableDescriptor.MAX_FILESIZE);
         if (maxFileSize == null) {
             maxFileSize = this.props.getLong(HConstants.HREGION_MAX_FILESIZE, HConstants.DEFAULT_MAX_FILE_SIZE);
@@ -1238,7 +1274,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         long indexMaxFileSize = maxFileSize * indexMaxFileSizePerc / 100;
         tableProps.put(HTableDescriptor.MAX_FILESIZE, indexMaxFileSize);
         tableProps.put(MetaDataUtil.IS_VIEW_INDEX_TABLE_PROP_NAME, TRUE_BYTES_AS_STRING);
-        HTableDescriptor desc = ensureTableCreated(physicalIndexName, PTableType.TABLE, tableProps, families, splits, false);
+        HTableDescriptor desc = ensureTableCreated(physicalIndexName, PTableType.TABLE, tableProps, families, splits,
+                false, isNamespaceMapped);
         if (desc != null) {
             if (!Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(desc.getValue(MetaDataUtil.IS_VIEW_INDEX_TABLE_PROP_BYTES)))) {
                 String fullTableName = Bytes.toString(physicalIndexName);
@@ -1250,10 +1287,14 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         }
     }
 
-    private void ensureLocalIndexTableCreated(byte[] physicalTableName, Map<String,Object> tableProps, List<Pair<byte[],Map<String,Object>>> families, byte[][] splits, long timestamp) throws SQLException {
+    private void ensureLocalIndexTableCreated(byte[] physicalTableName, Map<String, Object> tableProps,
+            List<Pair<byte[], Map<String, Object>>> families, byte[][] splits, long timestamp,
+            boolean isNamespaceMapped) throws SQLException {
         PTable table;
-        String parentTableName = Bytes.toString(physicalTableName, MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX_BYTES.length,
-            physicalTableName.length - MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX_BYTES.length);
+        String parentTableName = SchemaUtil
+                .getParentTableNameFromIndexTable(Bytes.toString(physicalTableName),
+                        MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX)
+                .replace(QueryConstants.NAMESPACE_SEPARATOR, QueryConstants.NAME_SEPARATOR);
         try {
             synchronized (latestMetaDataLock) {
                 throwConnectionClosedIfNullMetaData();
@@ -1272,10 +1313,12 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                 throw e;
             }
         }
-        ensureLocalIndexTableCreated(physicalTableName, tableProps, families, splits);
+        ensureLocalIndexTableCreated(physicalTableName, tableProps, families, splits, isNamespaceMapped);
     }
 
-    private void ensureLocalIndexTableCreated(byte[] physicalTableName, Map<String, Object> tableProps, List<Pair<byte[], Map<String, Object>>> families, byte[][] splits) throws SQLException, TableAlreadyExistsException {
+    private void ensureLocalIndexTableCreated(byte[] physicalTableName, Map<String, Object> tableProps,
+            List<Pair<byte[], Map<String, Object>>> families, byte[][] splits, boolean isNamespaceMapped)
+                    throws SQLException, TableAlreadyExistsException {
         
         // If we're not allowing local indexes or the hbase version is too low,
         // don't create the local index table
@@ -1285,7 +1328,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         }
         
         tableProps.put(MetaDataUtil.IS_LOCAL_INDEX_TABLE_PROP_NAME, TRUE_BYTES_AS_STRING);
-        HTableDescriptor desc = ensureTableCreated(physicalTableName, PTableType.TABLE, tableProps, families, splits, true);
+        HTableDescriptor desc = ensureTableCreated(physicalTableName, PTableType.TABLE, tableProps, families, splits,
+                true, isNamespaceMapped);
         if (desc != null) {
             if (!Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(desc.getValue(MetaDataUtil.IS_LOCAL_INDEX_TABLE_PROP_BYTES)))) {
                 String fullTableName = Bytes.toString(physicalTableName);
@@ -1352,8 +1396,10 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
     }
 
     @Override
-    public MetaDataMutationResult createTable(final List<Mutation> tableMetaData, byte[] physicalTableName, PTableType tableType,
-            Map<String,Object> tableProps, final List<Pair<byte[],Map<String,Object>>> families, byte[][] splits) throws SQLException {
+    public MetaDataMutationResult createTable(final List<Mutation> tableMetaData, byte[] physicalTableName,
+            PTableType tableType, Map<String, Object> tableProps,
+            final List<Pair<byte[], Map<String, Object>>> families, byte[][] splits, boolean isNamespaceMapped)
+                    throws SQLException {
         byte[][] rowKeyMetadata = new byte[3][];
         Mutation m = MetaDataUtil.getPutOnlyTableHeaderRow(tableMetaData);
         byte[] key = m.getRow();
@@ -1367,7 +1413,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         if ((tableType == PTableType.VIEW && physicalTableName != null) || (tableType != PTableType.VIEW && physicalTableName == null)) {
             // For views this will ensure that metadata already exists
             // For tables and indexes, this will create the metadata if it doesn't already exist
-            ensureTableCreated(tableName, tableType, tableProps, families, splits, true);
+            ensureTableCreated(tableName, tableType, tableProps, families, splits, true, isNamespaceMapped);
         }
         ImmutableBytesWritable ptr = new ImmutableBytesWritable();
         if (tableType == PTableType.INDEX) { // Index on view
@@ -1375,9 +1421,11 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
             // TODO: if viewIndexId is Short.MIN_VALUE, then we don't need to attempt to create it
             if (physicalTableName != null) {
                 if (localIndexTable) {
-                    ensureLocalIndexTableCreated(tableName, tableProps, families, splits, MetaDataUtil.getClientTimeStamp(m));
+                    ensureLocalIndexTableCreated(tableName, tableProps, families, splits,
+                            MetaDataUtil.getClientTimeStamp(m), isNamespaceMapped);
                 } else if (!MetaDataUtil.isMultiTenant(m, kvBuilder, ptr)) {
-                    ensureViewIndexTableCreated(tenantIdBytes.length == 0 ? null : PNameFactory.newName(tenantIdBytes), physicalTableName, MetaDataUtil.getClientTimeStamp(m));
+                    ensureViewIndexTableCreated(tenantIdBytes.length == 0 ? null : PNameFactory.newName(tenantIdBytes),
+                            physicalTableName, MetaDataUtil.getClientTimeStamp(m), isNamespaceMapped);
                 }
             }
         } else if (tableType == PTableType.TABLE && MetaDataUtil.isMultiTenant(m, kvBuilder, ptr)) { // Create view index table up front for multi tenant tables
@@ -1399,7 +1447,9 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                 familiesPlusDefault = Lists.newArrayList(families);
                 familiesPlusDefault.add(new Pair<byte[],Map<String,Object>>(defaultCF,Collections.<String,Object>emptyMap()));
             }
-            ensureViewIndexTableCreated(tableName, tableProps, familiesPlusDefault, MetaDataUtil.isSalted(m, kvBuilder, ptr) ? splits : null, MetaDataUtil.getClientTimeStamp(m));
+            ensureViewIndexTableCreated(tableName, tableProps, familiesPlusDefault,
+                    MetaDataUtil.isSalted(m, kvBuilder, ptr) ? splits : null, MetaDataUtil.getClientTimeStamp(m),
+                    isNamespaceMapped);
         }
 
         byte[] tableKey = SchemaUtil.getTableKey(tenantIdBytes, schemaBytes, tableBytes);
@@ -1496,7 +1546,13 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
             }
             invalidateTables(result.getTableNamesToDelete());
             if (tableType == PTableType.TABLE) {
-                byte[] physicalName = SchemaUtil.getTableNameAsBytes(schemaBytes, tableBytes);
+                boolean isNamespaceMapped = result.getTable().isNamespaceMapped();
+                byte[] physicalName;
+                if (!isNamespaceMapped) {
+                    physicalName = SchemaUtil.getTableNameAsBytes(schemaBytes, tableBytes);
+                } else {
+                    physicalName = TableName.valueOf(schemaBytes, tableBytes).getName();
+                }
                 long timestamp = MetaDataUtil.getClientTimeStamp(tableMetaData);
                 ensureViewIndexTableDropped(physicalName, timestamp);
                 ensureLocalIndexTableDropped(physicalName, timestamp);
@@ -1541,10 +1597,12 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                 }, PhoenixDatabaseMetaData.SYSTEM_FUNCTION_NAME_BYTES);
         return result;
     }
+
     private void invalidateTables(final List<byte[]> tableNamesToDelete) {
         if (tableNamesToDelete != null) {
-            for ( byte[] tableName : tableNamesToDelete ) {
-                tableStatsCache.invalidate(new ImmutableBytesPtr(tableName));
+            for (byte[] tableName : tableNamesToDelete) {
+                tableStatsCache.invalidate(new ImmutableBytesPtr(Bytes.toString(tableName)
+                        .replace(QueryConstants.NAMESPACE_SEPARATOR, QueryConstants.NAME_SEPARATOR).getBytes()));
             }
         }
     }
@@ -1576,12 +1634,14 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         return props;
     }
 
-    private void ensureViewIndexTableCreated(PName tenantId, byte[] physicalIndexTableName, long timestamp) throws SQLException {
+    private void ensureViewIndexTableCreated(PName tenantId, byte[] physicalIndexTableName, long timestamp,
+            boolean isNamespaceMapped) throws SQLException {
         PTable table;
-        String name = Bytes.toString(
-                physicalIndexTableName,
-                MetaDataUtil.VIEW_INDEX_TABLE_PREFIX_BYTES.length,
-                physicalIndexTableName.length-MetaDataUtil.VIEW_INDEX_TABLE_PREFIX_BYTES.length);
+        String name = Bytes
+                .toString(SchemaUtil.getParentTableNameFromIndexTable(physicalIndexTableName,
+                        MetaDataUtil.VIEW_INDEX_TABLE_PREFIX))
+                .replace(QueryConstants.NAMESPACE_SEPARATOR, QueryConstants.NAME_SEPARATOR);
+        
         try {
             PMetaData metadata = latestMetaData;
             if (metadata == null) {
@@ -1600,10 +1660,11 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                 throw e;
             }
         }
-        ensureViewIndexTableCreated(table, timestamp);
+        ensureViewIndexTableCreated(table, timestamp, isNamespaceMapped);
     }
 
-    private void ensureViewIndexTableCreated(PTable table, long timestamp) throws SQLException {
+	private void ensureViewIndexTableCreated(PTable table, long timestamp, boolean isNamespaceMapped)
+			throws SQLException {
         byte[] physicalTableName = table.getPhysicalName().getBytes();
         HTableDescriptor htableDesc = this.getTableDescriptor(physicalTableName);
         Map<String,Object> tableProps = createPropertiesMap(htableDesc.getValues());
@@ -1627,7 +1688,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
             splits = SaltingUtil.getSalteByteSplitPoints(table.getBucketNum());
         }
 
-        ensureViewIndexTableCreated(physicalTableName, tableProps, families, splits, timestamp);
+        ensureViewIndexTableCreated(physicalTableName, tableProps, families, splits, timestamp, isNamespaceMapped);
     }
     
     @Override
@@ -1725,7 +1786,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                     if (MetaDataUtil.getMutationValue(m, PhoenixDatabaseMetaData.MULTI_TENANT_BYTES, kvBuilder, ptr)){
                         long timestamp = MetaDataUtil.getClientTimeStamp(m);
                         if (Boolean.TRUE.equals(PBoolean.INSTANCE.toObject(ptr.get(), ptr.getOffset(), ptr.getLength()))) {
-                            this.ensureViewIndexTableCreated(table, timestamp);
+                            this.ensureViewIndexTableCreated(table, timestamp,table.isNamespaceMapped());
                         } else {
                             this.ensureViewIndexTableDropped(table.getPhysicalName().getBytes(), timestamp);
                         }
@@ -2271,8 +2332,14 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                             String globalUrl = JDBCUtil.removeProperty(url, PhoenixRuntime.TENANT_ID_ATTRIB);
                             metaConnection = new PhoenixConnection(
                                     ConnectionQueryServicesImpl.this, globalUrl, scnProps, newEmptyMetaData());
+                            
+                            if (SchemaUtil.isNamespaceMappingEnabled(PTableType.SYSTEM,
+                                    ConnectionQueryServicesImpl.this.getProps())) {
+                                ensureSystemTablesUpgraded(ConnectionQueryServicesImpl.this.getProps());
+                            }
                             try {
                                 metaConnection.createStatement().executeUpdate(QueryConstants.CREATE_TABLE_METADATA);
+
                             } catch (NewerTableAlreadyExistsException ignore) {
                                 // Ignore, as this will happen if the SYSTEM.CATALOG already exists at this fixed timestamp.
                                 // A TableAlreadyExistsException is not thrown, since the table only exists *after* this fixed timestamp.
@@ -2357,6 +2424,9 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                                         conn.close();
                                     }
                                 }
+                                // Add these columns one at a time, each with different timestamps so that if folks have
+                                // run the upgrade code already for a snapshot, we'll still enter this block (and do the
+                                // parts we haven't yet done).
                                 if (currentServerSideTableTimeStamp < MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_6_0) {
                                     columnsToAdd = PhoenixDatabaseMetaData.IS_ROW_TIMESTAMP + " " + PBoolean.INSTANCE.getSqlTypeName();
                                     metaConnection = addColumnsIfNotExists(metaConnection, PhoenixDatabaseMetaData.SYSTEM_CATALOG,
@@ -2366,9 +2436,6 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                                     // Drop old stats table so that new stats table is created
                                     metaConnection = dropStatsTable(metaConnection, 
                                             MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_7_0 - 4);
-                                    // Add these columns one at a time, each with different timestamps so that if folks have
-                                    // run the upgrade code already for a snapshot, we'll still enter this block (and do the
-                                    // parts we haven't yet done).
                                     metaConnection = addColumnsIfNotExists(metaConnection, PhoenixDatabaseMetaData.SYSTEM_CATALOG, 
                                             MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_7_0 - 3,
                                             PhoenixDatabaseMetaData.TRANSACTIONAL + " " + PBoolean.INSTANCE.getSqlTypeName());
@@ -2380,11 +2447,27 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                                     metaConnection = updateSystemCatalogTimestamp(metaConnection, 
                                             MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_7_0);
                                     ConnectionQueryServicesImpl.this.removeTable(null, PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME, null, MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_7_0);
-                                    logger.info("Update of SYSTEM.CATALOG complete");
 									clearCache();
                                 }
-                                
+
+                                if (currentServerSideTableTimeStamp < MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_8_0) {
+                                    metaConnection = addColumnsIfNotExists(metaConnection,
+                                            PhoenixDatabaseMetaData.SYSTEM_CATALOG,
+                                            MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_8_0,
+                                            PhoenixDatabaseMetaData.IS_NAMESPACE_MAPPED + " "
+                                                    + PBoolean.INSTANCE.getSqlTypeName());
+                                    ConnectionQueryServicesImpl.this.removeTable(null,
+                                            PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME, null,
+                                            MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_8_0);
+                                    clearCache();
+                                }
+                                try {
+                                    metaConnection.createStatement().executeUpdate(QueryConstants.CREATE_SYSTEM_SCHEMA);
+                                } catch (SchemaAlreadyExistsException sa) {
+
+                                }
                             }
+
                             int nSaltBuckets = ConnectionQueryServicesImpl.this.props.getInt(QueryServices.SEQUENCE_SALT_BUCKETS_ATTRIB,
                                     QueryServicesOptions.DEFAULT_SEQUENCE_TABLE_SALT_BUCKETS);
                             try {
@@ -2479,12 +2562,57 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                     }
                     return null;
                 }
+
+                private void ensureSystemTablesUpgraded(ReadOnlyProps props)
+                        throws SQLException, IOException, IllegalArgumentException, InterruptedException {
+                    if (!SchemaUtil.isNamespaceMappingEnabled(PTableType.SYSTEM, props)) { return; }
+                    HTableInterface metatable = null;
+                    try (HBaseAdmin admin = getAdmin()) {
+                        ensureNamespaceCreated(QueryConstants.SYSTEM_SCHEMA_NAME);
+                        List<HTableDescriptor> tables = Arrays
+                                .asList(admin.listTables(QueryConstants.SYSTEM_SCHEMA_NAME + "\\..*"));
+                        List<String> tableNames = getTableNames(tables);
+                        if (tableNames.size() == 0) { return; }
+                        if (tableNames.size() > 4) { throw new IllegalArgumentException(
+                                "Expected 4 system table only but found " + tableNames.size() + ":" + tableNames); }
+                        metatable = getTable(SchemaUtil
+                                .getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES, props).getName());
+                        if (tableNames.contains(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME)) {
+                            UpgradeUtil.mapTableToNamespace(admin, metatable,
+                                    PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME, props,
+                                    MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_1_0, PTableType.SYSTEM);
+                            tableNames.remove(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME);
+                            ConnectionQueryServicesImpl.this.removeTable(null,
+                                    PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME, null,
+                                    MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_1_0);
+                        }
+                        for (String table : tableNames) {
+                            UpgradeUtil.mapTableToNamespace(admin, metatable, table, props,
+                                    MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_1_0, PTableType.SYSTEM);
+                            ConnectionQueryServicesImpl.this.removeTable(null, table, null,
+                                    MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_1_0);
+                            clearCache();
+                        }
+                    } finally {
+                        if (metatable != null) {
+                            metatable.close();
+                        }
+                    }
+                }
             });
         } catch (Exception e) {
             Throwables.propagateIfInstanceOf(e, SQLException.class);
             throw Throwables.propagate(e);
         }
     }
+
+    private List<String> getTableNames(List<HTableDescriptor> tables) {
+        List<String> tableNames = new ArrayList<String>(4);
+        for (HTableDescriptor desc : tables) {
+            tableNames.add(desc.getNameAsString());
+        }
+        return tableNames;
+    }
     
     private String addColumn(String columnsToAddSoFar, String columns) {
         if (columnsToAddSoFar == null || columnsToAddSoFar.isEmpty()) {
@@ -2660,7 +2788,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
     public long clearCache() throws SQLException {
         try {
             SQLException sqlE = null;
-            HTableInterface htable = this.getTable(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES);
+            HTableInterface htable = this.getTable(SchemaUtil
+                    .getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES, this.getProps()).getName());
             try {
                 final Map<byte[], Long> results =
                     htable.coprocessorService(MetaDataService.class, HConstants.EMPTY_START_ROW,
@@ -2780,8 +2909,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
             sequence.getLock().lock();
             // Now that we have the lock we need, create the sequence
             Append append = sequence.createSequence(startWith, incrementBy, cacheSize, timestamp, minValue, maxValue, cycle);
-            HTableInterface htable =
-                    this.getTable(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES);
+            HTableInterface htable = this.getTable(SchemaUtil
+                    .getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES, this.getProps()).getName());
             htable.setAutoFlush(true);
             try {
                 Result result = htable.append(append);
@@ -2808,7 +2937,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
             sequence.getLock().lock();
             // Now that we have the lock we need, create the sequence
             Append append = sequence.dropSequence(timestamp);
-            HTableInterface htable = this.getTable(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES);
+            HTableInterface htable = this.getTable(SchemaUtil
+                    .getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES, this.getProps()).getName());
             try {
                 Result result = htable.append(append);
                 return sequence.dropSequence(result);
@@ -2904,7 +3034,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
             if (toIncrementList.isEmpty()) {
                 return;
             }
-            HTableInterface hTable = this.getTable(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES);
+            HTableInterface hTable = this.getTable(SchemaUtil.getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES,this.getProps()).getName());
             Object[] resultObjects = null;
             SQLException sqlE = null;
             try {
@@ -2953,7 +3083,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         // clear the meta data cache for the table here
         try {
             SQLException sqlE = null;
-            HTableInterface htable = this.getTable(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES);
+            HTableInterface htable = this.getTable(SchemaUtil
+                    .getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES, this.getProps()).getName());
             try {
                 htable.coprocessorService(MetaDataService.class, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW,
                         new Batch.Call<MetaDataService, ClearTableFromCacheResponse>() {
@@ -3027,7 +3158,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
             if (toReturnList.isEmpty()) {
                 return;
             }
-            HTableInterface hTable = this.getTable(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES);
+            HTableInterface hTable = this.getTable(SchemaUtil
+                    .getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES, this.getProps()).getName());
             Object[] resultObjects = null;
             SQLException sqlE = null;
             try {
@@ -3080,7 +3212,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         if (mutations.isEmpty()) {
             return;
         }
-        HTableInterface hTable = this.getTable(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES);
+        HTableInterface hTable = this.getTable(
+                SchemaUtil.getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_SEQUENCE_NAME_BYTES, this.getProps()).getName());
         SQLException sqlE = null;
         try {
             hTable.batch(mutations);
@@ -3189,7 +3322,9 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                      *  though, so we'll query them directly here and cache them so
                      *  we don't keep querying for them.
                      */
-                    HTableInterface statsHTable = ConnectionQueryServicesImpl.this.getTable(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME_BYTES);
+                    HTableInterface statsHTable = ConnectionQueryServicesImpl.this
+                            .getTable(SchemaUtil.getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_STATS_NAME_BYTES,
+                                    ConnectionQueryServicesImpl.this.getProps()).getName());
                     try {
                         return StatisticsUtil.readStatistics(statsHTable, physicalName, clientTimeStamp);
                     } catch (IOException e) {
@@ -3275,6 +3410,27 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
 
     }
 
+    @Override
+    public MetaDataMutationResult getSchema(final String schemaName, final long clientTimestamp) throws SQLException {
+        return metaDataCoprocessorExec(SchemaUtil.getSchemaKey(schemaName),
+                new Batch.Call<MetaDataService, MetaDataResponse>() {
+                    @Override
+                    public MetaDataResponse call(MetaDataService instance) throws IOException {
+                        ServerRpcController controller = new ServerRpcController();
+                        BlockingRpcCallback<MetaDataResponse> rpcCallback = new BlockingRpcCallback<MetaDataResponse>();
+                        GetSchemaRequest.Builder builder = GetSchemaRequest.newBuilder();
+                        builder.setSchemaName(schemaName);
+                        builder.setClientTimestamp(clientTimestamp);
+                        builder.setClientVersion(VersionUtil.encodeVersion(PHOENIX_MAJOR_VERSION, PHOENIX_MINOR_VERSION,
+                                PHOENIX_PATCH_NUMBER));
+                        instance.getSchema(controller, builder.build(), rpcCallback);
+                        if (controller.getFailedOn() != null) { throw controller.getFailedOn(); }
+                        return rpcCallback.get();
+                    }
+                });
+
+    }
+
     // TODO the mutations should be added to System functions table.
     @Override
     public MetaDataMutationResult createFunction(final List<Mutation> functionData,
@@ -3449,4 +3605,98 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         }
      }
 
+    @Override
+    public MetaDataMutationResult createSchema(final List<Mutation> schemaMutations, final String schemaName)
+            throws SQLException {
+        ensureNamespaceCreated(schemaName);
+        Mutation m = MetaDataUtil.getPutOnlyTableHeaderRow(schemaMutations);
+        byte[] key = m.getRow();
+        MetaDataMutationResult result = metaDataCoprocessorExec(key,
+                new Batch.Call<MetaDataService, MetaDataResponse>() {
+                    @Override
+                    public MetaDataResponse call(MetaDataService instance) throws IOException {
+                        ServerRpcController controller = new ServerRpcController();
+                        BlockingRpcCallback<MetaDataResponse> rpcCallback = new BlockingRpcCallback<MetaDataResponse>();
+                        CreateSchemaRequest.Builder builder = CreateSchemaRequest.newBuilder();
+                        for (Mutation m : schemaMutations) {
+                            MutationProto mp = ProtobufUtil.toProto(m);
+                            builder.addTableMetadataMutations(mp.toByteString());
+                        }
+                        builder.setSchemaName(schemaName);
+                        builder.setClientVersion(VersionUtil.encodeVersion(PHOENIX_MAJOR_VERSION, PHOENIX_MINOR_VERSION,
+                                PHOENIX_PATCH_NUMBER));
+                        instance.createSchema(controller, builder.build(), rpcCallback);
+                        if (controller.getFailedOn() != null) { throw controller.getFailedOn(); }
+                        return rpcCallback.get();
+                    }
+                });
+        return result;
+    }
+
+    @Override
+    public PMetaData addSchema(PSchema schema) throws SQLException {
+        return latestMetaData = latestMetaData.addSchema(schema);
+    }
+
+    @Override
+    public PMetaData removeSchema(PSchema schema, long schemaTimeStamp) {
+        return latestMetaData = latestMetaData.removeSchema(schema, schemaTimeStamp);
+    }
+
+    @Override
+    public MetaDataMutationResult dropSchema(final List<Mutation> schemaMetaData, final String schemaName)
+            throws SQLException {
+        final MetaDataMutationResult result = metaDataCoprocessorExec(SchemaUtil.getSchemaKey(schemaName),
+                new Batch.Call<MetaDataService, MetaDataResponse>() {
+                    @Override
+                    public MetaDataResponse call(MetaDataService instance) throws IOException {
+                        ServerRpcController controller = new ServerRpcController();
+                        BlockingRpcCallback<MetaDataResponse> rpcCallback = new BlockingRpcCallback<MetaDataResponse>();
+                        DropSchemaRequest.Builder builder = DropSchemaRequest.newBuilder();
+                        for (Mutation m : schemaMetaData) {
+                            MutationProto mp = ProtobufUtil.toProto(m);
+                            builder.addSchemaMetadataMutations(mp.toByteString());
+                        }
+                        builder.setSchemaName(schemaName);
+                        builder.setClientVersion(VersionUtil.encodeVersion(PHOENIX_MAJOR_VERSION, PHOENIX_MINOR_VERSION,
+                                PHOENIX_PATCH_NUMBER));
+                        instance.dropSchema(controller, builder.build(), rpcCallback);
+                        if (controller.getFailedOn() != null) { throw controller.getFailedOn(); }
+                        return rpcCallback.get();
+                    }
+                });
+
+        final MutationCode code = result.getMutationCode();
+        switch (code) {
+        case SCHEMA_ALREADY_EXISTS:
+            ensureNamespaceDropped(schemaName, result.getMutationTime());
+            break;
+        default:
+            break;
+        }
+        return result;
+    }
+
+    private void ensureNamespaceDropped(String schemaName, long mutationTime) throws SQLException {
+        SQLException sqlE = null;
+        try (HBaseAdmin admin = getAdmin()) {
+            final String quorum = ZKConfig.getZKQuorumServersString(config);
+            final String znode = this.props.get(HConstants.ZOOKEEPER_ZNODE_PARENT);
+            logger.debug("Found quorum: " + quorum + ":" + znode);
+            boolean nameSpaceExists = true;
+            try {
+                admin.getNamespaceDescriptor(schemaName);
+            } catch (org.apache.hadoop.hbase.NamespaceNotFoundException e) {
+                nameSpaceExists = false;
+            }
+            if (nameSpaceExists) {
+                admin.deleteNamespace(schemaName);
+            }
+        } catch (IOException e) {
+            sqlE = ServerUtil.parseServerException(e);
+        } finally {
+            if (sqlE != null) { throw sqlE; }
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
index b4bbe1f..ab70300 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
@@ -55,6 +55,7 @@ import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver.ConnectionInfo;
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.schema.FunctionNotFoundException;
 import org.apache.phoenix.schema.NewerTableAlreadyExistsException;
 import org.apache.phoenix.schema.PColumn;
@@ -67,6 +68,7 @@ import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.SchemaNotFoundException;
 import org.apache.phoenix.schema.Sequence;
 import org.apache.phoenix.schema.SequenceAllocation;
 import org.apache.phoenix.schema.SequenceAlreadyExistsException;
@@ -177,8 +179,12 @@ public class ConnectionlessQueryServicesImpl extends DelegateQueryServices imple
 
     @Override
     public PMetaData addColumn(PName tenantId, String tableName, List<PColumn> columns, long tableTimeStamp,
-            long tableSeqNum, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls, boolean isTransactional, long updateCacheFrequency, long resolvedTime) throws SQLException {
-        return metaData = metaData.addColumn(tenantId, tableName, columns, tableTimeStamp, tableSeqNum, isImmutableRows, isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency, resolvedTime);
+            long tableSeqNum, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls,
+            boolean isTransactional, long updateCacheFrequency, boolean isNamespaceMapped, long resolvedTime)
+                    throws SQLException {
+        return metaData = metaData.addColumn(tenantId, tableName, columns, tableTimeStamp, tableSeqNum, isImmutableRows,
+                isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency, isNamespaceMapped,
+                resolvedTime);
     }
 
     @Override
@@ -241,7 +247,9 @@ public class ConnectionlessQueryServicesImpl extends DelegateQueryServices imple
     }
     
     @Override
-    public MetaDataMutationResult createTable(List<Mutation> tableMetaData, byte[] physicalName, PTableType tableType, Map<String,Object> tableProps, List<Pair<byte[],Map<String,Object>>> families, byte[][] splits) throws SQLException {
+    public MetaDataMutationResult createTable(List<Mutation> tableMetaData, byte[] physicalName, PTableType tableType,
+            Map<String, Object> tableProps, List<Pair<byte[], Map<String, Object>>> families, byte[][] splits,
+            boolean isNamespaceMapped) throws SQLException {
         if (splits != null) {
             byte[] tableName = getTableName(tableMetaData, physicalName);
             tableSplits.put(Bytes.toString(tableName), generateRegionLocations(tableName, splits));
@@ -592,4 +600,33 @@ public class ConnectionlessQueryServicesImpl extends DelegateQueryServices imple
                        new HRegionInfo(TableName.valueOf(tableName), HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW),
                        SERVER_NAME, -1);
     }
+
+    @Override
+    public MetaDataMutationResult createSchema(List<Mutation> schemaMutations, String schemaName) {
+        return new MetaDataMutationResult(MutationCode.SCHEMA_NOT_FOUND, 0l, null);
+    }
+
+    @Override
+    public PMetaData addSchema(PSchema schema) throws SQLException {
+        return metaData = this.metaData.addSchema(schema);
+    }
+
+    @Override
+    public MetaDataMutationResult getSchema(String schemaName, long clientTimestamp) throws SQLException {
+        try {
+            PSchema schema = metaData.getSchema(new PTableKey(null, schemaName));
+            new MetaDataMutationResult(MutationCode.SCHEMA_ALREADY_EXISTS, schema, 0);
+        } catch (SchemaNotFoundException e) {}
+        return new MetaDataMutationResult(MutationCode.SCHEMA_NOT_FOUND, 0, null);
+    }
+
+    @Override
+    public PMetaData removeSchema(PSchema schema, long schemaTimeStamp) {
+        return metaData = metaData.removeSchema(schema, schemaTimeStamp);
+    }
+
+    @Override
+    public MetaDataMutationResult dropSchema(List<Mutation> schemaMetaData, String schemaName) {
+        return new MetaDataMutationResult(MutationCode.SCHEMA_ALREADY_EXISTS, 0, null);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
index 4c7446b..f3ee3c1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
@@ -36,6 +36,7 @@ import org.apache.phoenix.execute.MutationState;
 import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PMetaData;
 import org.apache.phoenix.schema.PName;
@@ -87,8 +88,12 @@ public class DelegateConnectionQueryServices extends DelegateQueryServices imple
 
     @Override
     public PMetaData addColumn(PName tenantId, String tableName, List<PColumn> columns, long tableTimeStamp,
-            long tableSeqNum, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls, boolean isTransactional, long updateCacheFrequency, long resolvedTime) throws SQLException {
-        return getDelegate().addColumn(tenantId, tableName, columns, tableTimeStamp, tableSeqNum, isImmutableRows, isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency, resolvedTime);
+            long tableSeqNum, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls,
+            boolean isTransactional, long updateCacheFrequency, boolean isNamespaceMapped, long resolvedTime)
+                    throws SQLException {
+        return getDelegate().addColumn(tenantId, tableName, columns, tableTimeStamp, tableSeqNum, isImmutableRows,
+                isWalDisabled, isMultitenant, storeNulls, isTransactional, updateCacheFrequency, isNamespaceMapped,
+                resolvedTime);
     }
 
     @Override
@@ -114,10 +119,11 @@ public class DelegateConnectionQueryServices extends DelegateQueryServices imple
     }
 
     @Override
-    public MetaDataMutationResult createTable(List<Mutation> tableMetaData, byte[] physicalName,
-            PTableType tableType, Map<String, Object> tableProps, List<Pair<byte[], Map<String, Object>>> families, byte[][] splits)
-            throws SQLException {
-        return getDelegate().createTable(tableMetaData, physicalName, tableType, tableProps, families, splits);
+    public MetaDataMutationResult createTable(List<Mutation> tableMetaData, byte[] physicalName, PTableType tableType,
+            Map<String, Object> tableProps, List<Pair<byte[], Map<String, Object>>> families, byte[][] splits,
+            boolean isNamespaceMapped) throws SQLException {
+        return getDelegate().createTable(tableMetaData, physicalName, tableType, tableProps, families, splits,
+                isNamespaceMapped);
     }
 
     @Override
@@ -310,4 +316,29 @@ public class DelegateConnectionQueryServices extends DelegateQueryServices imple
             throws SQLException {
         return getDelegate().getTableRegionLocation(tableName, row);
     }
+
+    @Override
+    public PMetaData addSchema(PSchema schema) throws SQLException {
+        return getDelegate().addSchema(schema);
+    }
+
+    @Override
+    public MetaDataMutationResult createSchema(List<Mutation> schemaMutations, String schemaName) throws SQLException {
+        return getDelegate().createSchema(schemaMutations, schemaName);
+    }
+
+    @Override
+    public MetaDataMutationResult getSchema(String schemaName, long clientTimestamp) throws SQLException {
+        return getDelegate().getSchema(schemaName, clientTimestamp);
+    }
+
+    @Override
+    public PMetaData removeSchema(PSchema schema, long schemaTimeStamp) {
+        return getDelegate().removeSchema(schema, schemaTimeStamp);
+    }
+
+    @Override
+    public MetaDataMutationResult dropSchema(List<Mutation> schemaMetaData, String schemaName) throws SQLException {
+        return getDelegate().dropSchema(schemaMetaData, schemaName);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/query/MetaDataMutated.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/MetaDataMutated.java b/phoenix-core/src/main/java/org/apache/phoenix/query/MetaDataMutated.java
index 753b172..f532dc8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/MetaDataMutated.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/MetaDataMutated.java
@@ -21,6 +21,7 @@ import java.sql.SQLException;
 import java.util.List;
 
 import org.apache.phoenix.parse.PFunction;
+import org.apache.phoenix.parse.PSchema;
 import org.apache.phoenix.schema.PColumn;
 import org.apache.phoenix.schema.PMetaData;
 import org.apache.phoenix.schema.PName;
@@ -38,8 +39,10 @@ public interface MetaDataMutated {
     PMetaData addTable(PTable table, long resolvedTime) throws SQLException;
     PMetaData updateResolvedTimestamp(PTable table, long resolvedTimestamp) throws SQLException;
     PMetaData removeTable(PName tenantId, String tableName, String parentTableName, long tableTimeStamp) throws SQLException;
-    PMetaData addColumn(PName tenantId, String tableName, List<PColumn> columns, long tableTimeStamp, long tableSeqNum, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls, boolean isTransactional, long updateCacheFrequency, long resolvedTime) throws SQLException;
+    PMetaData addColumn(PName tenantId, String tableName, List<PColumn> columns, long tableTimeStamp, long tableSeqNum, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls, boolean isTransactional, long updateCacheFrequency, boolean isNamespaceMapped, long resolvedTime) throws SQLException;
     PMetaData removeColumn(PName tenantId, String tableName, List<PColumn> columnsToRemove, long tableTimeStamp, long tableSeqNum, long resolvedTime) throws SQLException;
     PMetaData addFunction(PFunction function) throws SQLException;
     PMetaData removeFunction(PName tenantId, String function, long functionTimeStamp) throws SQLException;
+    PMetaData addSchema(PSchema schema) throws SQLException;
+    PMetaData removeSchema(PSchema schema, long schemaTimeStamp);
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
index 6def7db..450ccfe 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
@@ -50,6 +50,7 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_TYPE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_ARRAY;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_AUTOINCREMENT;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_CONSTANT;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_NAMESPACE_MAPPED;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_NULLABLE;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_ROW_TIMESTAMP;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_VIEW_REFERENCED;
@@ -127,6 +128,9 @@ import org.apache.phoenix.util.ByteUtil;
  */
 public interface QueryConstants {
     public static final String NAME_SEPARATOR = ".";
+    public static final String NAMESPACE_SEPARATOR = ":";
+    public static final byte[] NAMESPACE_SEPARATOR_BYTES = Bytes.toBytes(NAMESPACE_SEPARATOR);
+    public static final byte NAMESPACE_SEPARATOR_BYTE = NAMESPACE_SEPARATOR_BYTES[0];
     public static final String NAME_SEPARATOR_REGEX = "\\" + NAME_SEPARATOR;
     public final static byte[] NAME_SEPARATOR_BYTES = Bytes.toBytes(NAME_SEPARATOR);
     public static final byte NAME_SEPARATOR_BYTE = NAME_SEPARATOR_BYTES[0];
@@ -262,6 +266,7 @@ public interface QueryConstants {
             IS_ROW_TIMESTAMP + " BOOLEAN, " +
             TRANSACTIONAL + " BOOLEAN," +
             UPDATE_CACHE_FREQUENCY + " BIGINT," +
+            IS_NAMESPACE_MAPPED + " BOOLEAN," +
             "CONSTRAINT " + SYSTEM_TABLE_PK_NAME + " PRIMARY KEY (" + TENANT_ID + ","
             + TABLE_SCHEM + "," + TABLE_NAME + "," + COLUMN_NAME + "," + COLUMN_FAMILY + "))\n" +
             HConstants.VERSIONS + "=" + MetaDataProtocol.DEFAULT_MAX_META_DATA_VERSIONS + ",\n" +
@@ -306,6 +311,8 @@ public interface QueryConstants {
             HConstants.VERSIONS + "=" + MetaDataProtocol.DEFAULT_MAX_META_DATA_VERSIONS + ",\n" +
             HColumnDescriptor.KEEP_DELETED_CELLS + "="  + MetaDataProtocol.DEFAULT_META_DATA_KEEP_DELETED_CELLS + ",\n" +
             PhoenixDatabaseMetaData.TRANSACTIONAL + "=" + Boolean.FALSE;
+    public static final String CREATE_SYSTEM_SCHEMA = "CREATE SCHEMA " + SYSTEM_CATALOG_SCHEMA;
+    public static final String UPGRADE_TABLE_SNAPSHOT_PREFIX = "_UPGRADING_TABLE_";
 
     public static final String CREATE_FUNCTION_METADATA =
             "CREATE TABLE " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_FUNCTION_TABLE + "\"(\n" +

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
index 0de8b98..0e4271a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
@@ -48,6 +48,10 @@ public interface QueryServices extends SQLCloseable {
     public static final String HBASE_CLIENT_PRINCIPAL = "hbase.myclient.principal";
     public static final String SPOOL_DIRECTORY = "phoenix.spool.directory";
     public static final String AUTO_COMMIT_ATTRIB = "phoenix.connection.autoCommit";
+    
+    public static final String SCHEMA_ATTRIB = "phoenix.connection.schema";
+    public static final String IS_NAMESPACE_MAPPING_ENABLED  = "phoenix.connection.isNamespaceMappingEnabled";
+    public static final String IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE  = "phoenix.connection.mapSystemTablesToNamespace";
     // joni byte regex engine setting
     public static final String USE_BYTE_BASED_REGEX_ATTRIB = "phoenix.regex.byteBased";
     public static final String DRIVER_SHUTDOWN_TIMEOUT_MS = "phoenix.shutdown.timeoutMs";
@@ -210,6 +214,7 @@ public interface QueryServices extends SQLCloseable {
 
     // time to wait before running second index population upsert select (so that any pending batches of rows on region server are also written to index)
     public static final String INDEX_POPULATION_SLEEP_TIME = "phoenix.index.population.wait.time";
+
     /**
      * Get executor service used for parallel scans
      */

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
index 8d5cadf..c49ad1d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
@@ -39,6 +39,8 @@ import static org.apache.phoenix.query.QueryServices.GROUPBY_SPILL_FILES_ATTRIB;
 import static org.apache.phoenix.query.QueryServices.IMMUTABLE_ROWS_ATTRIB;
 import static org.apache.phoenix.query.QueryServices.INDEX_MUTATE_BATCH_SIZE_THRESHOLD_ATTRIB;
 import static org.apache.phoenix.query.QueryServices.INDEX_POPULATION_SLEEP_TIME;
+import static org.apache.phoenix.query.QueryServices.IS_NAMESPACE_MAPPING_ENABLED;
+import static org.apache.phoenix.query.QueryServices.IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE;
 import static org.apache.phoenix.query.QueryServices.KEEP_ALIVE_MS_ATTRIB;
 import static org.apache.phoenix.query.QueryServices.MASTER_INFO_PORT_ATTRIB;
 import static org.apache.phoenix.query.QueryServices.MAX_CLIENT_METADATA_CACHE_SIZE_ATTRIB;
@@ -132,6 +134,8 @@ public class QueryServicesOptions {
     // latency and client-side spooling/buffering. Smaller means less initial
     // latency and less parallelization.
     public static final long DEFAULT_SCAN_RESULT_CHUNK_SIZE = 2999;
+    public static final boolean DEFAULT_IS_NAMESPACE_MAPPING_ENABLED = false;
+    public static final boolean DEFAULT_IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE = false;
 
     //
     // Spillable GroupBy - SPGBY prefix
@@ -247,6 +251,7 @@ public class QueryServicesOptions {
         add("credential");
       }
     };
+    public static final String DEFAULT_SCHEMA = null;
     
     private final Configuration config;
 
@@ -310,8 +315,10 @@ public class QueryServicesOptions {
             .setIfUnset(ALLOW_VIEWS_ADD_NEW_CF_BASE_TABLE, DEFAULT_ALLOW_VIEWS_ADD_NEW_CF_BASE_TABLE)
             .setIfUnset(RENEW_LEASE_THRESHOLD_MILLISECONDS, DEFAULT_RENEW_LEASE_THRESHOLD_MILLISECONDS)
             .setIfUnset(RUN_RENEW_LEASE_FREQUENCY_INTERVAL_MILLISECONDS, DEFAULT_RUN_RENEW_LEASE_FREQUENCY_INTERVAL_MILLISECONDS)
-            .setIfUnset(RENEW_LEASE_THREAD_POOL_SIZE, DEFAULT_RENEW_LEASE_THREAD_POOL_SIZE);
-            ;
+            .setIfUnset(RENEW_LEASE_THREAD_POOL_SIZE, DEFAULT_RENEW_LEASE_THREAD_POOL_SIZE)
+            .setIfUnset(IS_NAMESPACE_MAPPING_ENABLED, DEFAULT_IS_NAMESPACE_MAPPING_ENABLED)
+            .setIfUnset(IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE, DEFAULT_IS_SYSTEM_TABLE_MAPPED_TO_NAMESPACE);
+            
         // HBase sets this to 1, so we reset it to something more appropriate.
         // Hopefully HBase will change this, because we can't know if a user set
         // it to 1, so we'll change it.

http://git-wip-us.apache.org/repos/asf/phoenix/blob/7e432be7/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
index b294f03..7b9af43 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/DelegateTable.java
@@ -271,4 +271,9 @@ public class DelegateTable implements PTable {
     public long getUpdateCacheFrequency() {
         return delegate.getUpdateCacheFrequency();
     }
+
+    @Override
+    public boolean isNamespaceMapped() {
+        return delegate.isNamespaceMapped();
+    }
 }


[06/52] [abbrv] phoenix git commit: PHOENIX-2822 Tests that extend BaseHBaseManagedTimeIT are very slow(Rahul Gidwani)

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortOrderIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortOrderIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortOrderIT.java
index b906ae2..4357272 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortOrderIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortOrderIT.java
@@ -54,180 +54,217 @@ import com.google.common.collect.Lists;
  */
 
 
-public class SortOrderIT extends BaseHBaseManagedTimeIT {
+public class SortOrderIT extends BaseHBaseManagedTimeTableReuseIT {
     
-    private static final String TABLE = "DescColumnSortOrderTest";
-
     @Test
     public void noOrder() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (pk VARCHAR NOT NULL PRIMARY KEY)";
-        runQueryTest(ddl, "pk", new Object[][]{{"a"}, {"b"}, {"c"}}, new Object[][]{{"a"}, {"b"}, {"c"}});
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (pk VARCHAR NOT NULL PRIMARY KEY)";
+        runQueryTest(ddl, "pk", new Object[][]{{"a"}, {"b"}, {"c"}}, new Object[][]{{"a"}, {"b"}, {"c"}},
+            table);
     }                                                           
 
     @Test
     public void noOrderCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid, code))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid, code))";
         Object[][] rows = new Object[][]{{"o1", 1}, {"o2", 2}, {"o3", 3}};
-        runQueryTest(ddl, upsert("oid", "code"), rows, rows);
+        runQueryTest(ddl, upsert("oid", "code"), rows, rows, table);
     }
     
     @Test
     public void ascOrderInlinePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (pk VARCHAR NOT NULL PRIMARY KEY ASC)";
-        runQueryTest(ddl, "pk", new Object[][]{{"a"}, {"b"}, {"c"}}, new Object[][]{{"a"}, {"b"}, {"c"}});
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (pk VARCHAR NOT NULL PRIMARY KEY ASC)";
+        runQueryTest(ddl, "pk", new Object[][]{{"a"}, {"b"}, {"c"}}, new Object[][]{{"a"}, {"b"}, {"c"}},
+            table);
     }
     
     @Test
     public void ascOrderCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid ASC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid ASC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"o1", 1}, {"o1", 2}, {"o1", 3}};
         Object[][] expectedRows = new Object[][]{{"o1", 3}, {"o1", 2}, {"o1", 1}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows);        
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, table);
     }
 
     @Test
     public void descOrderInlinePK() throws Exception {
+        String table = generateRandomString();
         for (String type : new String[]{"CHAR(2)", "VARCHAR"}) {
-            String ddl = "CREATE TABLE " + TABLE + " (pk ${type} NOT NULL PRIMARY KEY DESC)".replace("${type}", type);
-            runQueryTest(ddl, "pk", new Object[][]{{"aa"}, {"bb"}, {"cc"}}, new Object[][]{{"cc"}, {"bb"}, {"aa"}});
+            String ddl = "CREATE table " + table + " (pk ${type} NOT NULL PRIMARY KEY DESC)".replace("${type}", type);
+            runQueryTest(ddl, "pk", new Object[][]{{"aa"}, {"bb"}, {"cc"}}, new Object[][]{{"cc"}, {"bb"}, {"aa"}},
+                table);
         }
     }
     
     @Test
     public void descOrderCompositePK1() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code))";
         Object[][] insertedRows = new Object[][]{{"o1", 1}, {"o2", 2}, {"o3", 3}};
         Object[][] expectedRows = new Object[][]{{"o3", 3}, {"o2", 2}, {"o1", 1}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows);        
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, table);
     }
     
     @Test
     public void descOrderCompositePK2() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"o1", 1}, {"o1", 2}, {"o1", 3}};
         Object[][] expectedRows = new Object[][]{{"o1", 3}, {"o1", 2}, {"o1", 1}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows);        
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, table);
     }    
 
     @Test
     public void equalityDescInlinePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (pk VARCHAR NOT NULL PRIMARY KEY DESC)";
-        runQueryTest(ddl, upsert("pk"), new Object[][]{{"a"}, {"b"}, {"c"}}, new Object[][]{{"b"}}, new WhereCondition("pk", "=", "'b'"));
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (pk VARCHAR NOT NULL PRIMARY KEY DESC)";
+        runQueryTest(ddl, upsert("pk"), new Object[][]{{"a"}, {"b"}, {"c"}}, new Object[][]{{"b"}}, new WhereCondition("pk", "=", "'b'"),
+            table);
     }
     
     @Test
     public void equalityDescCompositePK1() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"o1", 1}, {"o2", 2}, {"o3", 3}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"o2", 2}}, new WhereCondition("oid", "=", "'o2'"));        
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"o2", 2}}, new WhereCondition("oid", "=", "'o2'"),
+            table);
     }
     
     @Test
     public void equalityDescCompositePK2() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"o1", 1}, {"o1", 2}, {"o1", 3}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"o1", 2}}, new WhereCondition("code", "=", "2"));        
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"o1", 2}}, new WhereCondition("code", "=", "2"),
+            table);
     }
     
     @Test
     public void inDescCompositePK1() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"o1", 1}, {"o1", 2}, {"o1", 3}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"o1", 2}}, new WhereCondition("code", "IN", "(2)"));        
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"o1", 2}}, new WhereCondition("code", "IN", "(2)"),
+            table);
     }
     
     @Test
     public void inDescCompositePK2() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"o1", 1}, {"o2", 2}, {"o3", 3}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"o2", 2}}, new WhereCondition("oid", "IN", "('o2')"));        
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"o2", 2}}, new WhereCondition("oid", "IN", "('o2')"),
+            table);
     }
     
     @Test
     public void likeDescCompositePK1() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"a1", 1}, {"b2", 2}, {"c3", 3}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"b2", 2}}, new WhereCondition("oid", "LIKE", "('b%')"));        
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"b2", 2}}, new WhereCondition("oid", "LIKE", "('b%')"),
+            table);
     }
     
     @Test
     public void likeDescCompositePK2() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code CHAR(2) NOT NULL constraint pk primary key (oid DESC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code CHAR(2) NOT NULL constraint pk primary key (oid DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"a1", "11"}, {"b2", "22"}, {"c3", "33"}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"b2", "22"}}, new WhereCondition("code", "LIKE", "('2%')"));        
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, new Object[][]{{"b2", "22"}}, new WhereCondition("code", "LIKE", "('2%')"),
+            table);
     }
     
     @Test
     public void greaterThanDescCompositePK3() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"o1", 1}, {"o1", 2}, {"o1", 3}};
         Object[][] expectedRows = new Object[][]{{"o1", 2}, {"o1", 1}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, new WhereCondition("code", "<", "3"));        
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, new WhereCondition("code", "<", "3"),
+            table);
     }
     
     @Test
     public void substrDescCompositePK1() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(3) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code ASC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(3) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code ASC))";
         Object[][] insertedRows = new Object[][]{{"ao1", 1}, {"bo2", 2}, {"co3", 3}};
         Object[][] expectedRows = new Object[][]{{"co3", 3}, {"bo2", 2}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, new WhereCondition("SUBSTR(oid, 3, 1)", ">", "'1'"));
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, new WhereCondition("SUBSTR(oid, 3, 1)", ">", "'1'"),
+            table);
     }
         
     @Test
     public void substrDescCompositePK2() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(4) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code ASC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(4) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code ASC))";
         Object[][] insertedRows = new Object[][]{{"aaaa", 1}, {"bbbb", 2}, {"cccd", 3}};
         Object[][] expectedRows = new Object[][]{{"cccd", 3}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, new WhereCondition("SUBSTR(oid, 4, 1)", "=", "'d'"));
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, new WhereCondition("SUBSTR(oid, 4, 1)", "=", "'d'"),
+            table);
     }    
     
     @Test
     public void substrFixedLengthDescPK1() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(3) PRIMARY KEY DESC)";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(3) PRIMARY KEY DESC)";
         Object[][] insertedRows = new Object[][]{{"a"}, {"ab"}};
         Object[][] expectedRows = new Object[][]{{"ab"}, {"a"} };
-        runQueryTest(ddl, upsert("oid"), insertedRows, expectedRows, new WhereCondition("SUBSTR(oid, 1, 1)", "=", "'a'"));
+        runQueryTest(ddl, upsert("oid"), insertedRows, expectedRows, new WhereCondition("SUBSTR(oid, 1, 1)", "=", "'a'"),
+            table);
     }
         
     @Test
     public void substrVarLengthDescPK1() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid VARCHAR PRIMARY KEY DESC)";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid VARCHAR PRIMARY KEY DESC)";
         Object[][] insertedRows = new Object[][]{{"a"}, {"ab"}};
         Object[][] expectedRows = new Object[][]{{"ab"}, {"a"} };
-        runQueryTest(ddl, upsert("oid"), insertedRows, expectedRows, new WhereCondition("SUBSTR(oid, 1, 1)", "=", "'a'"));
+        runQueryTest(ddl, upsert("oid"), insertedRows, expectedRows, new WhereCondition("SUBSTR(oid, 1, 1)", "=", "'a'"),
+            table);
     }
         
     @Test
     public void likeVarLengthDescPK1() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid VARCHAR PRIMARY KEY DESC)";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid VARCHAR PRIMARY KEY DESC)";
         Object[][] insertedRows = new Object[][]{{"a"}, {"ab"}};
         Object[][] expectedRows = new Object[][]{{"ab"}, {"a"} };
-        runQueryTest(ddl, upsert("oid"), insertedRows, expectedRows, new WhereCondition("oid", "like", "'a%'"));
+        runQueryTest(ddl, upsert("oid"), insertedRows, expectedRows, new WhereCondition("oid", "like", "'a%'"),
+            table);
     }
         
     @Test
     public void likeFixedLengthDescPK1() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(3) PRIMARY KEY DESC)";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(3) PRIMARY KEY DESC)";
         Object[][] insertedRows = new Object[][]{{"a"}, {"ab"}};
         Object[][] expectedRows = new Object[][]{{"ab"}, {"a"} };
-        runQueryTest(ddl, upsert("oid"), insertedRows, expectedRows, new WhereCondition("oid", "like", "'a%'"));
+        runQueryTest(ddl, upsert("oid"), insertedRows, expectedRows, new WhereCondition("oid", "like", "'a%'"),
+            table);
     }
         
     @Test
     public void decimalRangeDescPK1() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid DECIMAL PRIMARY KEY DESC)";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid DECIMAL PRIMARY KEY DESC)";
         Connection conn = DriverManager.getConnection(getUrl());
         conn.createStatement().execute(ddl);
-        conn.createStatement().execute("UPSERT INTO " + TABLE + " VALUES(4.99)");
-        conn.createStatement().execute("UPSERT INTO " + TABLE + " VALUES(4.0)");
-        conn.createStatement().execute("UPSERT INTO " + TABLE + " VALUES(5.0)");
-        conn.createStatement().execute("UPSERT INTO " + TABLE + " VALUES(5.001)");
-        conn.createStatement().execute("UPSERT INTO " + TABLE + " VALUES(5.999)");
-        conn.createStatement().execute("UPSERT INTO " + TABLE + " VALUES(6.0)");
-        conn.createStatement().execute("UPSERT INTO " + TABLE + " VALUES(6.001)");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES(4.99)");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES(4.0)");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES(5.0)");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES(5.001)");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES(5.999)");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES(6.0)");
+        conn.createStatement().execute("UPSERT INTO " + table + " VALUES(6.001)");
         conn.commit();
         
-        String query = "SELECT * FROM " + TABLE + " WHERE oid >= 5.0 AND oid < 6.0";
+        String query = "SELECT * FROM " + table + " WHERE oid >= 5.0 AND oid < 6.0";
         ResultSet rs = conn.createStatement().executeQuery(query);
         assertTrue(rs.next());
         assertTrue(new BigDecimal("5.999").compareTo(rs.getBigDecimal(1)) == 0);
@@ -240,193 +277,225 @@ public class SortOrderIT extends BaseHBaseManagedTimeIT {
         
     @Test
     public void lTrimDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid VARCHAR NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid VARCHAR NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{" o1 ", 1}, {"  o2", 2}, {"  o3", 3}};
         Object[][] expectedRows = new Object[][]{{"  o2", 2}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, new WhereCondition("LTRIM(oid)", "=", "'o2'"));
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, new WhereCondition("LTRIM(oid)", "=", "'o2'"),
+            table);
     }
     
     @Test
     public void lPadDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid VARCHAR NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid VARCHAR NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"aaaa", 1}, {"bbbb", 2}, {"cccc", 3}};
         Object[][] expectedRows = new Object[][]{{"bbbb", 2}};
-        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, new WhereCondition("LPAD(oid, 8, '123')", "=", "'1231bbbb'"));
+        runQueryTest(ddl, upsert("oid", "code"), insertedRows, expectedRows, new WhereCondition("LPAD(oid, 8, '123')", "=", "'1231bbbb'"),
+            table);
     }
 
     @Test
     public void countDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code ASC))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (oid CHAR(2) NOT NULL, code INTEGER NOT NULL constraint pk primary key (oid DESC, code ASC))";
         Object[][] insertedRows = new Object[][]{{"o1", 1}, {"o2", 2}, {"o3", 3}};
         Object[][] expectedRows = new Object[][]{{3l}};
-        runQueryTest(ddl, upsert("oid", "code"), select("COUNT(oid)"), insertedRows, expectedRows);
+        runQueryTest(ddl, upsert("oid", "code"), select("COUNT(oid)"), insertedRows, expectedRows,
+            table);
     }
     
     @Test
     public void sumDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL " + 
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL " +
             "constraint pk primary key (n1 DESC, n2 DESC, n3 DESC))";
         Object[][] insertedRows = new Object[][]{{10, bdec(10.2), 21l}, {20, bdec(20.2), 32l}, {30, bdec(30.2), 43l}};
         Object[][] expectedRows = new Object[][]{{60l, bdec(60.6), 96l}};
-        runQueryTest(ddl, upsert("n1", "n2", "n3"), select("SUM(n1), SUM(n2), SUM(n3)"), insertedRows, expectedRows);
+        runQueryTest(ddl, upsert("n1", "n2", "n3"), select("SUM(n1), SUM(n2), SUM(n3)"), insertedRows, expectedRows,
+            table);
     }    
     
     @Test
     public void avgDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL " + 
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL " +
             "constraint pk primary key (n1 DESC, n2 DESC, n3 DESC))";
         Object[][] insertedRows = new Object[][]{{10, bdec(10.2), 21l}, {20, bdec(20.2), 32l}, {30, bdec(30.2), 43l}};
         Object[][] expectedRows = new Object[][]{{new BigDecimal(bint(2), -1), bdec(20.2), BigDecimal.valueOf(32)}};
-        runQueryTest(ddl, upsert("n1", "n2", "n3"), select("AVG(n1), AVG(n2), AVG(n3)"), insertedRows, expectedRows);
+        runQueryTest(ddl, upsert("n1", "n2", "n3"), select("AVG(n1), AVG(n2), AVG(n3)"), insertedRows, expectedRows,
+            table);
     }
     
     @Test
     public void minDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL " + 
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL " +
             "constraint pk primary key (n1 DESC, n2 DESC, n3 DESC))";
         Object[][] insertedRows = new Object[][]{{10, bdec(10.2), 21l}, {20, bdec(20.2), 32l}, {30, bdec(30.2), 43l}};
         Object[][] expectedRows = new Object[][]{{10, bdec(10.2), 21l}};
-        runQueryTest(ddl, upsert("n1", "n2", "n3"), select("MIN(n1), MIN(n2), MIN(n3)"), insertedRows, expectedRows);
+        runQueryTest(ddl, upsert("n1", "n2", "n3"), select("MIN(n1), MIN(n2), MIN(n3)"), insertedRows, expectedRows,
+            table);
     }
     
     @Test
     public void maxDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL " + 
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL " +
             "constraint pk primary key (n1 DESC, n2 DESC, n3 DESC))";
         Object[][] insertedRows = new Object[][]{{10, bdec(10.2), 21l}, {20, bdec(20.2), 32l}, {30, bdec(30.2), 43l}};
         Object[][] expectedRows = new Object[][]{{30, bdec(30.2), 43l}};
-        runQueryTest(ddl, upsert("n1", "n2", "n3"), select("MAX(n1), MAX(n2), MAX(n3)"), insertedRows, expectedRows);
+        runQueryTest(ddl, upsert("n1", "n2", "n3"), select("MAX(n1), MAX(n2), MAX(n3)"), insertedRows, expectedRows,
+            table);
     }
     
     @Test
     public void havingSumDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (name CHAR(1) NOT NULL, code INTEGER NOT NULL " + 
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (name CHAR(1) NOT NULL, code INTEGER NOT NULL " +
             "constraint pk primary key (name DESC, code DESC))";
         Object[][] insertedRows = new Object[][]{{"a", 10}, {"a", 20}, {"b", 100}}; 
         Object[][] expectedRows = new Object[][]{{"a", 30l}};
         runQueryTest(ddl, upsert("name", "code"), select("name", "SUM(code)"), insertedRows, expectedRows, 
-            new HavingCondition("name", "SUM(code) = 30"));
+            new HavingCondition("name", "SUM(code) = 30"), table);
     }
     
     @Test
     public void queryDescDateWithExplicitOrderBy() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (c1 CHAR(1) NOT NULL, c2 CHAR(1) NOT NULL, d1 DATE NOT NULL, c3 CHAR(1) NOT NULL " + 
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (c1 CHAR(1) NOT NULL, c2 CHAR(1) NOT NULL, d1 DATE NOT NULL, c3 CHAR(1) NOT NULL " +
             "constraint pk primary key (c1, c2, d1 DESC, c3))";
         Object[] row1 = {"1", "2", date(10, 11, 2001), "3"};
         Object[] row2 = {"1", "2", date(10, 11, 2003), "3"};
         Object[][] insertedRows = new Object[][]{row1, row2};
         runQueryTest(ddl, upsert("c1", "c2", "d1", "c3"), select("c1, c2, d1", "c3"), insertedRows, new Object[][]{row2, row1},
-            null, null, new OrderBy("d1", OrderBy.Direction.DESC));
+            null, null, new OrderBy("d1", OrderBy.Direction.DESC), table);
     }    
     
     @Test
     public void additionOnDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL, d1 DATE NOT NULL " + 
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL, d1 DATE NOT NULL " +
             "constraint pk primary key (n1 DESC, n2 DESC, n3 DESC, d1 DESC))";
         Object[][] insertedRows = new Object[][]{
             {10, bdec(10.2), 21l, date(1, 10, 2001)}, {20, bdec(20.2), 32l, date(2, 6, 2001)}, {30, bdec(30.2), 43l, date(3, 1, 2001)}};
         Object[][] expectedRows = new Object[][]{
             {31l, bdec(32.2), 46l, date(3, 5, 2001)}, {21l, bdec(22.2), 35l, date(2, 10, 2001)}, {11l, bdec(12.2), 24l, date(1, 14, 2001)}};
-        runQueryTest(ddl, upsert("n1", "n2", "n3", "d1"), select("n1+1, n2+2, n3+3", "d1+4"), insertedRows, expectedRows);
+        runQueryTest(ddl, upsert("n1", "n2", "n3", "d1"), select("n1+1, n2+2, n3+3", "d1+4"), insertedRows, expectedRows,
+            table);
     }
     
     @Test
     public void subtractionOnDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL, d1 DATE NOT NULL " + 
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (n1 INTEGER NOT NULL, n2 DECIMAL(10, 2) NOT NULL, n3 BIGINT NOT NULL, d1 DATE NOT NULL " +
             "constraint pk primary key (n1 DESC, n2 DESC, n3 DESC, d1 DESC))";
         Object[][] insertedRows = new Object[][]{
             {10, bdec(10.2), 21l, date(1, 10, 2001)}, {20, bdec(20.2), 32l, date(2, 6, 2001)}, {30, bdec(30.2), 43l, date(3, 10, 2001)}};
         Object[][] expectedRows = new Object[][]{
             {29l, bdec(28.2), 40l, date(3, 6, 2001)}, {19l, bdec(18.2), 29l, date(2, 2, 2001)}, {9l, bdec(8.2), 18l, date(1, 6, 2001)}};
-        runQueryTest(ddl, upsert("n1", "n2", "n3", "d1"), select("n1-1, n2-2, n3-3", "d1-4"), insertedRows, expectedRows);
+        runQueryTest(ddl, upsert("n1", "n2", "n3", "d1"), select("n1-1, n2-2, n3-3", "d1-4"), insertedRows, expectedRows,
+            table);
     }
     
     @Test
     public void lessThanLeadingDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (id INTEGER NOT NULL, date DATE NOT NULL constraint pk primary key (id DESC, date))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (id INTEGER NOT NULL, date DATE NOT NULL constraint pk primary key (id DESC, date))";
         Object[][] insertedRows = new Object[][]{{1, date(1, 1, 2012)}, {3, date(1, 1, 2013)}, {2, date(1, 1, 2011)}};
         Object[][] expectedRows = new Object[][]{{1, date(1, 1, 2012)}};
-        runQueryTest(ddl, upsert("id", "date"), insertedRows, expectedRows, new WhereCondition("id", "<", "2"));
+        runQueryTest(ddl, upsert("id", "date"), insertedRows, expectedRows, new WhereCondition("id", "<", "2"),
+            table);
     }
     
     @Test
     public void lessThanTrailingDescCompositePK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (id INTEGER NOT NULL, date DATE NOT NULL constraint pk primary key (id DESC, date))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (id INTEGER NOT NULL, date DATE NOT NULL constraint pk primary key (id DESC, date))";
         Object[][] insertedRows = new Object[][]{{1, date(1, 1, 2002)}, {3, date(1, 1, 2003)}, {2, date(1, 1, 2001)}};
         Object[][] expectedRows = new Object[][]{{2, date(1, 1, 2001)}};
-        runQueryTest(ddl, upsert("id", "date"), insertedRows, expectedRows, new WhereCondition("date", "<", "TO_DATE('02-02-2001','mm-dd-yyyy')"));
+        runQueryTest(ddl, upsert("id", "date"), insertedRows, expectedRows, new WhereCondition("date", "<", "TO_DATE('02-02-2001','mm-dd-yyyy')"),
+            table);
     }
     
     @Test
     public void descVarLengthPK() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (id VARCHAR PRIMARY KEY DESC)";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (id VARCHAR PRIMARY KEY DESC)";
         Object[][] insertedRows = new Object[][]{{"a"}, {"ab"}, {"abc"}};
         Object[][] expectedRows = new Object[][]{{"abc"}, {"ab"}, {"a"}};
         runQueryTest(ddl, upsert("id"), select("id"), insertedRows, expectedRows,
-                null, null, new OrderBy("id", OrderBy.Direction.DESC));
+                null, null, new OrderBy("id", OrderBy.Direction.DESC), table);
     }
     
     @Test
     public void descVarLengthAscPKGT() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (k1 INTEGER NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1, k2))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (k1 INTEGER NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1, k2))";
         Object[][] insertedRows = new Object[][]{{0, null}, {1, "a"}, {2, "b"}, {3, "ba"}, {4, "baa"}, {5, "c"}, {6, "d"}};
         Object[][] expectedRows = new Object[][]{{3}, {4}, {5}, {6}};
         runQueryTest(ddl, upsert("k1", "k2"), select("k1"), insertedRows, expectedRows,
-                new WhereCondition("k2", ">", "'b'"), null, null);
+                new WhereCondition("k2", ">", "'b'"), null, null, table);
     }
         
     @Test
     public void descVarLengthDescPKGT() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (k1 INTEGER NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1, k2 desc))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (k1 INTEGER NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1, k2 desc))";
         Object[][] insertedRows = new Object[][]{{0, null}, {1, "a"}, {2, "b"}, {3, "ba"}, {4, "baa"}, {5, "c"}, {6, "d"}};
         Object[][] expectedRows = new Object[][]{{3}, {4}, {5}, {6}};
         runQueryTest(ddl, upsert("k1", "k2"), select("k1"), insertedRows, expectedRows,
-                new WhereCondition("k2", ">", "'b'"), null, null);
+                new WhereCondition("k2", ">", "'b'"), null, null, table);
     }
         
     @Test
     public void descVarLengthDescPKLTE() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (k1 INTEGER NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1, k2 desc))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (k1 INTEGER NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1, k2 desc))";
         Object[][] insertedRows = new Object[][]{{0, null}, {1, "a"}, {2, "b"}, {3, "ba"}, {4, "bb"}, {5, "bc"}, {6, "bba"}, {7, "c"}};
         Object[][] expectedRows = new Object[][]{{1}, {2}, {3}, {4}};
         runQueryTest(ddl, upsert("k1", "k2"), select("k1"), insertedRows, expectedRows,
-                new WhereCondition("k2", "<=", "'bb'"), null, null);
+                new WhereCondition("k2", "<=", "'bb'"), null, null, table);
     }
         
     @Test
     public void descVarLengthAscPKLTE() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (k1 INTEGER NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1, k2))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (k1 INTEGER NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1, k2))";
         Object[][] insertedRows = new Object[][]{{0, null}, {1, "a"}, {2, "b"}, {3, "ba"}, {4, "bb"}, {5, "bc"}, {6, "bba"}, {7, "c"}};
         Object[][] expectedRows = new Object[][]{{1}, {2}, {3}, {4}};
         runQueryTest(ddl, upsert("k1", "k2"), select("k1"), insertedRows, expectedRows,
-                new WhereCondition("k2", "<=", "'bb'"), null, null);
+                new WhereCondition("k2", "<=", "'bb'"), null, null, table);
     }
         
     @Test
     public void varLengthAscLT() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1, k2))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1, k2))";
         Object[][] insertedRows = new Object[][]{{"a", ""}, {"b",""}, {"b","a"}};
         Object[][] expectedRows = new Object[][]{{"a"}};
         runQueryTest(ddl, upsert("k1", "k2"), select("k1"), insertedRows, expectedRows,
-                new WhereCondition("k1", "<", "'b'"), null, null);
+                new WhereCondition("k1", "<", "'b'"), null, null, table);
     }
         
     @Test
     public void varLengthDescLT() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1 desc, k2))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1 desc, k2))";
         Object[][] insertedRows = new Object[][]{{"a", ""}, {"b",""}, {"b","a"}};
         Object[][] expectedRows = new Object[][]{{"a"}};
         runQueryTest(ddl, upsert("k1", "k2"), select("k1"), insertedRows, expectedRows,
-                new WhereCondition("k1", "<", "'b'"), null, null);
+                new WhereCondition("k1", "<", "'b'"), null, null, table);
     }
         
     @Test
     public void varLengthDescGT() throws Exception {
-        String ddl = "CREATE TABLE " + TABLE + " (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1 desc, k2))";
+        String table = generateRandomString();
+        String ddl = "CREATE table " + table + " (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT pk PRIMARY KEY (k1 desc, k2))";
         Object[][] insertedRows = new Object[][]{{"a", ""}, {"b",""}, {"b","a"}, {"ba","a"}};
         Object[][] expectedRows = new Object[][]{{"ba"}};
         runQueryTest(ddl, upsert("k1", "k2"), select("k1"), insertedRows, expectedRows,
-                new WhereCondition("k1", ">", "'b'"), null, null);
+                new WhereCondition("k1", ">", "'b'"), null, null, table);
     }
         
    @Test
@@ -489,35 +558,37 @@ public class SortOrderIT extends BaseHBaseManagedTimeIT {
         }
     }
 
-    private void runQueryTest(String ddl, String columnName, Object[][] rows, Object[][] expectedRows) throws Exception {
-        runQueryTest(ddl, new String[]{columnName}, rows, expectedRows, null);
+    private void runQueryTest(String ddl, String columnName, Object[][] rows,
+        Object[][] expectedRows, String table) throws Exception {
+        runQueryTest(ddl, new String[]{columnName}, rows, expectedRows, null, table);
     }
     
-    private void runQueryTest(String ddl, String[] columnNames, Object[][] rows, Object[][] expectedRows) throws Exception {
-        runQueryTest(ddl, columnNames, rows, expectedRows, null);
+    private void runQueryTest(String ddl, String[] columnNames, Object[][] rows,
+        Object[][] expectedRows, String table) throws Exception {
+        runQueryTest(ddl, columnNames, rows, expectedRows, null, table);
     }
     
-    private void runQueryTest(String ddl, String[] columnNames, Object[][] rows, Object[][] expectedRows, WhereCondition condition) throws Exception {
-        runQueryTest(ddl, columnNames, columnNames, rows, expectedRows, condition, null, null);
+    private void runQueryTest(String ddl, String[] columnNames, Object[][] rows, Object[][] expectedRows, WhereCondition condition,
+        String table) throws Exception {
+        runQueryTest(ddl, columnNames, columnNames, rows, expectedRows, condition, null, null,
+            table);
     }
     
-    private void runQueryTest(String ddl, String[] columnNames, String[] projections, Object[][] rows, Object[][] expectedRows) throws Exception {
-        runQueryTest(ddl, columnNames, projections, rows, expectedRows, null, null, null);
+    private void runQueryTest(String ddl, String[] columnNames, String[] projections, Object[][] rows, Object[][] expectedRows,
+        String table) throws Exception {
+        runQueryTest(ddl, columnNames, projections, rows, expectedRows, null, null, null, table);
     }
     
-    private void runQueryTest(String ddl, String[] columnNames, String[] projections, Object[][] rows, Object[][] expectedRows, HavingCondition havingCondition) throws Exception {
-        runQueryTest(ddl, columnNames, projections, rows, expectedRows, null, havingCondition, null);
+    private void runQueryTest(String ddl, String[] columnNames, String[] projections, Object[][] rows, Object[][] expectedRows, HavingCondition havingCondition,
+        String table) throws Exception {
+        runQueryTest(ddl, columnNames, projections, rows, expectedRows, null, havingCondition, null,
+            table);
     }
     
 
-    private void runQueryTest(
-        String ddl, 
-        String[] columnNames, 
-        String[] projections, 
-        Object[][] rows, Object[][] expectedRows, 
-        WhereCondition whereCondition, 
-        HavingCondition havingCondition,
-        OrderBy orderBy) 
+    private void runQueryTest(String ddl, String[] columnNames, String[] projections, Object[][] rows, Object[][] expectedRows,
+        WhereCondition whereCondition, HavingCondition havingCondition, OrderBy orderBy,
+        String table)
         throws Exception 
     {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
@@ -531,7 +602,7 @@ public class SortOrderIT extends BaseHBaseManagedTimeIT {
 
             String columns = appendColumns(columnNames);
             String placeholders = appendPlaceholders(columnNames);
-            String dml = "UPSERT INTO " + TABLE + " (" + columns + ") VALUES(" + placeholders +")";
+            String dml = "UPSERT INTO " + table + " (" + columns + ") VALUES(" + placeholders +")";
             PreparedStatement stmt = conn.prepareStatement(dml);
 
             for (int row = 0; row < rows.length; row++) {
@@ -543,7 +614,7 @@ public class SortOrderIT extends BaseHBaseManagedTimeIT {
             }
             conn.commit();
             
-            String selectClause = "SELECT " + appendColumns(projections) + " FROM " + TABLE;
+            String selectClause = "SELECT " + appendColumns(projections) + " FROM " + table;
             
             for (WhereCondition whereConditionClause : new WhereCondition[]{whereCondition, WhereCondition.reverse(whereCondition)}) {
                 String query = WhereCondition.appendWhere(whereConditionClause, selectClause);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatementHintsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatementHintsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatementHintsIT.java
index 70246f9..887a30e 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatementHintsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatementHintsIT.java
@@ -37,7 +37,9 @@ import org.junit.Test;
  */
 
 
-public class StatementHintsIT extends BaseHBaseManagedTimeIT {
+public class StatementHintsIT extends BaseHBaseManagedTimeTableReuseIT {
+
+    private static final String TABLE_NAME = generateRandomString();
 
     private static void initTableValues() throws Exception {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
@@ -45,7 +47,7 @@ public class StatementHintsIT extends BaseHBaseManagedTimeIT {
         conn.setAutoCommit(false);
         
         try {
-            String ddl = "CREATE TABLE test_table" +
+            String ddl = "CREATE TABLE " + TABLE_NAME  +
                     "   (a_integer integer not null, \n" +
                     "    a_string varchar not null, \n" +
                     "    a_id char(3) not null,\n" +
@@ -56,7 +58,7 @@ public class StatementHintsIT extends BaseHBaseManagedTimeIT {
             String query;
             PreparedStatement stmt;
             
-            query = "UPSERT INTO test_table"
+            query = "UPSERT INTO " + TABLE_NAME
                     + "(a_integer, a_string, a_id, b_string) "
                     + "VALUES(?,?,?,?)";
             stmt = conn.prepareStatement(query);
@@ -108,7 +110,7 @@ public class StatementHintsIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         try {
             initTableValues();
-            String query = "SELECT /*+ RANGE_SCAN */ * FROM test_table WHERE a_integer IN (1, 2, 3, 4)";
+            String query = "SELECT /*+ RANGE_SCAN */ * FROM " + TABLE_NAME + " WHERE a_integer IN (1, 2, 3, 4)";
             PreparedStatement stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             
@@ -145,7 +147,7 @@ public class StatementHintsIT extends BaseHBaseManagedTimeIT {
         try {
             initTableValues();
             // second slot on the 
-            String query = "SELECT /*+ SKIP_SCAN */ * FROM test_table WHERE a_string = 'abc'";
+            String query = "SELECT /*+ SKIP_SCAN */ * FROM " + TABLE_NAME + " WHERE a_string = 'abc'";
             PreparedStatement stmt = conn.prepareStatement(query);
             ResultSet rs = stmt.executeQuery();
             

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/StoreNullsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StoreNullsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StoreNullsIT.java
index 8efeefc..cbce02e 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StoreNullsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StoreNullsIT.java
@@ -35,6 +35,7 @@ import org.apache.phoenix.util.PhoenixRuntime;
 import org.apache.phoenix.util.SchemaUtil;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 import java.io.IOException;
@@ -57,24 +58,26 @@ import static org.junit.Assert.assertTrue;
  * functionality allows having row-level versioning (similar to how KEEP_DELETED_CELLS works), but
  * also allows permanently deleting a row.
  */
-public class StoreNullsIT extends BaseHBaseManagedTimeIT {
+public class StoreNullsIT extends BaseHBaseManagedTimeTableReuseIT {
 
     private static final Log LOG = LogFactory.getLog(StoreNullsIT.class);
+    private static final String WITH_NULLS = generateRandomString();
+    private static final String WITHOUT_NULLS = generateRandomString();
 
-    private Connection conn;
-    private Statement stmt;
+    private static Connection conn;
+    private static Statement stmt;
 
-    @Before
-    public void setUp() throws SQLException {
+    @BeforeClass
+    public static void setUp() throws SQLException {
         conn = DriverManager.getConnection(getUrl());
         conn.setAutoCommit(true);
 
         stmt = conn.createStatement();
-        stmt.execute("CREATE TABLE with_nulls (" +
+        stmt.execute("CREATE TABLE " + WITH_NULLS + " (" +
                         "id SMALLINT NOT NULL PRIMARY KEY, " +
                         "name VARCHAR) " +
                 "STORE_NULLS = true, VERSIONS = 1000, KEEP_DELETED_CELLS = false");
-        stmt.execute("CREATE TABLE without_nulls (" +
+        stmt.execute("CREATE TABLE " + WITHOUT_NULLS + " (" +
                         "id SMALLINT NOT NULL PRIMARY KEY, " +
                         "name VARCHAR) " +
                 "VERSIONS = 1000, KEEP_DELETED_CELLS = false");
@@ -88,19 +91,19 @@ public class StoreNullsIT extends BaseHBaseManagedTimeIT {
 
     @Test
     public void testQueryingHistory() throws SQLException, InterruptedException, IOException {
-        stmt.executeUpdate("UPSERT INTO with_nulls VALUES (1, 'v1')");
-        stmt.executeUpdate("UPSERT INTO without_nulls VALUES (1, 'v1')");
+        stmt.executeUpdate("UPSERT INTO " + WITH_NULLS + " VALUES (1, 'v1')");
+        stmt.executeUpdate("UPSERT INTO " + WITHOUT_NULLS + " VALUES (1, 'v1')");
 
         Thread.sleep(10L);
         long afterFirstInsert = System.currentTimeMillis();
         Thread.sleep(10L);
 
-        stmt.executeUpdate("UPSERT INTO with_nulls VALUES (1, null)");
-        stmt.executeUpdate("UPSERT INTO without_nulls VALUES (1, null)");
+        stmt.executeUpdate("UPSERT INTO " + WITH_NULLS + " VALUES (1, null)");
+        stmt.executeUpdate("UPSERT INTO " + WITHOUT_NULLS + " VALUES (1, null)");
         Thread.sleep(10L);
 
-        doMajorCompaction("with_nulls");
-        doMajorCompaction("without_nulls");
+        doMajorCompaction(WITH_NULLS);
+        doMajorCompaction(WITHOUT_NULLS);
 
         Properties historicalProps = new Properties();
         historicalProps.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB,
@@ -108,13 +111,14 @@ public class StoreNullsIT extends BaseHBaseManagedTimeIT {
         Connection historicalConn = DriverManager.getConnection(getUrl(), historicalProps);
         Statement historicalStmt = historicalConn.createStatement();
 
-        ResultSet rs = historicalStmt.executeQuery("SELECT name FROM with_nulls WHERE id = 1");
+        ResultSet rs = historicalStmt.executeQuery(
+            "SELECT name FROM " + WITH_NULLS + " WHERE id = 1");
         assertTrue(rs.next());
         assertEquals("v1", rs.getString(1));
         rs.close();
 
         // The single null wipes out all history for a field if STORE_NULLS is not enabled
-        rs = historicalStmt.executeQuery("SELECT name FROM without_nulls WHERE id = 1");
+        rs = historicalStmt.executeQuery("SELECT name FROM " + WITHOUT_NULLS + " WHERE id = 1");
         assertTrue(rs.next());
         assertNull(rs.getString(1));
         rs.close();
@@ -126,19 +130,19 @@ public class StoreNullsIT extends BaseHBaseManagedTimeIT {
     // Row deletes should work in the same way regardless of what STORE_NULLS is set to
     @Test
     public void testDeletes() throws SQLException, InterruptedException, IOException {
-        stmt.executeUpdate("UPSERT INTO with_nulls VALUES (1, 'v1')");
-        stmt.executeUpdate("UPSERT INTO without_nulls VALUES (1, 'v1')");
+        stmt.executeUpdate("UPSERT INTO " + WITH_NULLS + " VALUES (1, 'v1')");
+        stmt.executeUpdate("UPSERT INTO " + WITHOUT_NULLS + " VALUES (1, 'v1')");
 
         Thread.sleep(10L);
         long afterFirstInsert = System.currentTimeMillis();
         Thread.sleep(10L);
 
-        stmt.executeUpdate("DELETE FROM with_nulls WHERE id = 1");
-        stmt.executeUpdate("DELETE FROM without_nulls WHERE id = 1");
+        stmt.executeUpdate("DELETE FROM " + WITH_NULLS + " WHERE id = 1");
+        stmt.executeUpdate("DELETE FROM " + WITHOUT_NULLS + " WHERE id = 1");
         Thread.sleep(10L);
 
-        doMajorCompaction("with_nulls");
-        doMajorCompaction("without_nulls");
+        doMajorCompaction(WITH_NULLS);
+        doMajorCompaction(WITHOUT_NULLS);
 
         Properties historicalProps = new Properties();
         historicalProps.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB,
@@ -148,11 +152,12 @@ public class StoreNullsIT extends BaseHBaseManagedTimeIT {
 
         // The row should be completely gone for both tables now
 
-        ResultSet rs = historicalStmt.executeQuery("SELECT name FROM with_nulls WHERE id = 1");
+        ResultSet rs = historicalStmt.executeQuery(
+            "SELECT name FROM " + WITH_NULLS + " WHERE id = 1");
         assertFalse(rs.next());
         rs.close();
 
-        rs = historicalStmt.executeQuery("SELECT name FROM without_nulls WHERE id = 1");
+        rs = historicalStmt.executeQuery("SELECT name FROM " + WITHOUT_NULLS + " WHERE id = 1");
         assertFalse(rs.next());
         rs.close();
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java
index 6e6ac9f..d341646 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StringToArrayFunctionIT.java
@@ -25,14 +25,22 @@ import java.sql.*;
 
 import org.apache.phoenix.schema.types.PVarchar;
 import org.apache.phoenix.schema.types.PhoenixArray;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
-public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
+public class StringToArrayFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
 
-    private void initTables(Connection conn) throws Exception {
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY, string1 VARCHAR, string2 CHAR(50), delimiter1 VARCHAR, delimiter2 CHAR(20), nullstring1 VARCHAR, nullstring2 CHAR(20))";
+    private static final String TABLE_NAME = generateRandomString();
+
+    @BeforeClass
+    public static void initTables() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        String ddl = "CREATE TABLE " + TABLE_NAME
+            + " (region_name VARCHAR PRIMARY KEY, string1 VARCHAR, string2 CHAR(50), delimiter1 VARCHAR, delimiter2 CHAR(20), nullstring1 VARCHAR, nullstring2 CHAR(20))";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO regions(region_name, string1, string2, delimiter1, delimiter2, nullstring1, nullstring2) VALUES('SF Bay Area'," +
+        String dml = "UPSERT INTO " + TABLE_NAME
+            + "(region_name, string1, string2, delimiter1, delimiter2, nullstring1, nullstring2) VALUES('SF Bay Area',"
+            +
                 "'a,b,c,d'," +
                 "'1.2.3.4'," +
                 "','," +
@@ -48,10 +56,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string1, delimiter1) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(string1, delimiter1) FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", "c", "d"});
@@ -63,10 +72,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string1, delimiter1, nullstring1) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(string1, delimiter1, nullstring1) FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", null, "d"});
@@ -78,10 +88,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction3() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string1, delimiter1, 'a') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(string1, delimiter1, 'a') FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{null, "b", "c", "d"});
@@ -93,10 +104,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction4() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string1, delimiter1, 'd') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(string1, delimiter1, 'd') FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", "c", null});
@@ -108,10 +120,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction5() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string2, delimiter2) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(string2, delimiter2) FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"1", "2", "3", "4"});
@@ -123,10 +136,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction6() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string2, delimiter2, nullstring2) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(string2, delimiter2, nullstring2) FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"1", "2", null, "4"});
@@ -138,10 +152,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction7() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string2, delimiter2, '1') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(string2, delimiter2, '1') FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{null, "2", "3", "4"});
@@ -153,10 +168,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction8() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(string2, delimiter2, '4') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(string2, delimiter2, '4') FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"1", "2", "3", null});
@@ -168,10 +184,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction9() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(region_name, ' ', '4') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(region_name, ' ', '4') FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"SF", "Bay", "Area"});
@@ -183,10 +200,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction10() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY('hello,hello,hello', delimiter1) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY('hello,hello,hello', delimiter1) FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"hello", "hello", "hello"});
@@ -198,10 +216,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction11() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY('a,hello,hello,hello,b', ',', 'hello') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY('a,hello,hello,hello,b', ',', 'hello') FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", null, null, null, "b"});
@@ -213,10 +232,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunction12() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY('b.a.b', delimiter2, 'b') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY('b.a.b', delimiter2, 'b') FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{null, "a", null});
@@ -228,10 +248,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunctionWithNestedFunctions1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT ARRAY_LENGTH(STRING_TO_ARRAY('a, b, c', ', ')) FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT ARRAY_LENGTH(STRING_TO_ARRAY('a, b, c', ', ')) FROM " + TABLE_NAME
+                + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         assertEquals(3, rs.getInt(1));
@@ -241,10 +262,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunctionWithNestedFunctions2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(ARRAY_TO_STRING(ARRAY['a', 'b', 'c'], delimiter2), delimiter2, 'b') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(ARRAY_TO_STRING(ARRAY['a', 'b', 'c'], delimiter2), delimiter2, 'b') FROM "
+                + TABLE_NAME + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", null, "c"});
@@ -256,10 +278,11 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunctionWithNestedFunctions3() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT STRING_TO_ARRAY(ARRAY_TO_STRING(ARRAY['a', 'b', 'c'], delimiter2), ARRAY_ELEM(ARRAY[',', '.'], 2), 'b') FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT STRING_TO_ARRAY(ARRAY_TO_STRING(ARRAY['a', 'b', 'c'], delimiter2), ARRAY_ELEM(ARRAY[',', '.'], 2), 'b') FROM "
+                + TABLE_NAME + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", null, "c"});
@@ -272,15 +295,19 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     public void testStringToArrayFunctionWithUpsert1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
+        String tableName = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO regions(region_name,varchars) VALUES('SF Bay Area', STRING_TO_ARRAY('hello, world, :-)', ', '))";
+        String dml = "UPSERT INTO " + tableName
+            + "(region_name,varchars) VALUES('SF Bay Area', STRING_TO_ARRAY('hello, world, :-)', ', '))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchars FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT varchars FROM " + tableName + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"hello", "world", ":-)"});
@@ -293,15 +320,19 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     public void testStringToArrayFunctionWithUpsert2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE regions (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
+        String tableName = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + tableName + " (region_name VARCHAR PRIMARY KEY,varchars VARCHAR[])";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO regions(region_name,varchars) VALUES('SF Bay Area', STRING_TO_ARRAY('a, b, -, c', ', ', '-'))";
+        String dml = "UPSERT INTO " + tableName
+            + "(region_name,varchars) VALUES('SF Bay Area', STRING_TO_ARRAY('a, b, -, c', ', ', '-'))";
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchars FROM regions WHERE region_name = 'SF Bay Area'");
+        rs = conn.createStatement().executeQuery(
+            "SELECT varchars FROM " + tableName + " WHERE region_name = 'SF Bay Area'");
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", null, "c"});
@@ -314,25 +345,32 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     public void testStringToArrayFunctionWithUpsertSelect1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE source (region_name VARCHAR PRIMARY KEY, varchar VARCHAR)";
+        String table1 = generateRandomString();
+        String ddl =
+            "CREATE TABLE " + table1 + " (region_name VARCHAR PRIMARY KEY, varchar VARCHAR)";
         conn.createStatement().execute(ddl);
 
-        ddl = "CREATE TABLE target (region_name VARCHAR PRIMARY KEY, varchars VARCHAR[])";
+        String table2 = generateRandomString();
+        ddl = "CREATE TABLE " + table2 + " (region_name VARCHAR PRIMARY KEY, varchars VARCHAR[])";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO source(region_name, varchar) VALUES('SF Bay Area', 'a,b,c,d')";
+        String dml =
+            "UPSERT INTO " + table1 + "(region_name, varchar) VALUES('SF Bay Area', 'a,b,c,d')";
         conn.createStatement().execute(dml);
 
-        dml = "UPSERT INTO source(region_name, varchar) VALUES('SF Bay Area2', '1,2,3,4')";
+        dml = "UPSERT INTO " + table1 + "(region_name, varchar) VALUES('SF Bay Area2', '1,2,3,4')";
         conn.createStatement().execute(dml);
         conn.commit();
 
-        dml = "UPSERT INTO target(region_name, varchars) SELECT region_name, STRING_TO_ARRAY(varchar, ',') FROM source";
+        dml =
+            "UPSERT INTO " + table2
+                + "(region_name, varchars) SELECT region_name, STRING_TO_ARRAY(varchar, ',') FROM "
+                + table1;
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchars FROM target");
+        rs = conn.createStatement().executeQuery("SELECT varchars FROM " + table2);
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", "c", "d"});
@@ -350,25 +388,35 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     public void testStringToArrayFunctionWithUpsertSelect2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
 
-        String ddl = "CREATE TABLE source (region_name VARCHAR PRIMARY KEY, varchar VARCHAR)";
+        String sourceTable = generateRandomString();
+
+        String ddl =
+            "CREATE TABLE " + sourceTable + " (region_name VARCHAR PRIMARY KEY, varchar VARCHAR)";
         conn.createStatement().execute(ddl);
 
-        ddl = "CREATE TABLE target (region_name VARCHAR PRIMARY KEY, varchars VARCHAR[])";
+        String targetTable = generateRandomString();
+        ddl = "CREATE TABLE " + targetTable
+            + " (region_name VARCHAR PRIMARY KEY, varchars VARCHAR[])";
         conn.createStatement().execute(ddl);
 
-        String dml = "UPSERT INTO source(region_name, varchar) VALUES('SF Bay Area', 'a,b,-,c,d')";
+        String dml = "UPSERT INTO " + sourceTable
+            + "(region_name, varchar) VALUES('SF Bay Area', 'a,b,-,c,d')";
         conn.createStatement().execute(dml);
 
-        dml = "UPSERT INTO source(region_name, varchar) VALUES('SF Bay Area2', '1,2,-,3,4')";
+        dml = "UPSERT INTO " + sourceTable
+            + "(region_name, varchar) VALUES('SF Bay Area2', '1,2,-,3,4')";
         conn.createStatement().execute(dml);
         conn.commit();
 
-        dml = "UPSERT INTO target(region_name, varchars) SELECT region_name, STRING_TO_ARRAY(varchar, ',', '-') FROM source";
+        dml =
+            "UPSERT INTO " + targetTable
+                + "(region_name, varchars) SELECT region_name, STRING_TO_ARRAY(varchar, ',', '-') FROM "
+                + sourceTable;
         conn.createStatement().execute(dml);
         conn.commit();
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT varchars FROM target");
+        rs = conn.createStatement().executeQuery("SELECT varchars FROM " + targetTable);
         assertTrue(rs.next());
 
         PhoenixArray expected = new PhoenixArray(PVarchar.INSTANCE, new Object[]{"a", "b", null, "c", "d"});
@@ -385,10 +433,10 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunctionInWhere1() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE ARRAY['a', 'b', 'c', 'd']=STRING_TO_ARRAY(string1, delimiter1)");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + TABLE_NAME
+            + " WHERE ARRAY['a', 'b', 'c', 'd']=STRING_TO_ARRAY(string1, delimiter1)");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -398,10 +446,10 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunctionInWhere2() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE 'a'=ANY(STRING_TO_ARRAY(string1, delimiter1))");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + TABLE_NAME
+            + " WHERE 'a'=ANY(STRING_TO_ARRAY(string1, delimiter1))");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));
@@ -411,10 +459,10 @@ public class StringToArrayFunctionIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testStringToArrayFunctionInWhere3() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        initTables(conn);
 
         ResultSet rs;
-        rs = conn.createStatement().executeQuery("SELECT region_name FROM regions WHERE 'a'=ALL(STRING_TO_ARRAY('a,a,a,', delimiter1))");
+        rs = conn.createStatement().executeQuery("SELECT region_name FROM " + TABLE_NAME
+            + " WHERE 'a'=ALL(STRING_TO_ARRAY('a,a,a,', delimiter1))");
         assertTrue(rs.next());
 
         assertEquals("SF Bay Area", rs.getString(1));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/TimezoneOffsetFunctionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TimezoneOffsetFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TimezoneOffsetFunctionIT.java
index 324c494..e899eb2 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/TimezoneOffsetFunctionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/TimezoneOffsetFunctionIT.java
@@ -34,22 +34,25 @@ import org.apache.phoenix.exception.SQLExceptionCode;
 import org.junit.Test;
 
 
-public class TimezoneOffsetFunctionIT extends BaseHBaseManagedTimeIT {
+public class TimezoneOffsetFunctionIT extends BaseHBaseManagedTimeTableReuseIT {
 
 	@Test
 	public void testTimezoneOffset() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST"
+		String timezone_offset_test = generateRandomString();
+		String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test
 				+ " (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
 		conn.createStatement().execute(ddl);
-		String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (1, TO_DATE('2014-02-02 00:00:00'))";
+		String dml = "UPSERT INTO " + timezone_offset_test
+				+ " (k1, dates) VALUES (1, TO_DATE('2014-02-02 00:00:00'))";
 		conn.createStatement().execute(dml);
-		dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (2, TO_DATE('2014-06-02 00:00:00'))";
+		dml = "UPSERT INTO " + timezone_offset_test
+				+ " (k1, dates) VALUES (2, TO_DATE('2014-06-02 00:00:00'))";
 		conn.createStatement().execute(dml);
 		conn.commit();
 
 		ResultSet rs = conn.createStatement().executeQuery(
-				"SELECT k1, dates, TIMEZONE_OFFSET('Indian/Cocos', dates) FROM TIMEZONE_OFFSET_TEST");
+				"SELECT k1, dates, TIMEZONE_OFFSET('Indian/Cocos', dates) FROM " + timezone_offset_test);
 
 		assertTrue(rs.next());
 		assertEquals(390, rs.getInt(3));
@@ -61,16 +64,19 @@ public class TimezoneOffsetFunctionIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void testUnknownTimezone() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST"
+		String timezone_offset_test = generateRandomString();
+		String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test
 				+ " (k1 INTEGER NOT NULL, dates DATE CONSTRAINT pk PRIMARY KEY (k1))";
 		conn.createStatement().execute(ddl);
-		String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (1, TO_DATE('2014-02-02 00:00:00'))";
+		String dml = "UPSERT INTO " + timezone_offset_test
+				+ " (k1, dates) VALUES (1, TO_DATE('2014-02-02 00:00:00'))";
 		conn.createStatement().execute(dml);
 		conn.commit();
 
 		try {
 			ResultSet rs = conn.createStatement().executeQuery(
-					"SELECT k1, dates, TIMEZONE_OFFSET('Unknown_Timezone', dates) FROM TIMEZONE_OFFSET_TEST");
+					"SELECT k1, dates, TIMEZONE_OFFSET('Unknown_Timezone', dates) FROM "
+							+ timezone_offset_test);
 
 			rs.next();
 			assertEquals(0, rs.getInt(3));
@@ -83,18 +89,21 @@ public class TimezoneOffsetFunctionIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void testInRowKeyDSTTimezoneDesc() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST "
+		String timezone_offset_test = generateRandomString();
+		String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test + " "
 				+ "(k1 INTEGER NOT NULL, dates DATE NOT NULL CONSTRAINT pk PRIMARY KEY (k1, dates DESC))";
 		conn.createStatement().execute(ddl);
-		String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (1, TO_DATE('2014-02-02 00:00:00'))";
+		String dml = "UPSERT INTO " + timezone_offset_test
+				+ " (k1, dates) VALUES (1, TO_DATE('2014-02-02 00:00:00'))";
 		conn.createStatement().execute(dml);
-		dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates) VALUES (2, TO_DATE('2014-06-02 00:00:00'))";
+		dml = "UPSERT INTO " + timezone_offset_test
+				+ " (k1, dates) VALUES (2, TO_DATE('2014-06-02 00:00:00'))";
 		conn.createStatement().execute(dml);
 		conn.commit();
 
 		ResultSet rs = conn.createStatement().executeQuery(
 				"SELECT k1, dates, TIMEZONE_OFFSET('Europe/Prague', dates)"
-				+ "FROM TIMEZONE_OFFSET_TEST ORDER BY k1 ASC");
+				+ "FROM " + timezone_offset_test + " ORDER BY k1 ASC");
 
 		assertTrue(rs.next());
 		assertEquals(60, rs.getInt(3));
@@ -105,16 +114,17 @@ public class TimezoneOffsetFunctionIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void testBothParametersNull() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST "
+		String timezone_offset_test = generateRandomString();
+		String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test + " "
 				+ "(k1 INTEGER NOT NULL, dates DATE, v1 VARCHAR CONSTRAINT pk PRIMARY KEY (k1))";
 		conn.createStatement().execute(ddl);
-		String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates, v1) VALUES (2, null, null)";
+		String dml = "UPSERT INTO " + timezone_offset_test + " (k1, dates, v1) VALUES (2, null, null)";
 		conn.createStatement().execute(dml);
 		conn.commit();
 
 		ResultSet rs = conn.createStatement().executeQuery(
 				"SELECT k1, dates, TIMEZONE_OFFSET(v1, dates)"
-				+ "FROM TIMEZONE_OFFSET_TEST ORDER BY k1 ASC");
+				+ "FROM " + timezone_offset_test + " ORDER BY k1 ASC");
 
 		assertTrue(rs.next());
 		rs.getInt(3);
@@ -124,16 +134,18 @@ public class TimezoneOffsetFunctionIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void timezoneParameterNull() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST "
+		String timezone_offset_test = generateRandomString();
+		String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test + " "
 				+ "(k1 INTEGER NOT NULL, dates DATE, v1 VARCHAR CONSTRAINT pk PRIMARY KEY (k1))";
 		conn.createStatement().execute(ddl);
-		String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates, v1) VALUES (2, TO_DATE('2014-06-02 00:00:00'), null)";
+		String dml = "UPSERT INTO " + timezone_offset_test
+				+ " (k1, dates, v1) VALUES (2, TO_DATE('2014-06-02 00:00:00'), null)";
 		conn.createStatement().execute(dml);
 		conn.commit();
 
 		ResultSet rs = conn.createStatement().executeQuery(
 				"SELECT k1, dates, TIMEZONE_OFFSET(v1, dates)"
-				+ "FROM TIMEZONE_OFFSET_TEST ORDER BY k1 ASC");
+				+ "FROM " + timezone_offset_test + " ORDER BY k1 ASC");
 
 		assertTrue(rs.next());
 		rs.getInt(3);
@@ -143,16 +155,18 @@ public class TimezoneOffsetFunctionIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void dateParameterNull() throws Exception {
 		Connection conn = DriverManager.getConnection(getUrl());
-		String ddl = "CREATE TABLE IF NOT EXISTS TIMEZONE_OFFSET_TEST "
+		String timezone_offset_test = generateRandomString();
+		String ddl = "CREATE TABLE IF NOT EXISTS " + timezone_offset_test + " "
 				+ "(k1 INTEGER NOT NULL, dates DATE, v1 VARCHAR CONSTRAINT pk PRIMARY KEY (k1))";
 		conn.createStatement().execute(ddl);
-		String dml = "UPSERT INTO TIMEZONE_OFFSET_TEST (k1, dates, v1) VALUES (2, null, 'Asia/Aden')";
+		String dml =
+				"UPSERT INTO " + timezone_offset_test + " (k1, dates, v1) VALUES (2, null, 'Asia/Aden')";
 		conn.createStatement().execute(dml);
 		conn.commit();
 
 		ResultSet rs = conn.createStatement().executeQuery(
 				"SELECT k1, dates, TIMEZONE_OFFSET(v1, dates)"
-				+ "FROM TIMEZONE_OFFSET_TEST ORDER BY k1 ASC");
+				+ "FROM " + timezone_offset_test + " ORDER BY k1 ASC");
 
 		assertTrue(rs.next());
 		rs.getInt(3);
@@ -162,9 +176,10 @@ public class TimezoneOffsetFunctionIT extends BaseHBaseManagedTimeIT {
 	@Test
 	public void testInsertingRetrivingTimestamp() throws Exception {
 	    Connection conn = DriverManager.getConnection(getUrl());
-        String ddl = "CREATE TABLE T (K INTEGER NOT NULL PRIMARY KEY, V TIMESTAMP)";
+		String t = generateRandomString();
+		String ddl = "CREATE TABLE " + t + " (K INTEGER NOT NULL PRIMARY KEY, V TIMESTAMP)";
         conn.createStatement().execute(ddl);
-        String dml = "UPSERT INTO T VALUES (?, ?)";
+        String dml = "UPSERT INTO " + t + " VALUES (?, ?)";
         PreparedStatement stmt = conn.prepareStatement(dml);
         stmt.setInt(1, 1);
         Calendar cal = Calendar.getInstance();
@@ -173,7 +188,7 @@ public class TimezoneOffsetFunctionIT extends BaseHBaseManagedTimeIT {
         stmt.setTimestamp(2, new Timestamp(time), cal);
         stmt.executeUpdate();
         conn.commit();
-        String query = "SELECT V FROM T";
+        String query = "SELECT V FROM " + t;
         ResultSet rs = conn.createStatement().executeQuery(query);
         rs.next();
         assertEquals(new Timestamp(time), rs.getTimestamp(1));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ecc5ff2d/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertSelectAutoCommitIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertSelectAutoCommitIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertSelectAutoCommitIT.java
index 4b4f215..a0b3939 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertSelectAutoCommitIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertSelectAutoCommitIT.java
@@ -37,7 +37,7 @@ import org.apache.phoenix.util.PropertiesUtil;
 import org.junit.Test;
 
 
-public class UpsertSelectAutoCommitIT extends BaseHBaseManagedTimeIT {
+public class UpsertSelectAutoCommitIT extends BaseHBaseManagedTimeTableReuseIT {
 
     public UpsertSelectAutoCommitIT() {
     }
@@ -47,14 +47,17 @@ public class UpsertSelectAutoCommitIT extends BaseHBaseManagedTimeIT {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(true);
-        conn.createStatement().execute("CREATE TABLE atable (ORGANIZATION_ID CHAR(15) NOT NULL, ENTITY_ID CHAR(15) NOT NULL, A_STRING VARCHAR\n" +
+        String atable = generateRandomString();
+        conn.createStatement().execute("CREATE TABLE " + atable
+            + " (ORGANIZATION_ID CHAR(15) NOT NULL, ENTITY_ID CHAR(15) NOT NULL, A_STRING VARCHAR\n"
+            +
         "CONSTRAINT pk PRIMARY KEY (organization_id, entity_id))");
         
         String tenantId = getOrganizationId();
        // Insert all rows at ts
         PreparedStatement stmt = conn.prepareStatement(
-                "upsert into " +
-                "ATABLE(" +
+                "upsert into " + atable +
+                "(" +
                 "    ORGANIZATION_ID, " +
                 "    ENTITY_ID, " +
                 "    A_STRING " +
@@ -65,7 +68,7 @@ public class UpsertSelectAutoCommitIT extends BaseHBaseManagedTimeIT {
         stmt.setString(3, A_VALUE);
         stmt.execute();
         
-        String query = "SELECT entity_id, a_string FROM ATABLE";
+        String query = "SELECT entity_id, a_string FROM " + atable;
         PreparedStatement statement = conn.prepareStatement(query);
         ResultSet rs = statement.executeQuery();
         
@@ -73,12 +76,15 @@ public class UpsertSelectAutoCommitIT extends BaseHBaseManagedTimeIT {
         assertEquals(ROW1, rs.getString(1));
         assertEquals(A_VALUE, rs.getString(2));
         assertFalse(rs.next());
-        
-        conn.createStatement().execute("CREATE TABLE atable2 (ORGANIZATION_ID CHAR(15) NOT NULL, ENTITY_ID CHAR(15) NOT NULL, A_STRING VARCHAR\n" +
+
+        String atable2 = generateRandomString();
+        conn.createStatement().execute("CREATE TABLE " + atable2
+            + " (ORGANIZATION_ID CHAR(15) NOT NULL, ENTITY_ID CHAR(15) NOT NULL, A_STRING VARCHAR\n"
+            +
         "CONSTRAINT pk PRIMARY KEY (organization_id, entity_id DESC))");
         
-        conn.createStatement().execute("UPSERT INTO atable2 SELECT * FROM ATABLE");
-        query = "SELECT entity_id, a_string FROM ATABLE2";
+        conn.createStatement().execute("UPSERT INTO " + atable2 + " SELECT * FROM " + atable);
+        query = "SELECT entity_id, a_string FROM " + atable2;
         statement = conn.prepareStatement(query);
         rs = statement.executeQuery();
         
@@ -92,14 +98,17 @@ public class UpsertSelectAutoCommitIT extends BaseHBaseManagedTimeIT {
     @Test
     public void testDynamicUpsertSelect() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
-        String cursorDDL = " CREATE TABLE IF NOT EXISTS CURSOR (ORGANIZATION_ID VARCHAR(15) NOT NULL, \n"
+        String tableName = generateRandomString();
+        String cursorDDL = " CREATE TABLE IF NOT EXISTS " + tableName
+            + " (ORGANIZATION_ID VARCHAR(15) NOT NULL, \n"
                 + "QUERY_ID VARCHAR(15) NOT NULL, \n"
                 + "CURSOR_ORDER UNSIGNED_LONG NOT NULL, \n"
                 + "CONSTRAINT API_HBASE_CURSOR_STORAGE_PK PRIMARY KEY (ORGANIZATION_ID, QUERY_ID, CURSOR_ORDER))\n"
                 + "SALT_BUCKETS = 4";
         conn.createStatement().execute(cursorDDL);
-        
-        String dataTableDDL = "CREATE TABLE IF NOT EXISTS PLINYTEST" +
+
+        String tableName2 = generateRandomString();
+        String dataTableDDL = "CREATE TABLE IF NOT EXISTS " + tableName2 +
                 "(" +
                 "ORGANIZATION_ID CHAR(15) NOT NULL, " +
                 "PLINY_ID CHAR(15) NOT NULL, " +
@@ -115,7 +124,7 @@ public class UpsertSelectAutoCommitIT extends BaseHBaseManagedTimeIT {
         
         conn.createStatement().execute(dataTableDDL);
         PreparedStatement stmt = null;
-        String upsert = "UPSERT INTO PLINYTEST VALUES (?, ?, ?, ?)";
+        String upsert = "UPSERT INTO " + tableName2 + " VALUES (?, ?, ?, ?)";
         stmt = conn.prepareStatement(upsert);
         stmt.setString(1, getOrganizationId());
         stmt.setString(2, "aaaaaaaaaaaaaaa");
@@ -124,7 +133,10 @@ public class UpsertSelectAutoCommitIT extends BaseHBaseManagedTimeIT {
         stmt.executeUpdate();
         conn.commit();
         
-        String upsertSelect = "UPSERT INTO CURSOR (ORGANIZATION_ID, QUERY_ID, CURSOR_ORDER, PLINY_ID CHAR(15),CREATED_DATE DATE) SELECT ?, ?, ?, PLINY_ID, CREATED_DATE FROM PLINYTEST WHERE ORGANIZATION_ID = ?";
+        String upsertSelect = "UPSERT INTO " + tableName
+            +
+            " (ORGANIZATION_ID, QUERY_ID, CURSOR_ORDER, PLINY_ID CHAR(15),CREATED_DATE DATE) SELECT ?, ?, ?, PLINY_ID, CREATED_DATE FROM "
+                + tableName2 + " WHERE ORGANIZATION_ID = ?";
         stmt = conn.prepareStatement(upsertSelect);
         String orgId = getOrganizationId();
         stmt.setString(1, orgId);
@@ -146,12 +158,16 @@ public class UpsertSelectAutoCommitIT extends BaseHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), props);
         conn.setAutoCommit(true);
         conn.createStatement().execute("CREATE SEQUENCE keys");
-        conn.createStatement().execute("CREATE TABLE foo (pk INTEGER PRIMARY KEY, val INTEGER)");
+        String tableName = generateRandomString();
+        conn.createStatement().execute(
+            "CREATE TABLE " + tableName + " (pk INTEGER PRIMARY KEY, val INTEGER)");
 
-        conn.createStatement().execute("UPSERT INTO foo VALUES (NEXT VALUE FOR keys,1)");
+        conn.createStatement().execute(
+            "UPSERT INTO " + tableName + " VALUES (NEXT VALUE FOR keys,1)");
         for (int i=0; i<6; i++) {
             Statement stmt = conn.createStatement();
-            int upsertCount = stmt.executeUpdate("UPSERT INTO foo SELECT NEXT VALUE FOR keys, val FROM foo");
+            int upsertCount = stmt.executeUpdate(
+                "UPSERT INTO " + tableName + " SELECT NEXT VALUE FOR keys, val FROM " + tableName);
             assertEquals((int)Math.pow(2, i), upsertCount);
         }
         conn.close();


[02/52] [abbrv] phoenix git commit: PHOENIX-2722 support mysql offset clause

Posted by sa...@apache.org.
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java
index 5670dae..b125ecc 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java
@@ -42,6 +42,7 @@ import org.apache.phoenix.iterate.FilterAggregatingResultIterator;
 import org.apache.phoenix.iterate.GroupedAggregatingResultIterator;
 import org.apache.phoenix.iterate.LimitingResultIterator;
 import org.apache.phoenix.iterate.MergeSortRowKeyResultIterator;
+import org.apache.phoenix.iterate.OffsetResultIterator;
 import org.apache.phoenix.iterate.OrderedAggregatingResultIterator;
 import org.apache.phoenix.iterate.OrderedResultIterator;
 import org.apache.phoenix.iterate.ParallelIteratorFactory;
@@ -63,8 +64,6 @@ import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.util.ScanUtil;
 
-
-
 /**
  *
  * Query plan for aggregating queries
@@ -78,18 +77,19 @@ public class AggregatePlan extends BaseQueryPlan {
     private List<KeyRange> splits;
     private List<List<Scan>> scans;
 
-    public AggregatePlan(
-            StatementContext context, FilterableStatement statement, TableRef table, RowProjector projector,
-            Integer limit, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory, GroupBy groupBy,
-            Expression having) {
-        this(context, statement, table, projector, limit, orderBy, parallelIteratorFactory, groupBy, having, null);
+    public AggregatePlan(StatementContext context, FilterableStatement statement, TableRef table,
+            RowProjector projector, Integer limit, Integer offset, OrderBy orderBy,
+            ParallelIteratorFactory parallelIteratorFactory, GroupBy groupBy, Expression having) {
+        this(context, statement, table, projector, limit, offset, orderBy, parallelIteratorFactory, groupBy, having,
+                null);
     }
-    
-    private AggregatePlan(
-            StatementContext context, FilterableStatement statement, TableRef table, RowProjector projector,
-            Integer limit, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory, GroupBy groupBy,
-            Expression having, Expression dynamicFilter) {
-        super(context, statement, table, projector, context.getBindManager().getParameterMetaData(), limit, orderBy, groupBy, parallelIteratorFactory, dynamicFilter);
+
+    private AggregatePlan(StatementContext context, FilterableStatement statement, TableRef table,
+            RowProjector projector, Integer limit, Integer offset, OrderBy orderBy,
+            ParallelIteratorFactory parallelIteratorFactory, GroupBy groupBy, Expression having,
+            Expression dynamicFilter) {
+        super(context, statement, table, projector, context.getBindManager().getParameterMetaData(), limit, offset,
+                orderBy, groupBy, parallelIteratorFactory, dynamicFilter);
         this.having = having;
         this.aggregators = context.getAggregationManager().getAggregators();
     }
@@ -195,12 +195,13 @@ public class AggregatePlan extends BaseQueryPlan {
                  *    order, so we can early exit, even when aggregate functions are used, as
                  *    the rows in the group are contiguous.
                  */
-                context.getScan().setAttribute(BaseScannerRegionObserver.GROUP_BY_LIMIT, PInteger.INSTANCE.toBytes(limit));
+                context.getScan().setAttribute(BaseScannerRegionObserver.GROUP_BY_LIMIT,
+                        PInteger.INSTANCE.toBytes(limit + (offset == null ? 0 : offset)));
             }
         }
-        BaseResultIterators iterators = statement.getHint().hasHint(HintNode.Hint.SERIAL) ?
-                new SerialIterators(this, null, wrapParallelIteratorFactory(), scanGrouper) :
-                new ParallelIterators(this, null, wrapParallelIteratorFactory());
+        BaseResultIterators iterators = statement.getHint().hasHint(HintNode.Hint.SERIAL)
+                ? new SerialIterators(this, null, null, wrapParallelIteratorFactory(), scanGrouper)
+                : new ParallelIterators(this, null, wrapParallelIteratorFactory());
 
         splits = iterators.getSplits();
         scans = iterators.getScans();
@@ -228,13 +229,17 @@ public class AggregatePlan extends BaseQueryPlan {
 
         ResultIterator resultScanner = aggResultIterator;
         if (orderBy.getOrderByExpressions().isEmpty()) {
+            if (offset != null) {
+                resultScanner = new OffsetResultIterator(aggResultIterator, offset);
+            }
             if (limit != null) {
-                resultScanner = new LimitingResultIterator(aggResultIterator, limit);
+                resultScanner = new LimitingResultIterator(resultScanner, limit);
             }
         } else {
             int thresholdBytes = context.getConnection().getQueryServices().getProps().getInt(
                     QueryServices.SPOOL_THRESHOLD_BYTES_ATTRIB, QueryServicesOptions.DEFAULT_SPOOL_THRESHOLD_BYTES);
-            resultScanner = new OrderedAggregatingResultIterator(aggResultIterator, orderBy.getOrderByExpressions(), thresholdBytes, limit);
+            resultScanner = new OrderedAggregatingResultIterator(aggResultIterator, orderBy.getOrderByExpressions(),
+                    thresholdBytes, limit, offset);
         }
         if (context.getSequenceManager().getSequenceCount() > 0) {
             resultScanner = new SequenceResultIterator(resultScanner, context.getSequenceManager());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
index ee6d4ab..e08dae1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
@@ -99,6 +99,7 @@ public abstract class BaseQueryPlan implements QueryPlan {
     protected final RowProjector projection;
     protected final ParameterMetaData paramMetaData;
     protected final Integer limit;
+    protected final Integer offset;
     protected final OrderBy orderBy;
     protected final GroupBy groupBy;
     protected final ParallelIteratorFactory parallelIteratorFactory;    
@@ -114,7 +115,7 @@ public abstract class BaseQueryPlan implements QueryPlan {
 
     protected BaseQueryPlan(
             StatementContext context, FilterableStatement statement, TableRef table,
-            RowProjector projection, ParameterMetaData paramMetaData, Integer limit, OrderBy orderBy,
+            RowProjector projection, ParameterMetaData paramMetaData, Integer limit, Integer offset, OrderBy orderBy,
             GroupBy groupBy, ParallelIteratorFactory parallelIteratorFactory,
             Expression dynamicFilter) {
         this.context = context;
@@ -124,6 +125,7 @@ public abstract class BaseQueryPlan implements QueryPlan {
         this.projection = projection;
         this.paramMetaData = paramMetaData;
         this.limit = limit;
+        this.offset = offset;
         this.orderBy = orderBy;
         this.groupBy = groupBy;
         this.parallelIteratorFactory = parallelIteratorFactory;
@@ -175,6 +177,11 @@ public abstract class BaseQueryPlan implements QueryPlan {
     public Integer getLimit() {
         return limit;
     }
+    
+    @Override
+    public Integer getOffset() {
+        return offset;
+    }
 
     @Override
     public RowProjector getProjector() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java
index c1ef67d..f4e374e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java
@@ -17,7 +17,7 @@
  */
 package org.apache.phoenix.execute;
 
-import static org.apache.phoenix.query.QueryConstants.*;
+import static org.apache.phoenix.query.QueryConstants.UNGROUPED_AGG_ROW_KEY;
 
 import java.io.IOException;
 import java.sql.SQLException;
@@ -46,6 +46,7 @@ import org.apache.phoenix.iterate.FilterResultIterator;
 import org.apache.phoenix.iterate.GroupedAggregatingResultIterator;
 import org.apache.phoenix.iterate.LimitingResultIterator;
 import org.apache.phoenix.iterate.LookAheadResultIterator;
+import org.apache.phoenix.iterate.OffsetResultIterator;
 import org.apache.phoenix.iterate.OrderedAggregatingResultIterator;
 import org.apache.phoenix.iterate.OrderedResultIterator;
 import org.apache.phoenix.iterate.ParallelScanGrouper;
@@ -70,8 +71,8 @@ public class ClientAggregatePlan extends ClientProcessingPlan {
     private final Aggregators clientAggregators;
     
     public ClientAggregatePlan(StatementContext context, FilterableStatement statement, TableRef table, RowProjector projector,
-            Integer limit, Expression where, OrderBy orderBy, GroupBy groupBy, Expression having, QueryPlan delegate) {
-        super(context, statement, table, projector, limit, where, orderBy, delegate);
+            Integer limit, Integer offset, Expression where, OrderBy orderBy, GroupBy groupBy, Expression having, QueryPlan delegate) {
+        super(context, statement, table, projector, limit, offset, where, orderBy, delegate);
         this.groupBy = groupBy;
         this.having = having;
         this.serverAggregators =
@@ -100,7 +101,7 @@ public class ClientAggregatePlan extends ClientProcessingPlan {
                 for (Expression keyExpression : keyExpressions) {
                     keyExpressionOrderBy.add(new OrderByExpression(keyExpression, false, true));
                 }
-                iterator = new OrderedResultIterator(iterator, keyExpressionOrderBy, thresholdBytes, null, projector.getEstimatedRowByteSize());
+                iterator = new OrderedResultIterator(iterator, keyExpressionOrderBy, thresholdBytes, null, null, projector.getEstimatedRowByteSize());
             }
             aggResultIterator = new ClientGroupedAggregatingResultIterator(LookAheadResultIterator.wrap(iterator), serverAggregators, groupBy.getKeyExpressions());
             aggResultIterator = new GroupedAggregatingResultIterator(LookAheadResultIterator.wrap(aggResultIterator), clientAggregators);
@@ -116,13 +117,16 @@ public class ClientAggregatePlan extends ClientProcessingPlan {
 
         ResultIterator resultScanner = aggResultIterator;
         if (orderBy.getOrderByExpressions().isEmpty()) {
+            if (offset != null) {
+                resultScanner = new OffsetResultIterator(resultScanner, offset);
+            }
             if (limit != null) {
-                resultScanner = new LimitingResultIterator(aggResultIterator, limit);
+                resultScanner = new LimitingResultIterator(resultScanner, limit);
             }
         } else {
             int thresholdBytes = context.getConnection().getQueryServices().getProps().getInt(
                     QueryServices.SPOOL_THRESHOLD_BYTES_ATTRIB, QueryServicesOptions.DEFAULT_SPOOL_THRESHOLD_BYTES);
-            resultScanner = new OrderedAggregatingResultIterator(aggResultIterator, orderBy.getOrderByExpressions(), thresholdBytes, limit);
+            resultScanner = new OrderedAggregatingResultIterator(aggResultIterator, orderBy.getOrderByExpressions(), thresholdBytes, limit, offset);
         }
         if (context.getSequenceManager().getSequenceCount() > 0) {
             resultScanner = new SequenceResultIterator(resultScanner, context.getSequenceManager());
@@ -151,6 +155,9 @@ public class ClientAggregatePlan extends ClientProcessingPlan {
         if (statement.isDistinct() && statement.isAggregate()) {
             planSteps.add("CLIENT DISTINCT ON " + projector.toString());
         }
+        if (offset != null) {
+            planSteps.add("CLIENT OFFSET " + offset);
+        }
         if (orderBy.getOrderByExpressions().isEmpty()) {
             if (limit != null) {
                 planSteps.add("CLIENT " + limit + " ROW LIMIT");

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientProcessingPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientProcessingPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientProcessingPlan.java
index b189933..2cd5237 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientProcessingPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientProcessingPlan.java
@@ -39,11 +39,11 @@ public abstract class ClientProcessingPlan extends DelegateQueryPlan {
     protected final TableRef table;
     protected final RowProjector projector;
     protected final Integer limit;
+    protected final Integer offset;
     protected final Expression where;
     protected final OrderBy orderBy;
-
     public ClientProcessingPlan(StatementContext context, FilterableStatement statement, TableRef table, 
-            RowProjector projector, Integer limit, Expression where, OrderBy orderBy, QueryPlan delegate) {
+            RowProjector projector, Integer limit, Integer offset, Expression where, OrderBy orderBy, QueryPlan delegate) {
         super(delegate);
         this.context = context;
         this.statement = statement;
@@ -52,6 +52,7 @@ public abstract class ClientProcessingPlan extends DelegateQueryPlan {
         this.limit = limit;
         this.where = where;
         this.orderBy = orderBy;
+        this.offset = offset;
     }
     
     @Override
@@ -73,6 +74,11 @@ public abstract class ClientProcessingPlan extends DelegateQueryPlan {
     public Integer getLimit() {
         return limit;
     }
+    
+    @Override
+    public Integer getOffset() {
+        return offset;
+    }
 
     @Override
     public OrderBy getOrderBy() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java
index 4bf1889..003c995 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java
@@ -28,6 +28,7 @@ import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.iterate.FilterResultIterator;
 import org.apache.phoenix.iterate.LimitingResultIterator;
+import org.apache.phoenix.iterate.OffsetResultIterator;
 import org.apache.phoenix.iterate.OrderedResultIterator;
 import org.apache.phoenix.iterate.ParallelScanGrouper;
 import org.apache.phoenix.iterate.ResultIterator;
@@ -41,12 +42,10 @@ import com.google.common.collect.Lists;
 
 public class ClientScanPlan extends ClientProcessingPlan {
 
-    public ClientScanPlan(StatementContext context,
-            FilterableStatement statement, TableRef table,
-            RowProjector projector, Integer limit, Expression where,
-            OrderBy orderBy, QueryPlan delegate) {
-        super(context, statement, table, projector, limit, where, orderBy,
-                delegate);
+    public ClientScanPlan(StatementContext context, FilterableStatement statement, TableRef table,
+            RowProjector projector, Integer limit, Integer offset, Expression where, OrderBy orderBy,
+            QueryPlan delegate) {
+        super(context, statement, table, projector, limit, offset, where, orderBy, delegate);
     }
 
     @Override
@@ -59,9 +58,15 @@ public class ClientScanPlan extends ClientProcessingPlan {
         if (!orderBy.getOrderByExpressions().isEmpty()) { // TopN
             int thresholdBytes = context.getConnection().getQueryServices().getProps().getInt(
                     QueryServices.SPOOL_THRESHOLD_BYTES_ATTRIB, QueryServicesOptions.DEFAULT_SPOOL_THRESHOLD_BYTES);
-            iterator = new OrderedResultIterator(iterator, orderBy.getOrderByExpressions(), thresholdBytes, limit, projector.getEstimatedRowByteSize());
-        } else if (limit != null) {
-            iterator = new LimitingResultIterator(iterator, limit);
+            iterator = new OrderedResultIterator(iterator, orderBy.getOrderByExpressions(), thresholdBytes, limit,
+                    offset, projector.getEstimatedRowByteSize());
+        } else {
+            if (offset != null) {
+                iterator = new OffsetResultIterator(iterator, offset);
+            }
+            if (limit != null) {
+                iterator = new LimitingResultIterator(iterator, limit);
+            }
         }
         
         if (context.getSequenceManager().getSequenceCount() > 0) {
@@ -78,9 +83,18 @@ public class ClientScanPlan extends ClientProcessingPlan {
             planSteps.add("CLIENT FILTER BY " + where.toString());
         }
         if (!orderBy.getOrderByExpressions().isEmpty()) {
-            planSteps.add("CLIENT" + (limit == null ? "" : " TOP " + limit + " ROW"  + (limit == 1 ? "" : "S"))  + " SORTED BY " + orderBy.getOrderByExpressions().toString());
-        } else if (limit != null) {
-            planSteps.add("CLIENT " + limit + " ROW LIMIT");
+            if (offset != null) {
+                planSteps.add("CLIENT OFFSET " + offset);
+            }
+            planSteps.add("CLIENT" + (limit == null ? "" : " TOP " + limit + " ROW" + (limit == 1 ? "" : "S"))
+                    + " SORTED BY " + orderBy.getOrderByExpressions().toString());
+        } else {
+            if (offset != null) {
+                planSteps.add("CLIENT OFFSET " + offset);
+            }
+            if (limit != null) {
+                planSteps.add("CLIENT " + limit + " ROW LIMIT");
+            }
         }
         if (context.getSequenceManager().getSequenceCount() > 0) {
             int nSequences = context.getSequenceManager().getSequenceCount();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/DegenerateQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/DegenerateQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/DegenerateQueryPlan.java
index 21b25d6..36b725e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/DegenerateQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/DegenerateQueryPlan.java
@@ -37,7 +37,7 @@ import org.apache.phoenix.schema.TableRef;
 public class DegenerateQueryPlan extends BaseQueryPlan {
 
     public DegenerateQueryPlan(StatementContext context, FilterableStatement statement, TableRef table) {
-        super(context, statement, table, RowProjector.EMPTY_PROJECTOR, PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA, null, OrderBy.EMPTY_ORDER_BY, GroupBy.EMPTY_GROUP_BY, null, null);
+        super(context, statement, table, RowProjector.EMPTY_PROJECTOR, PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA, null,null, OrderBy.EMPTY_ORDER_BY, GroupBy.EMPTY_GROUP_BY, null, null);
         context.setScanRanges(ScanRanges.NOTHING);
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java
index 56e0ccd..8f0d224 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java
@@ -120,4 +120,8 @@ public abstract class DelegateQueryPlan implements QueryPlan {
 		return delegate.getOperation();
 	}
 	
+	@Override
+    public Integer getOffset() {
+        return delegate.getOffset();
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java
index ab13e6c..fe767d9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java
@@ -43,15 +43,15 @@ public class LiteralResultIterationPlan extends BaseQueryPlan {
 
     public LiteralResultIterationPlan(StatementContext context, 
             FilterableStatement statement, TableRef tableRef, RowProjector projection, 
-            Integer limit, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory) {
+            Integer limit, Integer offset, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory) {
         this(Collections.<Tuple> singletonList(new SingleKeyValueTuple(KeyValue.LOWESTKEY)), 
-                context, statement, tableRef, projection, limit, orderBy, parallelIteratorFactory);
+                context, statement, tableRef, projection, limit, offset, orderBy, parallelIteratorFactory);
     }
 
     public LiteralResultIterationPlan(Iterable<Tuple> tuples, StatementContext context, 
             FilterableStatement statement, TableRef tableRef, RowProjector projection, 
-            Integer limit, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory) {
-        super(context, statement, tableRef, projection, context.getBindManager().getParameterMetaData(), limit, orderBy, GroupBy.EMPTY_GROUP_BY, parallelIteratorFactory, null);
+            Integer limit, Integer offset, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory) {
+        super(context, statement, tableRef, projection, context.getBindManager().getParameterMetaData(), limit, offset, orderBy, GroupBy.EMPTY_GROUP_BY, parallelIteratorFactory, null);
         this.tuples = tuples;
     }
 
@@ -77,6 +77,7 @@ public class LiteralResultIterationPlan extends BaseQueryPlan {
             private final Iterator<Tuple> tupleIterator = tuples.iterator();
             private boolean closed = false;
             private int count = 0;
+            private int offsetCount = 0;
 
             @Override
             public void close() throws SQLException {
@@ -85,6 +86,10 @@ public class LiteralResultIterationPlan extends BaseQueryPlan {
 
             @Override
             public Tuple next() throws SQLException {
+                while (!this.closed && (offset != null && offsetCount < offset) && tupleIterator.hasNext()) {
+                    offsetCount++;
+                    tupleIterator.next();
+                }
                 if (!this.closed 
                         && (limit == null || count++ < limit)
                         && tupleIterator.hasNext()) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
index 4a5cb83..93ae5d6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
@@ -37,6 +37,7 @@ import org.apache.phoenix.iterate.ConcatResultIterator;
 import org.apache.phoenix.iterate.LimitingResultIterator;
 import org.apache.phoenix.iterate.MergeSortRowKeyResultIterator;
 import org.apache.phoenix.iterate.MergeSortTopNResultIterator;
+import org.apache.phoenix.iterate.OffsetResultIterator;
 import org.apache.phoenix.iterate.ParallelIteratorFactory;
 import org.apache.phoenix.iterate.ParallelIterators;
 import org.apache.phoenix.iterate.ParallelScanGrouper;
@@ -59,6 +60,7 @@ import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.stats.GuidePostsInfo;
 import org.apache.phoenix.schema.stats.StatisticsUtil;
 import org.apache.phoenix.util.LogUtil;
+import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.ScanUtil;
 import org.apache.phoenix.util.SchemaUtil;
 import org.slf4j.Logger;
@@ -79,14 +81,14 @@ public class ScanPlan extends BaseQueryPlan {
     private List<List<Scan>> scans;
     private boolean allowPageFilter;
     
-    public ScanPlan(StatementContext context, FilterableStatement statement, TableRef table, RowProjector projector, Integer limit, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory, boolean allowPageFilter) throws SQLException {
-        this(context, statement, table, projector, limit, orderBy, parallelIteratorFactory, allowPageFilter, null);
+    public ScanPlan(StatementContext context, FilterableStatement statement, TableRef table, RowProjector projector, Integer limit, Integer offset, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory, boolean allowPageFilter) throws SQLException {
+        this(context, statement, table, projector, limit, offset, orderBy, parallelIteratorFactory, allowPageFilter, null);
     }
     
-    private ScanPlan(StatementContext context, FilterableStatement statement, TableRef table, RowProjector projector, Integer limit, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory, boolean allowPageFilter, Expression dynamicFilter) throws SQLException {
-        super(context, statement, table, projector, context.getBindManager().getParameterMetaData(), limit, orderBy, GroupBy.EMPTY_GROUP_BY,
+    private ScanPlan(StatementContext context, FilterableStatement statement, TableRef table, RowProjector projector, Integer limit, Integer offset, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory, boolean allowPageFilter, Expression dynamicFilter) throws SQLException {
+        super(context, statement, table, projector, context.getBindManager().getParameterMetaData(), limit,offset, orderBy, GroupBy.EMPTY_GROUP_BY,
                 parallelIteratorFactory != null ? parallelIteratorFactory :
-                        buildResultIteratorFactory(context, statement, table, orderBy, limit, allowPageFilter), dynamicFilter);
+                        buildResultIteratorFactory(context, statement, table, orderBy, limit, offset, allowPageFilter), dynamicFilter);
         this.allowPageFilter = allowPageFilter;
         if (!orderBy.getOrderByExpressions().isEmpty()) { // TopN
             int thresholdBytes = context.getConnection().getQueryServices().getProps().getInt(
@@ -96,7 +98,7 @@ public class ScanPlan extends BaseQueryPlan {
     }
 
     private static boolean isSerial(StatementContext context, FilterableStatement statement,
-            TableRef tableRef, OrderBy orderBy, Integer limit, boolean allowPageFilter) throws SQLException {
+            TableRef tableRef, OrderBy orderBy, Integer limit, Integer offset, boolean allowPageFilter) throws SQLException {
         if (statement.getHint().hasHint(HintNode.Hint.SERIAL)) {
             return true;
         }
@@ -142,13 +144,11 @@ public class ScanPlan extends BaseQueryPlan {
     }
     
     private static ParallelIteratorFactory buildResultIteratorFactory(StatementContext context, FilterableStatement statement,
-            TableRef table, OrderBy orderBy, Integer limit, boolean allowPageFilter) throws SQLException {
+            TableRef table, OrderBy orderBy, Integer limit,Integer offset, boolean allowPageFilter) throws SQLException {
 
-        if (isSerial(context, statement, table, orderBy, limit, allowPageFilter)
-                || ScanUtil.isRoundRobinPossible(orderBy, context)
-                || ScanUtil.isPacingScannersPossible(context)) {
-            return ParallelIteratorFactory.NOOP_FACTORY;
-        }
+        if ((isSerial(context, statement, table, orderBy, limit, offset, allowPageFilter)
+                || ScanUtil.isRoundRobinPossible(orderBy, context) || ScanUtil.isPacingScannersPossible(context))
+                && offset == null) { return ParallelIteratorFactory.NOOP_FACTORY; }
         ParallelIteratorFactory spoolingResultIteratorFactory =
                 new SpoolingResultIterator.SpoolingResultIteratorFactory(
                         context.getConnection().getQueryServices());
@@ -180,6 +180,13 @@ public class ScanPlan extends BaseQueryPlan {
             return scans;
     }
 
+    private static boolean isOffsetPossibleOnServer(StatementContext context, OrderBy orderBy, Integer offset,
+            boolean isSalted, IndexType indexType) {
+        return offset != null && orderBy.getOrderByExpressions().isEmpty()
+                && !((isSalted || indexType == IndexType.LOCAL)
+                        && ScanUtil.shouldRowsBeInRowKeyOrder(orderBy, context));
+    }
+
     @Override
     protected ResultIterator newIterator(ParallelScanGrouper scanGrouper) throws SQLException {
         // Set any scan attributes before creating the scanner, as it will be too late afterwards
@@ -193,21 +200,31 @@ public class ScanPlan extends BaseQueryPlan {
          * limit is provided, run query serially.
          */
         boolean isOrdered = !orderBy.getOrderByExpressions().isEmpty();
-        boolean isSerial = isSerial(context, statement, tableRef, orderBy, limit, allowPageFilter);
+        boolean isSerial = isSerial(context, statement, tableRef, orderBy, limit, offset, allowPageFilter);
         Integer perScanLimit = !allowPageFilter || isOrdered ? null : limit;
+        if (perScanLimit != null) {
+            perScanLimit = QueryUtil.getOffsetLimit(perScanLimit, offset);
+        }
         BaseResultIterators iterators;
-        if (isSerial) {
-        	iterators = new SerialIterators(this, perScanLimit, parallelIteratorFactory, scanGrouper);
+        boolean isOffsetOnServer = isOffsetPossibleOnServer(context, orderBy, offset, isSalted, table.getIndexType());
+        if (isOffsetOnServer) {
+            iterators = new SerialIterators(this, perScanLimit, offset, parallelIteratorFactory, scanGrouper);
+        } else if (isSerial) {
+            iterators = new SerialIterators(this, perScanLimit, null, parallelIteratorFactory, scanGrouper);
         } else {
-        	iterators = new ParallelIterators(this, perScanLimit, parallelIteratorFactory, scanGrouper);
+            iterators = new ParallelIterators(this, perScanLimit, parallelIteratorFactory, scanGrouper);
         }
         splits = iterators.getSplits();
         scans = iterators.getScans();
         estimatedSize = iterators.getEstimatedByteCount();
         estimatedRows = iterators.getEstimatedRowCount();
-        
-        if (isOrdered) {
-            scanner = new MergeSortTopNResultIterator(iterators, limit, orderBy.getOrderByExpressions());
+        if (isOffsetOnServer) {
+            scanner = new ConcatResultIterator(iterators);
+            if (limit != null) {
+                scanner = new LimitingResultIterator(scanner, limit);
+            }
+        } else if (isOrdered) {
+            scanner = new MergeSortTopNResultIterator(iterators, limit, offset, orderBy.getOrderByExpressions());
         } else {
             if ((isSalted || table.getIndexType() == IndexType.LOCAL) && ScanUtil.shouldRowsBeInRowKeyOrder(orderBy, context)) {
                 /*
@@ -226,6 +243,9 @@ public class ScanPlan extends BaseQueryPlan {
             } else {
                 scanner = new ConcatResultIterator(iterators);
             }
+            if (offset != null) {
+                scanner = new OffsetResultIterator(scanner, offset);
+            }
             if (limit != null) {
                 scanner = new LimitingResultIterator(scanner, limit);
             }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java
index 41cae79..e181e80 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java
@@ -187,6 +187,11 @@ public class SortMergeJoinPlan implements QueryPlan {
     }
 
     @Override
+    public Integer getOffset() {
+        return null;
+    }
+
+    @Override
     public OrderBy getOrderBy() {
         return null;
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java
index 3208913..808141e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/UnionPlan.java
@@ -35,6 +35,7 @@ import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.iterate.ConcatResultIterator;
 import org.apache.phoenix.iterate.LimitingResultIterator;
 import org.apache.phoenix.iterate.MergeSortTopNResultIterator;
+import org.apache.phoenix.iterate.OffsetResultIterator;
 import org.apache.phoenix.iterate.ParallelScanGrouper;
 import org.apache.phoenix.iterate.ResultIterator;
 import org.apache.phoenix.iterate.UnionResultIterators;
@@ -56,6 +57,7 @@ public class UnionPlan implements QueryPlan {
     private final OrderBy orderBy;
     private final StatementContext parentContext;
     private final Integer limit;
+    private final Integer offset;
     private final GroupBy groupBy;
     private final RowProjector projector;
     private final boolean isDegenerate;
@@ -63,7 +65,7 @@ public class UnionPlan implements QueryPlan {
     private UnionResultIterators iterators;
 
     public UnionPlan(StatementContext context, FilterableStatement statement, TableRef table, RowProjector projector,
-            Integer limit, OrderBy orderBy, GroupBy groupBy, List<QueryPlan> plans, ParameterMetaData paramMetaData) throws SQLException {
+            Integer limit, Integer offset, OrderBy orderBy, GroupBy groupBy, List<QueryPlan> plans, ParameterMetaData paramMetaData) throws SQLException {
         this.parentContext = context;
         this.statement = statement;
         this.tableRef = table;
@@ -72,6 +74,7 @@ public class UnionPlan implements QueryPlan {
         this.orderBy = orderBy;
         this.groupBy = groupBy;
         this.plans = plans;
+        this.offset= offset;
         this.paramMetaData = paramMetaData;
         boolean isDegen = true;
         for (QueryPlan plan : plans) {           
@@ -123,6 +126,11 @@ public class UnionPlan implements QueryPlan {
     }
 
     @Override
+    public Integer getOffset() {
+        return offset;
+    }
+
+    @Override
     public RowProjector getProjector() {
         return projector;
     }
@@ -143,9 +151,12 @@ public class UnionPlan implements QueryPlan {
         boolean isOrdered = !orderBy.getOrderByExpressions().isEmpty();
 
         if (isOrdered) { // TopN
-            scanner = new MergeSortTopNResultIterator(iterators, limit, orderBy.getOrderByExpressions());
+            scanner = new MergeSortTopNResultIterator(iterators, limit, offset, orderBy.getOrderByExpressions());
         } else {
             scanner = new ConcatResultIterator(iterators);
+            if (offset != null) {
+                scanner = new OffsetResultIterator(scanner, offset);
+            }
             if (limit != null) {
                 scanner = new LimitingResultIterator(scanner, limit);
             }          

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
index 8d4b34b..0299f18 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
@@ -62,6 +62,7 @@ import org.apache.phoenix.coprocessor.UngroupedAggregateRegionObserver;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.exception.SQLExceptionInfo;
 import org.apache.phoenix.execute.MutationState;
+import org.apache.phoenix.execute.ScanPlan;
 import org.apache.phoenix.filter.ColumnProjectionFilter;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.hbase.index.util.VersionUtil;
@@ -152,7 +153,7 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
         return true;
     }
     
-    private static void initializeScan(QueryPlan plan, Integer perScanLimit) {
+    private static void initializeScan(QueryPlan plan, Integer perScanLimit, Integer offset) {
         StatementContext context = plan.getContext();
         TableRef tableRef = plan.getTableRef();
         PTable table = tableRef.getTable();
@@ -218,6 +219,10 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
             if (perScanLimit != null) {
                 ScanUtil.andFilterAtEnd(scan, new PageFilter(perScanLimit));
             }
+            
+            if(offset!=null){
+                ScanUtil.addOffsetAttribute(scan, offset);
+            }
 
             if (optimizeProjection) {
                 optimizeProjection(context, scan, table, statement);
@@ -326,8 +331,9 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
         }
     }
     
-    public BaseResultIterators(QueryPlan plan, Integer perScanLimit, ParallelScanGrouper scanGrouper) throws SQLException {
-        super(plan.getContext(), plan.getTableRef(), plan.getGroupBy(), plan.getOrderBy(), plan.getStatement().getHint(), plan.getLimit());
+    public BaseResultIterators(QueryPlan plan, Integer perScanLimit, Integer offset, ParallelScanGrouper scanGrouper) throws SQLException {
+        super(plan.getContext(), plan.getTableRef(), plan.getGroupBy(), plan.getOrderBy(),
+                plan.getStatement().getHint(), plan.getLimit(), plan instanceof ScanPlan ? plan.getOffset() : null);
         this.plan = plan;
         this.scanGrouper = scanGrouper;
         StatementContext context = plan.getContext();
@@ -341,7 +347,7 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
         // Used to tie all the scans together during logging
         scanId = UUID.randomUUID().toString();
         
-        initializeScan(plan, perScanLimit);
+        initializeScan(plan, perScanLimit, offset);
         
         this.scans = getParallelScans();
         List<KeyRange> splitRanges = Lists.newArrayListWithExpectedSize(scans.size() * ESTIMATED_GUIDEPOSTS_PER_REGION);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
index 74797e7..c5c9aa2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
@@ -59,18 +59,21 @@ public abstract class ExplainTable {
     protected final OrderBy orderBy;
     protected final HintNode hint;
     protected final Integer limit;
+    protected final Integer offset;
    
     public ExplainTable(StatementContext context, TableRef table) {
-        this(context,table,GroupBy.EMPTY_GROUP_BY, OrderBy.EMPTY_ORDER_BY, HintNode.EMPTY_HINT_NODE, null);
+        this(context, table, GroupBy.EMPTY_GROUP_BY, OrderBy.EMPTY_ORDER_BY, HintNode.EMPTY_HINT_NODE, null, null);
     }
 
-    public ExplainTable(StatementContext context, TableRef table, GroupBy groupBy, OrderBy orderBy, HintNode hintNode, Integer limit) {
+    public ExplainTable(StatementContext context, TableRef table, GroupBy groupBy, OrderBy orderBy, HintNode hintNode,
+            Integer limit, Integer offset) {
         this.context = context;
         this.tableRef = table;
         this.groupBy = groupBy;
         this.orderBy = orderBy;
         this.hint = hintNode;
         this.limit = limit;
+        this.offset = offset;
     }
 
     private boolean explainSkipScan(StringBuilder buf) {
@@ -150,8 +153,13 @@ public abstract class ExplainTable {
         if (!orderBy.getOrderByExpressions().isEmpty() && groupBy.isEmpty()) { // with GROUP BY, sort happens client-side
             planSteps.add("    SERVER" + (limit == null ? "" : " TOP " + limit + " ROW" + (limit == 1 ? "" : "S"))
                     + " SORTED BY " + orderBy.getOrderByExpressions().toString());
-        } else if (pageFilter != null) {
-            planSteps.add("    SERVER " + pageFilter.getPageSize() + " ROW LIMIT");                
+        } else {
+            if (offset != null) {
+                planSteps.add("    SERVER OFFSET " + offset);
+            }
+            if (pageFilter != null) {
+                planSteps.add("    SERVER " + pageFilter.getPageSize() + " ROW LIMIT");
+            }
         }
         Integer groupByLimit = null;
         byte[] groupByLimitBytes = scan.getAttribute(BaseScannerRegionObserver.GROUP_BY_LIMIT);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/iterate/LimitingResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/LimitingResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/LimitingResultIterator.java
index c789093..7cf8d3e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/LimitingResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/LimitingResultIterator.java
@@ -50,7 +50,7 @@ public class LimitingResultIterator extends DelegateResultIterator {
     @Override
     public void explain(List<String> planSteps) {
         super.explain(planSteps);
-        planSteps.add("CLIENT " + limit + " ROW LIMIT");
+            planSteps.add("CLIENT " + limit + " ROW LIMIT");
     }
 
 	@Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java
index 4c4097f..a9d8046 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java
@@ -36,13 +36,17 @@ public class MergeSortTopNResultIterator extends MergeSortResultIterator {
 
     private final int limit;
     private int count = 0;
+    private int offsetCount = 0;
     private final List<OrderByExpression> orderByColumns;
     private final ImmutableBytesWritable ptr1 = new ImmutableBytesWritable();
     private final ImmutableBytesWritable ptr2 = new ImmutableBytesWritable();
+    private final int offset;
     
-    public MergeSortTopNResultIterator(ResultIterators iterators, Integer limit, List<OrderByExpression> orderByColumns) {
+    public MergeSortTopNResultIterator(ResultIterators iterators, Integer limit, Integer offset,
+            List<OrderByExpression> orderByColumns) {
         super(iterators);
         this.limit = limit == null ? -1 : limit;
+        this.offset = offset == null ? -1 : offset;
         this.orderByColumns = orderByColumns;
     }
 
@@ -71,6 +75,10 @@ public class MergeSortTopNResultIterator extends MergeSortResultIterator {
 
     @Override
     public Tuple peek() throws SQLException {
+        while (offsetCount < offset) {
+            if (super.next() == null) { return null; }
+            offsetCount++;
+        }
         if (limit >= 0 && count >= limit) {
             return null;
         }
@@ -79,9 +87,11 @@ public class MergeSortTopNResultIterator extends MergeSortResultIterator {
 
     @Override
     public Tuple next() throws SQLException {
-        if (limit >= 0 && count++ >= limit) {
-            return null;
+        while (offsetCount < offset) {
+            if (super.next() == null) { return null; }
+            offsetCount++;
         }
+        if (limit >= 0 && count++ >= limit) { return null; }
         return super.next();
     }
 
@@ -90,12 +100,15 @@ public class MergeSortTopNResultIterator extends MergeSortResultIterator {
     public void explain(List<String> planSteps) {
         resultIterators.explain(planSteps);
         planSteps.add("CLIENT MERGE SORT");
+        if (offset > 0) {
+            planSteps.add("CLIENT OFFSET " + offset);
+        }
     }
 
 	@Override
 	public String toString() {
 		return "MergeSortTopNResultIterator [limit=" + limit + ", count="
 				+ count + ", orderByColumns=" + orderByColumns + ", ptr1="
-				+ ptr1 + ", ptr2=" + ptr2 + "]";
+				+ ptr1 + ", ptr2=" + ptr2 + ",offset=" + offset + "]";
 	}
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/iterate/OffsetResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/OffsetResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/OffsetResultIterator.java
new file mode 100644
index 0000000..ef8eacf
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/OffsetResultIterator.java
@@ -0,0 +1,62 @@
+/*
+ * 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.phoenix.iterate;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.phoenix.schema.tuple.Tuple;
+
+/**
+ * Iterates through tuples up to a limit
+ *
+ * @since 1.2
+ */
+public class OffsetResultIterator extends DelegateResultIterator {
+    private int rowCount;
+    private int offset;
+
+    public OffsetResultIterator(ResultIterator delegate, Integer offset) {
+        super(delegate);
+        this.offset = offset == null ? -1 : offset;
+    }
+
+    @Override
+    public Tuple next() throws SQLException {
+        while (rowCount < offset) {
+            if (super.next() == null) { return null; }
+            rowCount++;
+        }
+        return super.next();
+    }
+
+    @Override
+    public void explain(List<String> planSteps) {
+        super.explain(planSteps);
+        planSteps.add("CLIENT OFFSET " + offset);
+    }
+
+    @Override
+    public String toString() {
+        return "OffsetResultIterator [rowCount=" + rowCount + ", offset=" + offset + "]";
+    }
+
+    public Integer getUnusedOffset() {
+        return (offset - rowCount) > 0 ? (offset - rowCount) : 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedAggregatingResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedAggregatingResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedAggregatingResultIterator.java
index 6f86605..da2be48 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedAggregatingResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedAggregatingResultIterator.java
@@ -35,9 +35,9 @@ import org.apache.phoenix.schema.tuple.Tuple;
 public class OrderedAggregatingResultIterator extends OrderedResultIterator implements AggregatingResultIterator {
 
     public OrderedAggregatingResultIterator(AggregatingResultIterator delegate,
-                                List<OrderByExpression> orderByExpressions,
-                                int thresholdBytes, Integer limit) throws SQLException {
-        super (delegate, orderByExpressions, thresholdBytes, limit);
+            List<OrderByExpression> orderByExpressions, int thresholdBytes, Integer limit, Integer offset)
+                    throws SQLException {
+        super(delegate, orderByExpressions, thresholdBytes, limit, offset);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java
index d999ecb..8dcb2e8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java
@@ -92,6 +92,7 @@ public class OrderedResultIterator implements PeekingResultIterator {
 
     private final int thresholdBytes;
     private final Integer limit;
+    private final Integer offset;
     private final ResultIterator delegate;
     private final List<OrderByExpression> orderByExpressions;
     private final long estimatedByteSize;
@@ -103,24 +104,28 @@ public class OrderedResultIterator implements PeekingResultIterator {
         return delegate;
     }
     
-    public OrderedResultIterator(ResultIterator delegate,
-                                 List<OrderByExpression> orderByExpressions,
-                                 int thresholdBytes, Integer limit) {
-        this(delegate, orderByExpressions, thresholdBytes, limit, 0);
+    public OrderedResultIterator(ResultIterator delegate, List<OrderByExpression> orderByExpressions,
+            int thresholdBytes, Integer limit, Integer offset) {
+        this(delegate, orderByExpressions, thresholdBytes, limit, offset, 0);
     }
 
-    public OrderedResultIterator(ResultIterator delegate,
-            List<OrderByExpression> orderByExpressions, int thresholdBytes) throws SQLException {
-        this(delegate, orderByExpressions, thresholdBytes, null);
+    public OrderedResultIterator(ResultIterator delegate, List<OrderByExpression> orderByExpressions,
+            int thresholdBytes) throws SQLException {
+        this(delegate, orderByExpressions, thresholdBytes, null, null);
     }
 
     public OrderedResultIterator(ResultIterator delegate, List<OrderByExpression> orderByExpressions, 
-            int thresholdBytes, Integer limit, int estimatedRowSize) {
+            int thresholdBytes, Integer limit, Integer offset,int estimatedRowSize) {
         checkArgument(!orderByExpressions.isEmpty());
         this.delegate = delegate;
         this.orderByExpressions = orderByExpressions;
         this.thresholdBytes = thresholdBytes;
-        this.limit = limit;
+        this.offset = offset == null ? 0 : offset;
+        if (limit != null) {
+            this.limit = limit + this.offset;
+        } else {
+            this.limit = null;
+        }
         long estimatedEntrySize =
             // ResultEntry
             SizedUtil.OBJECT_SIZE + 
@@ -130,9 +135,9 @@ public class OrderedResultIterator implements PeekingResultIterator {
             SizedUtil.OBJECT_SIZE + estimatedRowSize;
 
         // Make sure we don't overflow Long, though this is really unlikely to happen.
-        assert(limit == null || Long.MAX_VALUE / estimatedEntrySize >= limit);
+        assert(limit == null || Long.MAX_VALUE / estimatedEntrySize >= limit + this.offset);
 
-        this.estimatedByteSize = limit == null ? 0 : limit * estimatedEntrySize;
+        this.estimatedByteSize = limit == null ? 0 : (limit + this.offset) * estimatedEntrySize;
     }
 
     public Integer getLimit() {
@@ -202,13 +207,20 @@ public class OrderedResultIterator implements PeekingResultIterator {
         List<Expression> expressions = Lists.newArrayList(Collections2.transform(orderByExpressions, TO_EXPRESSION));
         final Comparator<ResultEntry> comparator = buildComparator(orderByExpressions);
         try{
-            final MappedByteBufferSortedQueue queueEntries = new MappedByteBufferSortedQueue(comparator, limit, thresholdBytes);
+            final MappedByteBufferSortedQueue queueEntries = new MappedByteBufferSortedQueue(comparator, limit,
+                    thresholdBytes);
             resultIterator = new PeekingResultIterator() {
                 int count = 0;
+
                 @Override
                 public Tuple next() throws SQLException {
                     ResultEntry entry = queueEntries.poll();
-                    if (entry == null || (limit != null && ++count > limit)) {
+                    while (entry != null && offset != null && count < offset) {
+                        count++;
+                        if (entry.getResult() == null) { return null; }
+                        entry = queueEntries.poll();
+                    }
+                    if (entry == null || (limit != null && count++ > limit)) {
                         resultIterator.close();
                         resultIterator = PeekingResultIterator.EMPTY_ITERATOR;
                         return null;
@@ -218,13 +230,15 @@ public class OrderedResultIterator implements PeekingResultIterator {
                 
                 @Override
                 public Tuple peek() throws SQLException {
-                    if (limit != null && count > limit) {
-                        return null;
-                    }
-                    ResultEntry entry =  queueEntries.peek();
-                    if (entry == null) {
-                        return null;
+                    ResultEntry entry = queueEntries.peek();
+                    while (entry != null && offset != null && count < offset) {
+                        entry = queueEntries.poll();
+                        count++;
+                        if (entry == null) { return null; }
                     }
+                    if (limit != null && count > limit) { return null; }
+                    entry = queueEntries.peek();
+                    if (entry == null) { return null; }
                     return entry.getResult();
                 }
 
@@ -273,13 +287,15 @@ public class OrderedResultIterator implements PeekingResultIterator {
     @Override
     public void explain(List<String> planSteps) {
         delegate.explain(planSteps);
-        planSteps.add("CLIENT" + (limit == null ? "" : " TOP " + limit + " ROW"  + (limit == 1 ? "" : "S"))  + " SORTED BY " + orderByExpressions.toString());
+        planSteps.add("CLIENT" + (offset != null ? "" : " OFFSET " + offset)
+                + (limit == null ? "" : " TOP " + limit + " ROW" + (limit == 1 ? "" : "S")) + " SORTED BY "
+                + orderByExpressions.toString());
     }
 
     @Override
     public String toString() {
         return "OrderedResultIterator [thresholdBytes=" + thresholdBytes
-                + ", limit=" + limit + ", delegate=" + delegate
+                + ", limit=" + limit + ", offset=" + offset + ", delegate=" + delegate
                 + ", orderByExpressions=" + orderByExpressions
                 + ", estimatedByteSize=" + estimatedByteSize
                 + ", resultIterator=" + resultIterator + ", byteSize="

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
index 4339b05..1351735 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java
@@ -30,8 +30,8 @@ import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.job.JobManager.JobCallable;
-import org.apache.phoenix.monitoring.MetricType;
 import org.apache.phoenix.monitoring.CombinableMetric;
+import org.apache.phoenix.monitoring.MetricType;
 import org.apache.phoenix.monitoring.ReadMetricQueue;
 import org.apache.phoenix.monitoring.TaskExecutionMetricsHolder;
 import org.apache.phoenix.trace.util.Tracing;
@@ -56,7 +56,7 @@ public class ParallelIterators extends BaseResultIterators {
     
     public ParallelIterators(QueryPlan plan, Integer perScanLimit, ParallelIteratorFactory iteratorFactory, ParallelScanGrouper scanGrouper)
             throws SQLException {
-        super(plan, perScanLimit, scanGrouper);
+        super(plan, perScanLimit, null, scanGrouper);
         this.iteratorFactory = iteratorFactory;
     }   
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
index 60b9f44..f3b9e7d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
@@ -27,12 +27,14 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 
 import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.job.JobManager.JobCallable;
 import org.apache.phoenix.monitoring.TaskExecutionMetricsHolder;
 import org.apache.phoenix.parse.HintNode;
+import org.apache.phoenix.query.QueryConstants;
 import org.apache.phoenix.trace.util.Tracing;
 import org.apache.phoenix.util.ScanUtil;
 
@@ -52,10 +54,13 @@ public class SerialIterators extends BaseResultIterators {
 	private static final String NAME = "SERIAL";
     private final ParallelIteratorFactory iteratorFactory;
     
-    public SerialIterators(QueryPlan plan, Integer perScanLimit, ParallelIteratorFactory iteratorFactory, ParallelScanGrouper scanGrouper)
+    public SerialIterators(QueryPlan plan, Integer perScanLimit, Integer offset,
+            ParallelIteratorFactory iteratorFactory, ParallelScanGrouper scanGrouper)
             throws SQLException {
-        super(plan, perScanLimit, scanGrouper);
-        Preconditions.checkArgument(perScanLimit != null || plan.getStatement().getHint().hasHint(HintNode.Hint.SERIAL)); // must be a limit specified or a SERIAL hint
+        super(plan, perScanLimit, offset, scanGrouper);
+        // must be a offset or a limit specified or a SERIAL hint
+        Preconditions.checkArgument(
+                offset != null || perScanLimit != null || plan.getStatement().getHint().hasHint(HintNode.Hint.SERIAL));
         this.iteratorFactory = iteratorFactory;
     }
 
@@ -78,14 +83,18 @@ public class SerialIterators extends BaseResultIterators {
             final TaskExecutionMetricsHolder taskMetrics = new TaskExecutionMetricsHolder(context.getReadMetricsQueue(), tableName);
             final PhoenixConnection conn = context.getConnection();
             final long renewLeaseThreshold = conn.getQueryServices().getRenewLeaseThresholdMilliSeconds();
+            lastScan.setAttribute(QueryConstants.LAST_SCAN, Bytes.toBytes(Boolean.TRUE));
             Future<PeekingResultIterator> future = executor.submit(Tracing.wrap(new JobCallable<PeekingResultIterator>() {
                 @Override
                 public PeekingResultIterator call() throws Exception {
+                    PeekingResultIterator previousIterator = null;
                 	List<PeekingResultIterator> concatIterators = Lists.newArrayListWithExpectedSize(scans.size());
                 	for (final Scan scan : scans) {
-                	    TableResultIterator scanner = new TableResultIterator(mutationState, tableRef, scan, context.getReadMetricsQueue().allotMetric(SCAN_BYTES, tableName), renewLeaseThreshold);
+                	    TableResultIterator scanner = new TableResultIterator(mutationState, tableRef, scan, context.getReadMetricsQueue().allotMetric(SCAN_BYTES, tableName), renewLeaseThreshold, previousIterator);
                 	    conn.addIterator(scanner);
-                	    concatIterators.add(iteratorFactory.newIterator(context, scanner, scan, tableName));
+                	    PeekingResultIterator iterator = iteratorFactory.newIterator(context, scanner, scan, tableName);
+                	    concatIterators.add(iterator);
+                	    previousIterator = iterator;
                 	}
                 	PeekingResultIterator concatIterator = ConcatResultIterator.newIterator(concatIterators);
                     allIterators.add(concatIterator);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
index 11ea39a..f5a9dc4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
@@ -32,12 +32,14 @@ import javax.annotation.concurrent.GuardedBy;
 import org.apache.hadoop.hbase.client.AbstractClientScanner;
 import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Scan;
+import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
 import org.apache.phoenix.execute.MutationState;
 import org.apache.phoenix.monitoring.CombinableMetric;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.Closeables;
+import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.ServerUtil;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -68,6 +70,7 @@ public class TableResultIterator implements ResultIterator {
 
     @GuardedBy("this")
     private long renewLeaseTime = 0;
+    private PeekingResultIterator previousIterator;
 
     @VisibleForTesting // Exposed for testing. DON'T USE ANYWHERE ELSE!
     TableResultIterator() {
@@ -81,14 +84,20 @@ public class TableResultIterator implements ResultIterator {
         RENEWED, CLOSED, UNINITIALIZED, THRESHOLD_NOT_REACHED, NOT_RENEWED
     };
 
-
-    public TableResultIterator(MutationState mutationState, TableRef tableRef, Scan scan, CombinableMetric scanMetrics, long renewLeaseThreshold) throws SQLException {
+    public TableResultIterator(MutationState mutationState, TableRef tableRef, Scan scan, CombinableMetric scanMetrics,
+			long renewLeaseThreshold) throws SQLException {
+    	this(mutationState,tableRef,scan,scanMetrics,renewLeaseThreshold,null);
+    }
+    
+    public TableResultIterator(MutationState mutationState, TableRef tableRef, Scan scan, CombinableMetric scanMetrics,
+            long renewLeaseThreshold, PeekingResultIterator previousIterator) throws SQLException {
         this.scan = scan;
         this.scanMetrics = scanMetrics;
         PTable table = tableRef.getTable();
         htable = mutationState.getHTable(table);
         this.scanIterator = UNINITIALIZED_SCANNER;
         this.renewLeaseThreshold = renewLeaseThreshold;
+        this.previousIterator = previousIterator;
     }
 
     @Override
@@ -120,6 +129,15 @@ public class TableResultIterator implements ResultIterator {
         ResultIterator delegate = this.scanIterator;
         if (delegate == UNINITIALIZED_SCANNER) {
             try {
+                if (previousIterator != null && scan.getAttribute(BaseScannerRegionObserver.SCAN_OFFSET) != null) {
+                    byte[] unusedOffset = QueryUtil.getUnusedOffset(previousIterator.peek());
+                    if (unusedOffset != null) {
+                        scan.setAttribute(BaseScannerRegionObserver.SCAN_OFFSET, unusedOffset);
+                        previousIterator.next();
+                    } else {
+                        scan.setAttribute(BaseScannerRegionObserver.SCAN_OFFSET, null);
+                    }
+                }
                 this.scanIterator =
                         new ScanningResultIterator(htable.getScanner(scan), scanMetrics);
             } catch (IOException e) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
index f36bbd8..c365d19 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
@@ -108,6 +108,7 @@ import org.apache.phoenix.parse.ListJarsStatement;
 import org.apache.phoenix.parse.LiteralParseNode;
 import org.apache.phoenix.parse.NamedNode;
 import org.apache.phoenix.parse.NamedTableNode;
+import org.apache.phoenix.parse.OffsetNode;
 import org.apache.phoenix.parse.OrderByNode;
 import org.apache.phoenix.parse.PFunction;
 import org.apache.phoenix.parse.ParseNode;
@@ -369,14 +370,14 @@ public class PhoenixStatement implements Statement, SQLCloseable {
     
     private static class ExecutableSelectStatement extends SelectStatement implements CompilableStatement {
         private ExecutableSelectStatement(TableNode from, HintNode hint, boolean isDistinct, List<AliasedNode> select, ParseNode where,
-                List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit, int bindCount, boolean isAggregate, boolean hasSequence, Map<String, UDFParseNode> udfParseNodes) {
-            this(from, hint, isDistinct, select, where, groupBy, having, orderBy, limit, bindCount, isAggregate, hasSequence, Collections.<SelectStatement>emptyList(), udfParseNodes);
+                List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit,OffsetNode offset, int bindCount, boolean isAggregate, boolean hasSequence, Map<String, UDFParseNode> udfParseNodes) {
+            this(from, hint, isDistinct, select, where, groupBy, having, orderBy, limit,offset, bindCount, isAggregate, hasSequence, Collections.<SelectStatement>emptyList(), udfParseNodes);
         }
 
         private ExecutableSelectStatement(TableNode from, HintNode hint, boolean isDistinct, List<AliasedNode> select, ParseNode where,
-                List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit, int bindCount, boolean isAggregate,
+                List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit,OffsetNode offset, int bindCount, boolean isAggregate,
                 boolean hasSequence, List<SelectStatement> selects, Map<String, UDFParseNode> udfParseNodes) {
-            super(from, hint, isDistinct, select, where, groupBy, having, orderBy, limit, bindCount, isAggregate, hasSequence, selects, udfParseNodes);
+            super(from, hint, isDistinct, select, where, groupBy, having, orderBy, limit, offset, bindCount, isAggregate, hasSequence, selects, udfParseNodes);
         }
         
         @SuppressWarnings("unchecked")
@@ -508,6 +509,11 @@ public class PhoenixStatement implements Statement, SQLCloseable {
                 }
 
                 @Override
+                public Integer getOffset() {
+                    return null;
+                }
+
+                @Override
                 public OrderBy getOrderBy() {
                     return OrderBy.EMPTY_ORDER_BY;
                 }
@@ -1006,10 +1012,10 @@ public class PhoenixStatement implements Statement, SQLCloseable {
     protected static class ExecutableNodeFactory extends ParseNodeFactory {
         @Override
         public ExecutableSelectStatement select(TableNode from, HintNode hint, boolean isDistinct, List<AliasedNode> select, ParseNode where,
-                List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit, int bindCount, boolean isAggregate,
+                List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit, OffsetNode offset, int bindCount, boolean isAggregate,
                 boolean hasSequence, List<SelectStatement> selects, Map<String, UDFParseNode> udfParseNodes) {
             return new ExecutableSelectStatement(from, hint, isDistinct, select, where, groupBy == null ? Collections.<ParseNode>emptyList() : groupBy,
-                    having, orderBy == null ? Collections.<OrderByNode>emptyList() : orderBy, limit, bindCount, isAggregate, hasSequence, selects == null ? Collections.<SelectStatement>emptyList() : selects, udfParseNodes);
+                    having, orderBy == null ? Collections.<OrderByNode>emptyList() : orderBy, limit, offset, bindCount, isAggregate, hasSequence, selects == null ? Collections.<SelectStatement>emptyList() : selects, udfParseNodes);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/join/HashJoinInfo.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/join/HashJoinInfo.java b/phoenix-core/src/main/java/org/apache/phoenix/join/HashJoinInfo.java
index 31718e5..3161eb4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/join/HashJoinInfo.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/join/HashJoinInfo.java
@@ -222,7 +222,7 @@ public class HashJoinInfo {
                 forceProjection = input.readBoolean();
             } catch (EOFException ignore) {
             }
-            return new HashJoinInfo(joinedSchema, joinIds, joinExpressions, joinTypes, earlyEvaluation, schemas, fieldPositions, postJoinFilterExpression, limit >= 0 ? limit : null, forceProjection);
+            return new HashJoinInfo(joinedSchema, joinIds, joinExpressions, joinTypes, earlyEvaluation, schemas, fieldPositions, postJoinFilterExpression, limit >= 0 ? limit : null,  forceProjection);
         } catch (IOException e) {
             throw new RuntimeException(e);
         } finally {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java b/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
index 40591c2..6eb6cb0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
@@ -285,7 +285,7 @@ public class QueryOptimizer {
                             aliasedNodes.add(FACTORY.aliasedNode(null, indexColNode));
                             nodes.add(new ColumnParseNode(null, '"' + column.getName().getString() + '"'));
                         }
-                        SelectStatement innerSelect = FACTORY.select(indexSelect.getFrom(), indexSelect.getHint(), false, aliasedNodes, where, null, null, null, null, indexSelect.getBindCount(), false, indexSelect.hasSequence(), Collections.<SelectStatement>emptyList(), indexSelect.getUdfParseNodes());
+                        SelectStatement innerSelect = FACTORY.select(indexSelect.getFrom(), indexSelect.getHint(), false, aliasedNodes, where, null, null, null, null, null, indexSelect.getBindCount(), false, indexSelect.hasSequence(), Collections.<SelectStatement>emptyList(), indexSelect.getUdfParseNodes());
                         ParseNode outerWhere = FACTORY.in(nodes.size() == 1 ? nodes.get(0) : FACTORY.rowValueConstructor(nodes), FACTORY.subquery(innerSelect, false), false, true);
                         ParseNode extractedCondition = whereRewriter.getExtractedCondition();
                         if (extractedCondition != null) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteStatement.java
index 276e6aa..fb2d327 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/DeleteStatement.java
@@ -71,4 +71,10 @@ public class DeleteStatement extends DMLStatement implements FilterableStatement
     public Operation getOperation() {
         return Operation.DELETE;
     }
+
+    @Override
+    public OffsetNode getOffset() {
+        return null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/parse/FilterableStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/FilterableStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/FilterableStatement.java
index eda13c8..ad54d98 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/FilterableStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/FilterableStatement.java
@@ -26,4 +26,5 @@ public interface FilterableStatement extends BindableStatement {
     public boolean isAggregate();
     public List<OrderByNode> getOrderBy();
     public LimitNode getLimit();
+    public OffsetNode getOffset();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/f65d0481/phoenix-core/src/main/java/org/apache/phoenix/parse/OffsetNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/OffsetNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/OffsetNode.java
new file mode 100644
index 0000000..0387f5c
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/OffsetNode.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.phoenix.parse;
+
+
+public class OffsetNode {
+    private final BindParseNode bindNode;
+    private final LiteralParseNode offsetNode;
+    
+    OffsetNode(BindParseNode bindNode) {
+        this.bindNode = bindNode;
+        offsetNode = null;
+    }
+    
+    OffsetNode(LiteralParseNode limitNode) {
+        this.offsetNode = limitNode;
+        this.bindNode = null;
+    }
+    
+    public ParseNode getOffsetParseNode() {
+        return bindNode == null ? offsetNode : bindNode;
+    }
+    
+    @Override
+    public String toString() {
+        return bindNode == null ? offsetNode.toString() : bindNode.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((bindNode == null) ? 0 : bindNode.hashCode());
+        result = prime * result + ((offsetNode == null) ? 0 : offsetNode.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        OffsetNode other = (OffsetNode)obj;
+        if (bindNode == null) {
+            if (other.bindNode != null) return false;
+        } else if (!bindNode.equals(other.bindNode)) return false;
+        if (offsetNode == null) {
+            if (other.offsetNode != null) return false;
+        } else if (!offsetNode.equals(other.offsetNode)) return false;
+        return true;
+    }
+}