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 2015/01/15 04:33:00 UTC
phoenix git commit: Refactored set properties code to
ConnectionQueryServices. Reduced rpc calls for setting properties and
creating column families to 1
Repository: phoenix
Updated Branches:
refs/heads/master c5edd3a71 -> d3aba78a5
Refactored set properties code to ConnectionQueryServices. Reduced rpc calls for setting properties and creating column families to 1
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/d3aba78a
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/d3aba78a
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/d3aba78a
Branch: refs/heads/master
Commit: d3aba78a57167fbad24ee15a8f00d44a11e1021a
Parents: c5edd3a
Author: Samarth <sa...@salesforce.com>
Authored: Wed Jan 14 19:32:42 2015 -0800
Committer: Samarth <sa...@salesforce.com>
Committed: Wed Jan 14 19:32:42 2015 -0800
----------------------------------------------------------------------
.../apache/phoenix/end2end/AlterTableIT.java | 145 ++++++-
.../phoenix/coprocessor/MetaDataProtocol.java | 3 +-
.../phoenix/query/ConnectionQueryServices.java | 6 +-
.../query/ConnectionQueryServicesImpl.java | 400 +++++++++++++------
.../query/ConnectionlessQueryServicesImpl.java | 11 +-
.../query/DelegateConnectionQueryServices.java | 13 +-
.../apache/phoenix/schema/MetaDataClient.java | 266 ++----------
.../phoenix/compile/QueryCompilerTest.java | 2 +-
8 files changed, 452 insertions(+), 394 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d3aba78a/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 dcb6237..ac578c9 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
@@ -40,6 +40,7 @@ import java.util.Properties;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.KeepDeletedCells;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.phoenix.coprocessor.MetaDataProtocol;
@@ -55,6 +56,7 @@ import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.ReadOnlyProps;
import org.apache.phoenix.util.SchemaUtil;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
/**
@@ -928,7 +930,7 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
@Test
public void testAddColumnForNewColumnFamily() throws Exception {
Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
- String ddl = "CREATE TABLE T (\n"
+ String ddl = "CREATE TABLE testAddColumnForNewColumnFamily (\n"
+"ID1 VARCHAR(15) NOT NULL,\n"
+"ID2 VARCHAR(15) NOT NULL,\n"
+"CREATED_DATE DATE,\n"
@@ -937,8 +939,16 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
+"CONSTRAINT PK PRIMARY KEY (ID1, ID2)) SALT_BUCKETS = 8";
Connection conn1 = DriverManager.getConnection(getUrl(), props);
conn1.createStatement().execute(ddl);
- ddl = "ALTER TABLE T ADD CF.STRING VARCHAR";
+ ddl = "ALTER TABLE testAddColumnForNewColumnFamily ADD CF.STRING VARCHAR";
conn1.createStatement().execute(ddl);
+ try (HBaseAdmin admin = conn1.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+ HColumnDescriptor[] columnFamilies = admin.getTableDescriptor(Bytes.toBytes("testAddColumnForNewColumnFamily".toUpperCase())).getColumnFamilies();
+ assertEquals(2, columnFamilies.length);
+ assertEquals("0", columnFamilies[0].getNameAsString());
+ assertEquals(HColumnDescriptor.DEFAULT_TTL, columnFamilies[0].getTimeToLive());
+ assertEquals("CF", columnFamilies[1].getNameAsString());
+ assertEquals(HColumnDescriptor.DEFAULT_TTL, columnFamilies[1].getTimeToLive());
+ }
}
@Test
@@ -1024,7 +1034,7 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
assertImmutableRows(conn, "T3", true);
ddl = "ALTER TABLE T3 SET COMPACTION_ENABLED = FALSE, VERSIONS = 10";
conn.createStatement().execute(ddl);
- ddl = "ALTER TABLE T3 SET COMPACTION_ENABLED = FALSE, CF1.MIN_VERSIONS = 1, CF2.MIN_VERSIONS = 3, MIN_VERSIONS = 8, IMMUTABLE_ROWS=false";
+ ddl = "ALTER TABLE T3 SET COMPACTION_ENABLED = FALSE, CF1.MIN_VERSIONS = 1, CF2.MIN_VERSIONS = 3, MIN_VERSIONS = 8, IMMUTABLE_ROWS=false, CF1.KEEP_DELETED_CELLS = true, KEEP_DELETED_CELLS = false";
conn.createStatement().execute(ddl);
assertImmutableRows(conn, "T3", false);
@@ -1036,14 +1046,17 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
assertEquals("0", columnFamilies[0].getNameAsString());
assertEquals(8, columnFamilies[0].getMinVersions());
assertEquals(10, columnFamilies[0].getMaxVersions());
+ assertEquals(KeepDeletedCells.FALSE, columnFamilies[0].getKeepDeletedCells());
assertEquals("CF1", columnFamilies[1].getNameAsString());
assertEquals(1, columnFamilies[1].getMinVersions());
assertEquals(10, columnFamilies[1].getMaxVersions());
+ assertEquals(KeepDeletedCells.TRUE, columnFamilies[1].getKeepDeletedCells());
assertEquals("CF2", columnFamilies[2].getNameAsString());
assertEquals(3, columnFamilies[2].getMinVersions());
assertEquals(10, columnFamilies[2].getMaxVersions());
+ assertEquals(KeepDeletedCells.FALSE, columnFamilies[2].getKeepDeletedCells());
assertEquals(Boolean.toString(false), tableDesc.getValue(HTableDescriptor.COMPACTION_ENABLED));
}
@@ -1064,6 +1077,7 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
ddl = "ALTER TABLE T4 SET CF.COMPACTION_ENABLED = FALSE";
try {
conn1.createStatement().execute(ddl);
+ fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY.getErrorCode(), e.getErrorCode());
}
@@ -1084,6 +1098,7 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
ddl = "ALTER TABLE T5 SET CF.DISABLE_WAL = TRUE";
try {
conn1.createStatement().execute(ddl);
+ fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY.getErrorCode(), e.getErrorCode());
}
@@ -1125,6 +1140,7 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
ddl = "ALTER TABLE T7 SET CF.REPLICATION_SCOPE = 1";
try {
conn1.createStatement().execute(ddl);
+ fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.COLUMN_FAMILY_NOT_FOUND.getErrorCode(), e.getErrorCode());
}
@@ -1145,6 +1161,7 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
ddl = "ALTER TABLE T8 SET DEFAULT_COLUMN_FAMILY = 'A'";
try {
conn1.createStatement().execute(ddl);
+ fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.DEFAULT_COLUMN_FAMILY_ONLY_ON_CREATE_TABLE.getErrorCode(), e.getErrorCode());
}
@@ -1167,12 +1184,14 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
ddl = "ALTER VIEW v SET REPLICATION_SCOPE = 1";
try {
conn1.createStatement().execute(ddl);
+ fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.VIEW_WITH_PROPERTIES.getErrorCode(), e.getErrorCode());
}
ddl = "ALTER VIEW v SET COMPACTION_ENABLED = FALSE";
try {
conn1.createStatement().execute(ddl);
+ fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.VIEW_WITH_PROPERTIES.getErrorCode(), e.getErrorCode());
}
@@ -1201,6 +1220,7 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
ddl = "ALTER VIEW v SET DISABLE_WAL = TRUE";
try {
conn1.createStatement().execute(ddl);
+ fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.VIEW_WITH_PROPERTIES.getErrorCode(), e.getErrorCode());
}
@@ -1369,14 +1389,14 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
public void testSetPropertyAndAddColumnForDifferentColumnFamilies() throws Exception {
Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props);
- String ddl = "CREATE TABLE SETPROPDIFFCFSTABLE " +
- " (a_string varchar not null, col1 integer, CF1.col2 integer, CF2.col3 integer" +
- " CONSTRAINT pk PRIMARY KEY (a_string)) DEFAULT_COLUMN_FAMILY = 'XYZ'\n";
- try {
- conn.createStatement().execute(ddl);
- conn.createStatement().execute("ALTER TABLE SETPROPDIFFCFSTABLE ADD col4 integer, CF1.col5 integer, CF2.col6 integer, CF3.col7 integer CF1.REPLICATION_SCOPE=1, CF1.IN_MEMORY=false, IN_MEMORY=true ");
- try (HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
- HColumnDescriptor[] columnFamilies = admin.getTableDescriptor(Bytes.toBytes("SETPROPDIFFCFSTABLE")).getColumnFamilies();
+ String ddl = "CREATE TABLE XYZ.SETPROPDIFFCFSTABLE " +
+ " (a_string varchar not null, col1 integer, CF1.col2 integer, CF2.col3 integer" +
+ " CONSTRAINT pk PRIMARY KEY (a_string)) DEFAULT_COLUMN_FAMILY = 'XYZ'\n";
+ try {
+ conn.createStatement().execute(ddl);
+ conn.createStatement().execute("ALTER TABLE XYZ.SETPROPDIFFCFSTABLE ADD col4 integer, CF1.col5 integer, CF2.col6 integer, CF3.col7 integer CF1.REPLICATION_SCOPE=1, CF1.IN_MEMORY=false, IN_MEMORY=true ");
+ try (HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+ HColumnDescriptor[] columnFamilies = admin.getTableDescriptor(Bytes.toBytes(SchemaUtil.getTableName("XYZ", "SETPROPDIFFCFSTABLE"))).getColumnFamilies();
assertEquals(4, columnFamilies.length);
assertEquals("CF1", columnFamilies[0].getNameAsString());
assertFalse(columnFamilies[0].isInMemory());
@@ -1553,7 +1573,7 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
conn.createStatement().execute(ddl);
fail();
} catch (SQLException e) {
- assertEquals(SQLExceptionCode.CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN.getErrorCode(), e.getErrorCode());
+ assertEquals(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_FOR_TTL.getErrorCode(), e.getErrorCode());
} finally {
conn.close();
}
@@ -1782,6 +1802,7 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
ddl = "ALTER TABLE RANDMONPROPTABLE ADD NEWCF.COL3 INTEGER NEWCF.UNKNOWN_PROP='ABC'";
try {
conn.createStatement().execute(ddl);
+ fail();
} catch (SQLException e) {
assertEquals(SQLExceptionCode.CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN.getErrorCode(), e.getErrorCode());
}
@@ -1822,4 +1843,104 @@ public class AlterTableIT extends BaseOwnClusterHBaseManagedTimeIT {
stmt.close();
}
+
+ @Test
+ @Ignore //FIXME: https://issues.apache.org/jira/browse/PHOENIX-1581
+ public void testTogglingDisableWal() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ try {
+ String ddl = "create table IF NOT EXISTS testReenablingWal ("
+ + " id char(1) NOT NULL,"
+ + " col1 integer NOT NULL,"
+ + " col2 bigint NOT NULL,"
+ + " CONSTRAINT NAME_PK PRIMARY KEY (id, col1, col2)"
+ + " )";
+ conn.createStatement().execute(ddl);
+ asssertIsWALDisabled(conn, "testReenablingWal".toUpperCase(), false);
+
+ ddl = "ALTER TABLE testReenablingWal SET DISABLE_WAL = true";
+ conn.createStatement().execute(ddl);
+ asssertIsWALDisabled(conn, "testReenablingWal".toUpperCase(), true);
+
+ ddl = "ALTER TABLE testReenablingWal SET DISABLE_WAL = false";
+ conn.createStatement().execute(ddl);
+ asssertIsWALDisabled(conn, "testReenablingWal".toUpperCase(), false);
+
+ } finally {
+ conn.close();
+ }
+ }
+
+ @Test
+ public void testAddingPkColAndSettingProperties() throws Exception {
+ Connection conn = DriverManager.getConnection(getUrl());
+ try {
+ String ddl = "create table IF NOT EXISTS testAddingPkColAndSettingProperties ("
+ + " k1 char(1) NOT NULL,"
+ + " k2 integer NOT NULL,"
+ + " col1 bigint,"
+ + " CONSTRAINT NAME_PK PRIMARY KEY (k1, k2)"
+ + " )";
+ conn.createStatement().execute(ddl);
+
+ // set HTableProperty when adding a pk column should fail
+ ddl = "ALTER TABLE testAddingPkColAndSettingProperties ADD k3 DECIMAL PRIMARY KEY COMPACTION_ENABLED = false";
+ try {
+ conn.createStatement().execute(ddl);
+ fail();
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN.getErrorCode(), e.getErrorCode());
+ }
+
+ // set HColumnProperty when adding only a pk column should fail
+ ddl = "ALTER TABLE testAddingPkColAndSettingProperties ADD k3 DECIMAL PRIMARY KEY REPLICATION_SCOPE = 0";
+ try {
+ conn.createStatement().execute(ddl);
+ fail();
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.SET_UNSUPPORTED_PROP_ON_ALTER_TABLE.getErrorCode(), e.getErrorCode());
+ }
+
+ // set phoenix table property when adding a pk column should fail
+ ddl = "ALTER TABLE testAddingPkColAndSettingProperties ADD k3 DECIMAL PRIMARY KEY DISABLE_WAL = true";
+ try {
+ conn.createStatement().execute(ddl);
+ fail();
+ } catch (SQLException e) {
+ assertEquals(SQLExceptionCode.CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN.getErrorCode(), e.getErrorCode());
+ }
+
+ // set HColumnProperty property when adding a pk column and other key value columns should work
+ ddl = "ALTER TABLE testAddingPkColAndSettingProperties ADD k3 DECIMAL PRIMARY KEY, col2 bigint, CF.col3 bigint IN_MEMORY = true, CF.IN_MEMORY=false, CF.REPLICATION_SCOPE = 1";
+ conn.createStatement().execute(ddl);
+ String tableName = "testAddingPkColAndSettingProperties".toUpperCase();
+ // assert that k3 was added as new pk
+ ResultSet rs = conn.getMetaData().getPrimaryKeys("", "", tableName);
+ assertTrue(rs.next());
+ assertEquals("K1",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"));
+ assertTrue(rs.next());
+ assertEquals("K3",rs.getString("COLUMN_NAME"));
+ assertEquals(3, rs.getShort("KEY_SEQ"));
+ assertFalse(rs.next());
+
+ try (HBaseAdmin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+ HTableDescriptor tableDesc = admin.getTableDescriptor(Bytes.toBytes(tableName));
+ HColumnDescriptor[] columnFamilies = tableDesc.getColumnFamilies();
+ assertEquals(2, columnFamilies.length);
+ assertEquals("0", columnFamilies[0].getNameAsString());
+ assertEquals(true, columnFamilies[0].isInMemory());
+ assertEquals(0, columnFamilies[0].getScope());
+ assertEquals("CF", columnFamilies[1].getNameAsString());
+ assertEquals(false, columnFamilies[1].isInMemory());
+ assertEquals(1, columnFamilies[1].getScope());
+ }
+
+ } finally {
+ conn.close();
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d3aba78a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
index 4b795e7..357ebdd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
@@ -81,7 +81,8 @@ public abstract class MetaDataProtocol extends MetaDataService {
NEWER_TABLE_FOUND,
UNALLOWED_TABLE_MUTATION,
NO_PK_COLUMNS,
- PARENT_TABLE_NOT_FOUND
+ PARENT_TABLE_NOT_FOUND,
+ NO_OP
};
public static class MetaDataMutationResult {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d3aba78a/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 f0fbf1d..fa44835 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
@@ -17,12 +17,11 @@
*/
package org.apache.phoenix.query;
-import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.concurrent.TimeoutException;
+import java.util.Set;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.HTableDescriptor;
@@ -73,7 +72,7 @@ public interface ConnectionQueryServices extends QueryServices, MetaDataMutated
public MetaDataMutationResult getTable(PName tenantId, byte[] schemaName, byte[] tableName, long tableTimestamp, long clientTimetamp) throws SQLException;
public MetaDataMutationResult createTable(List<Mutation> tableMetaData, byte[] tableName, PTableType tableType, Map<String,Object> tableProps, List<Pair<byte[],Map<String,Object>>> families, byte[][] splits) throws SQLException;
public MetaDataMutationResult dropTable(List<Mutation> tableMetadata, PTableType tableType, boolean cascade) throws SQLException;
- public MetaDataMutationResult addColumn(List<Mutation> tableMetaData, List<Pair<byte[],Map<String,Object>>> families, PTable table) throws SQLException;
+ public MetaDataMutationResult addColumn(List<Mutation> tableMetaData, PTable table, Map<String, List<Pair<String,Object>>> properties, Set<String> colFamiliesForPColumnsToBeAdded) throws SQLException;
public MetaDataMutationResult dropColumn(List<Mutation> tableMetadata, PTableType tableType) throws SQLException;
public MetaDataMutationResult updateIndexState(List<Mutation> tableMetadata, String parentTableName) throws SQLException;
public MutationState updateData(MutationPlan plan) throws SQLException;
@@ -112,5 +111,4 @@ public interface ConnectionQueryServices extends QueryServices, MetaDataMutated
public void clearCache() throws SQLException;
public int getSequenceSaltBuckets();
- public void modifyTable(byte[] tableName, HTableDescriptor newDesc) throws IOException, InterruptedException, TimeoutException;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d3aba78a/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 d9490ce..dcf3753 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
@@ -17,12 +17,16 @@
*/
package org.apache.phoenix.query;
+import static org.apache.hadoop.hbase.HColumnDescriptor.TTL;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES;
import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_DROP_METADATA;
import java.io.IOException;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -107,6 +111,7 @@ import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
import org.apache.phoenix.jdbc.PhoenixEmbeddedDriver.ConnectionInfo;
import org.apache.phoenix.protobuf.ProtobufUtil;
+import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
import org.apache.phoenix.schema.EmptySequenceCacheException;
import org.apache.phoenix.schema.MetaDataSplitPolicy;
import org.apache.phoenix.schema.NewerTableAlreadyExistsException;
@@ -125,6 +130,7 @@ import org.apache.phoenix.schema.Sequence;
import org.apache.phoenix.schema.SequenceKey;
import org.apache.phoenix.schema.TableAlreadyExistsException;
import org.apache.phoenix.schema.TableNotFoundException;
+import org.apache.phoenix.schema.TableProperty;
import org.apache.phoenix.schema.stats.PTableStats;
import org.apache.phoenix.schema.stats.StatisticsUtil;
import org.apache.phoenix.schema.types.PBoolean;
@@ -193,7 +199,9 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
// setting this member variable guarded by "connectionCountLock"
private volatile ConcurrentMap<SequenceKey,Sequence> sequenceMap = Maps.newConcurrentMap();
private KeyValueBuilder kvBuilder;
-
+
+ private static final HColumnDescriptor defaultColDescriptor = new HColumnDescriptor(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES);
+
private PMetaData newEmptyMetaData() {
long maxSizeBytes = props.getLong(QueryServices.MAX_CLIENT_METADATA_CACHE_SIZE_ATTRIB,
QueryServicesOptions.DEFAULT_MAX_CLIENT_METADATA_CACHE_SIZE);
@@ -562,14 +570,22 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
return columnDesc;
}
- private void modifyColumnFamilyDescriptor(HColumnDescriptor hcd, Pair<byte[],Map<String,Object>> family) throws SQLException {
- for (Entry<String, Object> entry : family.getSecond().entrySet()) {
- String key = entry.getKey();
- Object value = entry.getValue();
- hcd.setValue(key, value == null ? null : value.toString());
- }
+ private void modifyColumnFamilyDescriptor(HColumnDescriptor hcd, Pair<byte[], Map<String,Object>> family) throws SQLException {
+ if (Bytes.equals(hcd.getName(), family.getFirst())) {
+ modifyColumnFamilyDescriptor(hcd, family.getSecond());
+ } else {
+ throw new IllegalArgumentException("Column family names don't match. Column descriptor family name: " + hcd.getNameAsString() + ", Family name: " + Bytes.toString(family.getFirst()));
+ }
}
-
+
+ private void modifyColumnFamilyDescriptor(HColumnDescriptor hcd, Map<String,Object> props) throws SQLException {
+ for (Entry<String, Object> entry : props.entrySet()) {
+ String propName = entry.getKey();
+ Object value = entry.getValue();
+ hcd.setValue(propName, value == null ? null : value.toString());
+ }
+ }
+
private HTableDescriptor generateTableDescriptor(byte[] tableName, HTableDescriptor existingDesc, PTableType tableType, Map<String,Object> tableProps, List<Pair<byte[],Map<String,Object>>> families, byte[][] splits) throws SQLException {
String defaultFamilyName = (String)tableProps.remove(PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME);
HTableDescriptor tableDescriptor = (existingDesc != null) ? new HTableDescriptor(existingDesc) :
@@ -679,93 +695,6 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
}
}
- private void ensureFamilyCreated(byte[] tableName, PTableType tableType , Pair<byte[],Map<String,Object>> family) throws SQLException {
- HBaseAdmin admin = null;
- SQLException sqlE = null;
- try {
- admin = new HBaseAdmin(config);
- try {
- HTableDescriptor existingTableDesc = admin.getTableDescriptor(tableName);
- HColumnDescriptor oldColumnDesc = existingTableDesc.getFamily(family.getFirst());
- HColumnDescriptor newColumnDesc = null;
-
- if (oldColumnDesc == null) {
- if (tableType == PTableType.VIEW) {
- String fullTableName = Bytes.toString(tableName);
- throw new ReadOnlyTableException(
- "The HBase column families for a VIEW must already exist",
- SchemaUtil.getSchemaNameFromFullName(fullTableName),
- SchemaUtil.getTableNameFromFullName(fullTableName),
- Bytes.toString(family.getFirst()));
- }
- newColumnDesc = generateColumnFamilyDescriptor(family, tableType );
- } else {
- newColumnDesc = new HColumnDescriptor(oldColumnDesc);
- // Don't attempt to make any metadata changes for a VIEW
- if (tableType == PTableType.VIEW) {
- return;
- }
- modifyColumnFamilyDescriptor(newColumnDesc, family);
- }
-
- if (newColumnDesc.equals(oldColumnDesc)) {
- // Table already has family and it's the same.
- return;
- }
- addOrModifyColumnDescriptor(tableName, admin, oldColumnDesc, newColumnDesc);
- } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
- sqlE = new SQLExceptionInfo.Builder(SQLExceptionCode.TABLE_UNDEFINED).setRootCause(e).build().buildException();
- } catch (InterruptedException e) {
- // restore the interrupt status
- Thread.currentThread().interrupt();
- sqlE = new SQLExceptionInfo.Builder(SQLExceptionCode.INTERRUPTED_EXCEPTION).setRootCause(e).build().buildException();
- } catch (TimeoutException e) {
- sqlE = new SQLExceptionInfo.Builder(SQLExceptionCode.OPERATION_TIMED_OUT).setRootCause(e.getCause() != null ? e.getCause() : e).build().buildException();
- }
- } catch (IOException e) {
- sqlE = ServerUtil.parseServerException(e);
- } finally {
- try {
- if (admin != null) {
- admin.close();
- }
- } catch (IOException e) {
- if (sqlE == null) {
- sqlE = ServerUtil.parseServerException(e);
- } else {
- sqlE.setNextException(ServerUtil.parseServerException(e));
- }
- } finally {
- if (sqlE != null) {
- throw sqlE;
- }
- }
- }
- }
-
- private void addOrModifyColumnDescriptor(byte[] tableName, HBaseAdmin admin, HColumnDescriptor oldColumnDesc,
- HColumnDescriptor newColumnDesc) throws IOException, InterruptedException, TimeoutException {
- boolean isOnlineSchemaUpgradeEnabled = ConnectionQueryServicesImpl.this.props.getBoolean(
- QueryServices.ALLOW_ONLINE_TABLE_SCHEMA_UPDATE,
- QueryServicesOptions.DEFAULT_ALLOW_ONLINE_TABLE_SCHEMA_UPDATE);
- if (!isOnlineSchemaUpgradeEnabled) {
- admin.disableTable(tableName);
- if (oldColumnDesc == null) {
- admin.addColumn(tableName, newColumnDesc);
- } else {
- admin.modifyColumn(tableName, newColumnDesc);
- }
- admin.enableTable(tableName);
- } else {
- if (oldColumnDesc == null) {
- admin.addColumn(tableName, newColumnDesc);
- } else {
- admin.modifyColumn(tableName, newColumnDesc);
- }
- pollForUpdatedColumnDescriptor(admin, tableName, newColumnDesc);
- }
- }
-
private static interface RetriableOperation {
boolean checkForCompletion() throws TimeoutException, IOException;
String getOperatioName();
@@ -788,23 +717,6 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
});
}
- private void pollForUpdatedColumnDescriptor(final HBaseAdmin admin, final byte[] tableName,
- final HColumnDescriptor columnFamilyDesc) throws InterruptedException, TimeoutException {
- checkAndRetry(new RetriableOperation() {
-
- @Override
- public String getOperatioName() {
- return "UpdateOrNewColumnDescriptor";
- }
-
- @Override
- public boolean checkForCompletion() throws TimeoutException, IOException {
- HTableDescriptor newTableDesc = admin.getTableDescriptor(tableName);
- return newTableDesc.getFamilies().contains(columnFamilyDesc);
- }
- });
- }
-
private void checkAndRetry(RetriableOperation op) throws InterruptedException, TimeoutException {
int maxRetries = ConnectionQueryServicesImpl.this.props.getInt(
QueryServices.NUM_RETRIES_FOR_SCHEMA_UPDATE_CHECK,
@@ -839,7 +751,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
if (!success) {
throw new TimeoutException("Operation " + op.getOperatioName() + " didn't complete within "
+ watch.elapsedMillis() + " ms "
- + (numTries > 1 ? ("after retrying " + numTries + (numTries > 1 ? "times." : "time.")) : ""));
+ + (numTries > 1 ? ("after trying " + numTries + (numTries > 1 ? "times." : "time.")) : ""));
} else {
if (logger.isDebugEnabled()) {
logger.debug("Operation "
@@ -847,7 +759,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
+ " completed within "
+ watch.elapsedMillis()
+ "ms "
- + (numTries > 1 ? ("after retrying " + numTries + (numTries > 1 ? "times." : "time.")) : ""));
+ + (numTries > 1 ? ("after trying " + numTries + (numTries > 1 ? "times." : "time.")) : ""));
}
}
}
@@ -937,7 +849,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
return existingDesc;
}
- modifyTable(tableName, newDesc);
+ modifyTable(tableName, newDesc, true);
return newDesc;
}
@@ -969,8 +881,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
return null; // will never make it here
}
- @Override
- public void modifyTable(byte[] tableName, HTableDescriptor newDesc) throws IOException,
+ private void modifyTable(byte[] tableName, HTableDescriptor newDesc, boolean shouldPoll) throws IOException,
InterruptedException, TimeoutException {
try (HBaseAdmin admin = new HBaseAdmin(config)) {
if (!allowOnlineTableSchemaUpdate()) {
@@ -979,7 +890,9 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
admin.enableTable(tableName);
} else {
admin.modifyTable(tableName, newDesc);
- pollForUpdatedTableDescriptor(admin, newDesc, tableName);
+ if (shouldPoll) {
+ pollForUpdatedTableDescriptor(admin, newDesc, tableName);
+ }
}
}
}
@@ -1505,11 +1418,42 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
ensureViewIndexTableCreated(physicalTableName, tableProps, families, splits, timestamp);
}
-
+
@Override
- public MetaDataMutationResult addColumn(final List<Mutation> tableMetaData, List<Pair<byte[],Map<String,Object>>> families, PTable table) throws SQLException {
- byte[][] rowKeyMetaData = new byte[3][];
- PTableType tableType = table.getType();
+ public MetaDataMutationResult addColumn(final List<Mutation> tableMetaData, PTable table, Map<String, List<Pair<String,Object>>> stmtProperties, Set<String> colFamiliesForPColumnsToBeAdded) throws SQLException {
+ List<Pair<byte[], Map<String, Object>>> families = new ArrayList<>(stmtProperties.size());
+ Map<String, Object> tableProps = new HashMap<String, Object>();
+ HTableDescriptor tableDescriptor = separateAndValidateProperties(table, stmtProperties, colFamiliesForPColumnsToBeAdded, families, tableProps);
+ SQLException sqlE = null;
+ if (tableDescriptor != null) {
+ try {
+ boolean pollingNotNeeded = (!tableProps.isEmpty() && families.isEmpty() && colFamiliesForPColumnsToBeAdded.isEmpty());
+ modifyTable(table.getPhysicalName().getBytes(), tableDescriptor, !pollingNotNeeded);
+ } catch (IOException e) {
+ sqlE = ServerUtil.parseServerException(e);
+ } catch (InterruptedException e) {
+ // restore the interrupt status
+ Thread.currentThread().interrupt();
+ sqlE = new SQLExceptionInfo.Builder(SQLExceptionCode.INTERRUPTED_EXCEPTION).setRootCause(e).build().buildException();
+ } catch (TimeoutException e) {
+ sqlE = new SQLExceptionInfo.Builder(SQLExceptionCode.OPERATION_TIMED_OUT).setRootCause(e.getCause() != null ? e.getCause() : e).build().buildException();
+ } finally {
+ if (sqlE != null) {
+ throw sqlE;
+ }
+ }
+ }
+
+ // Special case for call during drop table to ensure that the empty column family exists.
+ // In this, case we only include the table header row, as until we add schemaBytes and tableBytes
+ // as args to this function, we have no way of getting them in this case.
+ // TODO: change to if (tableMetaData.isEmpty()) once we pass through schemaBytes and tableBytes
+ // Also, could be used to update property values on ALTER TABLE t SET prop=xxx
+ if ((tableMetaData.isEmpty()) || (tableMetaData.size() == 1 && tableMetaData.get(0).isEmpty())) {
+ return new MetaDataMutationResult(MutationCode.NO_OP, System.currentTimeMillis(), table);
+ }
+ byte[][] rowKeyMetaData = new byte[3][];
+ PTableType tableType = table.getType();
Mutation m = tableMetaData.get(0);
byte[] rowKey = m.getRow();
@@ -1518,17 +1462,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
byte[] schemaBytes = rowKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX];
byte[] tableBytes = rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX];
byte[] tableKey = SchemaUtil.getTableKey(tenantIdBytes, schemaBytes, tableBytes);
- for ( Pair<byte[],Map<String,Object>> family : families) {
- ensureFamilyCreated(table.getPhysicalName().getBytes(), tableType, family);
- }
- // Special case for call during drop table to ensure that the empty column family exists.
- // In this, case we only include the table header row, as until we add schemaBytes and tableBytes
- // as args to this function, we have no way of getting them in this case.
- // TODO: change to if (tableMetaData.isEmpty()) once we pass through schemaBytes and tableBytes
- // Also, could be used to update property values on ALTER TABLE t SET prop=xxx
- if (tableMetaData.size() == 1 && tableMetaData.get(0).isEmpty()) {
- return null;
- }
+
ImmutableBytesWritable ptr = new ImmutableBytesWritable();
MetaDataMutationResult result = metaDataCoprocessorExec(tableKey,
new Batch.Call<MetaDataService, MetaDataResponse>() {
@@ -1572,7 +1506,207 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
}
return result;
}
+
+ private 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 {
+ Map<String, Map<String, Object>> stmtFamiliesPropsMap = new HashMap<>(properties.size());
+ Map<String,Object> commonFamilyProps = new HashMap<>();
+ boolean addingColumns = colFamiliesForPColumnsToBeAdded != null && colFamiliesForPColumnsToBeAdded.size() > 0;
+ HashSet<String> existingColumnFamilies = existingColumnFamilies(table);
+ Map<String, Map<String, Object>> allFamiliesProps = new HashMap<>(existingColumnFamilies.size());
+ for (String family : properties.keySet()) {
+ List<Pair<String, Object>> propsList = properties.get(family);
+ if (propsList != null && propsList.size() > 0) {
+ Map<String, Object> colFamilyPropsMap = new HashMap<String, Object>(propsList.size());
+ for (Pair<String, Object> prop : propsList) {
+ String propName = prop.getFirst();
+ Object propValue = prop.getSecond();
+ if ((isHTableProperty(propName) || TableProperty.isPhoenixTableProperty(propName)) && addingColumns) {
+ // setting HTable and PhoenixTable properties while adding a column is not allowed.
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN)
+ .setMessage("Property: " + propName).build()
+ .buildException();
+ }
+ if (isHTableProperty(propName)) {
+ // Can't have a column family name for a property that's an HTableProperty
+ if (!family.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY)) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY)
+ .setMessage("Column Family: " + family + ", Property: " + propName).build()
+ .buildException();
+ }
+ tableProps.put(propName, propValue);
+ } else {
+ if (TableProperty.isPhoenixTableProperty(propName)) {
+ TableProperty.valueOf(propName).validate(true, !family.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY), table.getType());
+ if (propName.equals(TTL)) {
+ // Even though TTL is really a HColumnProperty we treat it specially.
+ // We enforce that all column families have the same TTL.
+ commonFamilyProps.put(propName, prop.getSecond());
+ }
+ } else {
+ if (isHColumnProperty(propName)) {
+ if (family.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY)) {
+ commonFamilyProps.put(propName, prop.getSecond());
+ } else {
+ colFamilyPropsMap.put(propName, prop.getSecond());
+ }
+ } else {
+ // invalid property - neither of HTableProp, HColumnProp or PhoenixTableProp
+ // FIXME: This isn't getting triggered as currently a property gets evaluated
+ // as HTableProp if its neither HColumnProp or PhoenixTableProp.
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.SET_UNSUPPORTED_PROP_ON_ALTER_TABLE)
+ .setMessage("Column Family: " + family + ", Property: " + propName).build()
+ .buildException();
+ }
+ }
+ }
+ }
+ if (!colFamilyPropsMap.isEmpty()) {
+ stmtFamiliesPropsMap.put(family, colFamilyPropsMap);
+ }
+
+ }
+ }
+ commonFamilyProps = Collections.unmodifiableMap(commonFamilyProps);
+ boolean isAddingPkColOnly = colFamiliesForPColumnsToBeAdded.size() == 1 && colFamiliesForPColumnsToBeAdded.contains(null);
+ if (!commonFamilyProps.isEmpty()) {
+ if (!addingColumns) {
+ // Add the common family props to all existing column families
+ for (String existingColFamily : existingColumnFamilies) {
+ Map<String, Object> m = new HashMap<String, Object>(commonFamilyProps.size());
+ m.putAll(commonFamilyProps);
+ allFamiliesProps.put(existingColFamily, m);
+ }
+ } else {
+ // Add the common family props to the column families of the columns being added
+ for (String colFamily : colFamiliesForPColumnsToBeAdded) {
+ if (colFamily != null) {
+ // only set properties for key value columns
+ Map<String, Object> m = new HashMap<String, Object>(commonFamilyProps.size());
+ m.putAll(commonFamilyProps);
+ allFamiliesProps.put(colFamily, m);
+ } else if (isAddingPkColOnly) {
+ // Setting HColumnProperty for a pk column is invalid
+ // because it will be part of the row key and not a key value column family.
+ // However, if both pk cols as well as key value columns are getting added
+ // together, then its allowed. The above if block will make sure that we add properties
+ // only for the kv cols and not pk cols.
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.SET_UNSUPPORTED_PROP_ON_ALTER_TABLE)
+ .build().buildException();
+ }
+ }
+ }
+ }
+
+ // Now go through the column family properties specified in the statement
+ // and merge them with the common family properties.
+ for (String f : stmtFamiliesPropsMap.keySet()) {
+ if (!addingColumns && !existingColumnFamilies.contains(f)) {
+ throw new ColumnFamilyNotFoundException(f);
+ }
+ if (addingColumns && !colFamiliesForPColumnsToBeAdded.contains(f)) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_SET_PROPERTY_FOR_COLUMN_NOT_ADDED).build().buildException();
+ }
+ Map<String, Object> commonProps = allFamiliesProps.get(f);
+ Map<String, Object> stmtProps = stmtFamiliesPropsMap.get(f);
+ if (commonProps != null) {
+ if (stmtProps != null) {
+ // merge common props with statement props for the family
+ commonProps.putAll(stmtProps);
+ }
+ } else {
+ // if no common props were specified, then assign family specific props
+ if (stmtProps != null) {
+ allFamiliesProps.put(f, stmtProps);
+ }
+ }
+ }
+
+ // case when there is a column family being added but there are no props
+ // For ex - in DROP COLUMN when a new empty CF needs to be added since all
+ // the columns of the existing empty CF are getting dropped. Or the case
+ // when one is just adding a column for a column family like this:
+ // ALTER TABLE ADD CF.COL
+ for (String cf : colFamiliesForPColumnsToBeAdded) {
+ if (cf != null && allFamiliesProps.get(cf) == null) {
+ allFamiliesProps.put(cf, new HashMap<String, Object>());
+ }
+ }
+
+ if (table.getColumnFamilies().isEmpty() && !addingColumns && !commonFamilyProps.isEmpty()) {
+ allFamiliesProps.put(Bytes.toString(table.getDefaultFamilyName() == null ? QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES : table.getDefaultFamilyName().getBytes() ), commonFamilyProps);
+ }
+
+ // Views are not allowed to have any of these properties.
+ if (table.getType() == PTableType.VIEW && (!stmtFamiliesPropsMap.isEmpty() || !commonFamilyProps.isEmpty() || !tableProps.isEmpty())) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.VIEW_WITH_PROPERTIES).build()
+ .buildException();
+ }
+ HTableDescriptor newTableDescriptor = null;
+ if (!allFamiliesProps.isEmpty() || !tableProps.isEmpty()) {
+ byte[] tableNameBytes = Bytes.toBytes(table.getPhysicalName().getString());
+ HTableDescriptor existingTableDescriptor = getTableDescriptor(tableNameBytes);
+ newTableDescriptor = new HTableDescriptor(existingTableDescriptor);
+ if (!tableProps.isEmpty()) {
+ // add all the table properties to the existing table descriptor
+ for (Entry<String, Object> entry : tableProps.entrySet()) {
+ newTableDescriptor.setValue(entry.getKey(), entry.getValue() != null ? entry.getValue().toString() : null);
+ }
+ }
+ if (addingColumns) {
+ // Make sure that all the CFs of the table have the same TTL as the empty CF.
+ setTTLToEmptyCFTTL(allFamiliesProps, table, newTableDescriptor);
+ }
+ for (Entry<String, Map<String, Object>> entry : allFamiliesProps.entrySet()) {
+ byte[] cf = entry.getKey().getBytes();
+ HColumnDescriptor colDescriptor = newTableDescriptor.getFamily(cf);
+ if (colDescriptor == null) {
+ // new column family
+ colDescriptor = generateColumnFamilyDescriptor(new Pair<>(cf, entry.getValue()), table.getType());
+ newTableDescriptor.addFamily(colDescriptor);
+ } else {
+ modifyColumnFamilyDescriptor(colDescriptor, entry.getValue());
+ }
+ }
+ }
+ return newTableDescriptor;
+ }
+
+ private boolean isHColumnProperty(String propName) {
+ return defaultColDescriptor.getValue(propName) != null;
+ }
+
+ private boolean isHTableProperty(String propName) {
+ return !isHColumnProperty(propName) && !TableProperty.isPhoenixTableProperty(propName);
+ }
+
+ private HashSet<String> existingColumnFamilies(PTable table) {
+ List<PColumnFamily> cfs = table.getColumnFamilies();
+ HashSet<String> cfNames = new HashSet<>(cfs.size());
+ for (PColumnFamily cf : table.getColumnFamilies()) {
+ cfNames.add(cf.getName().getString());
+ }
+ return cfNames;
+ }
+
+ private int getTTLForEmptyCf(byte[] emptyCf, byte[] tableNameBytes, HTableDescriptor tableDescriptor) throws SQLException {
+ if (tableDescriptor == null) {
+ tableDescriptor = getTableDescriptor(tableNameBytes);
+ }
+ return tableDescriptor.getFamily(emptyCf).getTimeToLive();
+ }
+
+ private void setTTLToEmptyCFTTL(Map<String, Map<String, Object>> familyProps, PTable table,
+ HTableDescriptor tableDesc) throws SQLException {
+ if (!familyProps.isEmpty()) {
+ int emptyCFTTL = getTTLForEmptyCf(SchemaUtil.getEmptyColumnFamily(table), table.getPhysicalName().getBytes(), tableDesc);
+ for (String family : familyProps.keySet()) {
+ Map<String, Object> props = familyProps.get(family) != null ? familyProps.get(family) : new HashMap<String, Object>();
+ props.put(TTL, emptyCFTTL);
+ }
+ }
+ }
+
@Override
public MetaDataMutationResult dropColumn(final List<Mutation> tableMetaData, PTableType tableType) throws SQLException {
byte[][] rowKeyMetadata = new byte[3][];
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d3aba78a/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 da893e6..434f3eb 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
@@ -19,13 +19,12 @@ package org.apache.phoenix.query;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_STATE_BYTES;
-import java.io.IOException;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.concurrent.TimeoutException;
+import java.util.Set;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
@@ -223,7 +222,7 @@ public class ConnectionlessQueryServicesImpl extends DelegateQueryServices imple
}
@Override
- public MetaDataMutationResult addColumn(List<Mutation> tableMetaData, List<Pair<byte[],Map<String,Object>>> families, PTable table) throws SQLException {
+ public MetaDataMutationResult addColumn(List<Mutation> tableMetaData, PTable table, Map<String, List<Pair<String,Object>>> properties, Set<String> colFamiliesForPColumnsToBeAdded) throws SQLException {
return new MetaDataMutationResult(MutationCode.TABLE_ALREADY_EXISTS, 0, null);
}
@@ -480,9 +479,5 @@ public class ConnectionlessQueryServicesImpl extends DelegateQueryServices imple
return getProps().getInt(QueryServices.SEQUENCE_SALT_BUCKETS_ATTRIB,
QueryServicesOptions.DEFAULT_SEQUENCE_TABLE_SALT_BUCKETS);
}
-
- @Override
- public void modifyTable(byte[] tableName, HTableDescriptor newDesc) throws IOException,
- InterruptedException, TimeoutException {
- }
+
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d3aba78a/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 a76738e..9a33fa3 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
@@ -17,12 +17,11 @@
*/
package org.apache.phoenix.query;
-import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.concurrent.TimeoutException;
+import java.util.Set;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.HTableDescriptor;
@@ -118,8 +117,8 @@ public class DelegateConnectionQueryServices extends DelegateQueryServices imple
}
@Override
- public MetaDataMutationResult addColumn(List<Mutation> tabeMetaData, List<Pair<byte[],Map<String,Object>>> families, PTable table) throws SQLException {
- return getDelegate().addColumn(tabeMetaData, families, table);
+ public MetaDataMutationResult addColumn(List<Mutation> tableMetaData, PTable table, Map<String, List<Pair<String,Object>>> properties, Set<String> colFamiliesForPColumnsToBeAdded) throws SQLException {
+ return getDelegate().addColumn(tableMetaData, table, properties, colFamiliesForPColumnsToBeAdded);
}
@@ -251,10 +250,4 @@ public class DelegateConnectionQueryServices extends DelegateQueryServices imple
public int getSequenceSaltBuckets() {
return getDelegate().getSequenceSaltBuckets();
}
-
- @Override
- public void modifyTable(byte[] tableName, HTableDescriptor newDesc) throws IOException,
- InterruptedException, TimeoutException {
- getDelegate().modifyTable(tableName, newDesc);
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d3aba78a/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 ea3af37..5fffbf2 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
@@ -47,9 +47,9 @@ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.PARENT_TENANT_ID;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.PHYSICAL_NAME;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.PK_NAME;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.REGION_NAME;
-import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORE_NULLS;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SALT_BUCKETS;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SORT_ORDER;
+import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORE_NULLS;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
@@ -74,21 +74,17 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Types;
-import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
-import java.util.concurrent.TimeoutException;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.HColumnDescriptor;
@@ -140,7 +136,6 @@ import org.apache.phoenix.parse.ParseNodeFactory;
import org.apache.phoenix.parse.PrimaryKeyConstraint;
import org.apache.phoenix.parse.TableName;
import org.apache.phoenix.parse.UpdateStatisticsStatement;
-import org.apache.phoenix.query.ConnectionQueryServices;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.query.QueryServicesOptions;
@@ -159,7 +154,6 @@ import org.apache.phoenix.util.MetaDataUtil;
import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.ReadOnlyProps;
import org.apache.phoenix.util.SchemaUtil;
-import org.apache.phoenix.util.ServerUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -168,6 +162,7 @@ import com.google.common.collect.Iterators;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import com.google.common.primitives.Ints;
public class MetaDataClient {
@@ -276,9 +271,6 @@ public class MetaDataClient {
private final PhoenixConnection connection;
- private static final HColumnDescriptor defaultColDescriptor = new HColumnDescriptor(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES);
-
-
public MetaDataClient(PhoenixConnection connection) {
this.connection = connection;
}
@@ -1881,6 +1873,7 @@ public class MetaDataClient {
}
throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_MUTATE_TABLE)
.setSchemaName(schemaName).setTableName(tableName).setFamilyName(familyName).setColumnName(columnName).setMessage(msg).build().buildException();
+ case NO_OP:
case COLUMN_ALREADY_EXISTS:
case COLUMN_NOT_FOUND:
break;
@@ -1978,76 +1971,34 @@ public class MetaDataClient {
Boolean disableWALProp = null;
Boolean storeNullsProp = null;
- // flatten, separate and validate properties
- ListMultimap<String,Pair<String,Object>> stmtPropsMap = statement.getProps();
- Map<String, Map<String, Object>> stmtFamiliesPropsMap = new HashMap<>(stmtPropsMap.size());
- Map<String, Object> tableProps = new HashMap<>(stmtPropsMap.size());
+ ListMultimap<String,Pair<String,Object>> stmtProperties = statement.getProps();
+ Map<String, List<Pair<String, Object>>> properties = new HashMap<>(stmtProperties.size());
PTable table = FromCompiler.getResolver(statement, connection).getTables().get(0).getTable();
- Map<String,Object> commonFamilyProps = new HashMap<>();
List<ColumnDef> columnDefs = statement.getColumnDefs();
if (columnDefs == null) {
- columnDefs = Lists.newArrayListWithExpectedSize(1);
+ columnDefs = Collections.emptyList();
}
- for (String family : stmtPropsMap.keySet()) {
- List<Pair<String, Object>> propsList = stmtPropsMap.get(family);
- Map<String, Object> colFamilyPropsMap = new HashMap<String, Object>(propsList.size());
+ for (String family : stmtProperties.keySet()) {
+ List<Pair<String, Object>> propsList = stmtProperties.get(family);
for (Pair<String, Object> prop : propsList) {
String propName = prop.getFirst();
- if ((isHTableProperty(propName) || TableProperty.isPhoenixTableProperty(propName)) && columnDefs.size() > 0) {
- // setting HTable and PhoenixTable properties while adding a column is not allowed.
- throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN)
- .setMessage("Property: " + propName).build()
- .buildException();
- }
- if (isHTableProperty(propName)) {
- // Can't have a column family name for a property that's an HTableProperty
- if (!family.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY)) {
- throw new SQLExceptionInfo.Builder(SQLExceptionCode.COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY)
- .setMessage("Column Family: " + family + ", Property: " + propName).build()
- .buildException();
+ if (TableProperty.isPhoenixTableProperty(propName)) {
+ TableProperty.valueOf(propName).validate(true, !family.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY), table.getType());
+ if (propName.equals(PTable.IS_IMMUTABLE_ROWS_PROP_NAME)) {
+ isImmutableRowsProp = (Boolean)prop.getSecond();
+ } else if (propName.equals(PhoenixDatabaseMetaData.MULTI_TENANT)) {
+ multiTenantProp = (Boolean)prop.getSecond();
+ } else if (propName.equals(DISABLE_WAL)) {
+ disableWALProp = (Boolean)prop.getSecond();
+ } else if (propName.equals(STORE_NULLS)) {
+ storeNullsProp = (Boolean)prop.getSecond();
}
- tableProps.put(propName, prop.getSecond());
- } else {
- if (TableProperty.isPhoenixTableProperty(propName)) {
- TableProperty.valueOf(propName).validate(true, !family.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY), table.getType());
- if (propName.equals(TTL)) {
- // Even though TTL is really a HColumnProperty we treat it specially.
- // We enforce that all column families have the same TTL.
- commonFamilyProps.put(propName, prop.getSecond());
- } else if (propName.equals(PTable.IS_IMMUTABLE_ROWS_PROP_NAME)) {
- isImmutableRowsProp = (Boolean)prop.getSecond();
- } else if (propName.equals(PhoenixDatabaseMetaData.MULTI_TENANT)) {
- multiTenantProp = (Boolean)prop.getSecond();
- } else if (propName.equals(DISABLE_WAL)) {
- disableWALProp = (Boolean)prop.getSecond();
- } else if (propName.equals(STORE_NULLS)) {
- storeNullsProp = (Boolean) prop.getSecond();
- }
- } else {
- if (isHColumnProperty(propName)) {
- if (family.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY)) {
- commonFamilyProps.put(propName, prop.getSecond());
- } else {
- colFamilyPropsMap.put(propName, prop.getSecond());
- }
- } else {
- // invalid property - neither of HTableProp, HColumnProp or PhoenixTableProp
- // FIXME: This isn't getting triggered as currently a property gets evaluated
- // as HTableProp if its neither HColumnProp or PhoenixTableProp.
- throw new SQLExceptionInfo.Builder(SQLExceptionCode.SET_UNSUPPORTED_PROP_ON_ALTER_TABLE)
- .setMessage("Column Family: " + family + ", Property: " + propName).build()
- .buildException();
- }
- }
- }
- }
- if (!colFamilyPropsMap.isEmpty()) {
- stmtFamiliesPropsMap.put(family, colFamilyPropsMap);
+ }
}
+ properties.put(family, propsList);
}
-
-
boolean retried = false;
+ boolean changingPhoenixTableProperty = false;
while (true) {
ColumnResolver resolver = FromCompiler.getResolver(statement, connection);
table = resolver.getTables().get(0).getTable();
@@ -2075,24 +2026,28 @@ public class MetaDataClient {
if (isImmutableRowsProp != null) {
if (isImmutableRowsProp.booleanValue() != table.isImmutableRows()) {
isImmutableRows = isImmutableRowsProp;
+ changingPhoenixTableProperty = true;
}
}
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;
}
}
Boolean storeNulls = null;
if (storeNullsProp != null) {
if (storeNullsProp.booleanValue() != table.getStoreNulls()) {
storeNulls = storeNullsProp;
+ changingPhoenixTableProperty = true;
}
}
@@ -2101,7 +2056,7 @@ public class MetaDataClient {
List<PColumn> columns = Lists.newArrayListWithExpectedSize(columnDefs.size());
Set<String> colFamiliesForPColumnsToBeAdded = new LinkedHashSet<>();
- HashSet<String> existingColumnFamilies = existingColumnFamilies(table);
+ Set<String> families = new LinkedHashSet<>();
if (columnDefs.size() > 0 ) {
short nextKeySeq = SchemaUtil.getMaxKeySeq(table);
for( ColumnDef colDef : columnDefs) {
@@ -2126,8 +2081,9 @@ public class MetaDataClient {
pkName = table.getPKName() == null ? null : table.getPKName().getString();
keySeq = ++nextKeySeq;
} else {
- colFamiliesForPColumnsToBeAdded.add(column.getFamilyName().getString());
+ families.add(column.getFamilyName().getString());
}
+ colFamiliesForPColumnsToBeAdded.add(column.getFamilyName() == null ? null : column.getFamilyName().getString());
addColumnMutation(schemaName, tableName, column, colUpsert, null, pkName, keySeq, table.getBucketNum() != null);
}
@@ -2175,15 +2131,17 @@ public class MetaDataClient {
tableMetaData.addAll(connection.getMutationState().toMutations().next().getSecond());
connection.rollback();
}
- long seqNum = incrementTableSeqNum(table, statement.getTableType(), 1,
- isImmutableRows, disableWAL, multiTenant, storeNulls);
-
- tableMetaData.addAll(connection.getMutationState().toMutations().next().getSecond());
- connection.rollback();
+ long seqNum = table.getSequenceNumber();
+ if (changingPhoenixTableProperty || columnDefs.size() > 0) {
+ seqNum = incrementTableSeqNum(table, statement.getTableType(), 1, isImmutableRows, disableWAL, multiTenant, storeNulls);
+ tableMetaData.addAll(connection.getMutationState().toMutations().next().getSecond());
+ connection.rollback();
+ }
+
// Force the table header row to be first
Collections.reverse(tableMetaData);
- byte[] family = colFamiliesForPColumnsToBeAdded.size() > 0 ? colFamiliesForPColumnsToBeAdded.iterator().next().getBytes() : null;
+ byte[] family = families.size() > 0 ? families.iterator().next().getBytes() : null;
// Figure out if the empty column family is changing as a result of adding the new column
byte[] emptyCF = null;
@@ -2201,78 +2159,7 @@ public class MetaDataClient {
}
}
- Map<String, Map<String, Object>> allFamiliesProps = new HashMap<>(existingColumnFamilies.size() + stmtFamiliesPropsMap.size());
- commonFamilyProps = Collections.unmodifiableMap(commonFamilyProps);
- if (columnDefs.size() == 0) {
- // Add the common family props to all existing column families
- for (String existingColFamily : existingColumnFamilies) {
- Map<String, Object> m = new HashMap<String, Object>(commonFamilyProps.size());
- m.putAll(commonFamilyProps);
- allFamiliesProps.put(existingColFamily, m);
- }
- } else {
- // Add the common family props to the column families of the columns being added
- for (String colFamily : colFamiliesForPColumnsToBeAdded) {
- Map<String, Object> m = new HashMap<String, Object>(commonFamilyProps.size());
- m.putAll(commonFamilyProps);
- allFamiliesProps.put(colFamily, m);
- }
- }
-
- if (table.getColumnFamilies().isEmpty() && columnDefs.size() == 0 && !commonFamilyProps.isEmpty()) {
- allFamiliesProps.put(Bytes.toString(table.getDefaultFamilyName() == null ? QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES : table.getDefaultFamilyName().getBytes() ), commonFamilyProps);
- }
-
- // Now go through the column family properties specified in the statement
- // and merge them with the common family properties.
- for (String f : stmtFamiliesPropsMap.keySet()) {
- if (allFamiliesProps.get(f) != null) {
- Map<String, Object> props = allFamiliesProps.get(f);
- Map<String, Object> stmtProps = stmtFamiliesPropsMap.get(f);
- props.putAll(stmtProps);
- } else {
- if (columnDefs.size() == 0) {
- throw new ColumnFamilyNotFoundException(f);
- } else {
- if (!existingColumnFamilies.contains(f)) {
- throw new ColumnFamilyNotFoundException(f);
- } else {
- // If the family already exists then an attempt was made to
- // add property for a column family that doesn't have a column
- // being added in the statement.
- throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_SET_PROPERTY_FOR_COLUMN_NOT_ADDED).build()
- .buildException();
- }
- }
- }
- }
-
- // Views are not allowed to have any of these properties.
- if (table.getType() == PTableType.VIEW && (!stmtFamiliesPropsMap.isEmpty() || !commonFamilyProps.isEmpty() || !tableProps.isEmpty())) {
- throw new SQLExceptionInfo.Builder(SQLExceptionCode.VIEW_WITH_PROPERTIES).build()
- .buildException();
- }
-
- HTableDescriptor newTableDesc = null;
- if (!tableProps.isEmpty()) {
- newTableDesc = modifyTableProps(tableName, table, tableProps);
- }
-
- if (columnDefs.size() > 0) {
- // Make sure that all the CFs of the table have the same TTL as the empty CF.
- setTTLToEmptyCFTTL(allFamiliesProps, table, newTableDesc);
- }
-
- List<Pair<byte[], Map<String, Object>>> families = new ArrayList<>(allFamiliesProps.size());
- for (Entry<String, Map<String, Object>> entry : allFamiliesProps.entrySet()) {
- byte[] cf = entry.getKey().getBytes();
- Map<String, Object> props = entry.getValue();
- if (!props.isEmpty()) {
- families.add(new Pair<>(cf, props));
- }
- }
-
- MetaDataMutationResult result = connection.getQueryServices().addColumn(tableMetaData, families, table);
+ MetaDataMutationResult result = connection.getQueryServices().addColumn(tableMetaData, table, properties, colFamiliesForPColumnsToBeAdded);
try {
MutationCode code = processMutationResult(schemaName, tableName, result);
if (code == MutationCode.COLUMN_ALREADY_EXISTS) {
@@ -2336,48 +2223,6 @@ public class MetaDataClient {
}
}
- private void setTTLToEmptyCFTTL(Map<String, Map<String, Object>> familyProps, PTable table,
- HTableDescriptor newTableDesc) throws SQLException {
- if (!familyProps.isEmpty()) {
- int emptyCFTTL = getTTLForEmptyCf(SchemaUtil.getEmptyColumnFamily(table), table.getPhysicalName().getBytes(), newTableDesc);
- for (String family : familyProps.keySet()) {
- Map<String, Object> props = familyProps.get(family) != null ? familyProps.get(family) : new HashMap<String, Object>();
- props.put(TTL, emptyCFTTL);
- }
- }
- }
-
- private HTableDescriptor modifyTableProps(String tableName, PTable table, Map<String, Object> tableProps) throws SQLException {
- byte[] tableNameBytes = Bytes.toBytes(tableName);
- ConnectionQueryServices services = connection.getQueryServices();
- HTableDescriptor existingTableDescriptor = services.getTableDescriptor(tableNameBytes);
- HTableDescriptor newTableDescriptor = new HTableDescriptor(existingTableDescriptor);
- // add all the table properties to the existing table descriptor
- for (Entry<String, Object> entry : tableProps.entrySet()) {
- newTableDescriptor.setValue(entry.getKey(), entry.getValue() != null ? entry.getValue().toString() : null);
- }
- SQLException sqlE = null;
- try {
- services.modifyTable(tableNameBytes, newTableDescriptor);
- return newTableDescriptor;
- } catch (IOException e) {
- sqlE = ServerUtil.parseServerException(e);
- return null;
- } catch (InterruptedException e) {
- // restore the interrupt status
- Thread.currentThread().interrupt();
- sqlE = new SQLExceptionInfo.Builder(SQLExceptionCode.INTERRUPTED_EXCEPTION).setRootCause(e).build().buildException();
- return null;
- } catch (TimeoutException e) {
- sqlE = new SQLExceptionInfo.Builder(SQLExceptionCode.OPERATION_TIMED_OUT).setRootCause(e.getCause() != null ? e.getCause() : e).build().buildException();
- return null;
- } finally {
- if (sqlE != null) {
- throw sqlE;
- }
- }
- }
-
private String dropColumnMutations(PTable table, List<PColumn> columnsToDrop, List<Mutation> tableMetaData) throws SQLException {
String tenantId = connection.getTenantId() == null ? "" : connection.getTenantId().getString();
String schemaName = table.getSchemaName().getString();
@@ -2538,8 +2383,8 @@ public class MetaDataClient {
tableContainingColumnToDrop.getColumnFamily(emptyCF);
} catch (ColumnFamilyNotFoundException e) {
// Only if it's not already a column family do we need to ensure it's created
- List<Pair<byte[],Map<String,Object>>> family = Lists.newArrayListWithExpectedSize(1);
- family.add(new Pair<byte[],Map<String,Object>>(emptyCF,Collections.<String,Object>emptyMap()));
+ Map<String, List<Pair<String,Object>>> family = new HashMap<>(1);
+ family.put(Bytes.toString(emptyCF), Collections.<Pair<String, Object>>emptyList());
// Just use a Put without any key values as the Mutation, as addColumn will treat this specially
// TODO: pass through schema name and table name instead to these methods as it's cleaner
byte[] tenantIdBytes = connection.getTenantId() == null ? null : connection.getTenantId().getBytes();
@@ -2548,7 +2393,8 @@ public class MetaDataClient {
Collections.<Mutation>singletonList(new Put(SchemaUtil.getTableKey
(tenantIdBytes, tableContainingColumnToDrop.getSchemaName().getBytes(),
tableContainingColumnToDrop.getTableName().getBytes()))),
- family,tableContainingColumnToDrop);
+ tableContainingColumnToDrop, family, Sets.newHashSet(Bytes.toString(emptyCF)));
+
}
}
}
@@ -2740,34 +2586,4 @@ public class MetaDataClient {
return table.getTableStats();
}
- private boolean isHColumnProperty(String propName) {
- return defaultColDescriptor.getValue(propName) != null;
- }
-
- private boolean isHTableProperty(String propName) {
- return !isHColumnProperty(propName) && !TableProperty.isPhoenixTableProperty(propName);
- }
-
- private HashSet<String> existingColumnFamilies(PTable table) {
- List<PColumnFamily> cfs = table.getColumnFamilies();
- HashSet<String> cfNames = new HashSet<>(cfs.size());
- for (PColumnFamily cf : table.getColumnFamilies()) {
- cfNames.add(cf.getName().getString());
- }
- return cfNames;
- }
-
- private int getTTLForEmptyCf(byte[] emptyCf, byte[] tableNameBytes, HTableDescriptor tableDescriptor) throws SQLException {
- if (tableDescriptor == null) {
- tableDescriptor = connection.getQueryServices().getTableDescriptor(tableNameBytes);
- }
- HColumnDescriptor[] colDescriptors = tableDescriptor.getColumnFamilies();
- for (HColumnDescriptor colDesc : colDescriptors) {
- if (Bytes.equals(emptyCf, colDesc.getName())) {
- return colDesc.getTimeToLive();
- }
- }
- throw new IllegalArgumentException("No match for empty column family found");
- }
-
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/d3aba78a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
index a2779a2..4db04ca 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
@@ -954,7 +954,7 @@ public class QueryCompilerTest extends BaseConnectionlessQueryTest {
statement.execute();
fail();
} catch (SQLException e) { // expected
- assertEquals(SQLExceptionCode.CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN.getErrorCode(), e.getErrorCode());
+ assertEquals(SQLExceptionCode.SALT_ONLY_ON_CREATE_TABLE.getErrorCode(), e.getErrorCode());
}
try {
PreparedStatement statement = conn.prepareStatement("ALTER TABLE atable SET SALT_BUCKETS=4");