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/11/04 22:14:09 UTC

[42/50] [abbrv] phoenix git commit: Fail-fast iterators for EncodedColumnQualifierCellsList. Use list iterators instead of get(index) for navigating lists. Use HBase bytes utility for encoded column names. Fix test failures for immutable tables and index

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ede568e9/phoenix-core/src/test/java/org/apache/phoenix/query/EncodedColumnQualifierCellsListTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/EncodedColumnQualifierCellsListTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/EncodedColumnQualifierCellsListTest.java
new file mode 100644
index 0000000..564e75e
--- /dev/null
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/EncodedColumnQualifierCellsListTest.java
@@ -0,0 +1,608 @@
+/*
+ * 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.query;
+
+import static org.apache.phoenix.util.EncodedColumnsUtil.getEncodedColumnQualifier;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.schema.tuple.EncodedColumnQualiferCellsList;
+import org.junit.Test;
+
+public class EncodedColumnQualifierCellsListTest {
+    
+    private static final byte[] row = Bytes.toBytes("row");
+    private static final byte[] cf = Bytes.toBytes("cf");
+
+    
+    @Test
+    public void testIterator() {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] cells = new Cell[7];
+        int i = 0;
+        populateListAndArray(list, cells);
+        Iterator itr = list.iterator();
+        assertTrue(itr.hasNext());
+        
+        // test itr.next()
+        i = 0;
+        while (itr.hasNext()) {
+            assertEquals(cells[i++], itr.next());
+        }
+        
+        assertEquals(7, list.size());
+        
+        // test itr.remove()
+        itr = list.iterator();
+        i = 0;
+        int numRemoved = 0;
+        try {
+            itr.remove();
+            fail("Remove not allowed till next() is called");
+        } catch (IllegalStateException expected) {}
+        
+        while (itr.hasNext()) {
+            assertEquals(cells[i++], itr.next());
+            itr.remove();
+            numRemoved++;
+        }
+        assertEquals("Number of elements removed should have been the size of the list", 7, numRemoved);
+    }
+    
+    @Test
+    public void testSize() {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        assertEquals(0, list.size());
+        
+        populateList(list);
+        
+        assertEquals(7, list.size());
+        int originalSize = list.size();
+        
+        Iterator itr = list.iterator();
+        while (itr.hasNext()) {
+            itr.next();
+            itr.remove();
+            assertEquals(--originalSize, list.size());
+        }
+    }
+    
+    @Test
+    public void testIsEmpty() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        assertTrue(list.isEmpty());
+        populateList(list);
+        assertFalse(list.isEmpty());
+        Iterator itr = list.iterator();
+        while (itr.hasNext()) {
+            itr.next();
+            itr.remove();
+            if (itr.hasNext()) {
+                assertFalse(list.isEmpty());
+            }
+        }
+        assertTrue(list.isEmpty());
+    }
+    
+    @Test
+    public void testContains() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] cells = new Cell[7];
+        populateListAndArray(list, cells);
+        
+        for (Cell c : cells) {
+            assertTrue(list.contains(c));
+        }
+        assertFalse(list.contains(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(13))));
+    }
+    
+    @Test
+    public void testToArrayWithParam() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] cells = new Cell[7];
+        populateListAndArray(list, cells);
+        Cell[] array = list.toArray(new Cell[0]);
+        assertTrue(Arrays.equals(cells, array));
+    }
+    
+    @Test
+    public void testToArrayWithoutParam() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] cells = new Cell[7];
+        populateListAndArray(list, cells);
+        Object[] array = list.toArray();
+        assertTrue(Arrays.equals(cells, array));
+    }
+    
+    @Test
+    public void testRemove() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] cells = new Cell[7];
+        populateListAndArray(list, cells);
+        assertTrue(list.remove(cells[0]));
+        assertEquals(6, list.size());
+        assertTrue(list.remove(cells[6]));
+        assertEquals(5, list.size());
+        assertTrue(list.remove(cells[3]));
+        assertEquals(4, list.size());
+        assertFalse(list.remove(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(13))));
+        assertEquals(4, list.size());
+    }
+    
+    @Test
+    public void testContainsAll() throws Exception {
+        EncodedColumnQualiferCellsList list1 = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list1);
+        EncodedColumnQualiferCellsList list2 = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list2);
+        assertTrue(list1.containsAll(list2));
+        list2.remove(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(11)));
+        assertTrue(list1.containsAll(list2));
+        assertFalse(list2.containsAll(list1));
+        list2.add(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(13)));
+        assertFalse(list1.containsAll(list2));
+        assertFalse(list2.containsAll(list1));
+        List<Cell> arrayList = new ArrayList<>();
+        populateList(arrayList);
+        assertTrue(list1.containsAll(arrayList));
+    }
+    
+    @Test
+    public void testAddAll() throws Exception {
+        EncodedColumnQualiferCellsList list1 = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list1);
+        EncodedColumnQualiferCellsList list2 = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list2);
+        /* 
+         * Note that we don't care about equality of the element being added with the element already
+         * present at the index.
+         */
+        assertTrue(list1.addAll(list2));
+    }
+    
+    @Test
+    public void testAddAllAtIndexFails() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list);
+        try {
+            list.addAll(0, new ArrayList<Cell>());
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+    
+    @Test
+    public void testRemoveAll() throws Exception {
+        EncodedColumnQualiferCellsList list1 = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list1);
+        ArrayList<Cell> list2 = new ArrayList<>();
+        populateList(list2);
+        assertTrue(list1.removeAll(list2));
+        assertTrue(list1.isEmpty());
+        assertFalse(list2.isEmpty());
+    }
+    
+    @Test
+    public void testRetainAll() throws Exception {
+        EncodedColumnQualiferCellsList list1 = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list1);
+        EncodedColumnQualiferCellsList list2 = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list2);
+        // retainAll won't be modifying the list1 since they both have the same elements equality wise
+        assertFalse(list1.retainAll(list2));
+        list2.remove(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(12)));
+        assertTrue(list1.retainAll(list2));
+        assertEquals(list1.size(), list2.size());
+        for (Cell c : list1) {
+            assertTrue(list2.contains(c));
+        }
+    }
+    
+    @Test
+    public void testClear() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list);
+        list.clear();
+        assertTrue(list.isEmpty());
+        assertEquals(0, list.size());
+    }
+    
+    @Test
+    public void testGetIndex() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] cells = new Cell[7];
+        populateListAndArray(list, cells);
+        for (int i = 0; i < cells.length; i++) {
+            assertEquals(cells[i], list.get(i));
+        }
+    }
+    
+    @Test
+    public void testIndexOf() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] cells = new Cell[7];
+        populateListAndArray(list, cells);
+        for (int i = 0; i < cells.length; i++) {
+            assertEquals(i, list.indexOf(cells[i]));
+        }
+    }
+    
+    @Test
+    public void testLastIndexOf() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] cells = new Cell[7];
+        populateListAndArray(list, cells);
+        for (int i = 0; i < cells.length; i++) {
+            assertEquals(i, list.lastIndexOf(cells[i]));
+        }
+    }
+    
+    @Test
+    public void testListIterator() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] cells = new Cell[7];
+        int i = 0;
+        populateListAndArray(list, cells);
+        ListIterator<Cell> itr = list.listIterator();
+        assertTrue(itr.hasNext());
+        
+        // test itr.next()
+        i = 0;
+        while (itr.hasNext()) {
+            assertEquals(cells[i++], itr.next());
+        }
+        
+        assertEquals(7, list.size());
+        
+        // test itr.remove()
+        itr = list.listIterator();
+        i = 0;
+        int numRemoved = 0;
+        try {
+            itr.remove();
+            fail("Remove not allowed till next() is called");
+        } catch (IllegalStateException expected) {}
+        
+        while (itr.hasNext()) {
+            assertEquals(cells[i++], itr.next());
+            itr.remove();
+            numRemoved++;
+        }
+        assertEquals("Number of elements removed should have been the size of the list", 7, numRemoved);
+        assertTrue(list.isEmpty());
+    }
+    
+    @Test
+    public void testListIteratorSet() {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] array = new Cell[7];
+        populateListAndArray(list, array);
+        ListIterator<Cell> itr = list.listIterator();
+        // This cell is KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(12))
+        final Cell validCell = array[4];
+        // This cell is KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(14))
+        final Cell invalidCell = array[5];
+        String validCellName = "Valid Cell";
+        String invalidCellName = "Invalid Cell";
+        Cell validReplacementCell = new DelegateCell(validCell, validCellName);
+        Cell invalidReplacementCell = new DelegateCell(invalidCell, invalidCellName);
+        int i = 0;
+        while (itr.hasNext()) {
+            Cell c = itr.next();
+            if (i == 4) {
+                itr.set(validReplacementCell);
+            }
+            if (i == 6) {
+                try {
+                    itr.set(invalidReplacementCell);
+                    fail("This should have failed since " + invalidReplacementCell + " cannot be added where " + c + " is.");
+                } catch (IllegalArgumentException expected) {
+                }
+            }
+            i++;
+        }
+        itr = list.listIterator();
+        i = 0;
+        // Assert that the valid cell was added and invalid cell wasn't.
+        while (itr.hasNext()) {
+            Cell c = itr.next();
+            if (i == 4) {
+                assertEquals(validCellName, c.toString());
+            }
+            if (i == 6) {
+                assertNotEquals(invalidCellName, c.toString());
+            }
+            i++;
+        }
+    }
+    
+    @Test
+    public void testListIteratorNextAndPrevious()  throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        Cell[] array = new Cell[7];
+        populateListAndArray(list, array);
+        ListIterator<Cell> itr = list.listIterator();
+        try {
+            itr.previous();
+            fail("Call to itr.previous() should have failed since the iterator hasn't been moved forward yet");
+        } catch (NoSuchElementException expected) {
+            
+        }
+        Cell c = itr.next();
+        Cell d = itr.previous();
+        Cell e = itr.next();
+        Cell f = itr.previous();
+        assertTrue(c.equals(d) && c.equals(f) && c.equals(e));
+        itr = list.listIterator();
+        int i = 0;
+        assertEquals(array[i++], itr.next());
+        assertEquals(array[i++], itr.next()); 
+        assertEquals(array[i++], itr.next());
+        assertEquals(array[--i], itr.previous());
+        assertEquals(array[--i], itr.previous());
+        assertEquals(array[i++], itr.next());
+        
+        // move itr forward till next() is exhausted
+        while (itr.hasNext()) {
+            itr.next();
+        }
+        i = 6;
+        while (itr.hasPrevious()) {
+            assertEquals(array[i--], itr.previous());
+        }
+        assertEquals("Not all elements navigated using previous()", -1, i);
+        // now that previous is exhausted, move itr() forward till next() is exhausted
+        i = 0;
+        while (itr.hasNext()) {
+            assertEquals(array[i++], itr.next());
+        }
+        assertEquals("Not all elements navigated using next()", 7, i);
+    }
+    
+    @Test
+    public void testSetNull() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        try {
+            list.add(null);
+            fail("Adding null elements to the list is not allowed");
+        } catch (NullPointerException expected) {
+            
+        }
+    }
+    
+    @Test
+    public void testFailFastIterator() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list);
+        int i = 0;
+        Iterator<Cell> itr = list.iterator();
+        while (itr.hasNext()) {
+            i++;
+            try {
+                itr.next();
+                list.add(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(0)));
+                if (i == 2) {
+                    fail("ConcurrentModificationException should have been thrown as the list is being modified while being iterated through");
+                }
+            } catch (ConcurrentModificationException expected) {
+                assertEquals("Exception should have been thrown when getting the second element",
+                    2, i);
+                break;
+            }
+        }
+    }
+    
+    @Test
+    public void testFailFastListIterator() throws Exception {
+        EncodedColumnQualiferCellsList list = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list);
+        ListIterator<Cell> itr = list.listIterator();
+        itr.next();
+        list.add(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(0)));
+        try {
+            itr.next();
+            fail("ConcurrentModificationException should have been thrown as the list was modified without using iterator");
+        } catch (ConcurrentModificationException expected) {
+
+        }
+        list = new EncodedColumnQualiferCellsList(11, 16);
+        populateList(list);
+        itr = list.listIterator();
+        itr.next();
+        itr.next();
+        itr.remove();
+        itr.next();
+        list.remove(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(0)));
+        try {
+            itr.next();
+            fail("ConcurrentModificationException should have been thrown as the list was modified without using iterator");
+        } catch (ConcurrentModificationException expected) {
+
+        }
+    }
+    
+    private void populateListAndArray(List<Cell> list, Cell[] cells) {
+        // add elements in reserved range
+        list.add(cells[0] = KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(0)));
+        list.add(cells[1] = KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(5)));
+        list.add(cells[2] = KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(10)));
+
+        // add elements in qualifier range
+        list.add(cells[6] = KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(16)));
+        list.add(cells[4] = KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(12)));
+        list.add(cells[5] = KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(14)));
+        list.add(cells[3] = KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(11)));
+    }
+
+    private void populateList(List<Cell> list) {
+        // add elements in reserved range
+        list.add(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(0)));
+        list.add(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(5)));
+        list.add(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(10)));
+
+        // add elements in qualifier range
+        list.add(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(16)));
+        list.add(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(12)));
+        list.add(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(14)));
+        list.add(KeyValue.createFirstOnRow(row, cf, getEncodedColumnQualifier(11)));
+    }
+    
+    private class DelegateCell implements Cell {
+        private final Cell delegate;
+        private final String name;
+        public DelegateCell(Cell delegate, String name) {
+            this.delegate = delegate;
+            this.name = name;
+        }
+
+        @Override
+        public int getValueOffset() {
+            return delegate.getValueOffset();
+        }
+
+        @Override
+        public int getValueLength() {
+            return delegate.getValueLength();
+        }
+
+        @Override
+        public byte[] getValueArray() {
+            return delegate.getValueArray();
+        }
+
+        @Override
+        public byte[] getValue() {
+            return delegate.getValue();
+        }
+
+        @Override
+        public byte getTypeByte() {
+            return delegate.getTypeByte();
+        }
+
+        @Override
+        public long getTimestamp() {
+            return delegate.getTimestamp();
+        }
+
+        @Override
+        public int getTagsOffset() {
+            return delegate.getTagsOffset();
+        }
+
+        @Override
+        public int getTagsLengthUnsigned() {
+            return delegate.getTagsLengthUnsigned();
+        }
+
+        @Override
+        public short getTagsLength() {
+            return delegate.getTagsLength();
+        }
+
+        @Override
+        public byte[] getTagsArray() {
+            return delegate.getTagsArray();
+        }
+
+        @Override
+        public int getRowOffset() {
+            return delegate.getRowOffset();
+        }
+
+        @Override
+        public short getRowLength() {
+            return delegate.getRowLength();
+        }
+
+        @Override
+        public byte[] getRowArray() {
+            return delegate.getRowArray();
+        }
+
+        @Override
+        public byte[] getRow() {
+            return delegate.getRow();
+        }
+
+        @Override
+        public int getQualifierOffset() {
+            return delegate.getQualifierOffset();
+        }
+
+        @Override
+        public int getQualifierLength() {
+            return delegate.getQualifierLength();
+        }
+
+        @Override
+        public byte[] getQualifierArray() {
+            return delegate.getQualifierArray();
+        }
+
+        @Override
+        public byte[] getQualifier() {
+            return delegate.getQualifier();
+        }
+
+        @Override
+        public long getMvccVersion() {
+            return delegate.getMvccVersion();
+        }
+
+        @Override
+        public int getFamilyOffset() {
+            return delegate.getFamilyOffset();
+        }
+
+        @Override
+        public byte getFamilyLength() {
+            return delegate.getFamilyLength();
+        }
+
+        @Override
+        public byte[] getFamilyArray() {
+            return delegate.getFamilyArray();
+        }
+
+        @Override
+        public byte[] getFamily() {
+            return delegate.getFamily();
+        }
+        
+        @Override
+        public String toString() {
+            return name;
+        }
+
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ede568e9/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 5feedb1..5409554 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
@@ -304,11 +304,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) {
@@ -610,7 +610,7 @@ public class TestUtil {
     }
 
     public static void analyzeTable(Connection conn, String tableName) throws IOException, SQLException {
-    	analyzeTable(conn, tableName, false);
+        analyzeTable(conn, tableName, false);
     }
     
     public static void analyzeTable(Connection conn, String tableName, boolean transactional) throws IOException, SQLException {
@@ -652,17 +652,17 @@ public class TestUtil {
         Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i - 1) * MILLIS_IN_DAY);
         stmt.setDate(6, date);
     }
