From e273264332f5d1e619c50c6ee9727058ccdfb9b2 Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Tue, 11 Aug 2020 20:32:10 -0700 Subject: [PATCH] Fix two id-over-maxId errors in StringDimensionIndexer. (#10245) 1) lookupId could return IDs beyond maxId if called with a recently added value. 2) getRow could return an ID for null beyond maxId, if null was recently encountered in a dimension that initially didn't appear at all. (In this case, the dictionary ID for null can be > 0). Also add a comment explaining how this stuff is supposed to work. --- .../druid/segment/StringDimensionIndexer.java | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/processing/src/main/java/org/apache/druid/segment/StringDimensionIndexer.java b/processing/src/main/java/org/apache/druid/segment/StringDimensionIndexer.java index bca0a5c72a9..a6b121906c2 100644 --- a/processing/src/main/java/org/apache/druid/segment/StringDimensionIndexer.java +++ b/processing/src/main/java/org/apache/druid/segment/StringDimensionIndexer.java @@ -51,6 +51,7 @@ import org.apache.druid.segment.filter.BooleanValueMatcher; import org.apache.druid.segment.incremental.IncrementalIndex; import org.apache.druid.segment.incremental.IncrementalIndexRow; import org.apache.druid.segment.incremental.IncrementalIndexRowHolder; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import javax.annotation.Nullable; import java.util.ArrayList; @@ -87,7 +88,7 @@ public class StringDimensionIndexer implements DimensionIndexer -1) { + if (nullId >= 0 && nullId < maxId) { + // null was added to the dictionary before this selector was created; return its ID. if (nullIdIntArray == null) { nullIdIntArray = new int[]{nullId}; } row = nullIdIntArray; rowSize = 1; } else { - // doesn't contain nullId, then empty array is used + // null doesn't exist in the dictionary; return an empty array. // Choose to use ArrayBasedIndexedInts later, instead of special "empty" IndexedInts, for monomorphism row = IntArrays.EMPTY_ARRAY; rowSize = 0; @@ -668,6 +680,7 @@ public class StringDimensionIndexer implements DimensionIndexer= maxId) { + // Sanity check; IDs beyond maxId should not be known to callers. (See comment above.) throw new ISE("id[%d] >= maxId[%d]", id, maxId); } final String strValue = getActualValue(id, false); @@ -695,7 +708,16 @@ public class StringDimensionIndexer implements DimensionIndexer