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/10/19 18:59:30 UTC

[11/12] phoenix git commit: Fix test failures

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/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 b1dd5f4..edf27eb 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
@@ -23,6 +23,7 @@ import java.io.DataInputStream;
 import java.io.DataOutput;
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.nio.ByteBuffer;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -60,7 +61,6 @@ import org.apache.phoenix.expression.ExpressionType;
 import org.apache.phoenix.expression.KeyValueColumnExpression;
 import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.expression.visitor.KeyValueExpressionVisitor;
-import org.apache.phoenix.expression.visitor.ReplaceArrayColumnWithKeyValueColumnExpressionVisitor;
 import org.apache.phoenix.hbase.index.ValueGetter;
 import org.apache.phoenix.hbase.index.covered.update.ColumnReference;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
@@ -337,13 +337,7 @@ 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 = EncodedColumnsUtil.usesEncodedColumnNames(dataTable);
+        this.usesEncodedColumnNames = EncodedColumnsUtil.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.
@@ -526,7 +520,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
         initCachedState();
     }
     
-    public byte[] buildRowKey(ValueGetter valueGetter, ImmutableBytesWritable rowKeyPtr, byte[] regionStartKey, byte[] regionEndKey, boolean convertArrayColToKeyValueCol)  {
+    public byte[] buildRowKey(ValueGetter valueGetter, ImmutableBytesWritable rowKeyPtr, byte[] regionStartKey, byte[] regionEndKey)  {
         ImmutableBytesWritable ptr = new ImmutableBytesWritable();
         boolean prependRegionStartKey = isLocalIndex && regionStartKey != null;
         boolean isIndexSalted = !isLocalIndex && nIndexSaltBuckets > 0;
@@ -595,9 +589,6 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
                 SortOrder dataSortOrder;
                 if (dataPkPosition[i] == EXPRESSION_NOT_PRESENT) {
                 	Expression expression = expressionIterator.next();
-                	if (convertArrayColToKeyValueCol) {
-                	    expression = expression.accept(new ReplaceArrayColumnWithKeyValueColumnExpressionVisitor());
-                	}
                 	dataColumnType = expression.getDataType();
                 	dataSortOrder = expression.getSortOrder();
                     isNullable = expression.isNullable();
@@ -930,11 +921,11 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
         return indexRowKeySchema;
     }
 
-    public Put buildUpdateMutation(KeyValueBuilder kvBuilder, ValueGetter valueGetter, ImmutableBytesWritable dataRowKeyPtr, long ts, byte[] regionStartKey, byte[] regionEndKey, boolean convertArrayColToKeyValueCol) throws IOException {
-        Put put = null;
+    public Put buildUpdateMutation(KeyValueBuilder kvBuilder, ValueGetter valueGetter, ImmutableBytesWritable dataRowKeyPtr, long ts, byte[] regionStartKey, byte[] regionEndKey) throws IOException {
+    	byte[] indexRowKey = this.buildRowKey(valueGetter, dataRowKeyPtr, regionStartKey, regionEndKey);
+    	Put put = null;
         // New row being inserted: add the empty key value
         if (valueGetter.getLatestValue(dataEmptyKeyValueRef) == null) {
-            byte[] indexRowKey = this.buildRowKey(valueGetter, dataRowKeyPtr, regionStartKey, regionEndKey, convertArrayColToKeyValueCol);
             put = new Put(indexRowKey);
             // add the keyvalue for the empty row
             put.add(kvBuilder.buildPut(new ImmutableBytesPtr(indexRowKey),
@@ -943,40 +934,71 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
                 emptyKeyValueQualifierPtr));
             put.setDurability(!indexWALDisabled ? Durability.USE_DEFAULT : Durability.SKIP_WAL);
         }
-        byte[] indexRowKey = this.buildRowKey(valueGetter, dataRowKeyPtr, regionStartKey, regionEndKey, convertArrayColToKeyValueCol);
         ImmutableBytesPtr rowKey = new ImmutableBytesPtr(indexRowKey);
         if (storeColsInSingleCell) {
-            // map from column family to list of columns (for covered columns)
-            Map<String, List<ColumnReference>> familyToColListMap = Maps.newHashMap();
+            // map from index column family to list of pair of index column and data column (for covered columns)
+            Map<ByteBuffer, List<Pair<ColumnReference, ColumnReference>>> familyToColListMap = Maps.newHashMap();
             for (ColumnReference ref : this.getCoveredColumns()) {
-                String cf = Bytes.toString(ref.getFamily());
+            	ColumnReference indexColRef = this.coveredColumnsMap.get(ref);
+                ByteBuffer cf = ByteBuffer.wrap(indexColRef.getFamily());
                 if (!familyToColListMap.containsKey(cf)) {
-                    familyToColListMap.put(cf, Lists.<ColumnReference>newArrayList());
+                    familyToColListMap.put(cf, Lists.<Pair<ColumnReference, ColumnReference>>newArrayList());
                 }
-                familyToColListMap.get(cf).add(ref);
+                familyToColListMap.get(cf).add(Pair.newPair(indexColRef, ref));
             }
             // iterate over each column family and create a byte[] containing all the columns 
-            for (Entry<String, List<ColumnReference>> entry : familyToColListMap.entrySet()) {
-                byte[] columnFamily = entry.getKey().getBytes();
-                List<ColumnReference> colRefs = entry.getValue();
+            for (Entry<ByteBuffer, List<Pair<ColumnReference, ColumnReference>>> entry : familyToColListMap.entrySet()) {
+                byte[] columnFamily = entry.getKey().array();
+                List<Pair<ColumnReference, ColumnReference>> colRefPairs = entry.getValue();
                 int maxIndex = Integer.MIN_VALUE;
                 // find the max col qualifier
-                for (ColumnReference colRef : colRefs) {
-                    byte[] qualifier = this.coveredColumnsMap.get(colRef).getQualifier();
+                for (Pair<ColumnReference, ColumnReference> colRefPair : colRefPairs) {
+                    byte[] qualifier = colRefPair.getFirst().getQualifier();
                     maxIndex = Math.max(maxIndex, PInteger.INSTANCE.getCodec().decodeInt(qualifier, 0, SortOrder.getDefault()));
                 }
                 byte[][] colValues = new byte[maxIndex+1][];
                 // set the values of the columns
-                for (ColumnReference colRef : colRefs) {
-                    ImmutableBytesWritable value = valueGetter.getLatestValue(colRef);
-                    if (value != null) {
-                        byte[] qualifier = this.coveredColumnsMap.get(colRef).getQualifier();
-                        int index = PInteger.INSTANCE.getCodec().decodeInt(qualifier, 0, SortOrder.getDefault());
-                        colValues[index] = value.get();
+                for (Pair<ColumnReference, ColumnReference> colRefPair : colRefPairs) {
+                	ColumnReference indexColRef = colRefPair.getFirst();
+                	ColumnReference dataColRef = colRefPair.getSecond();
+                	int dataArrayPos = PInteger.INSTANCE.getCodec().decodeInt(dataColRef.getQualifier(), 0, SortOrder.getDefault());
+                	Expression expression = new ArrayColumnExpression(new PDatum() {
+						@Override
+						public boolean isNullable() {
+							return false;
+						}
+						
+						@Override
+						public SortOrder getSortOrder() {
+							return null;
+						}
+						
+						@Override
+						public Integer getScale() {
+							return null;
+						}
+						
+						@Override
+						public Integer getMaxLength() {
+							return null;
+						}
+						
+						@Override
+						public PDataType getDataType() {
+							return null;
+						}
+					}, dataColRef.getFamily(), dataArrayPos);
+                	ImmutableBytesPtr ptr = new ImmutableBytesPtr();
+                    expression.evaluate(new ValueGetterTuple(valueGetter), ptr);
+                    byte[] value = ptr.copyBytesIfNecessary();
+					if (value != null) {
+						byte[] qualifier = indexColRef.getQualifier();
+                        int indexArrayPos = PInteger.INSTANCE.getCodec().decodeInt(qualifier, 0, SortOrder.getDefault());
+                        colValues[indexArrayPos] = value;
                     }
                 }
                 
-                List<Expression> children = Lists.newArrayListWithExpectedSize(colRefs.size());
+                List<Expression> children = Lists.newArrayListWithExpectedSize(colRefPairs.size());
                 // create an expression list with all the columns
                 for (int j=0; j<colValues.length; ++j) {
                     children.add(new LiteralExpression(colValues[j]==null ? ByteUtil.EMPTY_BYTE_ARRAY : colValues[j] ));
@@ -1087,7 +1109,7 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
     
     @SuppressWarnings("deprecation")
     public Delete buildDeleteMutation(KeyValueBuilder kvBuilder, ValueGetter oldState, ImmutableBytesWritable dataRowKeyPtr, Collection<KeyValue> pendingUpdates, long ts, byte[] regionStartKey, byte[] regionEndKey) throws IOException {
-        byte[] indexRowKey = this.buildRowKey(oldState, dataRowKeyPtr, regionStartKey, regionEndKey, false);
+        byte[] indexRowKey = this.buildRowKey(oldState, dataRowKeyPtr, regionStartKey, regionEndKey);
         // Delete the entire row if any of the indexed columns changed
         DeleteType deleteType = null;
         if (oldState == null || (deleteType=getDeleteTypeOrNull(pendingUpdates)) != null || hasIndexedColumnChanged(oldState, pendingUpdates)) { // Deleting the entire row
@@ -1416,14 +1438,6 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
                 	}
                     return null;
                 }
-                @Override
-                public Void visit(ArrayColumnExpression expression) {
-					KeyValueColumnExpression colExpression = expression.getArrayExpression();
-					if (indexedColumns.add(new ColumnReference(colExpression.getColumnFamily(), colExpression.getColumnQualifier()))) {
-                		indexedColumnTypes.add(colExpression.getDataType());
-                	}
-					return null;
-                }
             };
             expression.accept(visitor);
         }
@@ -1696,4 +1710,14 @@ public class IndexMaintainer implements Writable, Iterable<ColumnReference> {
     public Set<Pair<String, String>> getIndexedColumnInfo() {
         return indexedColumnsInfo;
     }
+    
+    public StorageScheme getIndexStorageScheme() {
+        if (storeColsInSingleCell) {
+            return StorageScheme.COLUMNS_STORED_IN_SINGLE_CELL;
+        }
+        if (usesEncodedColumnNames) {
+            return StorageScheme.ENCODED_COLUMN_NAMES;
+        }
+        return StorageScheme.NON_ENCODED_COLUMN_NAMES;
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java
index b1454b7..9d2955b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java
@@ -74,7 +74,7 @@ public class PhoenixIndexCodec extends BaseIndexCodec {
             indexUpdate.setTable(maintainer.isLocalIndex() ? state.getEnvironment().getRegion()
                     .getTableDesc().getName() : maintainer.getIndexTableName());
             Put put = maintainer.buildUpdateMutation(KV_BUILDER, valueGetter, ptr, state.getCurrentTimestamp(), env
-                    .getRegion().getRegionInfo().getStartKey(), env.getRegion().getRegionInfo().getEndKey(), false);
+                    .getRegion().getRegionInfo().getStartKey(), env.getRegion().getRegionInfo().getEndKey());
             indexUpdate.setUpdate(put);
             indexUpdates.add(indexUpdate);
         }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/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 eb73d6b..d382005 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
@@ -158,12 +158,13 @@ public class PhoenixIndexFailurePolicy extends DelegateIndexFailurePolicy {
                     .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) 
+            if (blockWriteRebuildIndex) {
                 put.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES, PhoenixDatabaseMetaData.INDEX_STATE_BYTES,
                         PIndexState.ACTIVE.getSerializedBytes());
-            else  
+            } else {  
                 put.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES, PhoenixDatabaseMetaData.INDEX_STATE_BYTES,
                         PIndexState.DISABLE.getSerializedBytes());
+            }
             put.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES, PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP_BYTES,
                 PLong.INSTANCE.toBytes(minTimeStamp));
             final List<Mutation> tableMetadata = Collections.<Mutation>singletonList(put);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/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 0d6d881..5a61220 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
@@ -247,7 +247,6 @@ public abstract class BaseResultIterators extends ExplainTable implements Result
                         new DistinctPrefixFilter(plan.getTableRef().getTable().getRowKeySchema(),
                                 cols));
             }
-            //TODO: samarth add condition to not do position based look ups in case of joins so that we won't need to do the hacky check inside co-processors.
             if (setMinMaxQualifiersOnScan(table)) {
                 Pair<Integer, Integer> minMaxQualifiers = getMinMaxQualifiers(scan, context);
                 if (minMaxQualifiers != null) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/phoenix-core/src/main/java/org/apache/phoenix/iterate/RegionScannerResultIterator.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/RegionScannerResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/RegionScannerResultIterator.java
index 531bbe7..816b78c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/RegionScannerResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/RegionScannerResultIterator.java
@@ -38,9 +38,9 @@ public class RegionScannerResultIterator extends BaseResultIterator {
     private final Pair<Integer, Integer> minMaxQualifiers;
     private final boolean useQualifierAsIndex;
     
-    public RegionScannerResultIterator(RegionScanner scanner, Pair<Integer, Integer> minMaxQualifiers, boolean isJoin) {
+    public RegionScannerResultIterator(RegionScanner scanner, Pair<Integer, Integer> minMaxQualifiers) {
         this.scanner = scanner;
-        this.useQualifierAsIndex = ScanUtil.useQualifierAsIndex(minMaxQualifiers, isJoin);
+        this.useQualifierAsIndex = ScanUtil.useQualifierAsIndex(minMaxQualifiers);
         this.minMaxQualifiers = minMaxQualifiers;
     }
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/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 1f2f1cc..dce6142 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
@@ -151,7 +151,6 @@ import org.apache.phoenix.execute.MutationState;
 import org.apache.phoenix.expression.Determinism;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.RowKeyColumnExpression;
-import org.apache.phoenix.hbase.index.covered.update.ColumnReference;
 import org.apache.phoenix.index.IndexMaintainer;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
@@ -221,6 +220,7 @@ import org.apache.tephra.TxConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Strings;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Lists;
@@ -292,7 +292,7 @@ public class MetaDataClient {
                     PARENT_TENANT_ID + " " + PVarchar.INSTANCE.getSqlTypeName() + // Dynamic column for now to prevent schema change
                     ") VALUES (?, ?, ?, ?, ?, ?)";
     
-    private static final String UPDATE_ENCODED_COLUMN_COUNTER = 
+    public static final String UPDATE_ENCODED_COLUMN_COUNTER = 
             "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
             TENANT_ID + ", " + 
             TABLE_SCHEM + "," +
@@ -301,7 +301,7 @@ public class MetaDataClient {
             COLUMN_QUALIFIER_COUNTER + 
             ") VALUES (?, ?, ?, ?, ?)";
 
-    private static final String INCREMENT_SEQ_NUM =
+    public static final String INCREMENT_SEQ_NUM =
             "UPSERT INTO " + SYSTEM_CATALOG_SCHEMA + ".\"" + SYSTEM_CATALOG_TABLE + "\"( " +
                     TENANT_ID + "," +
                     TABLE_SCHEM + "," +
@@ -2045,8 +2045,6 @@ public class MetaDataClient {
                  * in the client cache. If the phoenix table already doesn't exist then the non-encoded column qualifier scheme works
                  * because we cannot control the column qualifiers that were used when populating the hbase table.
                  */
-                //TODO: samarth these checks for whether table exists need to be changed for local indexes. Hate having all of these special cases for local indexes.
-                // It is making the code unmaintainable. For local indexes, the physical table already exists.
                 byte[] tableNameBytes = SchemaUtil.getTableNameAsBytes(schemaName, tableName);
                 boolean tableExists = true;
                 try (HBaseAdmin admin = connection.getQueryServices().getAdmin()) {
@@ -2058,7 +2056,7 @@ public class MetaDataClient {
                 } catch (IOException e) {
                     throw new RuntimeException(e);
                 } catch (UnsupportedOperationException e) {
-                    //FIXME: samarth I am not sure about this.
+                    // thrown by ConnectionLessQueryServicesImpl
                 }
                 if (parent != null) {
                     storageScheme = parent.getStorageScheme();
@@ -2095,12 +2093,21 @@ public class MetaDataClient {
                 }
                 ColumnName columnDefName = colDef.getColumnDefName();
                 String colDefFamily = columnDefName.getFamilyName();
-                boolean isPkColumn = isPkColumn(pkConstraint, colDef, columnDefName); 
-                String familyName = isPkColumn ? null : (colDefFamily != null ? colDefFamily : (defaultFamilyName != null ? defaultFamilyName : DEFAULT_COLUMN_FAMILY));
-                Integer encodedCQ =  isPkColumn ? null : cqCounter.getValue(familyName);   
+                boolean isPkColumn = isPkColumn(pkConstraint, colDef, columnDefName);
+                String cqCounterFamily = null;
+                if (!isPkColumn) {
+                    if (storageScheme == StorageScheme.COLUMNS_STORED_IN_SINGLE_CELL) {
+                        // For this scheme we track column qualifier counters at the column family level.
+                        cqCounterFamily = colDefFamily != null ? colDefFamily : (defaultFamilyName != null ? defaultFamilyName : DEFAULT_COLUMN_FAMILY);
+                    } else {
+                        // For other schemes, column qualifier counters are tracked using the default column family.
+                        cqCounterFamily = defaultFamilyName != null ? defaultFamilyName : DEFAULT_COLUMN_FAMILY;
+                    }
+                }
+                Integer encodedCQ =  isPkColumn ? null : cqCounter.getValue(cqCounterFamily);   
                 PColumn column = newColumn(position++, colDef, pkConstraint, defaultFamilyName, false, encodedCQ);
-                if (cqCounter.increment(familyName)) {
-                    changedCqCounters.put(familyName, cqCounter.getValue(familyName));
+                if (cqCounter.increment(cqCounterFamily)) {
+                    changedCqCounters.put(cqCounterFamily, cqCounter.getValue(cqCounterFamily));
                 }
                 if (SchemaUtil.isPKColumn(column)) {
                     // TODO: remove this constraint?
@@ -2137,36 +2144,7 @@ public class MetaDataClient {
                 }
             }
             
-            if (EncodedColumnsUtil.usesEncodedColumnNames(storageScheme)) {
-                // Store the encoded column counter for phoenix entities that have their own hbase
-                // tables i.e. base tables and indexes.
-                String schemaNameToUse = tableType == VIEW ? viewPhysicalTable.getSchemaName().getString() : schemaName;
-                String tableNameToUse = tableType == VIEW ? viewPhysicalTable.getTableName().getString() : tableName;
-                boolean sharedIndex = tableType == PTableType.INDEX && (indexType == IndexType.LOCAL || parent.getType() == PTableType.VIEW);
-                // For local indexes and indexes on views, pass on the the tenant id since all their meta-data rows have
-                // tenant ids in there.
-                String tenantIdToUse = connection.getTenantId() != null && sharedIndex ? connection.getTenantId().getString() : null;
-                // 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.
-                for (Entry<String, Integer> entry : changedCqCounters.entrySet()) {
-                    try (PreparedStatement linkStatement = connection.prepareStatement(UPDATE_ENCODED_COLUMN_COUNTER)) {
-                        linkStatement.setString(1, tenantIdToUse);
-                        linkStatement.setString(2, schemaNameToUse);
-                        linkStatement.setString(3, tableNameToUse);
-                        linkStatement.setString(4, entry.getKey());
-                        linkStatement.setInt(5, entry.getValue());
-                        linkStatement.execute();
-                    }
-                }
-                if (tableType == VIEW && !changedCqCounters.isEmpty()) { //TODO: samarth think about shared indexes
-                    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) {
@@ -2259,6 +2237,42 @@ public class MetaDataClient {
                         Boolean.TRUE.equals(disableWAL), false, false, null, null, indexType, true, false, 0, 0L, isNamespaceMapped, autoPartitionSeq, isAppendOnlySchema, StorageScheme.NON_ENCODED_COLUMN_NAMES, PTable.EncodedCQCounter.NULL_COUNTER);
                 connection.addTable(table, MetaDataProtocol.MIN_TABLE_TIMESTAMP);
             }
+            
+            // Update column qualifier counters
+            if (EncodedColumnsUtil.usesEncodedColumnNames(storageScheme)) {
+                // Store the encoded column counter for phoenix entities that have their own hbase
+                // tables i.e. base tables and indexes.
+                String schemaNameToUse = tableType == VIEW ? viewPhysicalTable.getSchemaName().getString() : schemaName;
+                String tableNameToUse = tableType == VIEW ? viewPhysicalTable.getTableName().getString() : tableName;
+                boolean sharedIndex = tableType == PTableType.INDEX && (indexType == IndexType.LOCAL || parent.getType() == PTableType.VIEW);
+                // For local indexes and indexes on views, pass on the the tenant id since all their meta-data rows have
+                // tenant ids in there.
+                String tenantIdToUse = connection.getTenantId() != null && sharedIndex ? connection.getTenantId().getString() : null;
+                // 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.
+                for (Entry<String, Integer> entry : changedCqCounters.entrySet()) {
+                    try (PreparedStatement linkStatement = connection.prepareStatement(UPDATE_ENCODED_COLUMN_COUNTER)) {
+                        linkStatement.setString(1, tenantIdToUse);
+                        linkStatement.setString(2, schemaNameToUse);
+                        linkStatement.setString(3, tableNameToUse);
+                        linkStatement.setString(4, entry.getKey());
+                        linkStatement.setInt(5, entry.getValue());
+                        linkStatement.execute();
+                    }
+                }
+                if (tableType == VIEW && !changedCqCounters.isEmpty()) { //TODO: samarth think about shared indexes
+                    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();
+                }
+                if (connection.getMutationState().toMutations(timestamp).hasNext()) {
+                    tableMetaData.addAll(connection.getMutationState().toMutations(timestamp).next().getSecond());
+                    connection.rollback();
+                }
+            }
 
             short nextKeySeq = 0;
 
@@ -2390,7 +2404,7 @@ public class MetaDataClient {
              * 3) parent table header row
              */
             Collections.reverse(tableMetaData);
-
+            
 			if (indexType != IndexType.LOCAL) {
                 splits = SchemaUtil.processSplits(splits, pkColumns, saltBucketNum, connection.getQueryServices().getProps().getBoolean(
                         QueryServices.FORCE_ROW_KEY_ORDER_ATTRIB, QueryServicesOptions.DEFAULT_FORCE_ROW_KEY_ORDER));
@@ -2488,10 +2502,6 @@ public class MetaDataClient {
         return colDef.isPK() || (pkConstraint != null && pkConstraint.getColumnWithSortOrder(columnDefName) != null);
     }
     
-    private static boolean incrementEncodedCQCounter(StorageScheme storageScheme, ColumnDef colDef) {
-        return storageScheme != StorageScheme.NON_ENCODED_COLUMN_NAMES && !colDef.isPK();
-    }
-
     /**
      * A table can be a parent table to tenant-specific tables if all of the following conditions are true:
      * <p>
@@ -3082,12 +3092,22 @@ public class MetaDataClient {
                             if (!colDef.isPK()) {
                                 String colDefFamily = colDef.getColumnDefName().getFamilyName();
                                 //FIXME: samarth Think about local indexes. They have a different column family
-                                String familyName = (colDefFamily != null ? colDefFamily : (tableForCQCounters
-                                        .getDefaultFamilyName() != null ? tableForCQCounters.getDefaultFamilyName()
-                                        .getString() : DEFAULT_COLUMN_FAMILY));
-                                encodedCQ = cqCounterToUse.getValue(familyName);   
+                                String familyName = null;
+                                StorageScheme storageScheme = table.getStorageScheme();
+                                String defaultColumnFamily = tableForCQCounters.getDefaultFamilyName() != null && !Strings.isNullOrEmpty(tableForCQCounters.getDefaultFamilyName().getString()) ? 
+                                        tableForCQCounters.getDefaultFamilyName().getString() : DEFAULT_COLUMN_FAMILY;
+                                    if (table.getType() == PTableType.INDEX && table.getIndexType() == IndexType.LOCAL) {
+                                        defaultColumnFamily = QueryConstants.LOCAL_INDEX_COLUMN_FAMILY_PREFIX + defaultColumnFamily;
+                                    }
+                                if (storageScheme == StorageScheme.COLUMNS_STORED_IN_SINGLE_CELL) {
+                                    familyName = colDefFamily != null ? colDefFamily : defaultColumnFamily;
+                                } else {
+                                    familyName = defaultColumnFamily;
+                                }
+                                encodedCQ = cqCounterToUse.getValue(familyName);
                                 if (cqCounterToUse.increment(familyName)) {
-                                    changedCqCounters.put(familyName, cqCounterToUse.getValue(familyName));
+                                    changedCqCounters.put(familyName,
+                                        cqCounterToUse.getValue(familyName));
                                 }
                             }
                             PColumn column = newColumn(position++, colDef, PrimaryKeyConstraint.EMPTY, table.getDefaultFamilyName() == null ? null : table.getDefaultFamilyName().getString(), true, encodedCQ);
@@ -3178,13 +3198,9 @@ public class MetaDataClient {
                 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 (!changedCqCounters.isEmpty()) {
                     PreparedStatement linkStatement;
-                    //TODO: samarth i don't think we need the shared index check here.
-                    //if (!sharedIndex) {
                         linkStatement = connection.prepareStatement(UPDATE_ENCODED_COLUMN_COUNTER);
-                        
                         for (Entry<String, Integer> entry : changedCqCounters.entrySet()) {    
                             linkStatement.setString(1, tenantIdToUse);
                             linkStatement.setString(2, tableForCQCounters.getSchemaName().getString());
@@ -3194,7 +3210,6 @@ public class MetaDataClient {
                             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) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/EncodedColumnQualiferCellsList.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/EncodedColumnQualiferCellsList.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/EncodedColumnQualiferCellsList.java
index 4caabbb..40f8168 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/EncodedColumnQualiferCellsList.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/EncodedColumnQualiferCellsList.java
@@ -79,7 +79,7 @@ public class EncodedColumnQualiferCellsList implements List<Cell> {
     public int size() {
         return numNonNullElements;
     }
-
+    
     @Override
     public boolean isEmpty() {
         return numNonNullElements == 0;
@@ -132,8 +132,10 @@ public class EncodedColumnQualiferCellsList implements List<Cell> {
         int columnQualifier = PInteger.INSTANCE.getCodec().decodeInt(e.getQualifierArray(), e.getQualifierOffset(), SortOrder.ASC);
         checkQualifierRange(columnQualifier);
         int idx = getArrayIndex(columnQualifier);
+        if (array[idx] == null) {
+            numNonNullElements++;
+        }
         array[idx] = e;
-        numNonNullElements++;
         if (firstNonNullElementIdx == -1) {
             firstNonNullElementIdx = idx;
         }
@@ -228,30 +230,31 @@ public class EncodedColumnQualiferCellsList implements List<Cell> {
     public Cell get(int index) {
         rangeCheck(index);
         int numNonNullElementsFound = 0;
-        int i = 0;
-        for (; i < array.length; i++) {
+        for (int i = 0; i < array.length; i++) {
             if (array[i] != null) {
                 numNonNullElementsFound++;
-                if (numNonNullElementsFound - 1 == index) {
-                    break;
+                if (numNonNullElementsFound == index + 1) {
+                    return array[i];
                 }
             }
-            
         }
-        return (numNonNullElementsFound - 1) != index ? null : array[i];
+        throw new IllegalStateException("There was no element present in the list at index " + index + " even though number of elements in the list are " + size());
     }
 
     @Override
     public Cell set(int index, Cell e) {
+        // index is ignored since every column qualifier has a specific place in this list which is not dictated by index.
         int columnQualifier = PInteger.INSTANCE.getCodec().decodeInt(e.getQualifierArray(), e.getQualifierOffset(), SortOrder.ASC);
         checkQualifierRange(columnQualifier);
         int idx = getArrayIndex(columnQualifier);
-        if (idx != index) {
-            throw new IllegalArgumentException("Attempt made to add cell with encoded column qualifier " + columnQualifier +  "  to the encodedcolumnqualifier list at index " + index);
-        }
+//        if (idx != index) {
+//            throw new IllegalArgumentException("Attempt made to add cell with encoded column qualifier " + columnQualifier +  "  at index " + index);
+//        }
         Cell prev = array[idx];
         array[idx] = e;
-        numNonNullElements++;
+        if (prev == null) {
+            numNonNullElements++;
+        }
         if (firstNonNullElementIdx == -1) {
             firstNonNullElementIdx = idx;
         }
@@ -367,28 +370,31 @@ public class EncodedColumnQualiferCellsList implements List<Cell> {
     private class Itr implements Iterator<Cell> {
         private Cell current;
         private int currentIdx = 0;
-        private boolean exhausted = false;
+        private int modCount = 0;
+        private int expectedModCount = 0;
         private Itr() {
             moveToNextNonNullCell(true);
         }
 
         @Override
         public boolean hasNext() {
-            return !exhausted;
+            return current != null;
         }
 
         @Override
         public Cell next() {
-            if (exhausted) {
-                return null;
+            if (!hasNext()) {
+                throw new NoSuchElementException();
             }
             Cell next = current;
             moveToNextNonNullCell(false);
+            modCount++;
             return next;
         }
 
         @Override
         public void remove() {
+            
             throwUnsupportedOperationException();            
         }
 
@@ -399,9 +405,10 @@ public class EncodedColumnQualiferCellsList implements List<Cell> {
             }
             if (i < array.length) {
                 currentIdx = i;
+                current = array[currentIdx];
             } else {
                 currentIdx = -1;
-                exhausted = true;
+                current = null;
             }
         }
 
@@ -412,6 +419,7 @@ public class EncodedColumnQualiferCellsList implements List<Cell> {
         private int nextIndex;
         private Cell previous;
         private Cell next;
+        private int currentIndex = -1;
         
         private ListItr() {
             movePointersForward(true);
@@ -447,7 +455,7 @@ public class EncodedColumnQualiferCellsList implements List<Cell> {
             if (toReturn == null) {
                 throw new NoSuchElementException();
             }
-            movePointersBackward(false);
+            movePointersBackward();
             return toReturn;
         }
 
@@ -460,11 +468,13 @@ public class EncodedColumnQualiferCellsList implements List<Cell> {
         public int previousIndex() {
             return previousIndex;
         }
-
+        
+        //TODO: samarth implement all of these operations
         @Override
         public void remove() {
-            // TODO Auto-generated method stub
-            
+            if (currentIndex == -1) {
+                //throw 
+            }
         }
         
         // TODO: samarth this is one of these ouch methods that can make our implementation frgaile.
@@ -500,10 +510,25 @@ public class EncodedColumnQualiferCellsList implements List<Cell> {
                 nextIndex = -1;
                 next = null;
             }
+            if (!init) {
+                currentIndex = nextIndex;
+            }
         }
         
-        private void movePointersBackward(boolean init) {
-            int i = init ? 0 : previousIndex;
+        private void movePointersBackward() {
+            nextIndex = previousIndex;
+            next = previous;
+            int i = previousIndex - 1;
+            for (; i >= 0; i--) {
+                if (array[i] != null) {
+                    previousIndex = i;
+                    previous = array[i];
+                }
+            }
+            if (i < 0) {
+                previous = null; 
+            }
+            currentIndex = previousIndex;
         }
         
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedMultiKeyValueTuple.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedMultiKeyValueTuple.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedMultiKeyValueTuple.java
index 0c6ae22..cb087b7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedMultiKeyValueTuple.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedMultiKeyValueTuple.java
@@ -35,14 +35,14 @@ public class PositionBasedMultiKeyValueTuple extends BaseTuple {
     public PositionBasedMultiKeyValueTuple() {}
     
     public PositionBasedMultiKeyValueTuple(List<Cell> values) {
-        checkArgument(values instanceof EncodedColumnQualiferCellsList, "PositionBasedMultiKeyValueTuple only works with lists of type BoundedSkipNullCellsList");
+        checkArgument(values instanceof EncodedColumnQualiferCellsList, "PositionBasedMultiKeyValueTuple only works with lists of type EncodedColumnQualiferCellsList");
         this.values = (EncodedColumnQualiferCellsList)values;
     }
     
     /** Caller must not modify the list that is passed here */
     @Override
     public void setKeyValues(List<Cell> values) {
-        checkArgument(values instanceof EncodedColumnQualiferCellsList, "PositionBasedMultiKeyValueTuple only works with lists of type BoundedSkipNullCellsList");
+        checkArgument(values instanceof EncodedColumnQualiferCellsList, "PositionBasedMultiKeyValueTuple only works with lists of type EncodedColumnQualiferCellsList");
         this.values = (EncodedColumnQualiferCellsList)values;
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedResultTuple.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedResultTuple.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedResultTuple.java
index 8f4a846..c885da3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedResultTuple.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedResultTuple.java
@@ -33,6 +33,7 @@ public class PositionBasedResultTuple extends BaseTuple {
     //TODO: samarth see if we can get rid of this constructor altogether.
     public PositionBasedResultTuple(List<Cell> list) {
         checkArgument(list instanceof EncodedColumnQualiferCellsList, "Invalid list type");
+        //checkArgument(list.size() > 0, "Empty list");
         this.cells = (EncodedColumnQualiferCellsList)list;
     }
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/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
index 48ec277..aa6bfa1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java
@@ -21,7 +21,9 @@ import static com.google.common.base.Preconditions.checkArgument;
 
 import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.util.Pair;
+import org.apache.phoenix.hbase.index.covered.update.ColumnReference;
 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.PTable.StorageScheme;
@@ -53,12 +55,13 @@ public class EncodedColumnsUtil {
             // (with the qualifier name being same as the family name), just project the column family here
             // so that we can calculate estimatedByteSize correctly in ProjectionCompiler 
     		scan.addFamily(column.getFamilyName().getBytes());
+    		//scan.addColumn(column.getFamilyName().getBytes(), column.getFamilyName().getBytes());
         }
         else {
         	scan.addColumn(column.getFamilyName().getBytes(), EncodedColumnsUtil.getColumnQualifier(column, 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
@@ -90,5 +93,5 @@ public class EncodedColumnsUtil {
     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/c1958d07/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 2635c62..21e5217 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
@@ -89,7 +89,9 @@ 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.PTable.StorageScheme;
 import org.apache.phoenix.schema.ValueSchema.Field;
+import org.apache.phoenix.schema.tuple.PositionBasedResultTuple;
 import org.apache.phoenix.schema.tuple.ResultTuple;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PBinary;
@@ -282,8 +284,6 @@ public class IndexUtil {
                  * updating an existing row.
                  */
                 if (dataMutation instanceof Put) {
-                    // TODO: is this more efficient than looking in our mutation map
-                    // using the key plus finding the PColumn?
                     ValueGetter valueGetter = new ValueGetter() {
                     	
                     	@Override
@@ -300,19 +300,18 @@ public class IndexUtil {
                             }
                             byte[] family = ref.getFamily();
                             byte[] qualifier = ref.getQualifier();
-                            RowMutationState rowMutationState = valuesMap.get(ptr);
-                            PColumn column = null;
-                            try {
-                                column = table.getColumnFamily(family).getPColumnForColumnQualifier(qualifier);
-                            } catch (ColumnNotFoundException e) {
-                            } catch (ColumnFamilyNotFoundException e) {
+                            Map<byte [], List<Cell>> familyMap = dataMutation.getFamilyCellMap();
+                            List<Cell> kvs = familyMap.get(family);
+                            if (kvs == null) {
+                                return null;
                             }
-                            if (rowMutationState!=null && column!=null) {
-                                byte[] value = rowMutationState.getColumnValues().get(column);
-                                ImmutableBytesPtr ptr = new ImmutableBytesPtr();
-                                ptr.set(value==null ? ByteUtil.EMPTY_BYTE_ARRAY : value);
-                                SchemaUtil.padData(table.getName().getString(), column, ptr);
-                                return ptr;
+                            for (Cell kv : kvs) {
+                                if (Bytes.compareTo(kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength(), family, 0, family.length) == 0 &&
+                                    Bytes.compareTo(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength(), qualifier, 0, qualifier.length) == 0) {
+                                  ImmutableBytesPtr ptr = new ImmutableBytesPtr();
+                                  kvBuilder.getValueAsPtr(kv, ptr);
+                                  return ptr;
+                                }
                             }
                             return null;
                         }
@@ -325,7 +324,7 @@ public class IndexUtil {
                         regionStartKey = tableRegionLocation.getRegionInfo().getStartKey();
                         regionEndkey = tableRegionLocation.getRegionInfo().getEndKey();
                     }
-                    indexMutations.add(maintainer.buildUpdateMutation(kvBuilder, valueGetter, ptr, ts, regionStartKey, regionEndkey, true));
+                    indexMutations.add(maintainer.buildUpdateMutation(kvBuilder, valueGetter, ptr, ts, regionStartKey, regionEndkey));
                 }
             }
             return indexMutations;
@@ -499,8 +498,13 @@ public class IndexUtil {
             ptr.set(indexRowKey, firstCell.getRowOffset() + offset, firstCell.getRowLength() - offset);
             byte[] dataRowKey = indexMaintainer.buildDataRowKey(ptr, viewConstants);
             Get get = new Get(dataRowKey);
+            boolean colsStoredInSingleCell = indexMaintainer.getIndexStorageScheme() == StorageScheme.COLUMNS_STORED_IN_SINGLE_CELL;
             for (int i = 0; i < dataColumns.length; i++) {
-                get.addColumn(dataColumns[i].getFamily(), dataColumns[i].getQualifier());
+                if (colsStoredInSingleCell) {
+                    get.addFamily(dataColumns[i].getFamily());
+                } else {
+                    get.addColumn(dataColumns[i].getFamily(), dataColumns[i].getQualifier());
+                }
             }
             Result joinResult = null;
             if (dataRegion != null) {
@@ -517,9 +521,9 @@ public class IndexUtil {
                     if (table != null) table.close();
                 }
             }
-            
+            // at this point join result has data from the data table. We now need to take this result and
+            // add it to the cells that we are returning. 
             // TODO: handle null case (but shouldn't happen)
-            //TODO: samarth confirm if this is the right thing to do here i.e. pass false for look up.
             Tuple joinTuple = new ResultTuple(joinResult);
             // This will create a byte[] that captures all of the values from the data table
             byte[] value =
@@ -530,131 +534,131 @@ public class IndexUtil {
                         VALUE_COLUMN_QUALIFIER, firstCell.getTimestamp(), value, 0, value.length);
             result.add(keyValue);
         }
+        
+        //FIXME: samarth switch this to using a list iterator since result.get(i) is inefficient for our PositionBasedList
         for (int i = 0; i < result.size(); i++) {
             final Cell cell = result.get(i);
-            if (cell != null) {
-                // TODO: Create DelegateCell class instead
-                Cell newCell = new Cell() {
+            // TODO: Create DelegateCell class instead
+            Cell newCell = new Cell() {
 
-                    @Override
-                    public byte[] getRowArray() {
-                        return cell.getRowArray();
-                    }
+                @Override
+                public byte[] getRowArray() {
+                    return cell.getRowArray();
+                }
 
-                    @Override
-                    public int getRowOffset() {
-                        return cell.getRowOffset() + offset;
-                    }
+                @Override
+                public int getRowOffset() {
+                    return cell.getRowOffset() + offset;
+                }
 
-                    @Override
-                    public short getRowLength() {
-                        return (short)(cell.getRowLength() - offset);
-                    }
+                @Override
+                public short getRowLength() {
+                    return (short)(cell.getRowLength() - offset);
+                }
 
-                    @Override
-                    public byte[] getFamilyArray() {
-                        return cell.getFamilyArray();
-                    }
+                @Override
+                public byte[] getFamilyArray() {
+                    return cell.getFamilyArray();
+                }
 
-                    @Override
-                    public int getFamilyOffset() {
-                        return cell.getFamilyOffset();
-                    }
+                @Override
+                public int getFamilyOffset() {
+                    return cell.getFamilyOffset();
+                }
 
-                    @Override
-                    public byte getFamilyLength() {
-                        return cell.getFamilyLength();
-                    }
+                @Override
+                public byte getFamilyLength() {
+                    return cell.getFamilyLength();
+                }
 
-                    @Override
-                    public byte[] getQualifierArray() {
-                        return cell.getQualifierArray();
-                    }
+                @Override
+                public byte[] getQualifierArray() {
+                    return cell.getQualifierArray();
+                }
 
-                    @Override
-                    public int getQualifierOffset() {
-                        return cell.getQualifierOffset();
-                    }
+                @Override
+                public int getQualifierOffset() {
+                    return cell.getQualifierOffset();
+                }
 
-                    @Override
-                    public int getQualifierLength() {
-                        return cell.getQualifierLength();
-                    }
+                @Override
+                public int getQualifierLength() {
+                    return cell.getQualifierLength();
+                }
 
-                    @Override
-                    public long getTimestamp() {
-                        return cell.getTimestamp();
-                    }
+                @Override
+                public long getTimestamp() {
+                    return cell.getTimestamp();
+                }
 
-                    @Override
-                    public byte getTypeByte() {
-                        return cell.getTypeByte();
-                    }
+                @Override
+                public byte getTypeByte() {
+                    return cell.getTypeByte();
+                }
 
-                    @Override
-                    public long getMvccVersion() {
-                        return cell.getMvccVersion();
-                    }
+                @Override
+                public long getMvccVersion() {
+                    return cell.getMvccVersion();
+                }
 
-                    @Override
-                    public byte[] getValueArray() {
-                        return cell.getValueArray();
-                    }
+                @Override
+                public byte[] getValueArray() {
+                    return cell.getValueArray();
+                }
 
-                    @Override
-                    public int getValueOffset() {
-                        return cell.getValueOffset();
-                    }
+                @Override
+                public int getValueOffset() {
+                    return cell.getValueOffset();
+                }
 
-                    @Override
-                    public int getValueLength() {
-                        return cell.getValueLength();
-                    }
+                @Override
+                public int getValueLength() {
+                    return cell.getValueLength();
+                }
 
-                    @Override
-                    public byte[] getTagsArray() {
-                        return cell.getTagsArray();
-                    }
+                @Override
+                public byte[] getTagsArray() {
+                    return cell.getTagsArray();
+                }
 
-                    @Override
-                    public int getTagsOffset() {
-                        return cell.getTagsOffset();
-                    }
+                @Override
+                public int getTagsOffset() {
+                    return cell.getTagsOffset();
+                }
 
-                    @Override
-                    public short getTagsLength() {
-                        return cell.getTagsLength();
-                    }
+                @Override
+                public short getTagsLength() {
+                    return cell.getTagsLength();
+                }
 
-                    @Override
-                    public byte[] getValue() {
-                        return cell.getValue();
-                    }
+                @Override
+                public byte[] getValue() {
+                    return cell.getValue();
+                }
 
-                    @Override
-                    public byte[] getFamily() {
-                        return cell.getFamily();
-                    }
+                @Override
+                public byte[] getFamily() {
+                    return cell.getFamily();
+                }
 
-                    @Override
-                    public byte[] getQualifier() {
-                        return cell.getQualifier();
-                    }
+                @Override
+                public byte[] getQualifier() {
+                    return cell.getQualifier();
+                }
 
-                    @Override
-                    public byte[] getRow() {
-                        return cell.getRow();
-                    }
+                @Override
+                public byte[] getRow() {
+                    return cell.getRow();
+                }
 
-                    @Override
-                    @Deprecated
-                    public int getTagsLengthUnsigned() {
-                        return cell.getTagsLengthUnsigned();
-                    }
-                };
-                // Wrap cell in cell that offsets row key
-                result.set(i, newCell);
-            }
+                @Override
+                @Deprecated
+                public int getTagsLengthUnsigned() {
+                    return cell.getTagsLengthUnsigned();
+                }
+            };
+            // Wrap cell in cell that offsets row key
+            result.set(i, newCell);
         }
     }
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/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 c98aab2..534aaae 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
@@ -603,4 +603,10 @@ public class MetaDataUtil {
     public static boolean isHTableProperty(String propName) {
         return !isHColumnProperty(propName) && !TableProperty.isPhoenixTableProperty(propName);
     }
+    
+    public static final byte[] getPhysicalTableRowForView(PTable view) {
+        byte[] physicalTableSchemaName = Bytes.toBytes(SchemaUtil.getSchemaNameFromFullName(view.getPhysicalName().getString()));
+        byte[] physicalTableName = Bytes.toBytes(SchemaUtil.getTableNameFromFullName(view.getPhysicalName().getString()));
+        return SchemaUtil.getTableKey(ByteUtil.EMPTY_BYTE_ARRAY, physicalTableSchemaName, physicalTableName);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/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 70d7db7..b3cc4a3 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
@@ -915,8 +915,8 @@ public class ScanUtil {
         return new Pair<>(minQ, maxQ);
     }
     
-    public static boolean useQualifierAsIndex(Pair<Integer, Integer> minMaxQualifiers, boolean isJoin) {
-        return minMaxQualifiers != null;// && isJoin;
+    public static boolean useQualifierAsIndex(Pair<Integer, Integer> minMaxQualifiers) {
+        return minMaxQualifiers != null;
     }
     
     public static boolean setMinMaxQualifiersOnScan(PTable table) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/c1958d07/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 abcf0c8..5887e5b 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
@@ -141,7 +141,7 @@ public class IndexMaintainerTest  extends BaseConnectionlessQueryTest {
             Mutation indexMutation = indexMutations.get(0);
             ImmutableBytesWritable indexKeyPtr = new ImmutableBytesWritable(indexMutation.getRow());
             ptr.set(rowKeyPtr.get(), rowKeyPtr.getOffset(), rowKeyPtr.getLength());
-            byte[] mutablelndexRowKey = im1.buildRowKey(valueGetter, ptr, null, null, false);
+            byte[] mutablelndexRowKey = im1.buildRowKey(valueGetter, ptr, null, null);
             byte[] immutableIndexRowKey = indexKeyPtr.copyBytes();
             assertArrayEquals(immutableIndexRowKey, mutablelndexRowKey);
             for (ColumnReference ref : im1.getCoveredColumns()) {