This is an automated email from the ASF dual-hosted git repository. mhubail pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/asterixdb.git
commit b88d3fc569ebb507ab5584b22b8e622619ad463d Author: Ritik Raj <[email protected]> AuthorDate: Wed Mar 26 19:42:59 2025 +0530 [ASTERIXDB-3586][STO] Sync tupleIndex while skipping tuples - user model changes: no - storage format changes: no - interface changes: yes Details: When `compiler.column.filter` is enabled, the assembler’s `valueIndex` (denoted as `tupleIndex` currently) may become out of sync with the filter’s `tupleIndex`. This misalignment between the filter and assembler can lead to incorrect query results. This change ensures proper synchronization of `tupleIndex` while skipping tuples to maintain correctness. Ext-ref: MB-66000 Change-Id: I260612851c4dabfb9e74f2902f421720d9f88657 Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19555 Integration-Tests: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Reviewed-by: Peeyush Gupta <[email protected]> --- .../assembler/AbstractPrimitiveValueAssembler.java | 4 ++ .../column/filter/FalseColumnFilterEvaluator.java | 8 ++- .../column/filter/TrueColumnFilterEvaluator.java | 8 ++- .../iterable/IColumnIterableFilterEvaluator.java | 5 +- .../evaluator/AbstractIterableFilterEvaluator.java | 28 ++++++++-- .../evaluator/ColumnIterableFilterEvaluator.java | 9 ++-- .../ColumnarRepeatedIterableFilterEvaluator.java | 5 -- .../column/operation/query/ColumnAssembler.java | 14 +++++ .../column/tuple/MergeColumnTupleReference.java | 11 +++- .../column/tuple/QueryColumnTupleReference.java | 56 +++++++++++++------ .../tuple/QueryColumnWithMetaTupleReference.java | 63 +++++++++++++++------- .../values/reader/AbstractColumnValuesReader.java | 11 ++-- .../values/reader/PrimitiveColumnValuesReader.java | 2 +- .../lsm/btree/column/api/IColumnTupleIterator.java | 23 ++++---- .../btree/column/error/ColumnarValueException.java | 4 ++ .../impls/lsm/LSMColumnBTreeRangeSearchCursor.java | 4 +- .../lsm/tuples/AbstractColumnTupleReference.java | 19 ++----- 17 files changed, 188 insertions(+), 86 deletions(-) diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AbstractPrimitiveValueAssembler.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AbstractPrimitiveValueAssembler.java index 3c5d726aee..eb2ddf866e 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AbstractPrimitiveValueAssembler.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AbstractPrimitiveValueAssembler.java @@ -81,6 +81,10 @@ public abstract class AbstractPrimitiveValueAssembler extends AbstractValueAssem reader.skip(count); } + public IColumnValuesReader getReader() { + return reader; + } + /** * Reset the assembler * diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/FalseColumnFilterEvaluator.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/FalseColumnFilterEvaluator.java index 51f125bd3f..5ea7fc3c70 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/FalseColumnFilterEvaluator.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/FalseColumnFilterEvaluator.java @@ -19,6 +19,7 @@ package org.apache.asterix.column.filter; import org.apache.asterix.column.filter.iterable.IColumnIterableFilterEvaluator; +import org.apache.hyracks.storage.am.lsm.btree.column.error.ColumnarValueException; public class FalseColumnFilterEvaluator implements IColumnIterableFilterEvaluator { public static final IColumnIterableFilterEvaluator INSTANCE = new FalseColumnFilterEvaluator(); @@ -27,7 +28,7 @@ public class FalseColumnFilterEvaluator implements IColumnIterableFilterEvaluato } @Override - public void reset() { + public void reset(int tupleCount) { } @@ -50,4 +51,9 @@ public class FalseColumnFilterEvaluator implements IColumnIterableFilterEvaluato public void setAt(int index) { // NoOp } + + @Override + public void appendInformation(ColumnarValueException e) { + // NoOp + } } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/TrueColumnFilterEvaluator.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/TrueColumnFilterEvaluator.java index 0841e015e6..125d79cb01 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/TrueColumnFilterEvaluator.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/TrueColumnFilterEvaluator.java @@ -20,6 +20,7 @@ package org.apache.asterix.column.filter; import org.apache.asterix.column.filter.iterable.IColumnIterableFilterEvaluator; import org.apache.hyracks.api.exceptions.HyracksDataException; +import org.apache.hyracks.storage.am.lsm.btree.column.error.ColumnarValueException; /** * This evaluator is also used to indicate a NoOp filter @@ -36,7 +37,7 @@ public class TrueColumnFilterEvaluator implements IColumnIterableFilterEvaluator } @Override - public void reset() { + public void reset(int tupleCount) { // NoOp } @@ -54,4 +55,9 @@ public class TrueColumnFilterEvaluator implements IColumnIterableFilterEvaluator public void setAt(int index) { // NoOp } + + @Override + public void appendInformation(ColumnarValueException e) { + // NoOp + } } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/IColumnIterableFilterEvaluator.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/IColumnIterableFilterEvaluator.java index 1d2838e397..582f9ca9f6 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/IColumnIterableFilterEvaluator.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/IColumnIterableFilterEvaluator.java @@ -20,13 +20,16 @@ package org.apache.asterix.column.filter.iterable; import org.apache.asterix.column.filter.IColumnFilterEvaluator; import org.apache.hyracks.api.exceptions.HyracksDataException; +import org.apache.hyracks.storage.am.lsm.btree.column.error.ColumnarValueException; public interface IColumnIterableFilterEvaluator extends IColumnFilterEvaluator { - void reset(); + void reset(int tupleCount); int getTupleIndex(); int getValueIndex(); void setAt(int index) throws HyracksDataException; + + void appendInformation(ColumnarValueException e); } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/AbstractIterableFilterEvaluator.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/AbstractIterableFilterEvaluator.java index 8f0ad892cc..30c051fd84 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/AbstractIterableFilterEvaluator.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/AbstractIterableFilterEvaluator.java @@ -26,6 +26,10 @@ import org.apache.asterix.formats.nontagged.BinaryBooleanInspector; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; import org.apache.hyracks.api.exceptions.HyracksDataException; import org.apache.hyracks.data.std.primitive.VoidPointable; +import org.apache.hyracks.storage.am.lsm.btree.column.error.ColumnarValueException; + +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; abstract class AbstractIterableFilterEvaluator implements IColumnIterableFilterEvaluator { protected final IScalarEvaluator evaluator; @@ -34,19 +38,21 @@ abstract class AbstractIterableFilterEvaluator implements IColumnIterableFilterE private final VoidPointable booleanResult; protected int tupleIndex; protected int valueIndex; + private int tupleCount; AbstractIterableFilterEvaluator(IScalarEvaluator evaluator, List<IColumnValuesReader> readers) { this.evaluator = evaluator; this.primaryKeyReader = readers.get(0); this.readers = readers; this.booleanResult = new VoidPointable(); - reset(); + reset(-1); } @Override - public final void reset() { + public final void reset(int tupleCount) { tupleIndex = -1; valueIndex = -1; + this.tupleCount = tupleCount; } @Override @@ -68,6 +74,9 @@ abstract class AbstractIterableFilterEvaluator implements IColumnIterableFilterE // 0(skip) --> 1(skip) --> 2nd tuple // so the gap between index and tupleIndex is count. // and after increasing by (count - 1), evaluate() for the Xth tuple. + if (index > tupleCount) { + index = tupleCount; + } int count = index - this.tupleIndex; if (count > 0) { tupleIndex += count - 1; @@ -101,7 +110,7 @@ abstract class AbstractIterableFilterEvaluator implements IColumnIterableFilterE int nonAntiMatterCount = 0; for (int i = 0; i < count; i++) { primaryKeyReader.next(); - nonAntiMatterCount += primaryKeyReader.isValue() ? 0 : 1; + nonAntiMatterCount += primaryKeyReader.isValue() ? 1 : 0; } for (int i = 1; nonAntiMatterCount > 0 && i < readers.size(); i++) { readers.get(i).skip(nonAntiMatterCount); @@ -114,4 +123,17 @@ abstract class AbstractIterableFilterEvaluator implements IColumnIterableFilterE return BinaryBooleanInspector.getBooleanValue(booleanResult.getByteArray(), booleanResult.getStartOffset(), booleanResult.getLength()); } + + @Override + public void appendInformation(ColumnarValueException e) { + ObjectNode filterIteratorNode = e.createNode(getClass().getSimpleName()); + filterIteratorNode.put("filterTupleIndex", tupleIndex); + filterIteratorNode.put("filterValueIndex", valueIndex); + ArrayNode pkNodes = filterIteratorNode.putArray("filterPrimaryKeyReaders"); + primaryKeyReader.appendReaderInformation(pkNodes.addObject()); + ArrayNode valueNodes = filterIteratorNode.putArray("filterValueReaders"); + for (int i = 1; i < readers.size(); i++) { + readers.get(i).appendReaderInformation(valueNodes.addObject()); + } + } } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnIterableFilterEvaluator.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnIterableFilterEvaluator.java index 094b2bfd42..ad0e8a9a38 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnIterableFilterEvaluator.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnIterableFilterEvaluator.java @@ -33,14 +33,13 @@ public class ColumnIterableFilterEvaluator extends AbstractIterableFilterEvaluat @Override public boolean evaluate() throws HyracksDataException { boolean result = false; + // If next() returns false, it means there are no more matching tuples left. + // Inside the next() function, tupleIndex and valueIndex are incremented. + // This causes tupleIndex to eventually reach tupleCount, + // indicating that all tuples have been processed. while (!result && next()) { result = inspect(); } - if (!result) { - // Last tuple does not satisfy the condition - tupleIndex++; - valueIndex++; - } return result; } } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnarRepeatedIterableFilterEvaluator.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnarRepeatedIterableFilterEvaluator.java index 9a1f07f2cb..05e1daebe3 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnarRepeatedIterableFilterEvaluator.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnarRepeatedIterableFilterEvaluator.java @@ -46,11 +46,6 @@ public class ColumnarRepeatedIterableFilterEvaluator extends AbstractIterableFil // TODO we need a way to 'rewind' y for each x result = evaluateRepeated(); } - if (!result) { - // Last tuple does not satisfy the condition - tupleIndex++; - valueIndex++; - } return result; } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java index 82a9b635f2..e6ff021168 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java @@ -31,6 +31,7 @@ import org.apache.hyracks.api.exceptions.HyracksDataException; import org.apache.hyracks.data.std.api.IValueReference; import org.apache.hyracks.storage.am.lsm.btree.column.error.ColumnarValueException; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; public final class ColumnAssembler { @@ -132,6 +133,15 @@ public final class ColumnAssembler { } public void setAt(int index) throws HyracksDataException { + int skipCount = index - tupleIndex; + if (skipCount < 0) { + // should never happen as tupleIndex progress forward. + ColumnarValueException e = new ColumnarValueException(); + e.getNode().put("message", + "skipCount is negative, currentTupleIndex: " + tupleIndex + ", finalTupleIndex: " + index); + appendInformation(e); + throw e; + } skip(index - tupleIndex); } @@ -140,6 +150,10 @@ public final class ColumnAssembler { assemblerNode.put("tupleIndex", tupleIndex); assemblerNode.put("numberOfTuples", numberOfTuples); assemblerNode.put("numberOfSkips", numberOfSkips); + ArrayNode assemblerReaders = assemblerNode.putArray("assemblerReaders"); + for (int i = 0; i < assemblers.length; i++) { + assemblers[i].getReader().appendReaderInformation(assemblerReaders.addObject()); + } state.appendStateInfo(e); } } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/MergeColumnTupleReference.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/MergeColumnTupleReference.java index 8c434d7cb8..6e13113c1e 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/MergeColumnTupleReference.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/MergeColumnTupleReference.java @@ -101,7 +101,16 @@ public final class MergeColumnTupleReference extends AbstractAsterixColumnTupleR } @Override - public void skip(int count) throws HyracksDataException { + public void initSkip(int tupleIndex, int count) throws HyracksDataException { + skip(count); + } + + @Override + public void skipCurrentTuple() throws HyracksDataException { + skip(1); + } + + private void skip(int count) throws HyracksDataException { skipCount += count; } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java index 64ac0a278f..8113288e55 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java @@ -104,7 +104,7 @@ public final class QueryColumnTupleReference extends AbstractAsterixColumnTupleR //Check if we should read all column pages boolean readColumns = rangeFilterEvaluator.evaluate(); assembler.reset(readColumns ? numberOfTuples : 0); - columnFilterEvaluator.reset(); + columnFilterEvaluator.reset(numberOfTuples); previousIndex = -1; return readColumns; } @@ -131,8 +131,29 @@ public final class QueryColumnTupleReference extends AbstractAsterixColumnTupleR } @Override - public void skip(int count) throws HyracksDataException { - columnFilterEvaluator.setAt(assembler.skip(count)); + public void initSkip(int tupleIndex, int count) throws HyracksDataException { + columnFilterEvaluator.setAt(tupleIndex); + skip(count); + } + + @Override + public void skipCurrentTuple() throws HyracksDataException { + if (isFilterApplied()) { + // since cursorIndex is markedAsDeleted + // move filter evaluator to the next valid tuple + columnFilterEvaluator.setAt(tupleIndex + 1); + assembler.setAt(columnFilterEvaluator.getValueIndex()); + } else { + skip(1); + } + } + + private boolean isFilterApplied() { + return columnFilterEvaluator.getTupleIndex() != -1; + } + + private void skip(int count) throws HyracksDataException { + assembler.skip(count); } public IValueReference getAssembledValue() throws HyracksDataException { @@ -158,19 +179,22 @@ public final class QueryColumnTupleReference extends AbstractAsterixColumnTupleR } private IValueReference getFilteredAssembledValue() throws HyracksDataException { - int index = columnFilterEvaluator.getTupleIndex(); - // index == -1 if the normalized filter indicated that a mega leaf node - // is filtered - if (index == tupleIndex) { - antimatterGap = 0; - // setAt in the assembler expect the value index (i.e., tupleCount - antiMatterCount) - assembler.setAt(columnFilterEvaluator.getValueIndex()); - // set the next tuple index that satisfies the filter - columnFilterEvaluator.evaluate(); - return assembler.nextValue(); - } else { - antimatterGap++; + try { + int index = columnFilterEvaluator.getTupleIndex(); + // index == -1 if the normalized filter indicated that a mega leaf node + // is filtered + if (index == tupleIndex) { + // setAt in the assembler expect the value index (i.e., tupleCount - antiMatterCount) + assembler.setAt(columnFilterEvaluator.getValueIndex()); + // set the next tuple index that satisfies the filter + columnFilterEvaluator.evaluate(); + return assembler.nextValue(); + } + return MissingValueGetter.MISSING; + } catch (ColumnarValueException e) { + columnFilterEvaluator.appendInformation(e); + e.getNode().put("cursorTupleIndex", tupleIndex); + throw e; } - return MissingValueGetter.MISSING; } } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java index 4202f47a9a..2b8da6d74e 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java @@ -109,7 +109,7 @@ public final class QueryColumnWithMetaTupleReference extends AbstractAsterixColu boolean readColumns = rangeFilterEvaluator.evaluate(); assembler.reset(readColumns ? numberOfTuples : 0); metaAssembler.reset(readColumns ? numberOfTuples : 0); - columnFilterEvaluator.reset(); + columnFilterEvaluator.reset(numberOfTuples); previousIndex = -1; return readColumns; } @@ -141,9 +141,31 @@ public final class QueryColumnWithMetaTupleReference extends AbstractAsterixColu } @Override - public void skip(int count) throws HyracksDataException { + public void initSkip(int tupleIndex, int count) throws HyracksDataException { + columnFilterEvaluator.setAt(tupleIndex); + skip(count); + } + + @Override + public void skipCurrentTuple() throws HyracksDataException { + if (isFilterApplied()) { + // since cursorIndex is markedAsDeleted + // move filter evaluator to the next valid tuple + columnFilterEvaluator.setAt(tupleIndex + 1); + assembler.setAt(columnFilterEvaluator.getValueIndex()); + metaAssembler.setAt(columnFilterEvaluator.getValueIndex()); + } else { + skip(1); + } + } + + private boolean isFilterApplied() { + return columnFilterEvaluator.getTupleIndex() != -1; + } + + private void skip(int count) throws HyracksDataException { metaAssembler.skip(count); - columnFilterEvaluator.setAt(assembler.skip(count)); + assembler.skip(count); } public IValueReference getAssembledValue() throws HyracksDataException { @@ -181,22 +203,25 @@ public final class QueryColumnWithMetaTupleReference extends AbstractAsterixColu } private IValueReference getFilteredAssembledValue() throws HyracksDataException { - int index = columnFilterEvaluator.getTupleIndex(); - - // index == -1 if the normalized filter indicated that a mega leaf node is filtered - if (index == tupleIndex) { - // setAt in the assembler expect the value index (i.e., tupleCount - antiMatterCount) - antimatterGap = 0; - int valueIndex = columnFilterEvaluator.getValueIndex(); - assembler.setAt(valueIndex); - metaAssembler.setAt(valueIndex); - // set the next tuple index that satisfies the filter - columnFilterEvaluator.evaluate(); - return assembler.nextValue(); - } else { - antimatterGap++; - } + try { + int index = columnFilterEvaluator.getTupleIndex(); + + // index == -1 if the normalized filter indicated that a mega leaf node is filtered + if (index == tupleIndex) { + // setAt in the assembler expect the value index (i.e., tupleCount - antiMatterCount) + int valueIndex = columnFilterEvaluator.getValueIndex(); + assembler.setAt(valueIndex); + metaAssembler.setAt(valueIndex); + // set the next tuple index that satisfies the filter + columnFilterEvaluator.evaluate(); + return assembler.nextValue(); + } - return MissingValueGetter.MISSING; + return MissingValueGetter.MISSING; + } catch (ColumnarValueException e) { + columnFilterEvaluator.appendInformation(e); + e.getNode().put("cursorTupleIndex", tupleIndex); + throw e; + } } } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/AbstractColumnValuesReader.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/AbstractColumnValuesReader.java index 576b884fb2..62d45a4a8b 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/AbstractColumnValuesReader.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/AbstractColumnValuesReader.java @@ -31,6 +31,7 @@ import org.apache.asterix.column.values.reader.value.AbstractValueReader; import org.apache.asterix.om.types.ATypeTag; import org.apache.hyracks.api.exceptions.HyracksDataException; import org.apache.hyracks.data.std.api.IValueReference; +import org.apache.hyracks.storage.am.lsm.btree.column.error.ColumnarValueException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.parquet.bytes.BytesUtils; @@ -93,10 +94,12 @@ abstract class AbstractColumnValuesReader implements IColumnValuesReader { numberOfEncounteredMissing += isMissing() ? 1 : 0; numberOfEncounteredNull += isNull() ? 1 : 0; } catch (Exception e) { - ObjectNode infoNode = OBJECT_MAPPER.createObjectNode(); - appendReaderInformation(infoNode); - LOGGER.error("error reading nextLevel, collected info: {}", infoNode); - throw HyracksDataException.create(e); + ColumnarValueException ex = new ColumnarValueException(); + ObjectNode readerNode = ex.createNode(getClass().getSimpleName()); + appendReaderInformation(readerNode); + LOGGER.error("error reading nextLevel, collected info: {}", ex.getNode()); + ex.addSuppressed(e); + throw ex; } } diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/PrimitiveColumnValuesReader.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/PrimitiveColumnValuesReader.java index 7b02c70726..07569e65d4 100644 --- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/PrimitiveColumnValuesReader.java +++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/values/reader/PrimitiveColumnValuesReader.java @@ -117,8 +117,8 @@ public final class PrimitiveColumnValuesReader extends AbstractColumnValuesReade @Override public int reset(int startIndex, int skipCount) throws HyracksDataException { - ((IColumnKeyValueReader) valueReader).reset(startIndex, skipCount); // first item + ((IColumnKeyValueReader) valueReader).reset(startIndex, skipCount); nextLevel(); int numberOfAntiMatters = level < maxLevel ? 1 : 0; for (int i = 0; i < skipCount; i++) { diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/api/IColumnTupleIterator.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/api/IColumnTupleIterator.java index 4b9cc99a8f..7576f4a43b 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/api/IColumnTupleIterator.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/api/IColumnTupleIterator.java @@ -79,11 +79,21 @@ public interface IColumnTupleIterator extends ILSMTreeTupleReference, Comparable boolean isConsumed(); /** - * Skip a number of tuples + * Skip a number of tuples on page initialization * - * @param count the number of tuples that needed to be skipped + * @param tupleIndex + * @param count the number of tuples that needed to be skipped */ - void skip(int count) throws HyracksDataException; + void initSkip(int tupleIndex, int count) throws HyracksDataException; + + /** + * Skips the current tuple. + * This is used when a tuple is marked as deleted by the cursor, prompting + * the filter and column to also skip it. + * + * @throws HyracksDataException if an error occurs while skipping the tuple. + */ + void skipCurrentTuple() throws HyracksDataException; /** * Move to the next tuple @@ -108,11 +118,4 @@ public interface IColumnTupleIterator extends ILSMTreeTupleReference, Comparable void unpinColumnsPages() throws HyracksDataException; void close(); - - /** - * @return the gap between the lastAssembledTuple index and the current antimatter tuple index - */ - int getAntimatterGap(); - - void resetAntimatterGap(); } diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/error/ColumnarValueException.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/error/ColumnarValueException.java index 79c786496f..d3de601a5d 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/error/ColumnarValueException.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/error/ColumnarValueException.java @@ -39,6 +39,10 @@ public class ColumnarValueException extends IllegalStateException { node = OBJECT_MAPPER.createObjectNode(); } + public ObjectNode getNode() { + return node; + } + public ObjectNode createNode(String fieldName) { return node.putObject(fieldName); } diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/LSMColumnBTreeRangeSearchCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/LSMColumnBTreeRangeSearchCursor.java index cee77eddf8..c3fc53d93d 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/LSMColumnBTreeRangeSearchCursor.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/LSMColumnBTreeRangeSearchCursor.java @@ -86,9 +86,7 @@ public class LSMColumnBTreeRangeSearchCursor extends LSMBTreeRangeSearchCursor { IColumnTupleIterator columnTuple = (IColumnTupleIterator) e.getTuple(); if (!columnTuple.isAntimatter()) { // Skip non-key columns - int antiMatterGap = columnTuple.getAntimatterGap(); - columnTuple.skip(antiMatterGap + 1); - columnTuple.resetAntimatterGap(); + columnTuple.skipCurrentTuple(); } } diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java index 1937ffc65d..f079f51df2 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java @@ -44,9 +44,8 @@ public abstract class AbstractColumnTupleReference implements IColumnTupleIterat private final IColumnBufferProvider[] filterBufferProviders; private final IColumnBufferProvider[] buffersProviders; private final int numberOfPrimaryKeys; - private int endIndex; + protected int endIndex; protected int tupleIndex; - protected int antimatterGap; // For logging private final LongSet pinnedPages; @@ -103,7 +102,6 @@ public abstract class AbstractColumnTupleReference implements IColumnTupleIterat @Override public final void newPage() throws HyracksDataException { tupleIndex = 0; - antimatterGap = 0; ByteBuffer pageZero = frame.getBuffer(); pageZero.clear(); pageZero.position(HEADER_SIZE); @@ -121,7 +119,6 @@ public abstract class AbstractColumnTupleReference implements IColumnTupleIterat @Override public final void reset(int startIndex, int endIndex) throws HyracksDataException { tupleIndex = startIndex; - antimatterGap = 0; this.endIndex = endIndex; ByteBuffer pageZero = frame.getBuffer(); int numberOfTuples = frame.getTupleCount(); @@ -156,7 +153,7 @@ public abstract class AbstractColumnTupleReference implements IColumnTupleIterat * skipCount from calling setPrimaryKeysAt(startIndex, startIndex) is a negative value. For that reason, * non-key column should not skip any value. */ - skip(Math.max(skipCount, 0)); + initSkip(tupleIndex, Math.max(skipCount, 0)); } else { skipMegaLeafNode(); numOfSkippedMegaLeafNodes++; @@ -194,7 +191,7 @@ public abstract class AbstractColumnTupleReference implements IColumnTupleIterat * For values, we need to do 6 skips, as next will be called later by the assembler * -- setting the position at 12 as well. */ - skip(skipCount); + initSkip(tupleIndex, skipCount); } protected abstract int setPrimaryKeysAt(int index, int skipCount) throws HyracksDataException; @@ -296,14 +293,4 @@ public abstract class AbstractColumnTupleReference implements IColumnTupleIterat public final void resetByTupleIndex(ITreeIndexFrame frame, int tupleIndex) { throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_MSG); } - - @Override - public int getAntimatterGap() { - return antimatterGap; - } - - @Override - public void resetAntimatterGap() { - antimatterGap = 0; - } }
