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();
+ }
+ }
+
+ }