This is an automated email from the ASF dual-hosted git repository. achouhan pushed a commit to branch 4.14-HBase-1.3 in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/4.14-HBase-1.3 by this push: new ff32ea1 PHOENIX-5704 Covered column updates are not generated for previously deleted data table row ff32ea1 is described below commit ff32ea1959763df72e81182a6c8cb5f4fe83ac52 Author: Abhishek Singh Chouhan <abhishekchouhan...@gmail.com> AuthorDate: Mon Feb 3 16:16:57 2020 -0800 PHOENIX-5704 Covered column updates are not generated for previously deleted data table row --- .../phoenix/end2end/index/MutableIndexIT.java | 45 +++++++++++++++++++++- .../filter/ApplyAndFilterDeletesFilter.java | 9 ----- .../index/scanner/FilteredKeyValueScanner.java | 8 +++- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java index 9a9fa91..e47fe4c 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/MutableIndexIT.java @@ -908,7 +908,50 @@ public class MutableIndexIT extends ParallelStatsDisabledIT { store.triggerMajorCompaction(); store.compactRecentForTestingAssumingDefaultPolicy(1); } - } + } + + @Test + public void testUpsertingDeletedRowWithNullCoveredColumn() throws Exception { + testUpsertingDeletedRowWithNullCoveredColumn(false); + } + + @Test + public void testUpsertingDeletedRowWithNullCoveredColumnMultiCfs() throws Exception { + testUpsertingDeletedRowWithNullCoveredColumn(true); + } + + public void testUpsertingDeletedRowWithNullCoveredColumn(boolean multiCf) throws Exception { + String tableName = "TBL_" + generateUniqueName(); + String indexName = "IDX_" + generateUniqueName(); + String columnFamily1 = "cf1"; + String columnFamily2 = "cf2"; + String fullTableName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, tableName); + String fullIndexName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, indexName); + try (Connection conn = getConnection()) { + conn.createStatement() + .execute("create table " + fullTableName + " (id integer primary key, " + + (multiCf ? columnFamily1 + "." : "") + "f varchar, " + + (multiCf ? columnFamily2 + "." : "") + "s varchar)" + + tableDDLOptions); + conn.createStatement() + .execute("create " + (localIndex ? "LOCAL" : "") + " index " + indexName + + " on " + fullTableName + " (" + (multiCf ? columnFamily1 + "." : "") + + "f) include (" + (multiCf ? columnFamily2 + "." : "") + "s)"); + conn.createStatement() + .execute("upsert into " + fullTableName + " values (1, 'foo', 'bar')"); + conn.commit(); + conn.createStatement().execute("delete from " + fullTableName + " where id = 1"); + conn.commit(); + conn.createStatement() + .execute("upsert into " + fullTableName + " values (1, null, 'bar')"); + conn.commit(); + ResultSet rs = conn.createStatement().executeQuery("select * from " + fullIndexName); + assertTrue(rs.next()); + assertEquals(1, rs.getInt(2)); + assertEquals(null, rs.getString(1)); + assertEquals("bar", rs.getString(3)); + } + } /** * PHOENIX-4988 diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/filter/ApplyAndFilterDeletesFilter.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/filter/ApplyAndFilterDeletesFilter.java index b5c3414..66e2818 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/filter/ApplyAndFilterDeletesFilter.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/filter/ApplyAndFilterDeletesFilter.java @@ -53,7 +53,6 @@ import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr; */ public class ApplyAndFilterDeletesFilter extends FilterBase { - private boolean done = false; List<ImmutableBytesPtr> families; private final DeleteTracker coveringDelete = new DeleteTracker(); private Hinter currentHint; @@ -95,7 +94,6 @@ public class ApplyAndFilterDeletesFilter extends FilterBase { @Override public void reset(){ this.coveringDelete.reset(); - this.done = false; } @@ -106,11 +104,6 @@ public class ApplyAndFilterDeletesFilter extends FilterBase { @Override public ReturnCode filterKeyValue(Cell next) { - // we marked ourselves done, but the END_ROW_KEY didn't manage to seek to the very last key - if (this.done) { - return ReturnCode.SKIP; - } - KeyValue nextKV = KeyValueUtil.ensureKeyValue(next); switch (KeyValue.Type.codeToType(next.getTypeByte())) { /* @@ -192,8 +185,6 @@ public class ApplyAndFilterDeletesFilter extends FilterBase { getNextFamily(new ImmutableBytesPtr(peeked.getBuffer(), peeked.getFamilyOffset(), peeked.getFamilyLength())); if (nextFamily == null) { - // no known next family, so we can be completely done - done = true; return KeyValue.LOWESTKEY; } // there is a valid family, so we should seek to that diff --git a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/scanner/FilteredKeyValueScanner.java b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/scanner/FilteredKeyValueScanner.java index 072b624..a741257 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/scanner/FilteredKeyValueScanner.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/hbase/index/scanner/FilteredKeyValueScanner.java @@ -25,6 +25,7 @@ import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValueUtil; import org.apache.hadoop.hbase.filter.Filter; import org.apache.hadoop.hbase.filter.Filter.ReturnCode; +import org.apache.hadoop.hbase.regionserver.KeyValueScanner; import org.apache.phoenix.hbase.index.covered.KeyValueStore; /** @@ -94,7 +95,12 @@ public class FilteredKeyValueScanner implements ReseekableScanner { break; // use a seek hint to find out where we should go case SEEK_NEXT_USING_HINT: - delegate.seek(KeyValueUtil.ensureKeyValue(filter.getNextCellHint(peeked))); + Cell nextCellHint = filter.getNextCellHint(peeked); + if (nextCellHint == KeyValue.LOWESTKEY) { + delegate.next(); + } else { + delegate.seek(KeyValueUtil.ensureKeyValue(nextCellHint)); + } } } }