Skip to content

Commit

Permalink
PHOENIX-1882 Issue column family deletes instead of row deletes in PT…
Browse files Browse the repository at this point in the history
…ableImpl
  • Loading branch information
Thomas committed Apr 30, 2015
1 parent d2c1f2c commit efd7c9f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 29 deletions.
Expand Up @@ -19,23 +19,31 @@


import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES; import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;


import java.io.IOException; import java.io.IOException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List;
import java.util.Properties; import java.util.Properties;


import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTableInterface; import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.jdbc.PhoenixConnection; import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.util.PropertiesUtil; import org.apache.phoenix.util.PropertiesUtil;
import org.junit.Test; import org.junit.Test;
Expand All @@ -52,18 +60,44 @@ public void testMappingHbaseTableToPhoenixTable() throws Exception {
try { try {
// Create table then get the single region for our new table. // Create table then get the single region for our new table.
HTableDescriptor descriptor = new HTableDescriptor(tableName); HTableDescriptor descriptor = new HTableDescriptor(tableName);
HColumnDescriptor columnDescriptor = new HColumnDescriptor(Bytes.toBytes("cf")); HColumnDescriptor columnDescriptor1 = new HColumnDescriptor(Bytes.toBytes("cf1"));
descriptor.addFamily(columnDescriptor); HColumnDescriptor columnDescriptor2 = new HColumnDescriptor(Bytes.toBytes("cf2"));
descriptor.addFamily(columnDescriptor1);
descriptor.addFamily(columnDescriptor2);
admin.createTable(descriptor); admin.createTable(descriptor);
HTableInterface t = conn.getQueryServices().getTable(Bytes.toBytes("MTEST")); HTableInterface t = conn.getQueryServices().getTable(Bytes.toBytes("MTEST"));
insertData(tableName.getName(), admin, t); insertData(tableName.getName(), admin, t);
t.close(); t.close();
try { // create phoenix table that maps to existing HBase table
testCreateTableMismatchedType(); createPhoenixTable();
fail();
} catch (SQLException e) { String selectSql = "SELECT * FROM MTEST";
assertEquals(SQLExceptionCode.ILLEGAL_DATA.getErrorCode(),e.getErrorCode()); ResultSet rs = conn.createStatement().executeQuery(selectSql);
} ResultSetMetaData rsMetaData = rs.getMetaData();
assertTrue("Expected single row", rs.next());
// verify values from cf2 is not returned
assertEquals("Number of columns", 2, rsMetaData.getColumnCount());
assertEquals("Column Value", "value1", rs.getString(2));
assertFalse("Expected single row ", rs.next());

// delete the row
String deleteSql = "DELETE FROM MTEST WHERE id = 'row'";
conn.createStatement().executeUpdate(deleteSql);
conn.commit();

// verify that no rows are returned when querying through phoenix
rs = conn.createStatement().executeQuery(selectSql);
assertFalse("Expected no row` ", rs.next());

// verify that row with value for cf2 still exists when using hbase apis
Scan scan = new Scan();
ResultScanner results = t.getScanner(scan);
Result result = results.next();
assertNotNull("Expected single row", result);
List<KeyValue> kvs = result.getColumn(Bytes.toBytes("cf2"), Bytes.toBytes("q2"));
assertEquals("Expected single value ", 1, kvs.size());
assertEquals("Column Value", "value2", Bytes.toString(kvs.get(0).getValue()));
assertNull("Expected single row", results.next());
} finally { } finally {
admin.close(); admin.close();
} }
Expand All @@ -72,26 +106,23 @@ public void testMappingHbaseTableToPhoenixTable() throws Exception {
private void insertData(final byte[] tableName, HBaseAdmin admin, HTableInterface t) throws IOException, private void insertData(final byte[] tableName, HBaseAdmin admin, HTableInterface t) throws IOException,
InterruptedException { InterruptedException {
Put p = new Put(Bytes.toBytes("row")); Put p = new Put(Bytes.toBytes("row"));
p.add(Bytes.toBytes("cf"), Bytes.toBytes("q1"), Bytes.toBytes("value1")); p.add(Bytes.toBytes("cf1"), Bytes.toBytes("q1"), Bytes.toBytes("value1"));
p.add(Bytes.toBytes("cf2"), Bytes.toBytes("q2"), Bytes.toBytes("value2"));
t.put(p); t.put(p);
t.flushCommits(); t.flushCommits();
admin.flush(tableName); admin.flush(tableName);
} }


/** /**
* Test create a table in Phoenix with mismatched data type UNSIGNED_LONG * Create a table in Phoenix that only maps column family cf1
*/ */
private void testCreateTableMismatchedType() throws SQLException { private void createPhoenixTable() throws SQLException {
String ddl = "create table IF NOT EXISTS MTEST (" + " id varchar NOT NULL primary key," String ddl = "create table IF NOT EXISTS MTEST (" + " id varchar NOT NULL primary key,"
+ " \"cf\".\"q1\" unsigned_long" + " ) "; + " \"cf1\".\"q1\" varchar" + " ) ";
Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props); Connection conn = DriverManager.getConnection(getUrl(), props);
conn.createStatement().execute(ddl); conn.createStatement().execute(ddl);
conn.commit(); conn.commit();
String query = "select * from MTEST";
ResultSet rs = conn.createStatement().executeQuery(query);
rs.next();
rs.getLong(2);
} }


} }
Expand Up @@ -806,15 +806,8 @@ public boolean isRowDeleted(Collection<KeyValue> pendingUpdates) {
for (KeyValue kv : pendingUpdates) { for (KeyValue kv : pendingUpdates) {
if (kv.getTypeByte() == KeyValue.Type.DeleteFamily.getCode()) { if (kv.getTypeByte() == KeyValue.Type.DeleteFamily.getCode()) {
nDeleteCF++; nDeleteCF++;
boolean isEmptyCF = Bytes.compareTo(kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength(),
dataEmptyKeyValueCF, 0, dataEmptyKeyValueCF.length) == 0;
// This is what a delete looks like on the client side for immutable indexing...
if (isEmptyCF) {
return true;
}
} }
} }
// This is what a delete looks like on the server side for mutable indexing...
return nDeleteCF == this.nDataCFs; return nDeleteCF == this.nDataCFs;
} }


Expand Down
Expand Up @@ -718,10 +718,10 @@ public void setValue(PColumn column, byte[] byteValue) {
@Override @Override
public void delete() { public void delete() {
newMutations(); newMutations();
// FIXME: the version of the Delete constructor without the lock args was introduced Delete delete = new Delete(key);
// in 0.94.4, thus if we try to use it here we can no longer use the 0.94.2 version for (PColumnFamily colFamily : families) {
// of the client. delete.addFamily(colFamily.getName().getBytes(), ts);
Delete delete = new Delete(key,ts); }
deleteRow = delete; deleteRow = delete;
// No need to write to the WAL for indexes // No need to write to the WAL for indexes
if (PTableImpl.this.getType() == PTableType.INDEX) { if (PTableImpl.this.getType() == PTableType.INDEX) {
Expand Down

0 comments on commit efd7c9f

Please sign in to comment.