This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_10x in repository https://gitbox.apache.org/repos/asf/solr.git
commit c68c3cfa33e158ccc03b4a5845ec6cce363ee303 Author: David Smiley <[email protected]> AuthorDate: Sun Sep 6 00:05:39 2026 -0400 SlowCompositeReaderWrapper: fix index sort and hasBlocks (#4825) minor fixes; not seen in a realistic setting. (cherry picked from commit c78158b9811417543c4f7cdf99faed8d25c5943b) --- ...owCompositeReaderWrapper-sort-hasblocks-fix.yml | 6 +++ .../solr/index/SlowCompositeReaderWrapper.java | 43 +++++++++++++--------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/changelog/unreleased/SlowCompositeReaderWrapper-sort-hasblocks-fix.yml b/changelog/unreleased/SlowCompositeReaderWrapper-sort-hasblocks-fix.yml new file mode 100644 index 00000000000..c1f98f684cc --- /dev/null +++ b/changelog/unreleased/SlowCompositeReaderWrapper-sort-hasblocks-fix.yml @@ -0,0 +1,6 @@ +# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc +title: SlowCompositeReaderWrapper no longer misreports the index sort and hasBlocks of a multi-segment composite view; both were previously taken from the first segment only, which is wrong whenever there is more than one segment. +type: fixed # added, changed, fixed, deprecated, removed, dependency_update, security, other +authors: + - name: David Smiley +links: diff --git a/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java index a242ce849a3..3b20a178107 100644 --- a/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java +++ b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java @@ -51,6 +51,7 @@ import org.apache.lucene.index.TermVectors; import org.apache.lucene.index.Terms; import org.apache.lucene.search.AcceptDocs; import org.apache.lucene.search.KnnCollector; +import org.apache.lucene.search.Sort; import org.apache.lucene.util.Bits; import org.apache.lucene.util.Version; import org.apache.lucene.util.packed.PackedInts; @@ -84,38 +85,44 @@ public final class SlowCompositeReaderWrapper extends LeafReader { * This method is sugar for getting an {@link LeafReader} from an {@link IndexReader} of any kind. * If the reader is already atomic, it is returned unchanged, otherwise wrapped by this class. */ - public static LeafReader wrap(IndexReader reader) throws IOException { - if (reader instanceof CompositeReader) { - return new SlowCompositeReaderWrapper((CompositeReader) reader); + public static LeafReader wrap(IndexReader reader) { + if (reader instanceof CompositeReader compositeReader) { + return new SlowCompositeReaderWrapper(compositeReader); } else { assert reader instanceof LeafReader; return (LeafReader) reader; } } - SlowCompositeReaderWrapper(CompositeReader reader) throws IOException { + SlowCompositeReaderWrapper(CompositeReader reader) { in = reader; in.registerParentReader(this); - if (reader.leaves().isEmpty()) { + List<LeafReaderContext> leaves = reader.leaves(); + if (leaves.isEmpty()) { metaData = new LeafMetaData(Version.LATEST.major, Version.LATEST, null, false); } else { Version minVersion = Version.LATEST; - for (LeafReaderContext leafReaderContext : reader.leaves()) { - Version leafVersion = leafReaderContext.reader().getMetaData().minVersion(); - if (leafVersion == null) { - minVersion = null; - break; - } else if (minVersion.onOrAfter(leafVersion)) { - minVersion = leafVersion; + boolean hasBlocks = false; + for (LeafReaderContext leafReaderContext : leaves) { + LeafMetaData leafMetaData = leafReaderContext.reader().getMetaData(); + if (minVersion != null) { + Version leafVersion = leafMetaData.minVersion(); + if (leafVersion == null) { + minVersion = null; + } else if (minVersion.onOrAfter(leafVersion)) { + minVersion = leafVersion; + } } + // A block (child/nested docs), once written, is never split across segments, so the + // composite view has blocks as soon as any one of its segments does. + hasBlocks |= leafMetaData.hasBlocks(); } - LeafMetaData leafMetaData = reader.leaves().get(0).reader().getMetaData(); + LeafMetaData firstLeafMetaData = leaves.getFirst().reader().getMetaData(); + // The composite view is only actually sorted in the trivial single-leaf case: concatenating + // multiple segments does not preserve their shared per-segment sort as a sort of the whole. + Sort sort = leaves.size() == 1 ? firstLeafMetaData.sort() : null; metaData = - new LeafMetaData( - leafMetaData.createdVersionMajor(), - minVersion, - leafMetaData.sort(), - leafMetaData.hasBlocks()); + new LeafMetaData(firstLeafMetaData.createdVersionMajor(), minVersion, sort, hasBlocks); } fieldInfos = FieldInfos.getMergedFieldInfos(in); }
