You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by sa...@apache.org on 2016/09/20 01:50:33 UTC
[2/2] phoenix git commit: PHOENIX-3174 Make minor upgrade a manual
step
PHOENIX-3174 Make minor upgrade a manual step
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/887b57cf
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/887b57cf
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/887b57cf
Branch: refs/heads/4.x-HBase-0.98
Commit: 887b57cf9a02f8fdfb21e655f10029531568bf54
Parents: 97a6250
Author: Samarth <sa...@salesforce.com>
Authored: Mon Sep 19 18:50:13 2016 -0700
Committer: Samarth <sa...@salesforce.com>
Committed: Mon Sep 19 18:50:13 2016 -0700
----------------------------------------------------------------------
.../org/apache/phoenix/end2end/UpgradeIT.java | 156 ++-
phoenix-core/src/main/antlr3/PhoenixSQL.g | 10 +-
.../coprocessor/MetaDataEndpointImpl.java | 16 +-
.../coprocessor/MetaDataRegionObserver.java | 50 +-
.../phoenix/exception/SQLExceptionCode.java | 2 +
.../exception/UpgradeInProgressException.java | 28 +
.../exception/UpgradeNotRequiredException.java | 27 +
.../exception/UpgradeRequiredException.java | 29 +
.../apache/phoenix/jdbc/PhoenixConnection.java | 27 +-
.../phoenix/jdbc/PhoenixDatabaseMetaData.java | 2 +-
.../apache/phoenix/jdbc/PhoenixStatement.java | 72 +-
.../index/automation/PhoenixMRJobSubmitter.java | 4 +
.../phoenix/parse/ExecuteUpgradeStatement.java | 34 +
.../apache/phoenix/parse/ParseNodeFactory.java | 4 +
.../phoenix/query/ConnectionQueryServices.java | 3 +
.../query/ConnectionQueryServicesImpl.java | 952 ++++++++++---------
.../query/ConnectionlessQueryServicesImpl.java | 8 +
.../query/DelegateConnectionQueryServices.java | 10 +
.../org/apache/phoenix/query/QueryServices.java | 1 +
.../phoenix/query/QueryServicesOptions.java | 5 +-
.../apache/phoenix/schema/MetaDataClient.java | 2 +-
.../phoenix/trace/PhoenixMetricsSink.java | 37 +-
.../org/apache/phoenix/util/PhoenixRuntime.java | 2 +-
.../java/org/apache/phoenix/util/QueryUtil.java | 6 +-
.../org/apache/phoenix/util/UpgradeUtil.java | 19 +-
25 files changed, 1029 insertions(+), 477 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
index b47738d..bdd94a2 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpgradeIT.java
@@ -24,7 +24,9 @@ import static org.apache.phoenix.query.QueryConstants.DIVERGED_VIEW_BASE_COLUMN_
import static org.apache.phoenix.util.UpgradeUtil.SELECT_BASE_COLUMN_COUNT_FROM_HEADER_ROW;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.IOException;
import java.sql.Connection;
@@ -33,6 +35,9 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.client.HBaseAdmin;
@@ -41,8 +46,14 @@ import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.RowMutations;
import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.coprocessor.MetaDataProtocol;
+import org.apache.phoenix.exception.UpgradeInProgressException;
+import org.apache.phoenix.exception.UpgradeRequiredException;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.query.ConnectionQueryServices;
+import org.apache.phoenix.query.ConnectionQueryServicesImpl;
+import org.apache.phoenix.query.DelegateConnectionQueryServices;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.schema.PName;
@@ -51,7 +62,6 @@ import org.apache.phoenix.util.MetaDataUtil;
import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.SchemaUtil;
import org.apache.phoenix.util.UpgradeUtil;
-import org.junit.Ignore;
import org.junit.Test;
public class UpgradeIT extends BaseHBaseManagedTimeIT {
@@ -576,6 +586,150 @@ public class UpgradeIT extends BaseHBaseManagedTimeIT {
}
}
}
+
+ @Test
+ public void testUpgradeRequiredPreventsSQL() throws SQLException {
+ String tableName = generateRandomString();
+ try (Connection conn = getConnection(false, null)) {
+ conn.createStatement().execute(
+ "CREATE TABLE " + tableName
+ + " (PK1 VARCHAR NOT NULL, PK2 VARCHAR, KV1 VARCHAR, KV2 VARCHAR CONSTRAINT PK PRIMARY KEY(PK1, PK2))");
+ final ConnectionQueryServices delegate = conn.unwrap(PhoenixConnection.class).getQueryServices();
+ ConnectionQueryServices servicesWithUpgrade = new DelegateConnectionQueryServices(delegate) {
+ @Override
+ public boolean isUpgradeRequired() {
+ return true;
+ }
+ };
+ try (PhoenixConnection phxConn = new PhoenixConnection(servicesWithUpgrade,
+ conn.unwrap(PhoenixConnection.class), HConstants.LATEST_TIMESTAMP)) {
+ try {
+ phxConn.createStatement().execute(
+ "CREATE TABLE " + generateRandomString()
+ + " (k1 VARCHAR NOT NULL, k2 VARCHAR, CONSTRAINT PK PRIMARY KEY(K1,K2))");
+ fail("CREATE TABLE should have failed with UpgradeRequiredException");
+ } catch (UpgradeRequiredException expected) {
+
+ }
+ try {
+ phxConn.createStatement().execute("SELECT * FROM " + tableName);
+ fail("SELECT should have failed with UpgradeRequiredException");
+ } catch (UpgradeRequiredException expected) {
+
+ }
+ try {
+ phxConn.createStatement().execute("DELETE FROM " + tableName);
+ fail("DELETE should have failed with UpgradeRequiredException");
+ } catch (UpgradeRequiredException expected) {
+
+ }
+ try {
+ phxConn.createStatement().execute(
+ "CREATE INDEX " + tableName + "_IDX ON " + tableName + " (KV1) INCLUDE (KV2)" );
+ fail("CREATE INDEX should have failed with UpgradeRequiredException");
+ } catch (UpgradeRequiredException expected) {
+
+ }
+ try {
+ phxConn.createStatement().execute(
+ "UPSERT INTO " + tableName + " VALUES ('PK1', 'PK2', 'KV1', 'KV2')" );
+ fail("UPSERT VALUES should have failed with UpgradeRequiredException");
+ } catch (UpgradeRequiredException expected) {
+
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testUpgradingConnectionBypassesUpgradeRequiredCheck() throws Exception {
+ String tableName = generateRandomString();
+ try (Connection conn = getConnection(false, null)) {
+ conn.createStatement()
+ .execute(
+ "CREATE TABLE "
+ + tableName
+ + " (PK1 VARCHAR NOT NULL, PK2 VARCHAR, KV1 VARCHAR, KV2 VARCHAR CONSTRAINT PK PRIMARY KEY(PK1, PK2))");
+ final ConnectionQueryServices delegate = conn.unwrap(PhoenixConnection.class).getQueryServices();
+ ConnectionQueryServices servicesWithUpgrade = new DelegateConnectionQueryServices(delegate) {
+ @Override
+ public boolean isUpgradeRequired() {
+ return true;
+ }
+ };
+ try (PhoenixConnection phxConn = new PhoenixConnection(servicesWithUpgrade,
+ conn.unwrap(PhoenixConnection.class), HConstants.LATEST_TIMESTAMP)) {
+ // Because upgrade is required, this SQL should fail.
+ try {
+ phxConn.createStatement().executeQuery("SELECT * FROM " + tableName);
+ fail("SELECT should have failed with UpgradeRequiredException");
+ } catch (UpgradeRequiredException expected) {
+
+ }
+ // Marking connection as the one running upgrade should let SQL execute fine.
+ phxConn.setRunningUpgrade(true);
+ phxConn.createStatement().execute(
+ "UPSERT INTO " + tableName + " VALUES ('PK1', 'PK2', 'KV1', 'KV2')" );
+ phxConn.commit();
+ try (ResultSet rs = phxConn.createStatement().executeQuery("SELECT * FROM " + tableName)) {
+ assertTrue(rs.next());
+ assertFalse(rs.next());
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testConcurrentUpgradeThrowsUprgadeInProgressException() throws Exception {
+ final AtomicBoolean mutexStatus1 = new AtomicBoolean(false);
+ final AtomicBoolean mutexStatus2 = new AtomicBoolean(false);
+ final CountDownLatch latch = new CountDownLatch(2);
+ final AtomicInteger numExceptions = new AtomicInteger(0);
+ try (Connection conn = getConnection(false, null)) {
+ final ConnectionQueryServices services = conn.unwrap(PhoenixConnection.class).getQueryServices();
+ Thread t1 = new Thread(new AcquireMutexRunnable(mutexStatus1, services, latch, numExceptions));
+ t1.setDaemon(true);
+ Thread t2 = new Thread(new AcquireMutexRunnable(mutexStatus2, services, latch, numExceptions));
+ t2.setDaemon(true);;
+ t1.start();
+ t2.start();
+ latch.await();
+ assertTrue("One of the threads should have acquired the mutex", mutexStatus1.get() || mutexStatus2.get());
+ assertNotEquals("One and only one thread should have acquired the mutex ", mutexStatus1.get(), mutexStatus2.get());
+ assertEquals("One and only one thread should have caught UpgradeRequiredException ", 1, numExceptions.get());
+ }
+ }
+
+ private static class AcquireMutexRunnable implements Runnable {
+
+ private final AtomicBoolean acquireStatus;
+ private final ConnectionQueryServices services;
+ private final CountDownLatch latch;
+ private final AtomicInteger numExceptions;
+ public AcquireMutexRunnable(AtomicBoolean acquireStatus, ConnectionQueryServices services, CountDownLatch latch, AtomicInteger numExceptions) {
+ this.acquireStatus = acquireStatus;
+ this.services = services;
+ this.latch = latch;
+ this.numExceptions = numExceptions;
+ }
+ @Override
+ public void run() {
+ try {
+ ((ConnectionQueryServicesImpl)services).acquireUpgradeMutex(
+ MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_7_0,
+ PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES);
+ acquireStatus.set(true);
+ } catch (UpgradeInProgressException e) {
+ numExceptions.incrementAndGet();
+ }
+ catch (IOException | SQLException ignore) {
+
+ } finally {
+ latch.countDown();
+ }
+ }
+
+ }
private Connection createTenantConnection(String tenantId) throws SQLException {
Properties props = new Properties();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/antlr3/PhoenixSQL.g
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/antlr3/PhoenixSQL.g b/phoenix-core/src/main/antlr3/PhoenixSQL.g
index 6716fdb..a6f9ef4 100644
--- a/phoenix-core/src/main/antlr3/PhoenixSQL.g
+++ b/phoenix-core/src/main/antlr3/PhoenixSQL.g
@@ -132,6 +132,8 @@ tokens
ROW = 'row';
ROWS = 'rows';
ONLY = 'only';
+ EXECUTE = 'execute';
+ UPGRADE = 'upgrade';
}
@@ -417,6 +419,7 @@ oneStatement returns [BindableStatement ret]
| s=drop_schema_node
| s=use_schema_node
| s=update_statistics_node
+ | s=execute_upgrade_node
| s=explain_node) { $ret = s; }
;
finally{ contextStack.pop(); }
@@ -568,7 +571,7 @@ trace_node returns [TraceStatement ret]
{ret = factory.trace(Tracing.isTraceOn(flag.getText()), s == null ? Tracing.isTraceOn(flag.getText()) ? 1.0 : 0.0 : (((BigDecimal)s.getValue())).doubleValue());}
;
-// Parse a trace statement.
+// Parse a create function statement.
create_function_node returns [CreateFunctionStatement ret]
: CREATE (OR replace=REPLACE)? (temp=TEMPORARY)? FUNCTION function=identifier
(LPAREN args=zero_or_more_data_types RPAREN)
@@ -611,6 +614,11 @@ update_statistics_node returns [UpdateStatisticsStatement ret]
{ret = factory.updateStatistics(factory.namedTable(null, t), s == null ? StatisticsCollectionScope.getDefault() : StatisticsCollectionScope.valueOf(SchemaUtil.normalizeIdentifier(s.getText())), p);}
;
+execute_upgrade_node returns [ExecuteUpgradeStatement ret]
+ : EXECUTE UPGRADE
+ {ret = factory.executeUpgrade();}
+ ;
+
prop_name returns [String ret]
: p=identifier {$ret = SchemaUtil.normalizeIdentifier(p); }
;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 06c35d1..96d8575 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -79,7 +79,6 @@ import static org.apache.phoenix.util.SchemaUtil.getVarChars;
import java.io.IOException;
import java.sql.DriverManager;
-import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
@@ -127,6 +126,7 @@ import org.apache.phoenix.cache.GlobalCache;
import org.apache.phoenix.cache.GlobalCache.FunctionBytesPtr;
import org.apache.phoenix.compile.ColumnResolver;
import org.apache.phoenix.compile.FromCompiler;
+import org.apache.phoenix.compile.QueryPlan;
import org.apache.phoenix.compile.ScanRanges;
import org.apache.phoenix.compile.StatementContext;
import org.apache.phoenix.compile.WhereCompiler;
@@ -162,8 +162,10 @@ import org.apache.phoenix.hbase.index.util.GenericKeyValueBuilder;
import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
import org.apache.phoenix.index.IndexMaintainer;
+import org.apache.phoenix.iterate.ResultIterator;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+import org.apache.phoenix.jdbc.PhoenixResultSet;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.metrics.Metrics;
import org.apache.phoenix.parse.LiteralParseNode;
@@ -212,7 +214,6 @@ import org.apache.phoenix.util.EnvironmentEdgeManager;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.KeyValueUtil;
import org.apache.phoenix.util.MetaDataUtil;
-import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.QueryUtil;
import org.apache.phoenix.util.ReadOnlyProps;
import org.apache.phoenix.util.SchemaUtil;
@@ -1415,12 +1416,17 @@ public class MetaDataEndpointImpl extends MetaDataProtocol implements Coprocesso
if (parentTable!=null && parentTable.getAutoPartitionSeqName()!=null) {
long autoPartitionNum = 1;
final Properties props = new Properties();
- props.setProperty(PhoenixRuntime.NO_UPGRADE_ATTRIB, Boolean.TRUE.toString());
+ UpgradeUtil.doNotUpgradeOnFirstConnection(props);
try (PhoenixConnection connection = DriverManager.getConnection(MetaDataUtil.getJdbcUrl(env), props).unwrap(PhoenixConnection.class);
- Statement stmt = connection.createStatement()) {
+ Statement stmt = connection.createStatement()) {
String seqName = parentTable.getAutoPartitionSeqName();
+ // Not going through the standard route of using statement.execute() as that code path
+ // is blocked if the metadata hasn't been been upgraded to the new minor release.
String seqNextValueSql = String.format("SELECT NEXT VALUE FOR %s", seqName);
- ResultSet rs = stmt.executeQuery(seqNextValueSql);
+ PhoenixStatement ps = stmt.unwrap(PhoenixStatement.class);
+ QueryPlan plan = ps.compileQuery(seqNextValueSql);
+ ResultIterator resultIterator = plan.iterator();
+ PhoenixResultSet rs = ps.newResultSet(resultIterator, plan.getProjector(), plan.getContext());
rs.next();
autoPartitionNum = rs.getLong(1);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataRegionObserver.java
index aef5c69..2ab5df6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataRegionObserver.java
@@ -18,8 +18,10 @@
package org.apache.phoenix.coprocessor;
import java.io.IOException;
+import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -54,20 +56,23 @@ import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.phoenix.cache.GlobalCache;
import org.apache.phoenix.cache.ServerCacheClient;
+import org.apache.phoenix.coprocessor.MetaDataProtocol.MetaDataMutationResult;
+import org.apache.phoenix.coprocessor.MetaDataProtocol.MutationCode;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
import org.apache.phoenix.hbase.index.util.IndexManagementUtil;
import org.apache.phoenix.index.IndexMaintainer;
import org.apache.phoenix.index.PhoenixIndexCodec;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
import org.apache.phoenix.jdbc.PhoenixDriver;
-import org.apache.phoenix.parse.AlterIndexStatement;
-import org.apache.phoenix.parse.NamedTableNode;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.query.QueryServicesOptions;
import org.apache.phoenix.schema.MetaDataClient;
import org.apache.phoenix.schema.PIndexState;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.TableNotFoundException;
import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.schema.types.PLong;
import org.apache.phoenix.util.ByteUtil;
@@ -80,6 +85,7 @@ import org.apache.phoenix.util.UpgradeUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.protobuf.ServiceException;
/**
@@ -297,11 +303,7 @@ public class MetaDataRegionObserver extends BaseRegionObserver {
// Allow index to begin incremental maintenance as index is back online and we
// cannot transition directly from DISABLED -> ACTIVE
if (Bytes.compareTo(PIndexState.DISABLE.getSerializedBytes(), indexState) == 0) {
- AlterIndexStatement statement = new AlterIndexStatement(
- NamedTableNode.create(indexPTable.getSchemaName().getString(), indexPTable.getTableName().getString()),
- dataPTable.getTableName().getString(),
- false, PIndexState.INACTIVE);
- client.alterIndex(statement);
+ updateIndexState(indexTableFullName, env, PIndexState.DISABLE, PIndexState.INACTIVE);
}
List<PTable> indexesToPartiallyRebuild = dataTableToIndexesMap.get(dataPTable);
if (indexesToPartiallyRebuild == null) {
@@ -393,11 +395,9 @@ public class MetaDataRegionObserver extends BaseRegionObserver {
}
}
for (PTable indexPTable : indexesToPartiallyRebuild) {
- AlterIndexStatement statement = new AlterIndexStatement(
- NamedTableNode.create(indexPTable.getSchemaName().getString(), indexPTable
- .getTableName().getString()), dataPTable.getTableName().getString(),
- false, PIndexState.ACTIVE);
- client.alterIndex(statement);
+ String indexTableFullName = SchemaUtil.getTableName(indexPTable.getSchemaName()
+ .getString(), indexPTable.getTableName().getString());
+ updateIndexState(indexTableFullName, env, PIndexState.INACTIVE, PIndexState.ACTIVE);
}
} catch (Exception e) { // Log, but try next table's indexes
LOG.warn("Unable to rebuild " + dataPTable + " indexes " + indexesToPartiallyRebuild
@@ -426,4 +426,30 @@ public class MetaDataRegionObserver extends BaseRegionObserver {
}
}
}
+
+
+ private static void updateIndexState(String indexTableName, RegionCoprocessorEnvironment env, PIndexState oldState,
+ PIndexState newState) throws ServiceException, Throwable {
+ byte[] indexTableKey = SchemaUtil.getTableKeyFromFullName(indexTableName);
+ String schemaName = SchemaUtil.getSchemaNameFromFullName(indexTableName);
+ String indexName = SchemaUtil.getSchemaNameFromFullName(indexTableName);
+ // Mimic the Put that gets generated by the client on an update of the index state
+ Put put = new Put(indexTableKey);
+ put.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES, PhoenixDatabaseMetaData.INDEX_STATE_BYTES,
+ newState.getSerializedBytes());
+ if (newState == PIndexState.ACTIVE) {
+ put.add(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES, PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP_BYTES,
+ PLong.INSTANCE.toBytes(0));
+ }
+ final List<Mutation> tableMetadata = Collections.<Mutation> singletonList(put);
+ Connection conn = QueryUtil.getConnection(env.getConfiguration());
+ MetaDataMutationResult result = conn.unwrap(PhoenixConnection.class).getQueryServices()
+ .updateIndexState(tableMetadata, null);
+ MutationCode code = result.getMutationCode();
+ if (code == MutationCode.TABLE_NOT_FOUND) { throw new TableNotFoundException(schemaName, indexName); }
+ if (code == MutationCode.UNALLOWED_TABLE_MUTATION) { throw new SQLExceptionInfo.Builder(
+ SQLExceptionCode.INVALID_INDEX_STATE_TRANSITION)
+ .setMessage(" currentState=" + oldState + ". requestedState=" + newState).setSchemaName(schemaName)
+ .setTableName(indexName).build().buildException(); }
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
index 0ccecae..e6a26ae 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
@@ -371,6 +371,8 @@ public enum SQLExceptionCode {
INDEX_METADATA_NOT_FOUND(2008, "INT10", "Unable to find cached index metadata. "),
UNKNOWN_ERROR_CODE(2009, "INT11", "Unknown error code."),
CONCURRENT_UPGRADE_IN_PROGRESS(2010, "INT12", ""),
+ UPGRADE_REQUIRED(2011, "INT13", ""),
+ UPGRADE_NOT_REQUIRED(2012, "INT14", ""),
OPERATION_TIMED_OUT(6000, "TIM01", "Operation timed out.", new Factory() {
@Override
public SQLException newException(SQLExceptionInfo info) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeInProgressException.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeInProgressException.java b/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeInProgressException.java
new file mode 100644
index 0000000..5b15216
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeInProgressException.java
@@ -0,0 +1,28 @@
+/*
+ * 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.exception;
+
+import java.sql.SQLException;
+
+public class UpgradeInProgressException extends SQLException {
+ public UpgradeInProgressException(String upgradeFrom, String upgradeTo) {
+ super("Cluster is being concurrently upgraded from " + upgradeFrom + " to " + upgradeTo
+ + ". Please retry establishing connection.", SQLExceptionCode.CONCURRENT_UPGRADE_IN_PROGRESS
+ .getSQLState(), SQLExceptionCode.CONCURRENT_UPGRADE_IN_PROGRESS.getErrorCode());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeNotRequiredException.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeNotRequiredException.java b/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeNotRequiredException.java
new file mode 100644
index 0000000..0490319
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeNotRequiredException.java
@@ -0,0 +1,27 @@
+/*
+ * 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.exception;
+
+import java.sql.SQLException;
+
+public class UpgradeNotRequiredException extends SQLException {
+ public UpgradeNotRequiredException() {
+ super("Operation not allowed since cluster has already been upgraded. ", SQLExceptionCode.UPGRADE_NOT_REQUIRED
+ .getSQLState(), SQLExceptionCode.UPGRADE_NOT_REQUIRED.getErrorCode());
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeRequiredException.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeRequiredException.java b/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeRequiredException.java
new file mode 100644
index 0000000..005a1bd
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeRequiredException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.exception;
+
+import java.sql.SQLException;
+
+public class UpgradeRequiredException extends SQLException {
+
+ public UpgradeRequiredException() {
+ super("Operation not allowed since cluster hasn't been upgraded. Call EXECUTE UPGRADE. ",
+ SQLExceptionCode.UPGRADE_REQUIRED.getSQLState(), SQLExceptionCode.UPGRADE_REQUIRED.getErrorCode());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index 7ff4fdf..7cdab20 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -161,6 +161,7 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
private ParallelIteratorFactory parallelIteratorFactory;
private final LinkedBlockingQueue<WeakReference<TableResultIterator>> scannerQueue;
private TableResultIteratorFactory tableResultIteratorFactory;
+ private boolean isRunningUpgrade;
static {
Tracing.addTraceMetricsSource();
@@ -172,8 +173,8 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
return props;
}
- public PhoenixConnection(PhoenixConnection connection, boolean isDescRowKeyOrderUpgrade) throws SQLException {
- this(connection.getQueryServices(), connection.getURL(), connection.getClientInfo(), connection.metaData, connection.getMutationState(), isDescRowKeyOrderUpgrade);
+ public PhoenixConnection(PhoenixConnection connection, boolean isDescRowKeyOrderUpgrade, boolean isRunningUpgrade) throws SQLException {
+ this(connection.getQueryServices(), connection.getURL(), connection.getClientInfo(), connection.metaData, connection.getMutationState(), isDescRowKeyOrderUpgrade, isRunningUpgrade);
this.isAutoCommit = connection.isAutoCommit;
this.isAutoFlush = connection.isAutoFlush;
this.sampler = connection.sampler;
@@ -181,11 +182,11 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
}
public PhoenixConnection(PhoenixConnection connection) throws SQLException {
- this(connection, connection.isDescVarLengthRowKeyUpgrade());
+ this(connection, connection.isDescVarLengthRowKeyUpgrade(), connection.isRunningUpgrade());
}
public PhoenixConnection(PhoenixConnection connection, MutationState mutationState) throws SQLException {
- this(connection.getQueryServices(), connection.getURL(), connection.getClientInfo(), connection.getMetaDataCache(), mutationState, connection.isDescVarLengthRowKeyUpgrade());
+ this(connection.getQueryServices(), connection.getURL(), connection.getClientInfo(), connection.getMetaDataCache(), mutationState, connection.isDescVarLengthRowKeyUpgrade(), connection.isRunningUpgrade());
}
public PhoenixConnection(PhoenixConnection connection, long scn) throws SQLException {
@@ -193,7 +194,7 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
}
public PhoenixConnection(ConnectionQueryServices services, PhoenixConnection connection, long scn) throws SQLException {
- this(services, connection.getURL(), newPropsWithSCN(scn,connection.getClientInfo()), connection.metaData, connection.getMutationState(), connection.isDescVarLengthRowKeyUpgrade());
+ this(services, connection.getURL(), newPropsWithSCN(scn,connection.getClientInfo()), connection.metaData, connection.getMutationState(), connection.isDescVarLengthRowKeyUpgrade(), connection.isRunningUpgrade());
this.isAutoCommit = connection.isAutoCommit;
this.isAutoFlush = connection.isAutoFlush;
this.sampler = connection.sampler;
@@ -201,14 +202,14 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
}
public PhoenixConnection(ConnectionQueryServices services, String url, Properties info, PMetaData metaData) throws SQLException {
- this(services, url, info, metaData, null, false);
+ this(services, url, info, metaData, null, false, false);
}
public PhoenixConnection(PhoenixConnection connection, ConnectionQueryServices services, Properties info) throws SQLException {
- this(services, connection.url, info, connection.metaData, null, connection.isDescVarLengthRowKeyUpgrade());
+ this(services, connection.url, info, connection.metaData, null, connection.isDescVarLengthRowKeyUpgrade(), connection.isRunningUpgrade());
}
- public PhoenixConnection(ConnectionQueryServices services, String url, Properties info, PMetaData metaData, MutationState mutationState, boolean isDescVarLengthRowKeyUpgrade) throws SQLException {
+ public PhoenixConnection(ConnectionQueryServices services, String url, Properties info, PMetaData metaData, MutationState mutationState, boolean isDescVarLengthRowKeyUpgrade, boolean isRunningUpgrade) throws SQLException {
this.url = url;
this.isDescVarLengthRowKeyUpgrade = isDescVarLengthRowKeyUpgrade;
// Copy so client cannot change
@@ -294,6 +295,7 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
this.customTracingAnnotations = getImmutableCustomTracingAnnotations();
this.scannerQueue = new LinkedBlockingQueue<>();
this.tableResultIteratorFactory = new DefaultTableResultIteratorFactory();
+ this.isRunningUpgrade = isRunningUpgrade;
GLOBAL_OPEN_PHOENIX_CONNECTIONS.increment();
}
@@ -1055,4 +1057,13 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
getQueryServices().removeSchema(schema, schemaTimeStamp);
}
+
+ public boolean isRunningUpgrade() {
+ return isRunningUpgrade;
+ }
+
+ public void setRunningUpgrade(boolean isRunningUpgrade) {
+ this.isRunningUpgrade = isRunningUpgrade;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index 17c2a1c..5a4a791 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -515,7 +515,7 @@ public class PhoenixDatabaseMetaData implements DatabaseMetaData {
public PhoenixStatement newStatement(PhoenixConnection connection) {
return new PhoenixStatement(connection) {
@Override
- protected PhoenixResultSet newResultSet(ResultIterator iterator, RowProjector projector,
+ public PhoenixResultSet newResultSet(ResultIterator iterator, RowProjector projector,
StatementContext context) throws SQLException {
return new PhoenixResultSet(new TenantColumnFilteringIterator(iterator, projector),
projector, context);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
index a7b2587..da7c7e8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
@@ -37,6 +37,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
import org.apache.hadoop.conf.Configuration;
@@ -77,6 +78,7 @@ import org.apache.phoenix.coprocessor.MetaDataProtocol;
import org.apache.phoenix.exception.BatchUpdateExecution;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
+import org.apache.phoenix.exception.UpgradeRequiredException;
import org.apache.phoenix.execute.MutationState;
import org.apache.phoenix.expression.RowKeyColumnExpression;
import org.apache.phoenix.iterate.MaterializedResultIterator;
@@ -102,6 +104,7 @@ import org.apache.phoenix.parse.DropIndexStatement;
import org.apache.phoenix.parse.DropSchemaStatement;
import org.apache.phoenix.parse.DropSequenceStatement;
import org.apache.phoenix.parse.DropTableStatement;
+import org.apache.phoenix.parse.ExecuteUpgradeStatement;
import org.apache.phoenix.parse.ExplainStatement;
import org.apache.phoenix.parse.FilterableStatement;
import org.apache.phoenix.parse.HintNode;
@@ -189,7 +192,8 @@ public class PhoenixStatement implements Statement, SQLCloseable {
public enum Operation {
QUERY("queried", false),
DELETE("deleted", true),
- UPSERT("upserted", true);
+ UPSERT("upserted", true),
+ UPGRADE("upgrade", true);
private final String toString;
private final boolean isMutation;
@@ -238,7 +242,7 @@ public class PhoenixStatement implements Statement, SQLCloseable {
return resultSets;
}
- protected PhoenixResultSet newResultSet(ResultIterator iterator, RowProjector projector, StatementContext context) throws SQLException {
+ public PhoenixResultSet newResultSet(ResultIterator iterator, RowProjector projector, StatementContext context) throws SQLException {
return new PhoenixResultSet(iterator, projector, context);
}
@@ -265,7 +269,12 @@ public class PhoenixStatement implements Statement, SQLCloseable {
public PhoenixResultSet call() throws SQLException {
final long startTime = System.currentTimeMillis();
try {
- QueryPlan plan = stmt.compilePlan(PhoenixStatement.this, Sequence.ValueOp.VALIDATE_SEQUENCE);
+ PhoenixConnection conn = getConnection();
+ if (conn.getQueryServices().isUpgradeRequired() && !conn.isRunningUpgrade()
+ && stmt.getOperation() != Operation.UPGRADE) {
+ throw new UpgradeRequiredException();
+ }
+ QueryPlan plan = stmt.compilePlan(PhoenixStatement.this, Sequence.ValueOp.VALIDATE_SEQUENCE);
// Send mutations to hbase, so they are visible to subsequent reads.
// Use original plan for data table so that data and immutable indexes will be sent
// TODO: for joins, we need to iterate through all tables, but we need the original table,
@@ -330,6 +339,11 @@ public class PhoenixStatement implements Statement, SQLCloseable {
@Override
public Integer call() throws SQLException {
try {
+ PhoenixConnection conn = getConnection();
+ if (conn.getQueryServices().isUpgradeRequired() && !conn.isRunningUpgrade()
+ && stmt.getOperation() != Operation.UPGRADE) {
+ throw new UpgradeRequiredException();
+ }
MutationState state = connection.getMutationState();
MutationPlan plan = stmt.compilePlan(PhoenixStatement.this, Sequence.ValueOp.VALIDATE_SEQUENCE);
if (plan.getTargetRef() != null && plan.getTargetRef().getTable() != null && plan.getTargetRef().getTable().isTransactional()) {
@@ -1032,6 +1046,53 @@ public class PhoenixStatement implements Statement, SQLCloseable {
}
}
+
+ private static class ExecutableExecuteUpgradeStatement extends ExecuteUpgradeStatement implements CompilableStatement {
+ @SuppressWarnings("unchecked")
+ @Override
+ public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+ return new MutationPlan() {
+
+ @Override
+ public Set<TableRef> getSourceRefs() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public ParameterMetaData getParameterMetaData() {
+ return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
+ }
+
+ @Override
+ public Operation getOperation() {
+ return Operation.UPGRADE;
+ }
+
+ @Override
+ public ExplainPlan getExplainPlan() throws SQLException {
+ return new ExplainPlan(Collections.singletonList("EXECUTE UPGRADE"));
+ }
+
+ @Override
+ public StatementContext getContext() {
+ return new StatementContext(stmt);
+ }
+
+ @Override
+ public TableRef getTargetRef() {
+ return TableRef.EMPTY_TABLE_REF;
+ }
+
+ @Override
+ public MutationState execute() throws SQLException {
+ PhoenixConnection phxConn = stmt.getConnection();
+ Properties props = new Properties();
+ phxConn.getQueryServices().upgradeSystemTables(phxConn.getURL(), props);
+ return MutationState.emptyMutationState(-1, phxConn);
+ }
+ };
+ }
+ }
private static class ExecutableAddColumnStatement extends AddColumnStatement implements CompilableStatement {
@@ -1209,6 +1270,11 @@ public class PhoenixStatement implements Statement, SQLCloseable {
public UpdateStatisticsStatement updateStatistics(NamedTableNode table, StatisticsCollectionScope scope, Map<String,Object> props) {
return new ExecutableUpdateStatisticsStatement(table, scope, props);
}
+
+ @Override
+ public ExecuteUpgradeStatement executeUpgrade() {
+ return new ExecutableExecuteUpgradeStatement();
+ }
}
static class PhoenixStatementParser extends SQLParser {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/automation/PhoenixMRJobSubmitter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/automation/PhoenixMRJobSubmitter.java b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/automation/PhoenixMRJobSubmitter.java
index f6f2482..9c447e8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/automation/PhoenixMRJobSubmitter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/automation/PhoenixMRJobSubmitter.java
@@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -52,6 +53,7 @@ import org.apache.phoenix.schema.PTable.IndexType;
import org.apache.phoenix.schema.PTableType;
import org.apache.phoenix.schema.types.PDate;
import org.apache.phoenix.util.PhoenixMRJobUtil;
+import org.apache.phoenix.util.UpgradeUtil;
import org.apache.phoenix.util.PhoenixMRJobUtil.MR_SCHEDULER_TYPE;
import org.apache.phoenix.util.ZKBasedMasterElectionUtil;
import org.codehaus.jettison.json.JSONArray;
@@ -158,6 +160,8 @@ public class PhoenixMRJobSubmitter {
}
public Map<String, PhoenixAsyncIndex> getCandidateJobs() throws SQLException {
+ Properties props = new Properties();
+ UpgradeUtil.doNotUpgradeOnFirstConnection(props);
Connection con = DriverManager.getConnection("jdbc:phoenix:" + zkQuorum);
Statement s = con.createStatement();
ResultSet rs = s.executeQuery(CANDIDATE_INDEX_INFO_QUERY);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/parse/ExecuteUpgradeStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ExecuteUpgradeStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ExecuteUpgradeStatement.java
new file mode 100644
index 0000000..29edf8f
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ExecuteUpgradeStatement.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.parse;
+
+import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
+
+public class ExecuteUpgradeStatement implements BindableStatement {
+
+ @Override
+ public int getBindCount() {
+ return 0;
+ }
+
+ @Override
+ public Operation getOperation() {
+ return Operation.UPGRADE;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
index 282ec62..d633299 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
@@ -389,6 +389,10 @@ public class ParseNodeFactory {
public UpdateStatisticsStatement updateStatistics(NamedTableNode table, StatisticsCollectionScope scope, Map<String,Object> props) {
return new UpdateStatisticsStatement(table, scope, props);
}
+
+ public ExecuteUpgradeStatement executeUpgrade() {
+ return new ExecuteUpgradeStatement();
+ }
public FunctionParseNode functionDistinct(String name, List<ParseNode> args) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/887b57cf/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
index 7154d58..6f8b528 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
@@ -139,4 +139,7 @@ public interface ConnectionQueryServices extends QueryServices, MetaDataMutated
* @param tableName The table to remove stats for
*/
void invalidateStats(ImmutableBytesPtr tableName);
+
+ boolean isUpgradeRequired();
+ void upgradeSystemTables(String url, Properties props) throws SQLException;
}
\ No newline at end of file