Skip to content

Commit

Permalink
PHOENIX-4743: ALTER TABLE ADD COLUMN for global index should not modi…
Browse files Browse the repository at this point in the history
…fy HBase metadata if failed

Signed-off-by: Chinmay Kulkarni <chinmayskulkarni@apache.org>
  • Loading branch information
Sandeep Pal authored and ChinmaySKulkarni committed Aug 26, 2019
1 parent 43310a6 commit 197b6e3
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package org.apache.phoenix.end2end;

import static org.apache.phoenix.exception.SQLExceptionCode.CANNOT_MUTATE_TABLE;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER;
Expand Down Expand Up @@ -51,6 +52,7 @@
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.phoenix.exception.PhoenixParserException;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
Expand Down Expand Up @@ -852,6 +854,36 @@ public void testDropMultipleColumns() throws Exception {
conn1.close();
}

@Test
public void testAlterTableOnGlobalIndex() throws Exception {
try (Connection conn = DriverManager.getConnection(getUrl());
Statement stmt = conn.createStatement()) {
conn.setAutoCommit(false);
Admin admin = conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin();
String tableName = generateUniqueName();
String globalIndexTableName = generateUniqueName();

stmt.execute("CREATE TABLE " + tableName +
" (ID INTEGER PRIMARY KEY, COL1 VARCHAR(10), COL2 BOOLEAN)");

stmt.execute("CREATE INDEX " + globalIndexTableName + " on " + tableName + " (COL2)");
TableDescriptor originalDesc = admin.getDescriptor(TableName.valueOf(globalIndexTableName));
int expectedErrorCode = 0;
try {
stmt.execute("ALTER TABLE " + globalIndexTableName + " ADD CF1.AGE INTEGER ");
conn.commit();
fail("The alter table did not fail as expected");
} catch (SQLException e) {
assertEquals(e.getErrorCode(), CANNOT_MUTATE_TABLE.getErrorCode());
}

TableDescriptor finalDesc = admin.getDescriptor(TableName.valueOf(globalIndexTableName));
assertTrue(finalDesc.equals(originalDesc));

// drop the table
stmt.execute("DROP TABLE " + tableName);
}
}

@Test
public void testAlterStoreNulls() throws SQLException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2060,16 +2060,16 @@ public MetaDataMutationResult addColumn(final List<Mutation> tableMetaData,
// When adding a column to a view, base physical table should only be modified when new column families are being added.
modifyHTable = canViewsAddNewCF && !existingColumnFamiliesForBaseTable(table.getPhysicalName()).containsAll(colFamiliesForPColumnsToBeAdded);
}
if (modifyHTable) {
sendHBaseMetaData(tableDescriptors, pollingNeeded);
}

// 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())) {
if (modifyHTable) {
sendHBaseMetaData(tableDescriptors, pollingNeeded);
}
return new MetaDataMutationResult(MutationCode.NO_OP, EnvironmentEdgeManager.currentTimeMillis(), table);
}
byte[][] rowKeyMetaData = new byte[3][];
Expand Down Expand Up @@ -2127,6 +2127,10 @@ public MetaDataResponse call(MetaDataService instance) throws IOException {
}
}
}

if (modifyHTable && result.getMutationCode() != MutationCode.UNALLOWED_TABLE_MUTATION) {
sendHBaseMetaData(tableDescriptors, pollingNeeded);
}
} finally {
// If we weren't successful with our metadata update
// and we've already pushed the HBase metadata changes to the server
Expand Down

0 comments on commit 197b6e3

Please sign in to comment.