You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2014/03/12 23:40:22 UTC

[41/41] git commit: PHOENIX-130 Separate execution of slow (integration) tests from fast unit tests (GabrielReid)

PHOENIX-130 Separate execution of slow (integration) tests from fast unit tests (GabrielReid)


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

Branch: refs/heads/4.0
Commit: df23cf977f4c77c84cdd81cb59a226645f66a444
Parents: b0db920
Author: James Taylor <ja...@apache.org>
Authored: Wed Mar 12 15:39:31 2014 -0700
Committer: James Taylor <ja...@apache.org>
Committed: Wed Mar 12 15:39:31 2014 -0700

----------------------------------------------------------------------
 phoenix-core/pom.xml                            |    4 +
 .../wal/ReadWriteKeyValuesWithCodecIT.java      |  186 ++
 ...ReplayWithIndexWritesAndCompressedWALIT.java |  298 ++
 ...ritesAndUncompressedWALInHBase_094_9_IT.java |   45 +
 .../apache/phoenix/end2end/AlterTableIT.java    |  814 +++++
 .../phoenix/end2end/ArithmeticQueryIT.java      |  594 ++++
 .../org/apache/phoenix/end2end/ArrayIT.java     | 1240 ++++++++
 .../apache/phoenix/end2end/AutoCommitIT.java    |   81 +
 .../end2end/BaseClientManagedTimeIT.java        |   41 +
 .../phoenix/end2end/BaseConnectedQueryIT.java   |  760 +++++
 .../phoenix/end2end/BaseHBaseManagedTimeIT.java |   41 +
 .../BaseParallelIteratorsRegionSplitterIT.java  |   92 +
 .../end2end/BaseTenantSpecificTablesIT.java     |   69 +
 .../end2end/BaseTenantSpecificViewIndexIT.java  |  156 +
 .../org/apache/phoenix/end2end/BaseViewIT.java  |  133 +
 .../apache/phoenix/end2end/BinaryRowKeyIT.java  |  147 +
 .../phoenix/end2end/CSVCommonsLoaderIT.java     |  601 ++++
 .../phoenix/end2end/CoalesceFunctionIT.java     |   57 +
 .../end2end/ColumnProjectionOptimizationIT.java |  277 ++
 .../phoenix/end2end/CompareDecimalToLongIT.java |  238 ++
 .../ConnectionQueryServicesTestImpl.java        |  136 +
 .../apache/phoenix/end2end/CreateTableIT.java   |  102 +
 .../phoenix/end2end/CustomEntityDataIT.java     |  214 ++
 ...efaultParallelIteratorsRegionSplitterIT.java |  145 +
 .../org/apache/phoenix/end2end/DeleteIT.java    |  382 +++
 .../apache/phoenix/end2end/DistinctCountIT.java |  437 +++
 .../apache/phoenix/end2end/DynamicColumnIT.java |  218 ++
 .../apache/phoenix/end2end/DynamicFamilyIT.java |  360 +++
 .../apache/phoenix/end2end/DynamicUpsertIT.java |  225 ++
 .../phoenix/end2end/End2EndTestDriver.java      |  194 ++
 .../phoenix/end2end/ExecuteStatementsIT.java    |  301 ++
 .../phoenix/end2end/ExtendedQueryExecIT.java    |  188 ++
 .../apache/phoenix/end2end/FunkyNamesIT.java    |  143 +
 .../apache/phoenix/end2end/GroupByCaseIT.java   |  194 ++
 .../org/apache/phoenix/end2end/HashJoinIT.java  | 2242 ++++++++++++++
 .../phoenix/end2end/InMemoryOrderByIT.java      |   40 +
 .../org/apache/phoenix/end2end/IsNullIT.java    |   65 +
 .../org/apache/phoenix/end2end/KeyOnlyIT.java   |  146 +
 .../apache/phoenix/end2end/MD5FunctionIT.java   |   83 +
 .../phoenix/end2end/MultiCfQueryExecIT.java     |  229 ++
 .../phoenix/end2end/NativeHBaseTypesIT.java     |  305 ++
 .../org/apache/phoenix/end2end/OrderByIT.java   |  153 +
 .../apache/phoenix/end2end/PercentileIT.java    |  687 +++++
 .../phoenix/end2end/ProductMetricsIT.java       | 2025 ++++++++++++
 .../end2end/QueryDatabaseMetaDataIT.java        | 1051 +++++++
 .../phoenix/end2end/QueryExecWithoutSCNIT.java  |   49 +
 .../org/apache/phoenix/end2end/QueryIT.java     | 2889 ++++++++++++++++++
 .../org/apache/phoenix/end2end/QueryPlanIT.java |  201 ++
 .../phoenix/end2end/ReadIsolationLevelIT.java   |  150 +
 .../phoenix/end2end/ReverseFunctionIT.java      |  107 +
 .../RoundFloorCeilFunctionsEnd2EndIT.java       |  344 +++
 .../phoenix/end2end/RowValueConstructorIT.java  |  868 ++++++
 .../apache/phoenix/end2end/SaltedViewIT.java    |   35 +
 .../org/apache/phoenix/end2end/SequenceIT.java  |  594 ++++
 .../phoenix/end2end/ServerExceptionIT.java      |   67 +
 ...ipRangeParallelIteratorRegionSplitterIT.java |  368 +++
 .../apache/phoenix/end2end/SkipScanQueryIT.java |  275 ++
 .../apache/phoenix/end2end/SortOrderFIT.java    |  552 ++++
 .../phoenix/end2end/SpillableGroupByIT.java     |  134 +
 .../phoenix/end2end/SpooledOrderByIT.java       |   38 +
 .../phoenix/end2end/StatementHintsIT.java       |  161 +
 .../apache/phoenix/end2end/StatsManagerIT.java  |  195 ++
 .../org/apache/phoenix/end2end/StddevIT.java    |  135 +
 .../end2end/TenantSpecificTablesDDLIT.java      |  472 +++
 .../end2end/TenantSpecificTablesDMLIT.java      |  387 +++
 .../end2end/TenantSpecificViewIndexIT.java      |   33 +
 .../TenantSpecificViewIndexSaltedIT.java        |   17 +
 .../phoenix/end2end/ToCharFunctionIT.java       |  240 ++
 .../phoenix/end2end/ToNumberFunctionIT.java     |  301 ++
 .../java/org/apache/phoenix/end2end/TopNIT.java |  158 +
 .../phoenix/end2end/TruncateFunctionIT.java     |  121 +
 .../phoenix/end2end/UpsertBigValuesIT.java      |  369 +++
 .../end2end/UpsertSelectAutoCommitIT.java       |  135 +
 .../apache/phoenix/end2end/UpsertSelectIT.java  |  729 +++++
 .../apache/phoenix/end2end/UpsertValuesIT.java  |  539 ++++
 .../phoenix/end2end/VariableLengthPKIT.java     | 1953 ++++++++++++
 .../java/org/apache/phoenix/end2end/ViewIT.java |  220 ++
 .../phoenix/end2end/index/BaseIndexIT.java      |   29 +
 .../end2end/index/BaseMutableIndexIT.java       |  134 +
 .../phoenix/end2end/index/DropViewIT.java       |  100 +
 .../phoenix/end2end/index/ImmutableIndexIT.java |  367 +++
 .../phoenix/end2end/index/IndexMetadataIT.java  |  380 +++
 .../phoenix/end2end/index/IndexTestUtil.java    |  167 +
 .../end2end/index/MutableIndexFailureIT.java    |  124 +
 .../phoenix/end2end/index/MutableIndexIT.java   |  858 ++++++
 .../phoenix/end2end/index/SaltedIndexIT.java    |  207 ++
 .../phoenix/end2end/salted/SaltedTableIT.java   |  526 ++++
 .../salted/SaltedTableUpsertSelectIT.java       |  220 ++
 .../salted/SaltedTableVarLengthRowKeyIT.java    |   85 +
 .../FailForUnsupportedHBaseVersionsIT.java      |  158 +
 .../EndToEndCoveredColumnsIndexBuilderIT.java   |  346 +++
 .../example/EndToEndCoveredIndexingIT.java      |  880 ++++++
 .../EndtoEndIndexingWithCompressionIT.java      |   51 +
 .../covered/example/FailWithoutRetriesIT.java   |  150 +
 phoenix-core/src/it/resources/hbase-default.xml |   36 +
 phoenix-core/src/it/resources/log4j.properties  |   63 +
 .../regionserver/wal/IndexedHLogReader.java     |   12 -
 .../regionserver/wal/IndexedWALEditCodec.java   |    3 -
 .../phoenix/coprocessor/BaseRegionScanner.java  |    1 -
 .../GroupedAggregateRegionObserver.java         |    2 -
 .../coprocessor/MetaDataEndpointImpl.java       |    1 +
 .../phoenix/filter/ColumnProjectionFilter.java  |    2 +
 .../hbase/index/builder/BaseIndexBuilder.java   |    2 -
 .../phoenix/hbase/index/covered/Batch.java      |    1 +
 .../hbase/index/covered/LocalTableState.java    |    4 +-
 .../index/covered/data/LazyValueGetter.java     |    2 +-
 .../hbase/index/covered/data/LocalTable.java    |    2 -
 .../example/CoveredColumnIndexCodec.java        |   10 +-
 .../covered/example/CoveredColumnIndexer.java   |    1 +
 .../filter/ApplyAndFilterDeletesFilter.java     |    6 +-
 .../covered/filter/MaxTimestampFilter.java      |    5 +-
 .../index/covered/update/ColumnReference.java   |    2 +-
 .../index/scanner/FilteredKeyValueScanner.java  |    2 +-
 .../hbase/index/util/IndexManagementUtil.java   |    7 +-
 .../phoenix/hbase/index/wal/KeyValueCodec.java  |    1 -
 .../iterate/MappedByteBufferSortedQueue.java    |    1 +
 .../apache/phoenix/join/HashCacheFactory.java   |   23 +-
 .../phoenix/map/reduce/CSVBulkLoader.java       |    6 +-
 .../apache/phoenix/map/reduce/MapReduceJob.java |    3 +-
 .../query/ConnectionQueryServicesImpl.java      |    9 +-
 .../org/apache/phoenix/query/HTableFactory.java |    1 +
 .../apache/phoenix/schema/DelegateColumn.java   |    4 -
 .../apache/phoenix/schema/MetaDataClient.java   |    2 -
 .../wal/TestReadWriteKeyValuesWithCodec.java    |  186 --
 ...ALReplayWithIndexWritesAndCompressedWAL.java |  298 --
 ...exWritesAndUncompressedWALInHBase_094_9.java |   45 -
 .../apache/phoenix/end2end/AlterTableTest.java  |  814 -----
 .../phoenix/end2end/ArithmeticQueryTest.java    |  594 ----
 .../org/apache/phoenix/end2end/ArrayTest.java   | 1240 --------
 .../apache/phoenix/end2end/AutoCommitTest.java  |   81 -
 .../end2end/BaseClientManagedTimeTest.java      |   41 -
 .../phoenix/end2end/BaseConnectedQueryTest.java |  760 -----
 .../end2end/BaseHBaseManagedTimeTest.java       |   41 -
 ...BaseParallelIteratorsRegionSplitterTest.java |   92 -
 .../end2end/BaseTenantSpecificTablesTest.java   |   69 -
 .../BaseTenantSpecificViewIndexTest.java        |  156 -
 .../apache/phoenix/end2end/BaseViewTest.java    |  133 -
 .../phoenix/end2end/BinaryRowKeyTest.java       |  147 -
 .../phoenix/end2end/CSVCommonsLoaderTest.java   |  601 ----
 .../phoenix/end2end/CoalesceFunctionTest.java   |   57 -
 .../ColumnProjectionOptimizationTest.java       |  253 --
 .../end2end/CompareDecimalToLongTest.java       |  238 --
 .../ConnectionQueryServicesTestImpl.java        |  136 -
 .../apache/phoenix/end2end/CreateTableTest.java |  102 -
 .../phoenix/end2end/CustomEntityDataTest.java   |  214 --
 ...aultParallelIteratorsRegionSplitterTest.java |  145 -
 .../org/apache/phoenix/end2end/DeleteTest.java  |  382 ---
 .../phoenix/end2end/DistinctCountTest.java      |  437 ---
 .../phoenix/end2end/DynamicColumnTest.java      |  217 --
 .../phoenix/end2end/DynamicFamilyTest.java      |  359 ---
 .../phoenix/end2end/DynamicUpsertTest.java      |  225 --
 .../phoenix/end2end/End2EndTestDriver.java      |  194 --
 .../phoenix/end2end/ExecuteStatementsTest.java  |  301 --
 .../phoenix/end2end/ExtendedQueryExecTest.java  |  188 --
 .../apache/phoenix/end2end/FunkyNamesTest.java  |  143 -
 .../apache/phoenix/end2end/GroupByCaseTest.java |  194 --
 .../apache/phoenix/end2end/HashJoinTest.java    | 2242 --------------
 .../phoenix/end2end/InMemoryOrderByTest.java    |   40 -
 .../org/apache/phoenix/end2end/IsNullTest.java  |   65 -
 .../org/apache/phoenix/end2end/KeyOnlyTest.java |  146 -
 .../apache/phoenix/end2end/MD5FunctionTest.java |   83 -
 .../phoenix/end2end/MultiCfQueryExecTest.java   |  229 --
 .../phoenix/end2end/NativeHBaseTypesTest.java   |  305 --
 .../org/apache/phoenix/end2end/OrderByTest.java |  153 -
 .../apache/phoenix/end2end/PercentileTest.java  |  687 -----
 .../phoenix/end2end/ProductMetricsTest.java     | 2025 ------------
 .../end2end/QueryDatabaseMetaDataTest.java      | 1051 -------
 .../end2end/QueryExecWithoutSCNTest.java        |   49 -
 .../apache/phoenix/end2end/QueryPlanTest.java   |  201 --
 .../org/apache/phoenix/end2end/QueryTest.java   | 2889 ------------------
 .../phoenix/end2end/ReadIsolationLevelTest.java |  150 -
 .../phoenix/end2end/ReverseFunctionTest.java    |  107 -
 .../RoundFloorCeilFunctionsEnd2EndTest.java     |  344 ---
 .../end2end/RowValueConstructorTest.java        |  868 ------
 .../apache/phoenix/end2end/SaltedViewTest.java  |   35 -
 .../apache/phoenix/end2end/SequenceTest.java    |  594 ----
 .../phoenix/end2end/ServerExceptionTest.java    |   67 -
 ...RangeParallelIteratorRegionSplitterTest.java |  368 ---
 .../phoenix/end2end/SkipScanQueryTest.java      |  275 --
 .../apache/phoenix/end2end/SortOrderFTest.java  |  552 ----
 .../phoenix/end2end/SpillableGroupByTest.java   |  134 -
 .../phoenix/end2end/SpooledOrderByTest.java     |   38 -
 .../phoenix/end2end/StatementHintsTest.java     |  161 -
 .../phoenix/end2end/StatsManagerTest.java       |  195 --
 .../org/apache/phoenix/end2end/StddevTest.java  |  135 -
 .../end2end/TenantSpecificTablesDDLTest.java    |  472 ---
 .../end2end/TenantSpecificTablesDMLTest.java    |  387 ---
 .../TenantSpecificViewIndexSaltedTest.java      |   17 -
 .../end2end/TenantSpecificViewIndexTest.java    |   33 -
 .../phoenix/end2end/ToCharFunctionTest.java     |  240 --
 .../phoenix/end2end/ToNumberFunctionTest.java   |  301 --
 .../org/apache/phoenix/end2end/TopNTest.java    |  158 -
 .../phoenix/end2end/TruncateFunctionTest.java   |  121 -
 .../phoenix/end2end/UpsertBigValuesTest.java    |  369 ---
 .../end2end/UpsertSelectAutoCommitTest.java     |  135 -
 .../phoenix/end2end/UpsertSelectTest.java       |  729 -----
 .../phoenix/end2end/UpsertValuesTest.java       |  539 ----
 .../phoenix/end2end/VariableLengthPKTest.java   | 1953 ------------
 .../org/apache/phoenix/end2end/ViewTest.java    |  220 --
 .../phoenix/end2end/index/BaseIndexTest.java    |   29 -
 .../end2end/index/BaseMutableIndexTest.java     |  134 -
 .../phoenix/end2end/index/DropViewTest.java     |   99 -
 .../end2end/index/ImmutableIndexTest.java       |  367 ---
 .../end2end/index/IndexMetadataTest.java        |  380 ---
 .../phoenix/end2end/index/IndexTestUtil.java    |  166 -
 .../end2end/index/MutableIndexFailureTest.java  |  124 -
 .../phoenix/end2end/index/MutableIndexTest.java |  858 ------
 .../phoenix/end2end/index/SaltedIndexTest.java  |  207 --
 .../phoenix/end2end/salted/SaltedTableTest.java |  526 ----
 .../salted/SaltedTableUpsertSelectTest.java     |  221 --
 .../salted/SaltedTableVarLengthRowKeyTest.java  |   86 -
 .../phoenix/hbase/index/IndexTestingUtils.java  |    2 +-
 .../TestFailForUnsupportedHBaseVersions.java    |  159 -
 .../TestEndToEndCoveredColumnsIndexBuilder.java |  348 ---
 .../example/TestEndToEndCoveredIndexing.java    |  885 ------
 .../TestEndtoEndIndexingWithCompression.java    |   51 -
 .../covered/example/TestFailWithoutRetries.java |  152 -
 .../phoenix/index/IndexMaintainerTest.java      |    1 +
 .../iterate/AggregateResultScannerTest.java     |    3 -
 .../phoenix/query/ConnectionlessUpsertTest.java |    7 +-
 phoenix-flume/pom.xml                           |   13 +
 .../org/apache/phoenix/flume/PhoenixSinkIT.java |  196 ++
 .../phoenix/flume/RegexEventSerializerIT.java   |  416 +++
 .../apache/phoenix/flume/TestPhoenixSink.java   |  196 --
 .../phoenix/flume/TestRegexEventSerializer.java |  416 ---
 pom.xml                                         |   61 +-
 226 files changed, 34603 insertions(+), 34416 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/df23cf97/phoenix-core/pom.xml
