This is an automated email from the ASF dual-hosted git repository.

jackie 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 5416df1088 Bugfix: prevent certain `not (x and y)` filters from 
causing a NPE (#13527)
5416df1088 is described below

commit 5416df10883dcd8fc571e7d6007ab37824617ae1
Author: Christopher Peck <27231838+itschrisp...@users.noreply.github.com>
AuthorDate: Mon Jul 8 18:16:46 2024 -0700

    Bugfix: prevent certain `not (x and y)` filters from causing a NPE (#13527)
---
 .../operator/dociditerators/NotDocIdIterator.java  |   3 +
 .../pinot/queries/TransformFilterQueriesTest.java  | 165 +++++++++++++++++++++
 2 files changed, 168 insertions(+)

diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/dociditerators/NotDocIdIterator.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/dociditerators/NotDocIdIterator.java
index 5ce0de3a67..f5fbe52bdc 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/dociditerators/NotDocIdIterator.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/dociditerators/NotDocIdIterator.java
@@ -43,6 +43,9 @@ public class NotDocIdIterator implements BlockDocIdIterator {
 
   @Override
   public int next() {
+    if (_nextDocId >= _numDocs) {
+      return Constants.EOF;
+    }
     while (_nextDocId == _nextNonMatchingDocId) {
       _nextDocId++;
       int nextNonMatchingDocId = _childDocIdIterator.next();
diff --git 
a/pinot-core/src/test/java/org/apache/pinot/queries/TransformFilterQueriesTest.java
 
b/pinot-core/src/test/java/org/apache/pinot/queries/TransformFilterQueriesTest.java
new file mode 100644
index 0000000000..7116368bdd
--- /dev/null
+++ 
b/pinot-core/src/test/java/org/apache/pinot/queries/TransformFilterQueriesTest.java
@@ -0,0 +1,165 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.queries;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.commons.io.FileUtils;
+import org.apache.pinot.core.common.Operator;
+import org.apache.pinot.core.operator.blocks.results.SelectionResultsBlock;
+import 
org.apache.pinot.segment.local.indexsegment.immutable.ImmutableSegmentLoader;
+import 
org.apache.pinot.segment.local.segment.creator.impl.SegmentIndexCreationDriverImpl;
+import org.apache.pinot.segment.local.segment.readers.GenericRowRecordReader;
+import org.apache.pinot.segment.spi.ImmutableSegment;
+import org.apache.pinot.segment.spi.IndexSegment;
+import org.apache.pinot.segment.spi.creator.SegmentGeneratorConfig;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.config.table.TableType;
+import org.apache.pinot.spi.data.FieldSpec;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.data.readers.GenericRow;
+import org.apache.pinot.spi.data.readers.RecordReader;
+import org.apache.pinot.spi.utils.ReadMode;
+import org.apache.pinot.spi.utils.builder.TableConfigBuilder;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+
+public class TransformFilterQueriesTest extends BaseQueriesTest {
+  private static final File INDEX_DIR = new File(FileUtils.getTempDirectory(), 
"TransformFilterQueriesTest");
+  private static final String TABLE_NAME = "testTable";
+  private static final String SEGMENT_NAME = "testSegment";
+  private static final String INT_COLUMN = "intColumn";
+  private static final String STRING_COLUMN = "stringColumn";
+
+  private static final int NUM_ROWS = 4;
+
+  private IndexSegment _indexSegment;
+  private List<IndexSegment> _indexSegments;
+
+  @Override
+  protected String getFilter() {
+    return "";
+  }
+
+  @Override
+  protected IndexSegment getIndexSegment() {
+    return _indexSegment;
+  }
+
+  @Override
+  protected List<IndexSegment> getIndexSegments() {
+    return _indexSegments;
+  }
+
+  GenericRow createRecord(int intValue, String stringValue) {
+    GenericRow record = new GenericRow();
+    record.putValue(INT_COLUMN, intValue);
+    record.putValue(STRING_COLUMN, stringValue);
+
+    return record;
+  }
+
+  @BeforeClass
+  public void setUp()
+      throws Exception {
+    FileUtils.deleteDirectory(INDEX_DIR);
+
+    List<GenericRow> rows = new ArrayList<>(NUM_ROWS);
+    rows.add(createRecord(1, "apple"));
+    rows.add(createRecord(2, "banana"));
+    rows.add(createRecord(3, "carrot"));
+    rows.add(createRecord(4, "fruit"));
+
+    Schema schema = new 
Schema.SchemaBuilder().addSingleValueDimension(INT_COLUMN, 
FieldSpec.DataType.INT)
+        .addSingleValueDimension(STRING_COLUMN, 
FieldSpec.DataType.STRING).build();
+    TableConfig tableConfig = new 
TableConfigBuilder(TableType.OFFLINE).setTableName(TABLE_NAME)
+        .setNoDictionaryColumns(List.of(STRING_COLUMN, INT_COLUMN)).build();
+    SegmentGeneratorConfig config = new SegmentGeneratorConfig(tableConfig, 
schema);
+    config.setOutDir(INDEX_DIR.getPath());
+    config.setTableName(TABLE_NAME);
+    config.setSegmentName(SEGMENT_NAME);
+
+    SegmentIndexCreationDriverImpl driver = new 
SegmentIndexCreationDriverImpl();
+    try (RecordReader recordReader = new GenericRowRecordReader(rows)) {
+      driver.init(config, recordReader);
+      driver.build();
+    }
+
+    ImmutableSegment immutableSegment = ImmutableSegmentLoader.load(new 
File(INDEX_DIR, SEGMENT_NAME), ReadMode.mmap);
+    _indexSegment = immutableSegment;
+    _indexSegments = Arrays.asList(immutableSegment, immutableSegment);
+  }
+
+  @AfterClass
+  public void tearDown() {
+    _indexSegment.destroy();
+    FileUtils.deleteQuietly(INDEX_DIR);
+  }
+
+  @Test
+  public void testTransformDocIdsLessThanFiltered() {
+    Operator<SelectionResultsBlock> operator = getOperator(
+        "SELECT * FROM testTable WHERE NOT (intColumn = 3 AND 
lower(stringColumn) = 'banana')");
+    SelectionResultsBlock block = operator.nextBlock();
+    List<Object[]> rows = block.getRows();
+
+    assertNotNull(rows);
+    assertEquals(rows.size(), 4);
+    assertEquals(rows.get(0)[0], 1);
+    assertEquals(rows.get(1)[0], 2);
+    assertEquals(rows.get(2)[0], 3);
+    assertEquals(rows.get(3)[0], 4);
+  }
+
+  @Test
+  public void testTransformDocIdsGreaterThanFiltered() {
+    Operator<SelectionResultsBlock> operator = getOperator(
+        "SELECT * FROM testTable WHERE NOT (intColumn = 1 AND 
lower(stringColumn) = 'banana')");
+    SelectionResultsBlock block = operator.nextBlock();
+    List<Object[]> rows = block.getRows();
+
+    assertNotNull(rows);
+    assertEquals(rows.size(), 4);
+    assertEquals(rows.get(0)[0], 1);
+    assertEquals(rows.get(1)[0], 2);
+    assertEquals(rows.get(2)[0], 3);
+    assertEquals(rows.get(3)[0], 4);
+  }
+
+  @Test
+  public void testTransformDocIdsEqualToFiltered() {
+    Operator<SelectionResultsBlock> operator = getOperator(
+        "SELECT * FROM testTable WHERE NOT (intColumn = 2 AND 
lower(stringColumn) = 'banana')");
+    SelectionResultsBlock block = operator.nextBlock();
+    List<Object[]> rows = block.getRows();
+
+    assertNotNull(rows);
+    assertEquals(rows.size(), 3);
+    assertEquals(rows.get(0)[0], 1);
+    assertEquals(rows.get(1)[0], 3);
+    assertEquals(rows.get(2)[0], 4);
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org
For additional commands, e-mail: commits-h...@pinot.apache.org

Reply via email to