Repository: phoenix Updated Branches: refs/heads/4.x-HBase-1.1 716096498 -> 6b38c1e3d
PHOENIX-3837 cherry pick PHOENIX-3837,PHOENIX-4361 for 4.x-HBase-1.1 Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/6b38c1e3 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/6b38c1e3 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/6b38c1e3 Branch: refs/heads/4.x-HBase-1.1 Commit: 6b38c1e3d47bbd41a45c36080b82e29ae1e5db42 Parents: 7160964 Author: aertoria <casti...@gmail.com> Authored: Mon Nov 27 11:58:01 2017 -0800 Committer: aertoria <ew...@apache.org> Committed: Wed Apr 18 16:07:33 2018 -0700 ---------------------------------------------------------------------- .../apache/phoenix/end2end/AlterTableIT.java | 2 +- .../phoenix/end2end/index/IndexMetadataIT.java | 55 +++++ phoenix-core/src/main/antlr3/PhoenixSQL.g | 5 +- .../apache/phoenix/jdbc/PhoenixStatement.java | 10 +- .../phoenix/parse/AddColumnStatement.java | 2 +- .../phoenix/parse/AlterIndexStatement.java | 14 ++ .../apache/phoenix/parse/ParseNodeFactory.java | 6 +- .../phoenix/query/ConnectionQueryServices.java | 2 + .../query/ConnectionQueryServicesImpl.java | 24 +- .../query/ConnectionlessQueryServicesImpl.java | 7 + .../query/DelegateConnectionQueryServices.java | 8 +- .../apache/phoenix/schema/MetaDataClient.java | 244 +++++-------------- 12 files changed, 175 insertions(+), 204 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/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 index d999f6a..dd895dc 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java @@ -1080,7 +1080,7 @@ public class AlterTableIT extends ParallelStatsDisabledIT { } catch (SQLException e) { assertEquals(SQLExceptionCode.CANNOT_CREATE_TXN_TABLE_IF_TXNS_DISABLED.getErrorCode(), e.getErrorCode()); } - // altering a table to be transactional should fail if transactions are disabled + // altering a table to be transactional should fail if transactions are disabled conn.createStatement().execute("CREATE TABLE " + dataTableFullName + "(k INTEGER PRIMARY KEY, v VARCHAR)"); try { conn.createStatement().execute("ALTER TABLE " + dataTableFullName + " SET TRANSACTIONAL=true"); http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java index 0ce36dd..986c317 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexMetadataIT.java @@ -674,4 +674,59 @@ public class IndexMetadataIT extends ParallelStatsDisabledIT { conn.close(); } } + + + + @Test + public void testIndexAlterPhoenixProperty() throws Exception { + Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); + Connection conn = DriverManager.getConnection(getUrl(), props); + String testTable = generateUniqueName(); + + + String ddl = "create table " + testTable + " (k varchar primary key, v1 varchar)"; + Statement stmt = conn.createStatement(); + stmt.execute(ddl); + String indexName = "IDX_" + generateUniqueName(); + + ddl = "CREATE INDEX " + indexName + " ON " + testTable + " (v1) "; + stmt.execute(ddl); + conn.createStatement().execute("ALTER INDEX "+indexName+" ON " + testTable +" ACTIVE SET GUIDE_POSTS_WIDTH = 10"); + + ResultSet rs = conn.createStatement().executeQuery( + "select GUIDE_POSTS_WIDTH from SYSTEM.\"CATALOG\" where TABLE_NAME='" + indexName + "'");assertTrue(rs.next()); + assertEquals(10,rs.getInt(1)); + + conn.createStatement().execute("ALTER INDEX "+indexName+" ON " + testTable +" ACTIVE SET GUIDE_POSTS_WIDTH = 20"); + rs = conn.createStatement().executeQuery( + "select GUIDE_POSTS_WIDTH from SYSTEM.\"CATALOG\" where TABLE_NAME='" + indexName + "'");assertTrue(rs.next()); + assertEquals(20,rs.getInt(1)); + } + + + @Test + public void testIndexAlterHBaseProperty() throws Exception { + Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); + Connection conn = DriverManager.getConnection(getUrl(), props); + String testTable = generateUniqueName(); + + String ddl = "create table " + testTable + " (k varchar primary key, v1 varchar)"; + Statement stmt = conn.createStatement(); + stmt.execute(ddl); + String indexName = "IDX_" + generateUniqueName(); + + ddl = "CREATE INDEX " + indexName + " ON " + testTable + " (v1) "; + stmt.execute(ddl); + + conn.createStatement().execute("ALTER INDEX "+indexName+" ON " + testTable +" ACTIVE SET DISABLE_WAL=false"); + asssertIsWALDisabled(conn,indexName,false); + conn.createStatement().execute("ALTER INDEX "+indexName+" ON " + testTable +" ACTIVE SET DISABLE_WAL=true"); + asssertIsWALDisabled(conn,indexName,true); + } + + private static void asssertIsWALDisabled(Connection conn, String fullTableName, boolean expectedValue) throws SQLException { + PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class); + assertEquals(expectedValue, pconn.getTable(new PTableKey(pconn.getTenantId(), fullTableName)).isWALDisabled()); + } + } http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/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 93e0ede..476ce38 100644 --- a/phoenix-core/src/main/antlr3/PhoenixSQL.g +++ b/phoenix-core/src/main/antlr3/PhoenixSQL.g @@ -576,8 +576,9 @@ drop_index_node returns [DropIndexStatement ret] // Parse a alter index statement alter_index_node returns [AlterIndexStatement ret] - : ALTER INDEX (IF ex=EXISTS)? i=index_name ON t=from_table_name s=(USABLE | UNUSABLE | REBUILD | DISABLE | ACTIVE) (async=ASYNC)? - {ret = factory.alterIndex(factory.namedTable(null, TableName.create(t.getSchemaName(), i.getName())), t.getTableName(), ex!=null, PIndexState.valueOf(SchemaUtil.normalizeIdentifier(s.getText())), async!=null); } + : ALTER INDEX (IF ex=EXISTS)? i=index_name ON t=from_table_name + ((s=(USABLE | UNUSABLE | REBUILD | DISABLE | ACTIVE)) (async=ASYNC)? ((SET?)p=fam_properties)?) + {ret = factory.alterIndex(factory.namedTable(null, TableName.create(t.getSchemaName(), i.getName())), t.getTableName(), ex!=null, PIndexState.valueOf(SchemaUtil.normalizeIdentifier(s.getText())), async!=null, p); } ; // Parse a trace statement. http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/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 1f37ea1..00b60b9 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 @@ -1215,8 +1215,8 @@ public class PhoenixStatement implements Statement, SQLCloseable { private static class ExecutableAlterIndexStatement extends AlterIndexStatement implements CompilableStatement { - public ExecutableAlterIndexStatement(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState state, boolean async) { - super(indexTableNode, dataTableName, ifExists, state, async); + public ExecutableAlterIndexStatement(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState state, boolean async, ListMultimap<String,Pair<String,Object>> props) { + super(indexTableNode, dataTableName, ifExists, state, async, props); } @SuppressWarnings("unchecked") @@ -1562,10 +1562,10 @@ public class PhoenixStatement implements Statement, SQLCloseable { public DropIndexStatement dropIndex(NamedNode indexName, TableName tableName, boolean ifExists) { return new ExecutableDropIndexStatement(indexName, tableName, ifExists); } - + @Override - public AlterIndexStatement alterIndex(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState state, boolean async) { - return new ExecutableAlterIndexStatement(indexTableNode, dataTableName, ifExists, state, async); + public AlterIndexStatement alterIndex(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState state, boolean async, ListMultimap<String,Pair<String,Object>> props) { + return new ExecutableAlterIndexStatement(indexTableNode, dataTableName, ifExists, state, async, props); } @Override http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/phoenix-core/src/main/java/org/apache/phoenix/parse/AddColumnStatement.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/AddColumnStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/AddColumnStatement.java index 1890d31..678e560 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/parse/AddColumnStatement.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/AddColumnStatement.java @@ -48,4 +48,4 @@ public class AddColumnStatement extends AlterTableStatement { public ListMultimap<String,Pair<String,Object>> getProps() { return props; } -} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterIndexStatement.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterIndexStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterIndexStatement.java index 11328c2..de04505 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterIndexStatement.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/AlterIndexStatement.java @@ -17,20 +17,31 @@ */ package org.apache.phoenix.parse; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ListMultimap; +import org.apache.hadoop.hbase.util.Pair; import org.apache.phoenix.schema.PIndexState; +import org.apache.phoenix.schema.PTableType; public class AlterIndexStatement extends SingleTableStatement { private final String dataTableName; private final boolean ifExists; private final PIndexState indexState; private boolean async; + private ListMultimap<String,Pair<String,Object>> props; + private static final PTableType tableType=PTableType.INDEX; public AlterIndexStatement(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState indexState, boolean async) { + this(indexTableNode,dataTableName,ifExists,indexState,async,null); + } + + public AlterIndexStatement(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState indexState, boolean async, ListMultimap<String,Pair<String,Object>> props) { super(indexTableNode,0); this.dataTableName = dataTableName; this.ifExists = ifExists; this.indexState = indexState; this.async = async; + this.props= props==null ? ImmutableListMultimap.<String,Pair<String,Object>>of() : props; } public String getTableName() { @@ -54,4 +65,7 @@ public class AlterIndexStatement extends SingleTableStatement { return async; } + public ListMultimap<String,Pair<String,Object>> getProps() { return props; } + + public PTableType getTableType(){ return tableType; } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/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 0058f38..36510fe 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 @@ -374,10 +374,10 @@ public class ParseNodeFactory { return new DropIndexStatement(indexName, tableName, ifExists); } - public AlterIndexStatement alterIndex(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState state, boolean async) { - return new AlterIndexStatement(indexTableNode, dataTableName, ifExists, state, async); + public AlterIndexStatement alterIndex(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState state, boolean async, ListMultimap<String,Pair<String,Object>> props) { + return new AlterIndexStatement(indexTableNode, dataTableName, ifExists, state, async, props); } - + public AlterIndexStatement alterIndex(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState state) { return new AlterIndexStatement(indexTableNode, dataTableName, ifExists, state, false); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/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 3d1848f..092bfe9 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 @@ -90,6 +90,8 @@ public interface ConnectionQueryServices extends QueryServices, MetaDataMutated public MetaDataMutationResult addColumn(List<Mutation> tableMetaData, PTable table, Map<String, List<Pair<String,Object>>> properties, Set<String> colFamiliesForPColumnsToBeAdded, List<PColumn> columns) throws SQLException; public MetaDataMutationResult dropColumn(List<Mutation> tableMetadata, PTableType tableType) throws SQLException; public MetaDataMutationResult updateIndexState(List<Mutation> tableMetadata, String parentTableName) throws SQLException; + public MetaDataMutationResult updateIndexState(List<Mutation> tableMetadata, String parentTableName, Map<String, List<Pair<String,Object>>> stmtProperties, PTable table) throws SQLException; + public MutationState updateData(MutationPlan plan) throws SQLException; public void init(String url, Properties props) throws SQLException; http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java index 5e43b1d..e0f1366 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java @@ -1802,7 +1802,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement Set<HTableDescriptor> tableDescriptors = Collections.emptySet(); Set<HTableDescriptor> origTableDescriptors = Collections.emptySet(); boolean nonTxToTx = false; - Pair<HTableDescriptor,HTableDescriptor> tableDescriptorPair = separateAndValidateProperties(table, stmtProperties, colFamiliesForPColumnsToBeAdded, families, tableProps); + Pair<HTableDescriptor,HTableDescriptor> tableDescriptorPair = separateAndValidateProperties(table, stmtProperties, colFamiliesForPColumnsToBeAdded, tableProps); HTableDescriptor tableDescriptor = tableDescriptorPair.getSecond(); HTableDescriptor origTableDescriptor = tableDescriptorPair.getFirst(); if (tableDescriptor != null) { @@ -2020,7 +2020,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement this.addCoprocessors(tableDescriptor.getName(), tableDescriptor, tableType, tableProps); } - private Pair<HTableDescriptor,HTableDescriptor> separateAndValidateProperties(PTable table, Map<String, List<Pair<String, Object>>> properties, Set<String> colFamiliesForPColumnsToBeAdded, List<Pair<byte[], Map<String, Object>>> families, Map<String, Object> tableProps) throws SQLException { + private Pair<HTableDescriptor,HTableDescriptor> separateAndValidateProperties(PTable table, Map<String, List<Pair<String, Object>>> properties, Set<String> colFamiliesForPColumnsToBeAdded, Map<String, Object> tableProps) throws SQLException { Map<String, Map<String, Object>> stmtFamiliesPropsMap = new HashMap<>(properties.size()); Map<String,Object> commonFamilyProps = new HashMap<>(); boolean addingColumns = colFamiliesForPColumnsToBeAdded != null && !colFamiliesForPColumnsToBeAdded.isEmpty(); @@ -3747,6 +3747,26 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement } @Override + public MetaDataMutationResult updateIndexState(final List<Mutation> tableMetaData, String parentTableName, Map<String, List<Pair<String,Object>>> stmtProperties, PTable table) throws SQLException { + if(stmtProperties==null) return updateIndexState(tableMetaData,parentTableName); + + Map<String, Object> tableProps = new HashMap<String, Object>(); + Pair<HTableDescriptor,HTableDescriptor> tableDescriptorPair = separateAndValidateProperties(table, stmtProperties, new HashSet<String>(), tableProps); + HTableDescriptor tableDescriptor = tableDescriptorPair.getSecond(); + HTableDescriptor origTableDescriptor = tableDescriptorPair.getFirst(); + Set<HTableDescriptor> tableDescriptors = Collections.emptySet(); + Set<HTableDescriptor> origTableDescriptors = Collections.emptySet(); + if (tableDescriptor != null) { + tableDescriptors = Sets.newHashSetWithExpectedSize(3 + table.getIndexes().size()); + origTableDescriptors = Sets.newHashSetWithExpectedSize(3 + table.getIndexes().size()); + tableDescriptors.add(tableDescriptor); + origTableDescriptors.add(origTableDescriptor); + } + sendHBaseMetaData(tableDescriptors, true); + return updateIndexState(tableMetaData,parentTableName); + } + + @Override public long createSequence(String tenantId, String schemaName, String sequenceName, long startWith, long incrementBy, long cacheSize, long minValue, long maxValue, boolean cycle, long timestamp) throws SQLException { http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java index 4133b54..aba9600 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java @@ -426,6 +426,13 @@ public class ConnectionlessQueryServicesImpl extends DelegateQueryServices imple } @Override + public MetaDataMutationResult updateIndexState(List<Mutation> tableMetadata, + String parentTableName, Map<String, List<Pair<String, Object>>> stmtProperties, + PTable table) throws SQLException { + return updateIndexState(tableMetadata,parentTableName); + } + + @Override public HTableDescriptor getTableDescriptor(byte[] tableName) throws SQLException { return null; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java index 155cee0..cb7ce58 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java @@ -139,7 +139,13 @@ public class DelegateConnectionQueryServices extends DelegateQueryServices imple public MetaDataMutationResult updateIndexState(List<Mutation> tableMetadata, String parentTableName) throws SQLException { return getDelegate().updateIndexState(tableMetadata, parentTableName); } - + + @Override public MetaDataMutationResult updateIndexState(List<Mutation> tableMetadata, + String parentTableName, Map<String, List<Pair<String, Object>>> stmtProperties, + PTable table) throws SQLException { + return getDelegate().updateIndexState(tableMetadata, parentTableName, stmtProperties,table); + } + @Override public void init(String url, Properties props) throws SQLException { getDelegate().init(url, props); http://git-wip-us.apache.org/repos/asf/phoenix/blob/6b38c1e3/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java index 848dda7..782f556 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java @@ -3049,6 +3049,21 @@ public class MetaDataClient { return mutationCode; } + private long incrementTableSeqNum(PTable table, PTableType expectedType, int columnCountDelta, MetaPropertiesEvaluated metaPropertiesEvaluated) + throws SQLException { + return incrementTableSeqNum(table, expectedType, columnCountDelta, + metaPropertiesEvaluated.getIsTransactional(), + metaPropertiesEvaluated.getUpdateCacheFrequency(), + metaPropertiesEvaluated.getIsImmutableRows(), + metaPropertiesEvaluated.getDisableWAL(), + metaPropertiesEvaluated.getMultiTenant(), + metaPropertiesEvaluated.getStoreNulls(), + metaPropertiesEvaluated.getGuidePostWidth(), + metaPropertiesEvaluated.getAppendOnlySchema(), + metaPropertiesEvaluated.getImmutableStorageScheme(), + metaPropertiesEvaluated.getUseStatsForParallelization()); + } + private long incrementTableSeqNum(PTable table, PTableType expectedType, int columnCountDelta, Boolean isTransactional, Long updateCacheFrequency) throws SQLException { return incrementTableSeqNum(table, expectedType, columnCountDelta, isTransactional, updateCacheFrequency, null, null, null, null, -1L, null, null, null); } @@ -3180,19 +3195,6 @@ public class MetaDataClient { PName tenantId = connection.getTenantId(); String schemaName = table.getSchemaName().getString(); String tableName = table.getTableName().getString(); - Boolean isImmutableRowsProp = null; - Boolean multiTenantProp = null; - Boolean disableWALProp = null; - Boolean storeNullsProp = null; - Boolean isTransactionalProp = null; - Long updateCacheFrequencyProp = null; - Boolean appendOnlySchemaProp = null; - Long guidePostWidth = -1L; - ImmutableStorageScheme immutableStorageSchemeProp = null; - Boolean useStatsForParallelizationProp = null; - TransactionFactory.Provider provider = null; - - Map<String, List<Pair<String, Object>>> properties = new HashMap<>(stmtProperties.size()); List<ColumnDef> columnDefs = null; if (table.isAppendOnlySchema()) { // only make the rpc if we are adding new columns @@ -3228,50 +3230,13 @@ public class MetaDataClient { else { columnDefs = origColumnDefs == null ? Collections.<ColumnDef>emptyList() : origColumnDefs; } - for (String family : stmtProperties.keySet()) { - List<Pair<String, Object>> origPropsList = stmtProperties.get(family); - List<Pair<String, Object>> propsList = Lists.newArrayListWithExpectedSize(origPropsList.size()); - for (Pair<String, Object> prop : origPropsList) { - String propName = prop.getFirst(); - if (TableProperty.isPhoenixTableProperty(propName)) { - TableProperty tableProp = TableProperty.valueOf(propName); - tableProp.validate(true, !family.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY), table.getType()); - Object value = tableProp.getValue(prop.getSecond()); - if (propName.equals(PTable.IS_IMMUTABLE_ROWS_PROP_NAME)) { - isImmutableRowsProp = (Boolean)value; - } else if (propName.equals(PhoenixDatabaseMetaData.MULTI_TENANT)) { - multiTenantProp = (Boolean)value; - } else if (propName.equals(DISABLE_WAL)) { - disableWALProp = (Boolean)value; - } else if (propName.equals(STORE_NULLS)) { - storeNullsProp = (Boolean)value; - } else if (propName.equals(TRANSACTIONAL)) { - isTransactionalProp = (Boolean)value; - } else if (propName.equals(UPDATE_CACHE_FREQUENCY)) { - updateCacheFrequencyProp = (Long)value; - } else if (propName.equals(GUIDE_POSTS_WIDTH)) { - guidePostWidth = (Long)value; - } else if (propName.equals(APPEND_ONLY_SCHEMA)) { - appendOnlySchemaProp = (Boolean) value; - } else if (propName.equalsIgnoreCase(IMMUTABLE_STORAGE_SCHEME)) { - immutableStorageSchemeProp = (ImmutableStorageScheme)value; - } else if (propName.equalsIgnoreCase(USE_STATS_FOR_PARALLELIZATION)) { - useStatsForParallelizationProp = (Boolean)value; - } else if (propName.equalsIgnoreCase(TRANSACTION_PROVIDER)) { - provider = (TransactionFactory.Provider)value; - } - } - // if removeTableProps is true only add the property if it is not a HTable or Phoenix Table property - if (!removeTableProps || (!TableProperty.isPhoenixTableProperty(propName) && !MetaDataUtil.isHTableProperty(propName))) { - propsList.add(prop); - } - } - properties.put(family, propsList); - } boolean retried = false; boolean changingPhoenixTableProperty = false; - boolean nonTxToTx = false; + MetaProperties metaProperties = new MetaProperties(); while (true) { + Map<String, List<Pair<String, Object>>> properties=new HashMap<>(stmtProperties.size());; + metaProperties = loadStmtProperties(stmtProperties,properties,table,removeTableProps); + ColumnResolver resolver = FromCompiler.getResolver(namedTableNode, connection); table = resolver.getTables().get(0).getTable(); int nIndexes = table.getIndexes().size(); @@ -3298,128 +3263,12 @@ public class MetaDataClient { .setColumnName(lastPK.getName().getString()).build().buildException(); } - Boolean isImmutableRows = null; - if (isImmutableRowsProp != null) { - if (isImmutableRowsProp.booleanValue() != table.isImmutableRows()) { - if (table.getImmutableStorageScheme() != ImmutableStorageScheme.ONE_CELL_PER_COLUMN) { - throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_ALTER_IMMUTABLE_ROWS_PROPERTY) - .setSchemaName(schemaName).setTableName(tableName).build().buildException(); - } - isImmutableRows = isImmutableRowsProp; - changingPhoenixTableProperty = true; - } - } - boolean willBeImmutableRows = Boolean.TRUE.equals(isImmutableRows) || (isImmutableRows == null && table.isImmutableRows()); - Boolean multiTenant = null; - if (multiTenantProp != null) { - if (multiTenantProp.booleanValue() != table.isMultiTenant()) { - multiTenant = multiTenantProp; - changingPhoenixTableProperty = true; - } - } - Boolean disableWAL = null; - if (disableWALProp != null) { - if (disableWALProp.booleanValue() != table.isWALDisabled()) { - disableWAL = disableWALProp; - changingPhoenixTableProperty = true; - } - } - Long updateCacheFrequency = null; - if (updateCacheFrequencyProp != null) { - if (updateCacheFrequencyProp.longValue() != table.getUpdateCacheFrequency()) { - updateCacheFrequency = updateCacheFrequencyProp; - changingPhoenixTableProperty = true; - } - } - Boolean appendOnlySchema = null; - if (appendOnlySchemaProp !=null) { - if (appendOnlySchemaProp != table.isAppendOnlySchema()) { - appendOnlySchema = appendOnlySchemaProp; - changingPhoenixTableProperty = true; - } - } - ImmutableStorageScheme immutableStorageScheme = null; - if (immutableStorageSchemeProp!=null) { - if (table.getImmutableStorageScheme() == ONE_CELL_PER_COLUMN || - immutableStorageSchemeProp == ONE_CELL_PER_COLUMN) { - throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_IMMUTABLE_STORAGE_SCHEME_CHANGE) - .setSchemaName(schemaName).setTableName(tableName).build().buildException(); - } - else if (immutableStorageSchemeProp != table.getImmutableStorageScheme()) { - immutableStorageScheme = immutableStorageSchemeProp; - changingPhoenixTableProperty = true; - } - } - - if (guidePostWidth == null || guidePostWidth >= 0) { - changingPhoenixTableProperty = true; - } - Boolean storeNulls = null; - if (storeNullsProp != null) { - if (storeNullsProp.booleanValue() != table.getStoreNulls()) { - storeNulls = storeNullsProp; - changingPhoenixTableProperty = true; - } - } - Boolean useStatsForParallelization = null; - if (useStatsForParallelizationProp != null - && (table.useStatsForParallelization() == null - || (useStatsForParallelizationProp.booleanValue() != table - .useStatsForParallelization()))) { - useStatsForParallelization = useStatsForParallelizationProp; - changingPhoenixTableProperty = true; - } - Boolean isTransactional = null; - if (isTransactionalProp != null) { - if (isTransactionalProp.booleanValue() != table.isTransactional()) { - isTransactional = isTransactionalProp; - // We can only go one way: from non transactional to transactional - // Going the other way would require rewriting the cell timestamps - // and doing a major compaction to get rid of any Tephra specific - // delete markers. - if (!isTransactional) { - throw new SQLExceptionInfo.Builder(SQLExceptionCode.TX_MAY_NOT_SWITCH_TO_NON_TX) - .setSchemaName(schemaName).setTableName(tableName).build().buildException(); - } - // cannot create a transactional table if transactions are disabled - boolean transactionsEnabled = connection.getQueryServices().getProps().getBoolean( - QueryServices.TRANSACTIONS_ENABLED, - QueryServicesOptions.DEFAULT_TRANSACTIONS_ENABLED); - if (!transactionsEnabled) { - throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_ALTER_TO_BE_TXN_IF_TXNS_DISABLED) - .setSchemaName(schemaName).setTableName(tableName).build().buildException(); - } - // cannot make a table transactional if it has a row timestamp column - if (SchemaUtil.hasRowTimestampColumn(table)) { - throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_ALTER_TO_BE_TXN_WITH_ROW_TIMESTAMP) - .setSchemaName(schemaName).setTableName(tableName) - .build().buildException(); - } - changingPhoenixTableProperty = true; - nonTxToTx = true; - } - } - - if (provider == null) { - if (table.isTransactional()) { - provider = table.getTransactionProvider(); - } else { - provider = (Provider) - TableProperty.TRANSACTION_PROVIDER.getValue( - connection.getQueryServices().getProps().get( - QueryServices.DEFAULT_TRANSACTION_PROVIDER_ATTRIB, - QueryServicesOptions.DEFAULT_TRANSACTION_PROVIDER)); - } - } - if (nonTxToTx && provider.getTransactionProvider().isUnsupported(PhoenixTransactionProvider.Feature.ALTER_NONTX_TO_TX)) { - throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_ALTER_TABLE_FROM_NON_TXN_TO_TXNL) - .setMessage(provider.name() + ". ") - .setSchemaName(schemaName) - .setTableName(tableName) - .build().buildException(); - } - - Long timeStamp = TransactionUtil.getTableTimestamp(connection, table.isTransactional() || nonTxToTx, provider); + MetaPropertiesEvaluated metaPropertiesEvaluated = new MetaPropertiesEvaluated(); + changingPhoenixTableProperty = evaluateStmtProperties(metaProperties,metaPropertiesEvaluated,table,schemaName,tableName); + // If changing isImmutableRows to true or it's not being changed and is already true + boolean willBeImmutableRows = Boolean.TRUE.equals(metaPropertiesEvaluated.getIsImmutableRows()) || (metaPropertiesEvaluated.getIsImmutableRows() == null && table.isImmutableRows()); + boolean willBeTxnl = metaProperties.getNonTxToTx(); + Long timeStamp = TransactionUtil.getTableTimestamp(connection, table.isTransactional() || willBeTxnl, table.isTransactional() ? table.getTransactionProvider() : metaPropertiesEvaluated.getTransactionProvider()); int numPkColumnsAdded = 0; List<PColumn> columns = Lists.newArrayListWithExpectedSize(numCols); @@ -3538,7 +3387,7 @@ public class MetaDataClient { // Check that HBase configured properly for mutable secondary indexing // if we're changing from an immutable table to a mutable table and we // have existing indexes. - if (Boolean.FALSE.equals(isImmutableRows) && !table.getIndexes().isEmpty()) { + if (Boolean.FALSE.equals(metaPropertiesEvaluated.getIsImmutableRows()) && !table.getIndexes().isEmpty()) { int hbaseVersion = connection.getQueryServices().getLowestClusterHBaseVersion(); if (hbaseVersion < PhoenixDatabaseMetaData.MUTABLE_SI_VERSION_THRESHOLD) { throw new SQLExceptionInfo.Builder(SQLExceptionCode.NO_MUTABLE_INDEXES) @@ -3549,22 +3398,22 @@ public class MetaDataClient { .setSchemaName(schemaName).setTableName(tableName).build().buildException(); } } - if (Boolean.TRUE.equals(multiTenant)) { - throwIfInsufficientColumns(schemaName, tableName, table.getPKColumns(), table.getBucketNum()!=null, multiTenant); + if (Boolean.TRUE.equals(metaPropertiesEvaluated.getMultiTenant())) { + throwIfInsufficientColumns(schemaName, tableName, table.getPKColumns(), table.getBucketNum()!=null, metaPropertiesEvaluated.getMultiTenant()); } } - if (!table.getIndexes().isEmpty() && (numPkColumnsAdded>0 || nonTxToTx)) { + if (!table.getIndexes().isEmpty() && (numPkColumnsAdded>0 || metaProperties.getNonTxToTx())) { for (PTable index : table.getIndexes()) { - incrementTableSeqNum(index, index.getType(), numPkColumnsAdded, nonTxToTx ? Boolean.TRUE : null, updateCacheFrequency); + incrementTableSeqNum(index, index.getType(), numPkColumnsAdded, metaProperties.getNonTxToTx() ? Boolean.TRUE : null, metaPropertiesEvaluated.getUpdateCacheFrequency()); } tableMetaData.addAll(connection.getMutationState().toMutations(timeStamp).next().getSecond()); connection.rollback(); } if (changingPhoenixTableProperty || columnDefs.size() > 0) { - incrementTableSeqNum(table, tableType, columnDefs.size(), isTransactional, updateCacheFrequency, isImmutableRows, - disableWAL, multiTenant, storeNulls, guidePostWidth, appendOnlySchema, immutableStorageScheme, useStatsForParallelization); + incrementTableSeqNum(table, tableType, columnDefs.size(), metaPropertiesEvaluated); + tableMetaData.addAll(connection.getMutationState().toMutations(timeStamp).next().getSecond()); connection.rollback(); } @@ -3634,10 +3483,10 @@ public class MetaDataClient { // We could update the cache manually then too, it'd just be a pain. String fullTableName = SchemaUtil.getTableName(schemaName, tableName); long resolvedTimeStamp = TransactionUtil.getResolvedTime(connection, result); - if (table.getIndexes().isEmpty() || (numPkColumnsAdded==0 && !nonTxToTx)) { + if (table.getIndexes().isEmpty() || (numPkColumnsAdded==0 && ! metaProperties.getNonTxToTx())) { connection.addTable(result.getTable(), resolvedTimeStamp); table = result.getTable(); - } else if (updateCacheFrequency != null) { + } else if (metaPropertiesEvaluated.getUpdateCacheFrequency() != null) { // Force removal from cache as the update cache frequency has changed // Note that clients outside this JVM won't be affected. connection.removeTable(tenantId, fullTableName, null, resolvedTimeStamp); @@ -3645,7 +3494,7 @@ public class MetaDataClient { // Delete rows in view index if we haven't dropped it already // We only need to do this if the multiTenant transitioned to false if (table.getType() == PTableType.TABLE - && Boolean.FALSE.equals(multiTenant) + && Boolean.FALSE.equals(metaPropertiesEvaluated.getMultiTenant()) && MetaDataUtil.hasViewIndexTable(connection, table.getPhysicalName())) { connection.setAutoCommit(true); MetaDataUtil.deleteViewIndexSequences(connection, table.getPhysicalName(), table.isNamespaceMapped()); @@ -4007,9 +3856,19 @@ public class MetaDataClient { boolean wasAutoCommit = connection.getAutoCommit(); try { String dataTableName = statement.getTableName(); - String schemaName = statement.getTable().getName().getSchemaName(); String indexName = statement.getTable().getName().getTableName(); boolean isAsync = statement.isAsync(); + String tenantId = connection.getTenantId() == null ? null : connection.getTenantId().getString(); + PTable table = FromCompiler.getResolver(statement, connection).getTables().get(0).getTable(); + String schemaName = statement.getTable().getName().getSchemaName(); + String tableName = table.getTableName().getString(); + + Map<String, List<Pair<String, Object>>> properties=new HashMap<>(statement.getProps().size());; + MetaProperties metaProperties = loadStmtProperties(statement.getProps(),properties,table,false); + + MetaPropertiesEvaluated metaPropertiesEvaluated = new MetaPropertiesEvaluated(); + boolean changingPhoenixTableProperty= evaluateStmtProperties(metaProperties,metaPropertiesEvaluated,table,schemaName,tableName); + PIndexState newIndexState = statement.getIndexState(); if (isAsync && newIndexState != PIndexState.REBUILD) { throw new SQLExceptionInfo.Builder( SQLExceptionCode.ASYNC_NOT_ALLOWED) @@ -4047,7 +3906,15 @@ public class MetaDataClient { List<Mutation> tableMetadata = connection.getMutationState().toMutations(timeStamp).next().getSecond(); connection.rollback(); - MetaDataMutationResult result = connection.getQueryServices().updateIndexState(tableMetadata, dataTableName); + + if (changingPhoenixTableProperty) { + incrementTableSeqNum(table,statement.getTableType(), 0, metaPropertiesEvaluated); + tableMetadata.addAll(connection.getMutationState().toMutations(timeStamp).next().getSecond()); + connection.rollback(); + } + + MetaDataMutationResult result = connection.getQueryServices().updateIndexState(tableMetadata, dataTableName, properties, table); + MutationCode code = result.getMutationCode(); if (code == MutationCode.TABLE_NOT_FOUND) { throw new TableNotFoundException(schemaName,indexName); @@ -4625,6 +4492,5 @@ public class MetaDataClient { public void setTransactionProvider(TransactionFactory.Provider transactionProvider) { this.transactionProvider = transactionProvider; } - } }