----------------------------------------------------------------------
diff --git a/phoenix-core/pom.xml b/phoenix-core/pom.xml
index 90a8b89..63fe9e3 100644
--- a/phoenix-core/pom.xml
+++ b/phoenix-core/pom.xml
@@ -173,6 +173,10 @@
           <skipAssembly>true</skipAssembly>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-failsafe-plugin</artifactId>
+      </plugin>
     </plugins>
   </build>
 

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/df23cf97/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/ReadWriteKeyValuesWithCodecIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/ReadWriteKeyValuesWithCodecIT.java b/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/ReadWriteKeyValuesWithCodecIT.java
new file mode 100644
index 0000000..50dd6c0
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/ReadWriteKeyValuesWithCodecIT.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.regionserver.wal;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.KeyValueUtil;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Mutation;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.codec.Codec;
+import org.apache.hadoop.hbase.io.util.LRUDictionary;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.apache.phoenix.hbase.index.IndexTestingUtils;
+import org.apache.phoenix.hbase.index.wal.IndexedKeyValue;
+
+/**
+ * Simple test to read/write simple files via our custom {@link WALEditCodec} to ensure properly
+ * encoding/decoding without going through a cluster.
+ */
+public class ReadWriteKeyValuesWithCodecIT {
+
+  private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
+  private static final byte[] ROW = Bytes.toBytes("row");
+  private static final byte[] FAMILY = Bytes.toBytes("family");
+
+  @BeforeClass
+  public static void setupCodec() {
+    Configuration conf = UTIL.getConfiguration();
+    IndexTestingUtils.setupConfig(conf);
+    conf.set(WALCellCodec.WAL_CELL_CODEC_CLASS_KEY, IndexedWALEditCodec.class.getName());
+  }
+
+  @Test
+  public void testWithoutCompression() throws Exception {
+    // get the FS ready to read/write the edits
+    Path testDir = UTIL.getDataTestDir("TestReadWriteCustomEdits_withoutCompression");
+    Path testFile = new Path(testDir, "testfile");
+    FileSystem fs = UTIL.getTestFileSystem();
+
+    List<WALEdit> edits = getEdits();
+    writeReadAndVerify(null, fs, edits, testFile);
+  }
+
+  @Test
+  public void testWithCompression() throws Exception {
+    // get the FS ready to read/write the edit
+    Path testDir = UTIL.getDataTestDir("TestReadWriteCustomEdits_withCompression");
+    Path testFile = new Path(testDir, "testfile");
+    FileSystem fs = UTIL.getTestFileSystem();
+
+    List<WALEdit> edits = getEdits();
+    CompressionContext compression = new CompressionContext(LRUDictionary.class, false, false);
+    writeReadAndVerify(compression, fs, edits, testFile);
+  }
+
+  /**
+   * @return a bunch of {@link WALEdit}s that test a range of serialization possibilities.
+   */
+  private List<WALEdit> getEdits() {
+    // Build up a couple of edits
+    List<WALEdit> edits = new ArrayList<WALEdit>();
+    Put p = new Put(ROW);
+    p.add(FAMILY, null, Bytes.toBytes("v1"));
+
+    WALEdit withPut = new WALEdit();
+    addMutation(withPut, p, FAMILY);
+    edits.add(withPut);
+
+    Delete d = new Delete(ROW);
+    d.deleteColumn(FAMILY, null);
+    WALEdit withDelete = new WALEdit();
+    addMutation(withDelete, d, FAMILY);
+    edits.add(withDelete);
+    
+    WALEdit withPutsAndDeletes = new WALEdit();
+    addMutation(withPutsAndDeletes, d, FAMILY);
+    addMutation(withPutsAndDeletes, p, FAMILY);
+    edits.add(withPutsAndDeletes);
+    
+    WALEdit justIndexUpdates = new WALEdit();
+    byte[] table = Bytes.toBytes("targetTable");
+    IndexedKeyValue ikv = new IndexedKeyValue(table, p);
+    justIndexUpdates.add(ikv);
+    edits.add(justIndexUpdates);
+
+    WALEdit mixed = new WALEdit();
+    addMutation(mixed, d, FAMILY);
+    mixed.add(ikv);
+    addMutation(mixed, p, FAMILY);
+    edits.add(mixed);
+
+    return edits;
+  }
+
+  /**
+   * Add all the {@link KeyValue}s in the {@link Mutation}, for the pass family, to the given
+   * {@link WALEdit}.
+   */
+  private void addMutation(WALEdit edit, Mutation m, byte[] family) {
+    List<Cell> kvs = m.getFamilyCellMap().get(FAMILY);
+    for (Cell kv : kvs) {
+      edit.add(KeyValueUtil.ensureKeyValue(kv));
+    }
+  }
+
+  
+  private void writeWALEdit(WALCellCodec codec, List<KeyValue> kvs, FSDataOutputStream out) throws IOException {
+    out.writeInt(kvs.size());
+    Codec.Encoder cellEncoder = codec.getEncoder(out);
+    // We interleave the two lists for code simplicity
+    for (KeyValue kv : kvs) {
+        cellEncoder.write(kv);
+    }
+  }
+  
+  /**
+   * Write the edits to the specified path on the {@link FileSystem} using the given codec and then
+   * read them back in and ensure that we read the same thing we wrote.
+   */
+  private void writeReadAndVerify(final CompressionContext compressionContext, FileSystem fs, List<WALEdit> edits,
+      Path testFile) throws IOException {
+	  
+	WALCellCodec codec = WALCellCodec.create(UTIL.getConfiguration(), compressionContext);  
+    // write the edits out
+    FSDataOutputStream out = fs.create(testFile);
+    for (WALEdit edit : edits) {
+      writeWALEdit(codec, edit.getKeyValues(), out);
+    }
+    out.close();
+
+    // read in the edits
+    FSDataInputStream in = fs.open(testFile);
+    List<WALEdit> read = new ArrayList<WALEdit>();
+    for (int i = 0; i < edits.size(); i++) {
+      WALEdit edit = new WALEdit();
+      int numEdits = in.readInt();
+      edit.readFromCells(codec.getDecoder(in), numEdits);
+      read.add(edit);
+    }
+    in.close();
+
+    // make sure the read edits match the written
+    for(int i=0; i< edits.size(); i++){
+      WALEdit expected = edits.get(i);
+      WALEdit found = read.get(i);
+      for(int j=0; j< expected.getKeyValues().size(); j++){
+        KeyValue fkv = found.getKeyValues().get(j);
+        KeyValue ekv = expected.getKeyValues().get(j);
+        assertEquals("KV mismatch for edit! Expected: "+expected+", but found: "+found, ekv, fkv);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/df23cf97/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/WALReplayWithIndexWritesAndCompressedWALIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/WALReplayWithIndexWritesAndCompressedWALIT.java b/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/WALReplayWithIndexWritesAndCompressedWALIT.java
new file mode 100644
index 0000000..c93cf47
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/WALReplayWithIndexWritesAndCompressedWALIT.java
@@ -0,0 +1,298 @@
+/*
+ * 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.hadoop.hbase.regionserver.wal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.List;
+
+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.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+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.regionserver.HRegion;
+import org.apache.hadoop.hbase.regionserver.RegionServerAccounting;
+import org.apache.hadoop.hbase.regionserver.RegionServerServices;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.FSUtils;
+import org.apache.phoenix.util.ConfigUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import org.apache.phoenix.hbase.index.IndexTestingUtils;
+import org.apache.phoenix.hbase.index.TableName;
+import org.apache.phoenix.hbase.index.covered.example.ColumnGroup;
+import org.apache.phoenix.hbase.index.covered.example.CoveredColumn;
+import org.apache.phoenix.hbase.index.covered.example.CoveredColumnIndexSpecifierBuilder;
+import org.apache.phoenix.hbase.index.covered.example.CoveredColumnIndexer;
+
+/**
+ * For pre-0.94.9 instances, this class tests correctly deserializing WALEdits w/o compression. Post
+ * 0.94.9 we can support a custom {@link WALEditCodec}, which handles reading/writing the compressed
+ * edits.
+ * <p>
+ * Most of the underlying work (creating/splitting the WAL, etc) is from
+ * org.apache.hadoop.hhbase.regionserver.wal.TestWALReplay, copied here for completeness and ease of
+ * use.
+ * <p>
+ * This test should only have a single test - otherwise we will start/stop the minicluster multiple
+ * times, which is probably not what you want to do (mostly because its so much effort).
+ */
+public class WALReplayWithIndexWritesAndCompressedWALIT {
+
+  public static final Log LOG = LogFactory.getLog(TestWALReplay.class);
+  @Rule
+  public TableName table = new TableName();
+  private String INDEX_TABLE_NAME = table.getTableNameString() + "_INDEX";
+
+  final HBaseTestingUtility UTIL = new HBaseTestingUtility();
+  private Path hbaseRootDir = null;
+  private Path oldLogDir;
+  private Path logDir;
+  private FileSystem fs;
+  private Configuration conf;
+
+  @Before
+  public void setUp() throws Exception {
+    setupCluster();
+    this.conf = HBaseConfiguration.create(UTIL.getConfiguration());
+    this.fs = UTIL.getDFSCluster().getFileSystem();
+    this.hbaseRootDir = new Path(this.conf.get(HConstants.HBASE_DIR));
+    this.oldLogDir = new Path(this.hbaseRootDir, HConstants.HREGION_OLDLOGDIR_NAME);
+    this.logDir = new Path(this.hbaseRootDir, HConstants.HREGION_LOGDIR_NAME);
+    // reset the log reader to ensure we pull the one from this config
+    HLogFactory.resetLogReaderClass();
+  }
+
+  private void setupCluster() throws Exception {
+    configureCluster();
+    startCluster();
+  }
+
+  protected void configureCluster() throws Exception {
+    Configuration conf = UTIL.getConfiguration();
+    setDefaults(conf);
+
+    // enable WAL compression
+    conf.setBoolean(HConstants.ENABLE_WAL_COMPRESSION, true);
+    // set replication required parameter
+    ConfigUtil.setReplicationConfigIfAbsent(conf);
+  }
+
+  protected final void setDefaults(Configuration conf) {
+    // make sure writers fail quickly
+    conf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 3);
+    conf.setInt(HConstants.HBASE_CLIENT_PAUSE, 1000);
+    conf.setInt("zookeeper.recovery.retry", 3);
+    conf.setInt("zookeeper.recovery.retry.intervalmill", 100);
+    conf.setInt(HConstants.ZK_SESSION_TIMEOUT, 30000);
+    conf.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 5000);
+    // enable appends
+    conf.setBoolean("dfs.support.append", true);
+    IndexTestingUtils.setupConfig(conf);
+  }
+
+  protected void startCluster() throws Exception {
+    UTIL.startMiniDFSCluster(3);
+    UTIL.startMiniZKCluster();
+    UTIL.startMiniHBaseCluster(1, 1);
+
+    Path hbaseRootDir = UTIL.getDFSCluster().getFileSystem().makeQualified(new Path("/hbase"));
+    LOG.info("hbase.rootdir=" + hbaseRootDir);
+    UTIL.getConfiguration().set(HConstants.HBASE_DIR, hbaseRootDir.toString());
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    UTIL.shutdownMiniHBaseCluster();
+    UTIL.shutdownMiniDFSCluster();
+    UTIL.shutdownMiniZKCluster();
+  }
+
+
+  private void deleteDir(final Path p) throws IOException {
+    if (this.fs.exists(p)) {
+      if (!this.fs.delete(p, true)) {
+        throw new IOException("Failed remove of " + p);
+      }
+    }
+  }
+
+  /**
+   * Test writing edits into an HRegion, closing it, splitting logs, opening Region again. Verify
+   * seqids.
+   * @throws Exception on failure
+   */
+  @Test
+  public void testReplayEditsWrittenViaHRegion() throws Exception {
+    final String tableNameStr = "testReplayEditsWrittenViaHRegion";
+    final HRegionInfo hri = new HRegionInfo(org.apache.hadoop.hbase.TableName.valueOf(tableNameStr), 
+        null, null, false);
+    final Path basedir = FSUtils.getTableDir(hbaseRootDir, org.apache.hadoop.hbase.TableName.valueOf(tableNameStr));
+    deleteDir(basedir);
+    final HTableDescriptor htd = createBasic3FamilyHTD(tableNameStr);
+    
+    //setup basic indexing for the table
+    // enable indexing to a non-existant index table
+    byte[] family = new byte[] { 'a' };
+    ColumnGroup fam1 = new ColumnGroup(INDEX_TABLE_NAME);
+    fam1.add(new CoveredColumn(family, CoveredColumn.ALL_QUALIFIERS));
+    CoveredColumnIndexSpecifierBuilder builder = new CoveredColumnIndexSpecifierBuilder();
+    builder.addIndexGroup(fam1);
+    builder.build(htd);
+
+    // create the region + its WAL
+    HRegion region0 = HRegion.createHRegion(hri, hbaseRootDir, this.conf, htd);
+    region0.close();
+    region0.getLog().closeAndDelete();
+    HLog wal = createWAL(this.conf);
+    RegionServerServices mockRS = Mockito.mock(RegionServerServices.class);
+    // mock out some of the internals of the RSS, so we can run CPs
+    Mockito.when(mockRS.getWAL(null)).thenReturn(wal);
+    RegionServerAccounting rsa = Mockito.mock(RegionServerAccounting.class);
+    Mockito.when(mockRS.getRegionServerAccounting()).thenReturn(rsa);
+    ServerName mockServerName = Mockito.mock(ServerName.class);
+    Mockito.when(mockServerName.getServerName()).thenReturn(tableNameStr + ",1234");
+    Mockito.when(mockRS.getServerName()).thenReturn(mockServerName);
+    HRegion region = new HRegion(basedir, wal, this.fs, this.conf, hri, htd, mockRS);
+    region.initialize();
+    region.getSequenceId().set(0);
+
+    //make an attempted write to the primary that should also be indexed
+    byte[] rowkey = Bytes.toBytes("indexed_row_key");
+    Put p = new Put(rowkey);
+    p.add(family, Bytes.toBytes("qual"), Bytes.toBytes("value"));
+    region.put(p);
+
+    // we should then see the server go down
+    Mockito.verify(mockRS, Mockito.times(1)).abort(Mockito.anyString(),
+      Mockito.any(Exception.class));
+    region.close(true);
+    wal.close();
+
+    // then create the index table so we are successful on WAL replay
+    CoveredColumnIndexer.createIndexTable(UTIL.getHBaseAdmin(), INDEX_TABLE_NAME);
+
+    // run the WAL split and setup the region
+    runWALSplit(this.conf);
+    HLog wal2 = createWAL(this.conf);
+    HRegion region1 = new HRegion(basedir, wal2, this.fs, this.conf, hri, htd, mockRS);
+
+    // initialize the region - this should replay the WALEdits from the WAL
+    region1.initialize();
+
+    // now check to ensure that we wrote to the index table
+    HTable index = new HTable(UTIL.getConfiguration(), INDEX_TABLE_NAME);
+    int indexSize = getKeyValueCount(index);
+    assertEquals("Index wasn't propertly updated from WAL replay!", 1, indexSize);
+    Get g = new Get(rowkey);
+    final Result result = region1.get(g);
+    assertEquals("Primary region wasn't updated from WAL replay!", 1, result.size());
+
+    // cleanup the index table
+    HBaseAdmin admin = UTIL.getHBaseAdmin();
+    admin.disableTable(INDEX_TABLE_NAME);
+    admin.deleteTable(INDEX_TABLE_NAME);
+    admin.close();
+  }
+
+  /**
+   * Create simple HTD with three families: 'a', 'b', and 'c'
+   * @param tableName name of the table descriptor
+   * @return
+   */
+  private HTableDescriptor createBasic3FamilyHTD(final String tableName) {
+    HTableDescriptor htd = new HTableDescriptor(tableName);
+    HColumnDescriptor a = new HColumnDescriptor(Bytes.toBytes("a"));
+    htd.addFamily(a);
+    HColumnDescriptor b = new HColumnDescriptor(Bytes.toBytes("b"));
+    htd.addFamily(b);
+    HColumnDescriptor c = new HColumnDescriptor(Bytes.toBytes("c"));
+    htd.addFamily(c);
+    return htd;
+  }
+
+  /*
+   * @param c
+   * @return WAL with retries set down from 5 to 1 only.
+   * @throws IOException
+   */
+  private HLog createWAL(final Configuration c) throws IOException {
+    HLog wal = HLogFactory.createHLog(FileSystem.get(c), logDir, "localhost,1234", c);
+    // Set down maximum recovery so we dfsclient doesn't linger retrying something
+    // long gone.
+    HBaseTestingUtility.setMaxRecoveryErrorCount(((FSHLog) wal).getOutputStream(), 1);
+    return wal;
+  }
+
+  /*
+   * Run the split. Verify only single split file made.
+   * @param c
+   * @return The single split file made
+   * @throws IOException
+   */
+  private Path runWALSplit(final Configuration c) throws IOException {
+    FileSystem fs = FileSystem.get(c);
+    
+    List<Path> splits = HLogSplitter.split(this.hbaseRootDir, new Path(this.logDir, "localhost,1234"),
+        this.oldLogDir, fs, c);
+    // Split should generate only 1 file since there's only 1 region
+    assertEquals("splits=" + splits, 1, splits.size());
+    // Make sure the file exists
+    assertTrue(fs.exists(splits.get(0)));
+    LOG.info("Split file=" + splits.get(0));
+    return splits.get(0);
+  }
+
+  private int getKeyValueCount(HTable table) throws IOException {
+    Scan scan = new Scan();
+    scan.setMaxVersions(Integer.MAX_VALUE - 1);
+
+    ResultScanner results = table.getScanner(scan);
+    int count = 0;
+    for (Result res : results) {
+      count += res.list().size();
+      System.out.println(count + ") " + res);
+    }
+    results.close();
+
+    return count;
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/df23cf97/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/WALReplayWithIndexWritesAndUncompressedWALInHBase_094_9_IT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/WALReplayWithIndexWritesAndUncompressedWALInHBase_094_9_IT.java b/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/WALReplayWithIndexWritesAndUncompressedWALInHBase_094_9_IT.java
new file mode 100644
index 0000000..5edbdee
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/hadoop/hbase/regionserver/wal/WALReplayWithIndexWritesAndUncompressedWALInHBase_094_9_IT.java
@@ -0,0 +1,45 @@
+/*
+ * 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.hadoop.hbase.regionserver.wal;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HConstants;
+
+import org.apache.phoenix.hbase.index.util.IndexManagementUtil;
+import org.apache.phoenix.util.ConfigUtil;
+
+/**
+ * Do the WAL Replay test but with the WALEditCodec, rather than an {@link IndexedHLogReader}, but
+ * still with compression
+ */
+public class WALReplayWithIndexWritesAndUncompressedWALInHBase_094_9_IT extends WALReplayWithIndexWritesAndCompressedWALIT {
+
+  @Override
+  protected void configureCluster() throws Exception {
+    Configuration conf = UTIL.getConfiguration();
+    setDefaults(conf);
+    LOG.info("Setting HLog impl to indexed log reader");
+    conf.set(IndexManagementUtil.HLOG_READER_IMPL_KEY, IndexedHLogReader.class.getName());
+
+    // disable WAL compression
+    conf.setBoolean(HConstants.ENABLE_WAL_COMPRESSION, false);
+    // set replication required parameter
+    ConfigUtil.setReplicationConfigIfAbsent(conf);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/df23cf97/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
new file mode 100644
index 0000000..70b3d9a
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -0,0 +1,814 @@
+/*
+ * 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.apache.phoenix.util.TestUtil.closeConnection;
+import static org.apache.phoenix.util.TestUtil.closeStatement;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.math.BigDecimal;
+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 org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.client.HTableInterface;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.PTableKey;
+import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.util.IndexUtil;
+import org.apache.phoenix.util.SchemaUtil;
+import org.junit.Test;
+
+
+
+public class AlterTableIT extends BaseHBaseManagedTimeIT {
+    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");
+
+
+    @Test
+    public void testAlterTableWithVarBinaryKey() throws Exception {
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+        
+        try {
+            String ddl = "CREATE TABLE test_table " +
+                    "  (a_string varchar not null, a_binary varbinary not null, col1 integer" +
+                    "  CONSTRAINT pk PRIMARY KEY (a_string, a_binary))\n";
+            createTestTable(getUrl(), ddl);
+            
+            ddl = "ALTER TABLE test_table ADD b_string VARCHAR NULL PRIMARY KEY";
+            PreparedStatement stmt = conn.prepareStatement(ddl);
+            stmt.execute();
+            fail("Should have caught bad alter.");
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.VARBINARY_LAST_PK.getErrorCode(), e.getErrorCode());
+        } finally {
+            conn.close();
+        }
+    }
+
+    @Test
+    public void testAddVarCharColToPK() throws Exception {
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+        
+        try {
+            String ddl = "CREATE TABLE test_table " +
+                    "  (a_string varchar not null, col1 integer" +
+                    "  CONSTRAINT pk PRIMARY KEY (a_string))\n";
+            conn.createStatement().execute(ddl);
+            
+            String dml = "UPSERT INTO test_table VALUES(?)";
+            PreparedStatement stmt = conn.prepareStatement(dml);
+            stmt.setString(1, "b");
+            stmt.execute();
+            stmt.setString(1, "a");
+            stmt.execute();
+            conn.commit();
+            
+            String query = "SELECT * FROM test_table";
+            ResultSet rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("a",rs.getString(1));
+            assertTrue(rs.next());
+            assertEquals("b",rs.getString(1));
+            assertFalse(rs.next());
+            
+            ddl = "ALTER TABLE test_table ADD  b_string VARCHAR  NULL PRIMARY KEY  ";
+            conn.createStatement().execute(ddl);
+            
+            query = "SELECT * FROM test_table WHERE a_string = 'a' AND b_string IS NULL";
+            rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("a",rs.getString(1));
+            assertFalse(rs.next());
+            
+            dml = "UPSERT INTO test_table VALUES(?)";
+            stmt = conn.prepareStatement(dml);
+            stmt.setString(1, "c");
+            stmt.execute();
+            conn.commit();
+           
+            query = "SELECT * FROM test_table WHERE a_string = 'c' AND b_string IS NULL";
+            rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("c",rs.getString(1));
+            assertFalse(rs.next());
+            
+            dml = "UPSERT INTO test_table(a_string,col1) VALUES(?,?)";
+            stmt = conn.prepareStatement(dml);
+            stmt.setString(1, "a");
+            stmt.setInt(2, 5);
+            stmt.execute();
+            conn.commit();
+           
+            query = "SELECT a_string,col1 FROM test_table WHERE a_string = 'a' AND b_string IS NULL";
+            rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("a",rs.getString(1));
+            assertEquals(5,rs.getInt(2)); // TODO: figure out why this flaps
+            assertFalse(rs.next());
+            
+        } finally {
+            conn.close();
+        }
+    }
+    
+
+    
+    @Test
+    public void testAlterColumnFamilyProperty() throws Exception {
+
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        
+        String ddl = "CREATE TABLE test_table " +
+                "  (a_string varchar not null, col1 integer" +
+                "  CONSTRAINT pk PRIMARY KEY (a_string))\n";
+        try {
+                conn.createStatement().execute(ddl);
+              
+                conn.createStatement().execute("ALTER TABLE TEST_TABLE ADD col2 integer IN_MEMORY=true");
+                
+                HTableInterface htable1 = conn.unwrap(PhoenixConnection.class).getQueryServices().getTable(Bytes.toBytes("TEST_TABLE")); 
+                HTableDescriptor htableDesciptor1 = htable1.getTableDescriptor();
+                HColumnDescriptor hcolumnDescriptor1 = htableDesciptor1.getFamily(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES);
+                assertNotNull(hcolumnDescriptor1);
+               
+                try {
+                    
+                    conn.createStatement().execute("ALTER TABLE TEST_TABLE SET IN_MEMORY=false");
+                    fail("Should have caught exception.");
+                    
+                } catch (SQLException e) {
+                    assertTrue(e.getMessage(), e.getMessage().contains("ERROR 1025 (42Y84): Unsupported property set in ALTER TABLE command."));
+                } 
+        }finally {
+            conn.close();
+        }
+     }
+  
+    private static void assertIndexExists(Connection conn, boolean exists) throws SQLException {
+        ResultSet rs = conn.getMetaData().getIndexInfo(null, SCHEMA_NAME, DATA_TABLE_NAME, false, false);
+        assertEquals(exists, rs.next());
+    }
+    
+    @Test
+    public void testDropIndexedColumn() throws Exception {
+        String query;
+        ResultSet rs;
+        PreparedStatement stmt;
+    
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+    
+        // make sure that the tables are empty, but reachable
+        conn.createStatement().execute(
+          "CREATE TABLE " + DATA_TABLE_FULL_NAME
+              + " (k VARCHAR NOT NULL PRIMARY KEY, v1 VARCHAR, v2 VARCHAR)");
+        query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertFalse(rs.next());
+    
+        conn.createStatement().execute(
+          "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1, v2)");
+        query = "SELECT * FROM " + INDEX_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertFalse(rs.next());
+    
+        // load some data into the table
+        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();
+        
+        assertIndexExists(conn,true);
+        conn.createStatement().execute("ALTER TABLE " + DATA_TABLE_FULL_NAME + " DROP COLUMN v1");
+        assertIndexExists(conn,false);
+        
+        query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals("a",rs.getString(1));
+        assertEquals("1",rs.getString(2));
+        assertFalse(rs.next());
+        
+        // load some data into the table
+        stmt = conn.prepareStatement("UPSERT INTO " + DATA_TABLE_FULL_NAME + " VALUES(?,?)");
+        stmt.setString(1, "a");
+        stmt.setString(2, "2");
+        stmt.execute();
+        conn.commit();
+        
+        query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals("a",rs.getString(1));
+        assertEquals("2",rs.getString(2));
+        assertFalse(rs.next());
+    }
+    
+    @Test
+    public void testDropCoveredColumn() throws Exception {
+        String query;
+        ResultSet rs;
+        PreparedStatement stmt;
+    
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+    
+        // make sure that the tables are empty, but reachable
+        conn.createStatement().execute(
+          "CREATE TABLE " + DATA_TABLE_FULL_NAME
+              + " (k VARCHAR NOT NULL PRIMARY KEY, v1 VARCHAR, v2 VARCHAR, v3 VARCHAR)");
+        query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertFalse(rs.next());
+    
+        conn.createStatement().execute(
+          "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1) include (v2, v3)");
+        query = "SELECT * FROM " + INDEX_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertFalse(rs.next());
+    
+        // load some data into the table
+        stmt = conn.prepareStatement("UPSERT INTO " + DATA_TABLE_FULL_NAME + " VALUES(?,?,?,?)");
+        stmt.setString(1, "a");
+        stmt.setString(2, "x");
+        stmt.setString(3, "1");
+        stmt.setString(4, "j");
+        stmt.execute();
+        conn.commit();
+        
+        assertIndexExists(conn,true);
+        conn.createStatement().execute("ALTER TABLE " + DATA_TABLE_FULL_NAME + " DROP COLUMN v2");
+        // TODO: verify meta data that we get back to confirm our column was dropped
+        assertIndexExists(conn,true);
+        
+        query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals("a",rs.getString(1));
+        assertEquals("x",rs.getString(2));
+        assertEquals("j",rs.getString(3));
+        assertFalse(rs.next());
+        
+        // load some data into the table
+        stmt = conn.prepareStatement("UPSERT INTO " + DATA_TABLE_FULL_NAME + " VALUES(?,?,?)");
+        stmt.setString(1, "a");
+        stmt.setString(2, "y");
+        stmt.setString(3, "k");
+        stmt.execute();
+        conn.commit();
+        
+        query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals("a",rs.getString(1));
+        assertEquals("y",rs.getString(2));
+        assertEquals("k",rs.getString(3));
+        assertFalse(rs.next());
+    }
+    
+    @Test
+    public void testAddPKColumnToTableWithIndex() throws Exception {
+        String query;
+        ResultSet rs;
+        PreparedStatement stmt;
+    
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+    
+        // make sure that the tables are empty, but reachable
+        conn.createStatement().execute(
+          "CREATE TABLE " + DATA_TABLE_FULL_NAME
+              + " (k VARCHAR NOT NULL PRIMARY KEY, v1 VARCHAR, v2 VARCHAR)");
+        query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertFalse(rs.next());
+    
+        conn.createStatement().execute(
+          "CREATE INDEX " + INDEX_TABLE_NAME + " ON " + DATA_TABLE_FULL_NAME + " (v1) include (v2)");
+        query = "SELECT * FROM " + INDEX_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertFalse(rs.next());
+    
+        // load some data into the table
+        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();
+        
+        assertIndexExists(conn,true);
+        conn.createStatement().execute("ALTER TABLE " + DATA_TABLE_FULL_NAME + " ADD v3 VARCHAR, k2 DECIMAL PRIMARY KEY");
+        rs = conn.getMetaData().getPrimaryKeys("", SCHEMA_NAME, DATA_TABLE_NAME);
+        assertTrue(rs.next());
+        assertEquals("K",rs.getString("COLUMN_NAME"));
+        assertEquals(1, rs.getShort("KEY_SEQ"));
+        assertTrue(rs.next());
+        assertEquals("K2",rs.getString("COLUMN_NAME"));
+        assertEquals(2, rs.getShort("KEY_SEQ"));
+
+        rs = conn.getMetaData().getPrimaryKeys("", SCHEMA_NAME, INDEX_TABLE_NAME);
+        assertTrue(rs.next());
+        assertEquals(QueryConstants.DEFAULT_COLUMN_FAMILY + IndexUtil.INDEX_COLUMN_NAME_SEP + "V1",rs.getString("COLUMN_NAME"));
+        assertEquals(1, rs.getShort("KEY_SEQ"));
+        assertTrue(rs.next());
+        assertEquals(IndexUtil.INDEX_COLUMN_NAME_SEP + "K",rs.getString("COLUMN_NAME"));
+        assertEquals(2, rs.getShort("KEY_SEQ"));
+        assertTrue(rs.next());
+        assertEquals(IndexUtil.INDEX_COLUMN_NAME_SEP + "K2",rs.getString("COLUMN_NAME"));
+        assertEquals(3, rs.getShort("KEY_SEQ"));
+        
+        assertIndexExists(conn,true);
+        
+        query = "SELECT * FROM " + DATA_TABLE_FULL_NAME;
+        rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals("a",rs.getString(1));
+        assertEquals("x",rs.getString(2));
+        assertEquals("1",rs.getString(3));
+        assertNull(rs.getBigDecimal(4));
+        assertFalse(rs.next());
+        
+        // load some data into the table
+        stmt = conn.prepareStatement("UPSERT INTO " + DATA_TABLE_FULL_NAME + "(K,K2,V1,V2) VALUES(?,?,?,?)");
+        stmt.setString(1, "b");
+        stmt.setBigDecimal(2, BigDecimal.valueOf(2));
+        stmt.setString(3, "y");
+        stmt.setString(4, "2");
+        stmt.execute();
+        conn.commit();
+        
+        query = "SELECT k,k2 FROM " + DATA_TABLE_FULL_NAME + " WHERE v1='y'";
+        rs = conn.createStatement().executeQuery(query);
+        assertTrue(rs.next());
+        assertEquals("b",rs.getString(1));
+        assertEquals(BigDecimal.valueOf(2),rs.getBigDecimal(2));
+        assertFalse(rs.next());
+    }
+    
+    @Test
+    public void testSetSaltedTableAsImmutable() throws Exception {
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+        
+        try {
+            String ddl = "CREATE TABLE MESSAGES (\n" + 
+            		"        SENDER_ID UNSIGNED_LONG NOT NULL,\n" + 
+            		"        RECIPIENT_ID UNSIGNED_LONG NOT NULL,\n" + 
+            		"        M_TIMESTAMP DATE  NOT NULL,\n" + 
+            		"        ROW_ID UNSIGNED_LONG NOT NULL,\n" + 
+            		"        IS_READ TINYINT,\n" + 
+            		"        IS_DELETED TINYINT,\n" + 
+            		"        VISIBILITY TINYINT,\n" + 
+            		"        B.SENDER_IP VARCHAR,\n" + 
+            		"        B.JSON VARCHAR,\n" + 
+            		"        B.M_TEXT VARCHAR\n" + 
+            		"        CONSTRAINT ROWKEY PRIMARY KEY\n" + 
+            		"(SENDER_ID,RECIPIENT_ID,M_TIMESTAMP DESC,ROW_ID))\n" + 
+            		"SALT_BUCKETS=4";
+            conn.createStatement().execute(ddl);
+            
+            ddl = "ALTER TABLE MESSAGES SET IMMUTABLE_ROWS=true";
+            conn.createStatement().execute(ddl);
+            
+            conn.createStatement().executeQuery("select count(*) from messages").next();
+            
+        } finally {
+            conn.close();
+        }
+    }
+    
+    
+    @Test
+    public void testDropColumnFromSaltedTable() throws Exception {
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+        
+        try {
+            String ddl = "CREATE TABLE MESSAGES (\n" + 
+                    "        SENDER_ID UNSIGNED_LONG NOT NULL,\n" + 
+                    "        RECIPIENT_ID UNSIGNED_LONG NOT NULL,\n" + 
+                    "        M_TIMESTAMP DATE  NOT NULL,\n" + 
+                    "        ROW_ID UNSIGNED_LONG NOT NULL,\n" + 
+                    "        IS_READ TINYINT,\n" + 
+                    "        IS_DELETED TINYINT,\n" + 
+                    "        VISIBILITY TINYINT,\n" + 
+                    "        B.SENDER_IP VARCHAR,\n" + 
+                    "        B.JSON VARCHAR,\n" + 
+                    "        B.M_TEXT VARCHAR\n" + 
+                    "        CONSTRAINT ROWKEY PRIMARY KEY\n" + 
+                    "(SENDER_ID,RECIPIENT_ID,M_TIMESTAMP DESC,ROW_ID))\n" + 
+                    "SALT_BUCKETS=4";
+            conn.createStatement().execute(ddl);
+            
+            ddl = "ALTER TABLE MESSAGES DROP COLUMN B.JSON";
+            conn.createStatement().execute(ddl);
+            
+            conn.createStatement().executeQuery("select count(*) from messages").next();
+        } finally {
+            conn.close();
+        }
+
+    }
+    
+    
+    @Test
+    public void testAddVarCols() throws Exception {
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+        
+        try {
+            String ddl = "CREATE TABLE test_table " +
+                    "  (a_string varchar not null, col1 integer" +
+                    "  CONSTRAINT pk PRIMARY KEY (a_string))\n";
+            conn.createStatement().execute(ddl);
+            
+            String dml = "UPSERT INTO test_table VALUES(?)";
+            PreparedStatement stmt = conn.prepareStatement(dml);
+            stmt.setString(1, "b");
+            stmt.execute();
+            stmt.setString(1, "a");
+            stmt.execute();
+            conn.commit();
+            
+            String query = "SELECT * FROM test_table";
+            ResultSet rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("a",rs.getString(1));
+            assertTrue(rs.next());
+            assertEquals("b",rs.getString(1));
+            assertFalse(rs.next());
+            
+            
+            query = "SELECT * FROM test_table WHERE a_string = 'a' ";
+            rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("a",rs.getString(1));
+          
+            ddl = "ALTER TABLE test_table ADD  c1.col2 VARCHAR  , c1.col3 integer , c2.col4 integer";
+            conn.createStatement().execute(ddl);
+            
+            ddl = "ALTER TABLE test_table ADD   col5 integer , c1.col2 VARCHAR";
+            try {
+                conn.createStatement().execute(ddl);
+                fail();
+            } catch (SQLException e) {
+                assertEquals(SQLExceptionCode.COLUMN_EXIST_IN_DEF.getErrorCode(), e.getErrorCode());
+            }
+            
+            query = "SELECT col5 FROM test_table";
+            try {
+                conn.createStatement().executeQuery(query);
+                fail(); 
+            } catch(SQLException e) {
+                assertTrue(e.getMessage(), e.getMessage().contains("ERROR 504 (42703): Undefined column."));
+            }
+       
+            ddl = "ALTER TABLE test_table ADD IF NOT EXISTS col5 integer , c1.col2 VARCHAR";
+            conn.createStatement().execute(ddl);
+            
+            dml = "UPSERT INTO test_table VALUES(?,?,?,?,?)";
+            stmt = conn.prepareStatement(dml);
+            stmt.setString(1, "c");
+            stmt.setInt(2, 100);
+            stmt.setString(3, "d");
+            stmt.setInt(4, 101);
+            stmt.setInt(5, 102);
+            stmt.execute();
+            conn.commit();
+           
+            query = "SELECT * FROM test_table WHERE a_string = 'c' ";
+            rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("c",rs.getString(1));
+            assertEquals(100,rs.getInt(2));
+            assertEquals("d",rs.getString(3));
+            assertEquals(101,rs.getInt(4));
+            assertEquals(102,rs.getInt(5));
+            assertFalse(rs.next());
+            
+            ddl = "ALTER TABLE test_table ADD  col5 integer";
+            conn.createStatement().execute(ddl);
+            
+            query = "SELECT c1.* FROM test_table WHERE a_string = 'c' ";
+            rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("d",rs.getString(1));
+            assertEquals(101,rs.getInt(2));
+            assertFalse(rs.next());
+            
+            
+            dml = "UPSERT INTO test_table(a_string,col1,col5) VALUES(?,?,?)";
+            stmt = conn.prepareStatement(dml);
+            stmt.setString(1, "e");
+            stmt.setInt(2, 200);
+            stmt.setInt(3, 201);
+            stmt.execute();
+            conn.commit();
+            
+            
+            query = "SELECT a_string,col1,col5 FROM test_table WHERE a_string = 'e' ";
+            rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("e",rs.getString(1));
+            assertEquals(200,rs.getInt(2));
+            assertEquals(201,rs.getInt(3));
+            assertFalse(rs.next());
+            
+          } finally {
+            conn.close();
+        }
+    }
+
+    @Test
+    public void testDropVarCols() throws Exception {
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+        try {
+            String ddl = "CREATE TABLE test_table " + "  (a_string varchar not null, col1 integer, cf1.col2 integer"
+                    + "  CONSTRAINT pk PRIMARY KEY (a_string))\n";
+            conn.createStatement().execute(ddl);
+
+            ddl = "ALTER TABLE test_table DROP COLUMN col1";
+            conn.createStatement().execute(ddl);
+
+            ddl = "ALTER TABLE test_table DROP COLUMN cf1.col2";
+            conn.createStatement().execute(ddl);
+        } finally {
+            conn.close();
+        }
+    }
+    
+    @Test
+    public void testDisallowAddingNotNullableColumnNotPartOfPkForExistingTable() throws Exception {
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = null;
+        PreparedStatement stmt = null;
+        try {
+            conn = DriverManager.getConnection(getUrl(), props);
+            conn.setAutoCommit(false);
+            try {
+                String ddl = "CREATE TABLE test_table " + "  (a_string varchar not null, col1 integer, cf1.col2 integer"
+                        + "  CONSTRAINT pk PRIMARY KEY (a_string))\n";
+                stmt = conn.prepareStatement(ddl);
+                stmt.execute();
+            } finally {
+                closeStatement(stmt);
+            }
+            try {
+                stmt = conn.prepareStatement("ALTER TABLE test_table ADD b_string VARCHAR NOT NULL");
+                stmt.execute();
+                fail("Should have failed since altering a table by adding a non-nullable column is not allowed.");
+            } catch (SQLException e) {
+                assertEquals(SQLExceptionCode.CANNOT_ADD_NOT_NULLABLE_COLUMN.getErrorCode(), e.getErrorCode());
+            } finally {
+                closeStatement(stmt);
+            }
+        } finally {
+            closeConnection(conn);
+        }
+    }
+
+    private void asssertIsWALDisabled(Connection conn, String fullTableName, boolean expectedValue) throws SQLException {
+        PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
+        assertEquals(expectedValue, pconn.getMetaDataCache().getTable(new PTableKey(pconn.getTenantId(), fullTableName)).isWALDisabled());
+    }
+    
+    @Test
+    public void testDisableWAL() throws Exception {
+        String fullTableName = "TEST_TABLE";
+        String fullIndexName = "I";
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+
+        try {
+            conn.createStatement()
+                    .execute(
+                            "CREATE TABLE test_table "
+                                    + "  (a_string varchar not null, col1 integer, cf1.col2 integer, col3 integer , cf2.col4 integer "
+                                    + "  CONSTRAINT pk PRIMARY KEY (a_string)) immutable_rows=true, disable_wal=true ");
+
+            Connection conn2 = DriverManager.getConnection(getUrl(), props);
+            String query = "SELECT * FROM test_table";
+            ResultSet rs = conn2.createStatement().executeQuery(query);
+            assertFalse(rs.next());
+            asssertIsWALDisabled(conn2,fullTableName, true);
+            conn2.close();
+            asssertIsWALDisabled(conn,fullTableName, true);
+
+            conn.createStatement().execute("CREATE INDEX i ON test_table (col1) include (cf1.col2) SALT_BUCKETS=4");
+            conn2 = DriverManager.getConnection(getUrl(), props);
+            query = "SELECT * FROM i";
+            rs = conn2.createStatement().executeQuery(query);
+            asssertIsWALDisabled(conn2,fullIndexName, true);
+            assertFalse(rs.next());
+            conn2.close();
+            asssertIsWALDisabled(conn,fullIndexName, true);
+            
+            conn.createStatement().execute("DROP TABLE test_table");
+        } finally {
+            conn.close();
+        }
+        conn = DriverManager.getConnection(getUrl(), props);
+
+        try {
+            conn.createStatement()
+                    .execute(
+                            "CREATE TABLE test_table "
+                                    + "  (a_string varchar not null, col1 integer, cf1.col2 integer, col3 integer , cf2.col4 integer "
+                                    + "  CONSTRAINT pk PRIMARY KEY (a_string)) immutable_rows=true");
+
+            Connection conn2 = DriverManager.getConnection(getUrl(), props);
+            String query = "SELECT * FROM test_table";
+            ResultSet rs = conn2.createStatement().executeQuery(query);
+            assertFalse(rs.next());
+            asssertIsWALDisabled(conn,fullTableName, false);
+            conn2.close();
+            asssertIsWALDisabled(conn,fullTableName, false);
+
+            conn.createStatement().execute("CREATE INDEX i ON test_table (col1) include (cf1.col2) SALT_BUCKETS=4");
+            conn2 = DriverManager.getConnection(getUrl(), props);
+            query = "SELECT * FROM i";
+            rs = conn2.createStatement().executeQuery(query);
+            asssertIsWALDisabled(conn2,fullIndexName, true);
+            assertFalse(rs.next());
+            conn2.close();
+            asssertIsWALDisabled(conn,fullIndexName, true);
+            conn.createStatement().execute("DROP TABLE test_table");
+        } finally {
+            conn.close();
+        }
+        conn = DriverManager.getConnection(getUrl(), props);
+
+        try {
+            conn.createStatement()
+                    .execute(
+                            "CREATE TABLE test_table "
+                                    + "  (a_string varchar not null, col1 integer, cf1.col2 integer, col3 integer , cf2.col4 integer "
+                                    + "  CONSTRAINT pk PRIMARY KEY (a_string))");
+
+            Connection conn2 = DriverManager.getConnection(getUrl(), props);
+            String query = "SELECT * FROM test_table";
+            ResultSet rs = conn2.createStatement().executeQuery(query);
+            assertFalse(rs.next());
+            asssertIsWALDisabled(conn2,fullTableName, false);
+            conn2.close();
+            asssertIsWALDisabled(conn,fullTableName, false);
+
+            conn.createStatement().execute("CREATE INDEX i ON test_table (col1) include (cf1.col2) SALT_BUCKETS=4");
+            conn2 = DriverManager.getConnection(getUrl(), props);
+            query = "SELECT * FROM i";
+            rs = conn2.createStatement().executeQuery(query);
+            asssertIsWALDisabled(conn2,fullIndexName, false);
+            assertFalse(rs.next());
+            conn2.close();
+            asssertIsWALDisabled(conn,fullIndexName, false);
+            
+        } finally {
+            conn.close();
+        }
+    }
+
+    @Test
+    public void testDropColumnsWithImutability() throws Exception {
+
+        Properties props = new Properties(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+
+        try {
+            conn.createStatement()
+                    .execute(
+                            "CREATE TABLE test_table "
+                                    + "  (a_string varchar not null, col1 integer, cf1.col2 integer, col3 integer , cf2.col4 integer "
+                                    + "  CONSTRAINT pk PRIMARY KEY (a_string)) immutable_rows=true , SALT_BUCKETS=3 ");
+
+            String query = "SELECT * FROM test_table";
+            ResultSet rs = conn.createStatement().executeQuery(query);
+            assertFalse(rs.next());
+
+            conn.createStatement().execute("CREATE INDEX i ON test_table (col1) include (cf1.col2) SALT_BUCKETS=4");
+            query = "SELECT * FROM i";
+            rs = conn.createStatement().executeQuery(query);
+            assertFalse(rs.next());
+
+            String dml = "UPSERT INTO test_table VALUES(?,?,?,?,?)";
+            PreparedStatement stmt = conn.prepareStatement(dml);
+            stmt.setString(1, "b");
+            stmt.setInt(2, 10);
+            stmt.setInt(3, 20);
+            stmt.setInt(4, 30);
+            stmt.setInt(5, 40);
+            stmt.execute();
+            stmt.setString(1, "a");
+            stmt.setInt(2, 101);
+            stmt.setInt(3, 201);
+            stmt.setInt(4, 301);
+            stmt.setInt(5, 401);
+            stmt.execute();
+            conn.commit();
+
+            query = "SELECT * FROM test_table order by col1";
+            rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("b", rs.getString(1));
+            assertTrue(rs.next());
+            assertEquals("a", rs.getString(1));
+            assertFalse(rs.next());
+
+            String ddl = "ALTER TABLE test_table DROP COLUMN IF EXISTS col2,col3";
+            conn.createStatement().execute(ddl);
+            
+            ddl = "ALTER TABLE test_table DROP COLUMN a_string,col1";
+            try{
+                conn.createStatement().execute(ddl);
+                fail();
+            } catch (SQLException e) {
+                assertEquals(SQLExceptionCode.CANNOT_DROP_PK.getErrorCode(), e.getErrorCode());
+            }
+            
+            ddl = "ALTER TABLE test_table DROP COLUMN col4,col5";
+            try {
+                conn.createStatement().execute(ddl);
+                fail();
+            } catch (SQLException e) {
+                assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
+                assertTrue(e.getMessage(), e.getMessage().contains("ERROR 504 (42703): Undefined column. columnName=COL5"));
+            } 
+
+            ddl = "ALTER TABLE test_table DROP COLUMN IF EXISTS col1";
+            conn.createStatement().execute(ddl);
+            
+            query = "SELECT * FROM i";
+            try {
+                rs = conn.createStatement().executeQuery(query);
+                fail();
+            } catch (TableNotFoundException e) {}
+            
+            query = "select col4 FROM test_table";
+            rs = conn.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertTrue(rs.next());
+
+            query = "select col2,col3 FROM test_table";
+            try {
+                rs = conn.createStatement().executeQuery(query);
+                fail();
+            } catch (SQLException e) {
+                assertEquals(SQLExceptionCode.COLUMN_NOT_FOUND.getErrorCode(), e.getErrorCode());
+            }
+              
+        } finally {
+            conn.close();
+        }
+    }
+   
+ }