Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ private static Document getFirstLiveDoc(Terms terms, LeafReader reader) throws I
StoredFields storedFields = reader.storedFields();
// Deal with the chance that the first bunch of terms are in deleted documents. Is there a
// better way?
for (int idx = 0; idx < 1000 && postingsEnum == null; ++idx) {
for (int idx = 0; idx < 1000; ++idx) {
text = termsEnum.next();
// Ran off the end of the terms enum without finding any live docs with that field in them.
if (text == null) {
Expand All @@ -481,7 +481,7 @@ private static Document getFirstLiveDoc(Terms terms, LeafReader reader) throws I
postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
final Bits liveDocs = reader.getLiveDocs();
if (postingsEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
if (liveDocs != null && liveDocs.get(postingsEnum.docID())) {
if (liveDocs != null && !liveDocs.get(postingsEnum.docID())) {
continue;
}
return storedFields.document(postingsEnum.docID());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.EnumSet;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.luke.FieldFlag;
import org.apache.solr.index.NoMergePolicyFactory;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.CustomAnalyzerStrField;
import org.apache.solr.schema.IndexSchema;
Expand Down Expand Up @@ -294,4 +295,59 @@ public void testCatchAllCopyField() throws Exception {
deleteCore();
initCore("solrconfig.xml", "schema12.xml");
}

/**
* SOLR-18125: Tests that Luke reports index flags for fields even when a document has been
* deleted. Uses NoMergePolicy so the deleted doc remains in the same segment, keeping liveDocs
* non-null and exposing the inverted liveDocs check in getFirstLiveDoc.
*/
@Test
public void testIndexFlagsWithDeletedDocs() throws Exception {
deleteCore();
systemSetPropertySolrTestsMergePolicyFactory(NoMergePolicyFactory.class.getName());
try {
initCore("solrconfig.xml", "schema12.xml");

// Three docs in a single commit so they share one segment. Delete the middle term
// ("bbb") and keep the lexical edges ("aaa" and "ccc") live, so the first term
// encountered is always a live doc regardless of ascending or descending iteration.
// The bug's inverted liveDocs check skips live docs, so getFirstLiveDoc returns null
// and index flags go missing.
assertU(adoc("id", "1", "solr_s", "aaa"));
assertU(adoc("id", "2", "solr_s", "bbb"));
assertU(adoc("id", "3", "solr_s", "ccc"));
assertU(commit());

assertU(delI("2"));
assertU(commit());

assertQ(
"index flags should be present for solr_s despite deletion in segment",
req("qt", "/admin/luke", "fl", "solr_s"),
getFieldXPathPrefix("solr_s") + "[@name='index']");

// Now test the inverse: delete the edges and keep the middle. The first term
// encountered ("aaa" or "ccc") is deleted, so getFirstLiveDoc must skip it and
// continue to the live term ("bbb"). This exercises the retry loop — without it,
// the method gives up after the first deleted term.
clearIndex();
assertU(adoc("id", "4", "solr_s", "aaa"));
assertU(adoc("id", "5", "solr_s", "bbb"));
assertU(adoc("id", "6", "solr_s", "ccc"));
assertU(commit());

assertU(delI("4"));
assertU(delI("6"));
assertU(commit());

assertQ(
"index flags should be present for solr_s when edges are deleted",
req("qt", "/admin/luke", "fl", "solr_s"),
getFieldXPathPrefix("solr_s") + "[@name='index']");
} finally {
deleteCore();
System.clearProperty(SYSTEM_PROPERTY_SOLR_TESTS_MERGEPOLICYFACTORY);
initCore("solrconfig.xml", "schema12.xml");
}
}
}