This is an automated email from the ASF dual-hosted git repository.
somandal pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 3631b7d8e06 Handle null Geometry gracefully In H3Index (#16002)
3631b7d8e06 is described below
commit 3631b7d8e064557e38700a6d200828fcf34ef785
Author: Kartik Khare <[email protected]>
AuthorDate: Thu Jul 3 21:32:42 2025 +0530
Handle null Geometry gracefully In H3Index (#16002)
* Handle invalid geometry during H3 index creation
* Track null geometry rows in H3 index
* Add test for skipping invalid geometry
* Handle null Geometry gracefully in H3Index
* Address review comments
* Update table level metric only if tableNameWithType is not null
* Add IndexCreationContext::Common constructor without tableNameWithType
and mark it deprecated
* Address review comments
---------
Co-authored-by: KKCorps <[email protected]>
Co-authored-by: Sonam Mandal <[email protected]>
---
.../creator/impl/SegmentColumnarIndexCreator.java | 1 +
.../impl/inv/geospatial/BaseH3IndexCreator.java | 21 ++++--
.../impl/inv/geospatial/OffHeapH3IndexCreator.java | 7 +-
.../impl/inv/geospatial/OnHeapH3IndexCreator.java | 4 +-
.../local/segment/index/h3/H3IndexType.java | 6 +-
.../segment/index/loader/BaseIndexHandler.java | 2 +-
.../segment/index/loader/ForwardIndexHandler.java | 9 ++-
...IndexAndDictionaryBasedForwardIndexCreator.java | 6 +-
.../loader/bloomfilter/BloomFilterHandler.java | 2 +
.../defaultcolumn/BaseDefaultColumnHandler.java | 1 +
.../loader/invertedindex/FSTIndexHandler.java | 1 +
.../index/loader/invertedindex/H3IndexHandler.java | 2 +
.../loader/invertedindex/InvertedIndexHandler.java | 1 +
.../loader/invertedindex/JsonIndexHandler.java | 2 +
.../loader/invertedindex/RangeIndexHandler.java | 1 +
.../loader/invertedindex/TextIndexHandler.java | 1 +
.../loader/invertedindex/VectorIndexHandler.java | 2 +
.../segment/local/segment/index/H3IndexTest.java | 86 +++++++++++++++++++++-
.../segment/spi/creator/IndexCreationContext.java | 21 +++++-
.../spi/index/creator/GeoSpatialIndexCreator.java | 11 ++-
20 files changed, 163 insertions(+), 24 deletions(-)
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/SegmentColumnarIndexCreator.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/SegmentColumnarIndexCreator.java
index 295138f41cd..e138fea3ea2 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/SegmentColumnarIndexCreator.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/SegmentColumnarIndexCreator.java
@@ -167,6 +167,7 @@ public class SegmentColumnarIndexCreator implements
SegmentCreator {
.withImmutableToMutableIdMap(immutableToMutableIdMap)
.withRealtimeConversion(segmentCreationSpec.isRealtimeConversion())
.withConsumerDir(segmentCreationSpec.getConsumerDir())
+ .withTableNameWithType(_config.getTableConfig().getTableName())
.build();
//@formatter:on
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/BaseH3IndexCreator.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/BaseH3IndexCreator.java
index 91cbb62bdae..b3861073619 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/BaseH3IndexCreator.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/BaseH3IndexCreator.java
@@ -18,7 +18,6 @@
*/
package org.apache.pinot.segment.local.segment.creator.impl.inv.geospatial;
-import com.google.common.base.Preconditions;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
@@ -27,9 +26,14 @@ import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
+import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
+import javax.annotation.Nullable;
import org.apache.commons.io.FileUtils;
+import org.apache.pinot.common.metrics.ServerMeter;
+import org.apache.pinot.common.metrics.ServerMetrics;
+import org.apache.pinot.segment.local.segment.index.h3.H3IndexType;
import org.apache.pinot.segment.local.utils.GeometrySerializer;
import org.apache.pinot.segment.local.utils.H3Utils;
import org.apache.pinot.segment.spi.V1Constants;
@@ -67,6 +71,7 @@ public abstract class BaseH3IndexCreator implements
GeoSpatialIndexCreator {
static final String BITMAP_OFFSET_FILE_NAME = "bitmap.offset.buf";
static final String BITMAP_VALUE_FILE_NAME = "bitmap.value.buf";
+ final String _tableNameWithType;
final File _indexFile;
final File _tempDir;
final File _dictionaryFile;
@@ -83,8 +88,9 @@ public abstract class BaseH3IndexCreator implements
GeoSpatialIndexCreator {
int _nextDocId;
- BaseH3IndexCreator(File indexDir, String columnName, H3IndexResolution
resolution)
+ BaseH3IndexCreator(File indexDir, String columnName, String
tableNameWithType, H3IndexResolution resolution)
throws IOException {
+ _tableNameWithType = tableNameWithType;
_indexFile = new File(indexDir, columnName +
V1Constants.Indexes.H3_INDEX_FILE_EXTENSION);
_tempDir = new File(indexDir, columnName + TEMP_DIR_SUFFIX);
if (_tempDir.exists()) {
@@ -108,10 +114,15 @@ public abstract class BaseH3IndexCreator implements
GeoSpatialIndexCreator {
}
@Override
- public void add(Geometry geometry)
+ public void add(@Nullable Geometry geometry)
throws IOException {
- Preconditions.checkState(geometry instanceof Point, "H3 index can only be
applied to Point, got: %s",
- geometry.getGeometryType());
+ if (geometry == null || !(geometry instanceof Point)) {
+ String metricKeyName =
+ _tableNameWithType + "-" +
H3IndexType.INDEX_DISPLAY_NAME.toUpperCase(Locale.US) + "-indexingError";
+ ServerMetrics.get().addMeteredTableValue(metricKeyName,
ServerMeter.INDEXING_FAILURES, 1);
+ _nextDocId++;
+ return;
+ }
Coordinate coordinate = geometry.getCoordinate();
// TODO: support multiple resolutions
long h3Id = H3Utils.H3_CORE.latLngToCell(coordinate.y, coordinate.x,
_lowestResolution);
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/OffHeapH3IndexCreator.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/OffHeapH3IndexCreator.java
index 4e9334da708..35240582ca0 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/OffHeapH3IndexCreator.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/OffHeapH3IndexCreator.java
@@ -31,6 +31,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
+import javax.annotation.Nullable;
import org.apache.pinot.segment.spi.index.reader.H3IndexResolution;
import org.apache.pinot.segment.spi.memory.PinotDataBuffer;
import org.locationtech.jts.geom.Geometry;
@@ -60,15 +61,15 @@ public class OffHeapH3IndexCreator extends
BaseH3IndexCreator {
private long _postingListChunkOffset;
- public OffHeapH3IndexCreator(File indexDir, String columnName,
H3IndexResolution resolution)
+ public OffHeapH3IndexCreator(File indexDir, String columnName, String
tableNameWithType, H3IndexResolution resolution)
throws IOException {
- super(indexDir, columnName, resolution);
+ super(indexDir, columnName, tableNameWithType, resolution);
_postingListFile = new File(_tempDir, POSTING_LIST_FILE_NAME);
_postingListOutputStream = new DataOutputStream(new
BufferedOutputStream(new FileOutputStream(_postingListFile)));
}
@Override
- public void add(Geometry geometry)
+ public void add(@Nullable Geometry geometry)
throws IOException {
super.add(geometry);
if (_postingListMap.size() % FLUSH_THRESHOLD == 0) {
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/OnHeapH3IndexCreator.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/OnHeapH3IndexCreator.java
index d05d23784f0..c9583a45d75 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/OnHeapH3IndexCreator.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/inv/geospatial/OnHeapH3IndexCreator.java
@@ -34,9 +34,9 @@ import org.roaringbitmap.RoaringBitmapWriter;
*/
public class OnHeapH3IndexCreator extends BaseH3IndexCreator {
- public OnHeapH3IndexCreator(File indexDir, String columnName,
H3IndexResolution resolution)
+ public OnHeapH3IndexCreator(File indexDir, String columnName, String
tableNameWithType, H3IndexResolution resolution)
throws IOException {
- super(indexDir, columnName, resolution);
+ super(indexDir, columnName, tableNameWithType, resolution);
}
@Override
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/h3/H3IndexType.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/h3/H3IndexType.java
index 01cfa41f438..5d0996ef746 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/h3/H3IndexType.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/h3/H3IndexType.java
@@ -108,8 +108,10 @@ public class H3IndexType extends
AbstractIndexType<H3IndexConfig, H3IndexReader,
"H3 index is currently only supported on BYTES columns");
H3IndexResolution resolution =
Objects.requireNonNull(indexConfig).getResolution();
return context.isOnHeap()
- ? new OnHeapH3IndexCreator(context.getIndexDir(),
context.getFieldSpec().getName(), resolution)
- : new OffHeapH3IndexCreator(context.getIndexDir(),
context.getFieldSpec().getName(), resolution);
+ ? new OnHeapH3IndexCreator(context.getIndexDir(),
context.getFieldSpec().getName(),
+ context.getTableNameWithType(), resolution)
+ : new OffHeapH3IndexCreator(context.getIndexDir(),
context.getFieldSpec().getName(),
+ context.getTableNameWithType(), resolution);
}
@Override
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/BaseIndexHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/BaseIndexHandler.java
index 00c47586cdd..5b5f870553d 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/BaseIndexHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/BaseIndexHandler.java
@@ -115,7 +115,7 @@ public abstract class BaseIndexHandler implements
IndexHandler {
InvertedIndexAndDictionaryBasedForwardIndexCreator creator =
new InvertedIndexAndDictionaryBasedForwardIndexCreator(columnName,
_segmentDirectory, dictionaryEnabled,
- forwardIndexConfig, segmentWriter, isTemporaryForwardIndex);
+ forwardIndexConfig, segmentWriter, isTemporaryForwardIndex,
_tableConfig.getTableName());
creator.regenerateForwardIndex();
// Validate that the forward index is created.
if (!segmentWriter.hasIndexFor(columnName, StandardIndexes.forward())) {
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/ForwardIndexHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/ForwardIndexHandler.java
index ce347bdc31a..09785675297 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/ForwardIndexHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/ForwardIndexHandler.java
@@ -462,7 +462,8 @@ public class ForwardIndexHandler extends BaseIndexHandler {
throws Exception {
try (ForwardIndexReader<?> reader = ForwardIndexType.read(segmentWriter,
columnMetadata)) {
IndexCreationContext.Builder builder =
-
IndexCreationContext.builder().withIndexDir(indexDir).withColumnMetadata(columnMetadata);
+
IndexCreationContext.builder().withIndexDir(indexDir).withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName());
// Set entry length info for raw index creators. No need to set this
when changing dictionary id compression type.
if (!reader.isDictionaryEncoded() &&
!columnMetadata.getDataType().getStoredType().isFixedWidth()) {
int lengthOfLongestEntry = reader.getLengthOfLongestEntry();
@@ -887,7 +888,8 @@ public class ForwardIndexHandler extends BaseIndexHandler {
throws Exception {
try (ForwardIndexReader<?> reader = ForwardIndexType.read(segmentWriter,
existingColMetadata)) {
IndexCreationContext.Builder builder =
-
IndexCreationContext.builder().withIndexDir(indexDir).withColumnMetadata(existingColMetadata);
+
IndexCreationContext.builder().withIndexDir(indexDir).withColumnMetadata(existingColMetadata)
+ .withTableNameWithType(_tableConfig.getTableName());
// existingColMetadata has dictEnable=false. Overwrite the value.
builder.withDictionary(true);
IndexCreationContext context = builder.build();
@@ -961,7 +963,8 @@ public class ForwardIndexHandler extends BaseIndexHandler {
try (ForwardIndexReader<?> reader = ForwardIndexType.read(segmentWriter,
columnMetadata)) {
Dictionary dictionary = DictionaryIndexType.read(segmentWriter,
columnMetadata);
IndexCreationContext.Builder builder =
-
IndexCreationContext.builder().withIndexDir(indexDir).withColumnMetadata(columnMetadata);
+
IndexCreationContext.builder().withIndexDir(indexDir).withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName());
builder.withDictionary(false);
if (!columnMetadata.getDataType().getStoredType().isFixedWidth()) {
if (columnMetadata.isSingleValue()) {
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/InvertedIndexAndDictionaryBasedForwardIndexCreator.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/InvertedIndexAndDictionaryBasedForwardIndexCreator.java
index 2d71deaab62..a58b4ccce5e 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/InvertedIndexAndDictionaryBasedForwardIndexCreator.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/InvertedIndexAndDictionaryBasedForwardIndexCreator.java
@@ -82,6 +82,7 @@ public class
InvertedIndexAndDictionaryBasedForwardIndexCreator implements AutoC
private final ForwardIndexConfig _forwardIndexConfig;
private final SegmentDirectory.Writer _segmentWriter;
private final boolean _isTemporaryForwardIndex;
+ private final String _tableNameWithType;
// Metadata
private final SegmentDirectory _segmentDirectory;
@@ -114,13 +115,14 @@ public class
InvertedIndexAndDictionaryBasedForwardIndexCreator implements AutoC
public InvertedIndexAndDictionaryBasedForwardIndexCreator(String columnName,
SegmentDirectory segmentDirectory,
boolean dictionaryEnabled, ForwardIndexConfig fwdConf,
SegmentDirectory.Writer segmentWriter,
- boolean isTemporaryForwardIndex)
+ boolean isTemporaryForwardIndex, String tableNameWithType)
throws IOException {
_columnName = columnName;
_segmentDirectory = segmentDirectory;
_segmentMetadata = segmentDirectory.getSegmentMetadata();
_segmentWriter = segmentWriter;
_isTemporaryForwardIndex = isTemporaryForwardIndex;
+ _tableNameWithType = tableNameWithType;
_columnMetadata = _segmentMetadata.getColumnMetadataFor(columnName);
_singleValue = _columnMetadata.isSingleValue();
@@ -268,6 +270,7 @@ public class
InvertedIndexAndDictionaryBasedForwardIndexCreator implements AutoC
.withForwardIndexDisabled(false)
.withDictionary(_dictionaryEnabled)
.withLengthOfLongestEntry(lengthOfLongestEntry)
+ .withTableNameWithType(_tableNameWithType)
.build();
// note: this method closes buffers and removes files
@@ -354,6 +357,7 @@ public class
InvertedIndexAndDictionaryBasedForwardIndexCreator implements AutoC
.withMaxNumberOfMultiValueElements(maxNumberOfMultiValues[0])
.withMaxRowLengthInBytes(maxRowLengthInBytes[0])
.withLengthOfLongestEntry(lengthOfLongestEntry)
+ .withTableNameWithType(_tableNameWithType)
.build();
writeToForwardIndex(dictionary, context);
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/bloomfilter/BloomFilterHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/bloomfilter/BloomFilterHandler.java
index c1b29b4563d..9a6bd92fa6e 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/bloomfilter/BloomFilterHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/bloomfilter/BloomFilterHandler.java
@@ -117,6 +117,7 @@ public class BloomFilterHandler extends BaseIndexHandler {
IndexCreationContext context = IndexCreationContext.builder()
.withIndexDir(indexDir)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
try (BloomFilterCreator bloomFilterCreator =
StandardIndexes.bloomFilter().createIndexCreator(context,
bloomFilterConfig);
@@ -136,6 +137,7 @@ public class BloomFilterHandler extends BaseIndexHandler {
IndexCreationContext context = IndexCreationContext.builder()
.withIndexDir(indexDir)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
try (BloomFilterCreator bloomFilterCreator = StandardIndexes.bloomFilter()
.createIndexCreator(context, bloomFilterConfig);
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/defaultcolumn/BaseDefaultColumnHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/defaultcolumn/BaseDefaultColumnHandler.java
index 84129e7e0ce..3a575c439ac 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/defaultcolumn/BaseDefaultColumnHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/defaultcolumn/BaseDefaultColumnHandler.java
@@ -1199,6 +1199,7 @@ public abstract class BaseDefaultColumnHandler implements
DefaultColumnHandler {
.withColumnIndexCreationInfo(indexCreationInfo)
.withTotalDocs(numDocs)
.withDictionary(hasDictionary)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
ForwardIndexConfig forwardIndexConfig = null;
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/FSTIndexHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/FSTIndexHandler.java
index 1ebf84e562e..0ee9ce08677 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/FSTIndexHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/FSTIndexHandler.java
@@ -172,6 +172,7 @@ public class FSTIndexHandler extends BaseIndexHandler {
IndexCreationContext context = IndexCreationContext.builder()
.withIndexDir(indexDir)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
FstIndexConfig config =
_fieldIndexConfigs.get(columnName).getConfig(StandardIndexes.fst());
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/H3IndexHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/H3IndexHandler.java
index 78ddd6b110a..b244184a293 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/H3IndexHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/H3IndexHandler.java
@@ -162,6 +162,7 @@ public class H3IndexHandler extends BaseIndexHandler {
IndexCreationContext context = IndexCreationContext.builder()
.withIndexDir(indexDir)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
H3IndexConfig config = colIndexConf.getConfig(StandardIndexes.h3());
@@ -187,6 +188,7 @@ public class H3IndexHandler extends BaseIndexHandler {
IndexCreationContext context = IndexCreationContext.builder()
.withIndexDir(indexDir)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
H3IndexConfig config =
_fieldIndexConfigs.get(columnName).getConfig(StandardIndexes.h3());
try (ForwardIndexReader forwardIndexReader =
ForwardIndexType.read(segmentWriter, columnMetadata);
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/InvertedIndexHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/InvertedIndexHandler.java
index 56b4752415d..0feeab3ea13 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/InvertedIndexHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/InvertedIndexHandler.java
@@ -139,6 +139,7 @@ public class InvertedIndexHandler extends BaseIndexHandler {
IndexCreationContext.Common context = IndexCreationContext.builder()
.withIndexDir(indexDir)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
try (DictionaryBasedInvertedIndexCreator creator =
StandardIndexes.inverted()
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/JsonIndexHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/JsonIndexHandler.java
index 7b2e1fb0709..5954486111c 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/JsonIndexHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/JsonIndexHandler.java
@@ -160,6 +160,7 @@ public class JsonIndexHandler extends BaseIndexHandler {
IndexCreationContext context = IndexCreationContext.builder()
.withIndexDir(indexDir)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
JsonIndexConfig config = _jsonIndexConfigs.get(columnName);
try (ForwardIndexReader forwardIndexReader =
ForwardIndexType.read(segmentWriter, columnMetadata);
@@ -182,6 +183,7 @@ public class JsonIndexHandler extends BaseIndexHandler {
IndexCreationContext context = IndexCreationContext.builder()
.withIndexDir(indexDir)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
JsonIndexConfig config = _jsonIndexConfigs.get(columnName);
try (ForwardIndexReader forwardIndexReader =
ForwardIndexType.read(segmentWriter, columnMetadata);
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/RangeIndexHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/RangeIndexHandler.java
index c1e33427643..532b739ed9e 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/RangeIndexHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/RangeIndexHandler.java
@@ -260,6 +260,7 @@ public class RangeIndexHandler extends BaseIndexHandler {
IndexCreationContext context = IndexCreationContext.builder()
.withIndexDir(indexDir)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
RangeIndexConfig config =
_fieldIndexConfigs.get(columnMetadata.getColumnName())
.getConfig(StandardIndexes.range());
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/TextIndexHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/TextIndexHandler.java
index d3f7f311d61..9655252dc9d 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/TextIndexHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/TextIndexHandler.java
@@ -174,6 +174,7 @@ public class TextIndexHandler extends BaseIndexHandler {
.withColumnMetadata(columnMetadata)
.withIndexDir(segmentDirectory)
.withTextCommitOnClose(true)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
TextIndexConfig config =
_fieldIndexConfigs.get(columnName).getConfig(StandardIndexes.text());
diff --git
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/VectorIndexHandler.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/VectorIndexHandler.java
index 72d74763ca1..f09469e0c4a 100644
---
a/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/VectorIndexHandler.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/loader/invertedindex/VectorIndexHandler.java
@@ -167,6 +167,7 @@ public class VectorIndexHandler extends BaseIndexHandler {
IndexCreationContext context = IndexCreationContext.builder()
.withIndexDir(segmentDirectory)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
VectorIndexConfig config =
colIndexConf.getConfig(StandardIndexes.vector());
@@ -200,6 +201,7 @@ public class VectorIndexHandler extends BaseIndexHandler {
IndexCreationContext context = IndexCreationContext.builder()
.withIndexDir(segmentDirectory)
.withColumnMetadata(columnMetadata)
+ .withTableNameWithType(_tableConfig.getTableName())
.build();
VectorIndexConfig config =
_fieldIndexConfigs.get(columnName).getConfig(StandardIndexes.vector());
try (ForwardIndexReader forwardIndexReader =
ForwardIndexType.read(segmentWriter, columnMetadata);
diff --git
a/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/segment/index/H3IndexTest.java
b/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/segment/index/H3IndexTest.java
index d7e027d4267..7493d43db6f 100644
---
a/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/segment/index/H3IndexTest.java
+++
b/pinot-segment-local/src/test/java/org/apache/pinot/segment/local/segment/index/H3IndexTest.java
@@ -47,6 +47,7 @@ import
org.apache.pinot.segment.spi.index.reader.H3IndexResolution;
import org.apache.pinot.segment.spi.memory.PinotDataBuffer;
import org.apache.pinot.spi.config.table.FieldConfig;
import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.Point;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
@@ -91,9 +92,9 @@ public class H3IndexTest implements
PinotBuffersAfterMethodCheckRule {
try (MutableH3Index mutableH3Index = new
MutableH3Index(h3IndexResolution)) {
try (GeoSpatialIndexCreator onHeapCreator = new
OnHeapH3IndexCreator(TEMP_DIR, onHeapColumnName,
- h3IndexResolution);
+ "myTable_OFFLINE", h3IndexResolution);
GeoSpatialIndexCreator offHeapCreator = new
OffHeapH3IndexCreator(TEMP_DIR, offHeapColumnName,
- h3IndexResolution)) {
+ "myTable_OFFLINE", h3IndexResolution)) {
int docId = 0;
while (expectedCardinalities.size() < numUniqueH3Ids) {
double longitude = RANDOM.nextDouble() * 360 - 180;
@@ -126,6 +127,87 @@ public class H3IndexTest implements
PinotBuffersAfterMethodCheckRule {
}
}
+ @Test
+ public void testSkipInvalidGeometry()
+ throws Exception {
+ String columnName = "skipInvalid";
+ int res = 5;
+ H3IndexResolution resolution = new
H3IndexResolution(Collections.singletonList(res));
+
+ try (GeoSpatialIndexCreator creator = new OnHeapH3IndexCreator(TEMP_DIR,
columnName, "myTable_OFFLINE",
+ resolution)) {
+ Point point = GeometryUtils.GEOMETRY_FACTORY.createPoint(new
Coordinate(10, 20));
+ creator.add(point);
+
+ // Invalid serialized bytes should be skipped without throwing exception
+ creator.add(new byte[]{1, 2, 3}, -1);
+
+ creator.seal();
+ }
+
+ File indexFile = new File(TEMP_DIR, columnName +
V1Constants.Indexes.H3_INDEX_FILE_EXTENSION);
+ try (PinotDataBuffer buffer =
PinotDataBuffer.mapReadOnlyBigEndianFile(indexFile);
+ H3IndexReader reader = new ImmutableH3IndexReader(buffer)) {
+ long h3Id = H3Utils.H3_CORE.latLngToCell(20, 10, res);
+ Assert.assertEquals(reader.getDocIds(h3Id).getCardinality(), 1);
+ }
+ }
+
+ @Test
+ public void testSkipNullGeometry()
+ throws Exception {
+ String columnName = "skipNull";
+ int res = 5;
+ H3IndexResolution resolution = new
H3IndexResolution(Collections.singletonList(res));
+
+ try (GeoSpatialIndexCreator creator = new OnHeapH3IndexCreator(TEMP_DIR,
columnName, "myTable_OFFLINE",
+ resolution)) {
+ Point point = GeometryUtils.GEOMETRY_FACTORY.createPoint(new
Coordinate(10, 20));
+ creator.add(point);
+
+ // Explicit null geometry should also be skipped
+ creator.add(null);
+
+ creator.seal();
+ }
+
+ File indexFile = new File(TEMP_DIR, columnName +
V1Constants.Indexes.H3_INDEX_FILE_EXTENSION);
+ try (PinotDataBuffer buffer =
PinotDataBuffer.mapReadOnlyBigEndianFile(indexFile);
+ H3IndexReader reader = new ImmutableH3IndexReader(buffer)) {
+ long h3Id = H3Utils.H3_CORE.latLngToCell(20, 10, res);
+ Assert.assertEquals(reader.getDocIds(h3Id).getCardinality(), 1);
+ }
+ }
+
+ @Test
+ public void testSkipNonPointGeometry()
+ throws Exception {
+ String columnName = "skipInvalidGeometryType";
+ int res = 5;
+ H3IndexResolution resolution = new
H3IndexResolution(Collections.singletonList(res));
+
+ try (GeoSpatialIndexCreator creator = new OnHeapH3IndexCreator(TEMP_DIR,
columnName, "myTable_OFFLINE",
+ resolution)) {
+ Point point = GeometryUtils.GEOMETRY_FACTORY.createPoint(new
Coordinate(10, 42));
+ creator.add(point);
+
+ // Explicit non-point geometry should also be skipped
+ Point[] points = new Point[1];
+ points[0] = point;
+ MultiPoint multiPoint =
GeometryUtils.GEOMETRY_FACTORY.createMultiPoint(points);
+ creator.add(multiPoint);
+
+ creator.seal();
+ }
+
+ File indexFile = new File(TEMP_DIR, columnName +
V1Constants.Indexes.H3_INDEX_FILE_EXTENSION);
+ try (PinotDataBuffer buffer =
PinotDataBuffer.mapReadOnlyBigEndianFile(indexFile);
+ H3IndexReader reader = new ImmutableH3IndexReader(buffer)) {
+ long h3Id = H3Utils.H3_CORE.latLngToCell(42, 10, res);
+ Assert.assertEquals(reader.getDocIds(h3Id).getCardinality(), 1);
+ }
+ }
+
public static class ConfTest extends AbstractSerdeIndexContract {
protected void assertEquals(H3IndexConfig expected) {
diff --git
a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/creator/IndexCreationContext.java
b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/creator/IndexCreationContext.java
index 5d3a1a78ba7..a9c300721bf 100644
---
a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/creator/IndexCreationContext.java
+++
b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/creator/IndexCreationContext.java
@@ -111,6 +111,8 @@ public interface IndexCreationContext {
*/
int[] getImmutableToMutableIdMap();
+ String getTableNameWithType();
+
final class Builder {
private ColumnStatistics _columnStatistics;
private File _indexDir;
@@ -134,6 +136,7 @@ public interface IndexCreationContext {
private boolean _realtimeConversion = false;
private File _consumerDir;
private int[] _immutableToMutableIdMap;
+ private String _tableNameWithType;
public Builder withColumnIndexCreationInfo(ColumnIndexCreationInfo
columnIndexCreationInfo) {
return
withLengthOfLongestEntry(columnIndexCreationInfo.getLengthOfLongestEntry())
@@ -266,12 +269,17 @@ public interface IndexCreationContext {
return this;
}
+ public Builder withTableNameWithType(String tableNameWithType) {
+ _tableNameWithType = tableNameWithType;
+ return this;
+ }
+
public Common build() {
return new Common(Objects.requireNonNull(_indexDir),
_lengthOfLongestEntry, _maxNumberOfMultiValueElements,
_maxRowLengthInBytes, _onHeap, Objects.requireNonNull(_fieldSpec),
_sorted, _cardinality,
_totalNumberOfEntries, _totalDocs, _hasDictionary, _minValue,
_maxValue, _forwardIndexDisabled,
_sortedUniqueElementsArray, _optimizedDictionary, _fixedLength,
_textCommitOnClose, _columnStatistics,
- _realtimeConversion, _consumerDir, _immutableToMutableIdMap);
+ _realtimeConversion, _consumerDir, _immutableToMutableIdMap,
_tableNameWithType);
}
public Builder withSortedUniqueElementsArray(Object
sortedUniqueElementsArray) {
@@ -308,14 +316,15 @@ public interface IndexCreationContext {
private final boolean _realtimeConversion;
private final File _consumerDir;
private final int[] _immutableToMutableIdMap;
+ private final String _tableNameWithType;
- public Common(File indexDir, int lengthOfLongestEntry,
+ private Common(File indexDir, int lengthOfLongestEntry,
int maxNumberOfMultiValueElements, int maxRowLengthInBytes, boolean
onHeap,
FieldSpec fieldSpec, boolean sorted, int cardinality, int
totalNumberOfEntries,
int totalDocs, boolean hasDictionary, Comparable<?> minValue,
Comparable<?> maxValue,
boolean forwardIndexDisabled, Object sortedUniqueElementsArray,
boolean optimizeDictionary, boolean fixedLength,
boolean textCommitOnClose, ColumnStatistics columnStatistics, boolean
realtimeConversion, File consumerDir,
- int[] immutableToMutableIdMap) {
+ int[] immutableToMutableIdMap, String tableNameWithType) {
_indexDir = indexDir;
_lengthOfLongestEntry = lengthOfLongestEntry;
_maxNumberOfMultiValueElements = maxNumberOfMultiValueElements;
@@ -338,6 +347,7 @@ public interface IndexCreationContext {
_realtimeConversion = realtimeConversion;
_consumerDir = consumerDir;
_immutableToMutableIdMap = immutableToMutableIdMap;
+ _tableNameWithType = tableNameWithType;
}
public FieldSpec getFieldSpec() {
@@ -438,5 +448,10 @@ public interface IndexCreationContext {
public int[] getImmutableToMutableIdMap() {
return _immutableToMutableIdMap;
}
+
+ @Override
+ public String getTableNameWithType() {
+ return _tableNameWithType;
+ }
}
}
diff --git
a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/creator/GeoSpatialIndexCreator.java
b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/creator/GeoSpatialIndexCreator.java
index efec2027669..f7cf80f429d 100644
---
a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/creator/GeoSpatialIndexCreator.java
+++
b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/creator/GeoSpatialIndexCreator.java
@@ -34,7 +34,14 @@ public interface GeoSpatialIndexCreator extends IndexCreator
{
@Override
default void add(Object value, int dictId)
throws IOException {
- add(deserialize((byte[]) value));
+ Geometry geometry;
+ try {
+ geometry = deserialize((byte[]) value);
+ } catch (Exception e) {
+ // Swallow the exception and treat the geometry as null
+ geometry = null;
+ }
+ add(geometry);
}
@Override
@@ -45,7 +52,7 @@ public interface GeoSpatialIndexCreator extends IndexCreator {
/**
* Adds the next geospatial value.
*/
- void add(Geometry geometry)
+ void add(@Nullable Geometry geometry)
throws IOException;
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]