eomiks opened a new pull request #4295: URL: https://github.com/apache/hbase/pull/4295
since [HBASE-15616](https://issues.apache.org/jira/browse/HBASE-15616), setting column qualifier as null is possible. but when NewVersionBehavior is on, delete with null columnQualifier occurs NullPointerException. ```java @Test public void testNullColumnQualifier() throws IOException { try (Table t = createTable()) { Delete del = new Delete(ROW); del.addColumn(FAMILY, null); t.delete(del); Result r = t.get(new Get(ROW)); //NPE happens. assertTrue(r.isEmpty()); } } ``` * stacktrace ``` Caused by: java.lang.NullPointerException at org.apache.hadoop.hbase.regionserver.querymatcher.NewVersionBehaviorTracker.add(NewVersionBehaviorTracker.java:214) at org.apache.hadoop.hbase.regionserver.querymatcher.NormalUserScanQueryMatcher.match(NormalUserScanQueryMatcher.java:73) at org.apache.hadoop.hbase.regionserver.StoreScanner.next(StoreScanner.java:627) at org.apache.hadoop.hbase.regionserver.KeyValueHeap.next(KeyValueHeap.java:157) at org.apache.hadoop.hbase.regionserver.HRegion$RegionScannerImpl.populateResult(HRegion.java:6672) at org.apache.hadoop.hbase.regionserver.HRegion$RegionScannerImpl.nextInternal(HRegion.java:6836) at org.apache.hadoop.hbase.regionserver.HRegion$RegionScannerImpl.nextRaw(HRegion.java:6606) at org.apache.hadoop.hbase.regionserver.HRegion$RegionScannerImpl.next(HRegion.java:6583) at org.apache.hadoop.hbase.regionserver.HRegion$RegionScannerImpl.next(HRegion.java:6570) at org.apache.hadoop.hbase.regionserver.RSRpcServices.get(RSRpcServices.java:26 45) at org.apache.hadoop.hbase.regionserver.RSRpcServices.get(RSRpcServices.java:2571) at org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos$ClientService$2.callBlockingMethod(ClientProtos.java:42274) at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:418) ... 3 more ``` NPE happens because delColMap is not initialized and empty. in this case delColMap.ceilingEntry for empty returns null and NPE happens. https://github.com/apache/hbase/blob/1efd8fe53c13cdbfde7cb3d0ff7ebea7b8b7d3bb/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/querymatcher/NewVersionBehaviorTracker.java#L214 delColMap expected to be initialized (deep copying of delFamMap) when columnQualifier is changed. But, when null columnQualifier is presented, matchingCq == true and delColMap is never initialized for null columnQualifier deletes. https://github.com/apache/hbase/blob/1efd8fe53c13cdbfde7cb3d0ff7ebea7b8b7d3bb/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/querymatcher/NewVersionBehaviorTracker.java#L168-L169 I changed to initialize delColMap if null columnQualifier is presented. and only if cell is not for columnFamily or columnFamilfyVersion tombstone which is no need to initialize delColMap (for the performance). ``` private boolean isColumnQualifierChanged(Cell cell) { if (delColMap.isEmpty() && (PrivateCellUtil.isDeleteColumns(cell) || PrivateCellUtil.isDeleteColumnVersion(cell))) { // for null columnQualifier return true; } return !PrivateCellUtil.matchingQualifier(cell, lastCqArray, lastCqOffset, lastCqLength); } ``` I inverted ```matchCq``` to ```isColumnQualifierChanged``` and reformed if/else statement, I thought it's more clear and fit for purpose. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