-	
+    
     public static void validateRowKeyColumns(ResultSet rs, int i) throws SQLException {
-		assertTrue(rs.next());
-		assertEquals(rs.getString(1), "varchar" + String.valueOf(i));
-		assertEquals(rs.getString(2), "char" + String.valueOf(i));
-		assertEquals(rs.getInt(3), i);
-		assertEquals(rs.getInt(4), i);
-		assertEquals(rs.getBigDecimal(5), new BigDecimal(i*0.5d));
-		Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i - 1) * MILLIS_IN_DAY);
-		assertEquals(rs.getDate(6), date);
-	}
+        assertTrue(rs.next());
+        assertEquals(rs.getString(1), "varchar" + String.valueOf(i));
+        assertEquals(rs.getString(2), "char" + String.valueOf(i));
+        assertEquals(rs.getInt(3), i);
+        assertEquals(rs.getInt(4), i);
+        assertEquals(rs.getBigDecimal(5), new BigDecimal(i*0.5d));
+        Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i - 1) * MILLIS_IN_DAY);
+        assertEquals(rs.getDate(6), date);
+    }
     
     public static String getTableName(Boolean mutable, Boolean transactional) {
         StringBuilder tableNameBuilder = new StringBuilder(DEFAULT_DATA_TABLE_NAME);
@@ -694,7 +694,7 @@ public class TestUtil {
                 
                 @Override
                 public SortOrder getSortOrder() {
-                	return SortOrder.getDefault();
+                    return SortOrder.getDefault();
                 }
                 
                 @Override
@@ -720,11 +720,15 @@ public class TestUtil {
                 public boolean isRowTimestamp() {
                     return false;
                 }
-    			@Override
-    			public boolean isDynamic() {
-    				return false;
-    			}
-            })), null);
+                @Override
+                public boolean isDynamic() {
+                    return false;
+                }
+                @Override
+                public Integer getEncodedColumnQualifier() {
+                    return null;
+                }
+            }, false)), null);
             aggregationManager.setAggregators(new ClientAggregators(Collections.<SingleAggregateFunction>singletonList(func), 1));
             ClientAggregators aggregators = aggregationManager.getAggregators();
             return aggregators;
@@ -821,4 +825,3 @@ public class TestUtil {
     }
 
 }
-

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ede568e9/phoenix-protocol/src/main/PTable.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PTable.proto b/phoenix-protocol/src/main/PTable.proto
index a16263f..d5df2f3 100644
--- a/phoenix-protocol/src/main/PTable.proto
+++ b/phoenix-protocol/src/main/PTable.proto
@@ -47,6 +47,7 @@ message PColumn {
   optional string expression = 12;
   optional bool isRowTimestamp = 13;
   optional bool isDynamic = 14;
+  optional int32 columnQualifier = 15;
 }
 
 message PTableStats {
@@ -95,4 +96,11 @@ message PTable {
   optional string autoParititonSeqName = 31;
   optional bool isAppendOnlySchema = 32;
   optional bytes parentNameBytes = 33;
+  optional bytes storageScheme = 34;
+  repeated EncodedCQCounter encodedCQCounters = 35;
+}
+
+message EncodedCQCounter {
+	required string colFamily = 1;
+	required int32 counter = 2;
 }