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]


Reply via email to