From f3f787e0b83a935dbb93627412c3c3ca16c88e8b Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Wed, 17 Sep 2025 21:22:37 -0700 Subject: [PATCH 01/15] fix flaky integration tests Signed-off-by: Anthony Leong --- .../opensearch/index/query/IntervalBuilder.java | 14 ++++++++++++++ .../index/query/IntervalsSourceProvider.java | 3 +++ .../org/opensearch/test/AbstractQueryTestCase.java | 8 +++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/opensearch/index/query/IntervalBuilder.java b/server/src/main/java/org/opensearch/index/query/IntervalBuilder.java index d37519120b325..323806cc188bc 100644 --- a/server/src/main/java/org/opensearch/index/query/IntervalBuilder.java +++ b/server/src/main/java/org/opensearch/index/query/IntervalBuilder.java @@ -144,6 +144,20 @@ protected IntervalsSource analyzeTerm(TokenStream ts) throws IOException { return Intervals.term(BytesRef.deepCopyOf(bytesAtt.getBytesRef())); } + static boolean canCombineSources(List sources) { + int sourceIndex = 0; + long disjunctionCount = 1; + + while (sourceIndex < sources.size()) { + disjunctionCount = disjunctionCount * sources.get(sourceIndex).pullUpDisjunctions().size(); + if (disjunctionCount > IndexSearcher.getMaxClauseCount()) { + return false; + } + sourceIndex += 1; + } + return true; + } + protected static IntervalsSource combineSources(List sources, int maxGaps, IntervalMode mode) { if (sources.size() == 0) { return NO_INTERVALS; diff --git a/server/src/main/java/org/opensearch/index/query/IntervalsSourceProvider.java b/server/src/main/java/org/opensearch/index/query/IntervalsSourceProvider.java index 1fc596011d84a..128ad7e2a736a 100644 --- a/server/src/main/java/org/opensearch/index/query/IntervalsSourceProvider.java +++ b/server/src/main/java/org/opensearch/index/query/IntervalsSourceProvider.java @@ -443,6 +443,9 @@ public IntervalsSource getSource(QueryShardContext ctx, MappedFieldType fieldTyp for (IntervalsSourceProvider provider : subSources) { ss.add(provider.getSource(ctx, fieldType)); } + if (maxGaps == 0 && mode == IntervalMode.ORDERED && IntervalBuilder.canCombineSources(ss) == false) { + throw new IllegalArgumentException("Too many disjunctions to expand"); + } IntervalsSource source = IntervalBuilder.combineSources(ss, maxGaps, mode); if (filter != null) { return filter.filter(source, ctx, fieldType); diff --git a/test/framework/src/main/java/org/opensearch/test/AbstractQueryTestCase.java b/test/framework/src/main/java/org/opensearch/test/AbstractQueryTestCase.java index bffde62b193da..325a92fa353e7 100644 --- a/test/framework/src/main/java/org/opensearch/test/AbstractQueryTestCase.java +++ b/test/framework/src/main/java/org/opensearch/test/AbstractQueryTestCase.java @@ -448,7 +448,13 @@ public void testToQuery() throws IOException { * We do it this way in SearchService where * we first rewrite the query with a private context, then reset the context and then build the actual lucene query*/ QueryBuilder rewritten = rewriteQuery(firstQuery, new QueryShardContext(context)); - Query firstLuceneQuery = rewritten.toQuery(context); + Query firstLuceneQuery; + try { + firstLuceneQuery = rewritten.toQuery(context); + } catch (IllegalArgumentException e) { + assertEquals("Too many disjunctions to expand", e.getMessage()); + continue; + } assertNotNull("toQuery should not return null", firstLuceneQuery); assertLuceneQuery(firstQuery, firstLuceneQuery, context); // remove after assertLuceneQuery since the assertLuceneQuery impl might access the context as well From 179f819e62cd950c19dd2935e82f42de7e02b5e2 Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Thu, 18 Sep 2025 08:57:18 -0700 Subject: [PATCH 02/15] add unit tests Signed-off-by: Anthony Leong --- .../CombineIntervalsSourceProviderTests.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/server/src/test/java/org/opensearch/index/query/CombineIntervalsSourceProviderTests.java b/server/src/test/java/org/opensearch/index/query/CombineIntervalsSourceProviderTests.java index f1a7cc4e5cfeb..115189793e43b 100644 --- a/server/src/test/java/org/opensearch/index/query/CombineIntervalsSourceProviderTests.java +++ b/server/src/test/java/org/opensearch/index/query/CombineIntervalsSourceProviderTests.java @@ -32,13 +32,17 @@ package org.opensearch.index.query; +import org.apache.lucene.queries.intervals.Intervals; +import org.apache.lucene.queries.intervals.IntervalsSource; import org.opensearch.core.common.io.stream.NamedWriteableRegistry; import org.opensearch.core.common.io.stream.Writeable; import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.index.query.IntervalsSourceProvider.Combine; import org.opensearch.search.SearchModule; import org.opensearch.test.AbstractSerializingTestCase; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import static org.opensearch.index.query.IntervalsSourceProvider.Combine; @@ -104,4 +108,28 @@ protected Combine doParseInstance(XContentParser parser) throws IOException { assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken()); return combine; } + + public void testCanCombineSourcesFail() { + List sources = new ArrayList<>(); + + for (int i = 0; i < 11; i++) { + IntervalsSource source1 = Intervals.maxgaps(0, Intervals.ordered(Intervals.term("term_" + 2 * i))); + IntervalsSource source2 = Intervals.maxgaps(0, Intervals.ordered(Intervals.term("term_" + (2 * i + 1)))); + sources.add(Intervals.or(source1, source2)); + } + + assertFalse(IntervalBuilder.canCombineSources(sources)); + } + + public void testCanCombineSourcesSuccess() { + List sources = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + IntervalsSource source1 = Intervals.maxgaps(0, Intervals.ordered(Intervals.term("term_" + 2 * i))); + IntervalsSource source2 = Intervals.maxgaps(0, Intervals.ordered(Intervals.term("term_" + (2 * i + 1)))); + sources.add(Intervals.or(source1, source2)); + } + + assertTrue(IntervalBuilder.canCombineSources(sources)); + } } From 897f4b673a0d44e3620b225bdb74af021809196b Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Thu, 18 Sep 2025 10:44:47 -0700 Subject: [PATCH 03/15] retry Signed-off-by: Anthony Leong From 3a9f1bc70651955e0ce42fbdc9b50fd040a08505 Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Thu, 18 Sep 2025 10:47:16 -0700 Subject: [PATCH 04/15] add changelog entry Signed-off-by: Anthony Leong --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7ebc675f000a..737e32c1ce56a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Fix QueryPhaseResultConsumer incomplete callback loops ([#19231](https://github.com/opensearch-project/OpenSearch/pull/19231)) - Fix the `scaled_float` precision issue ([#19188](https://github.com/opensearch-project/OpenSearch/pull/19188)) - Fix Using an excessively large reindex slice can lead to a JVM OutOfMemoryError on coordinator.([#18964](https://github.com/opensearch-project/OpenSearch/pull/18964)) +- Fix IntervalQuery flaky test ([#19332](https://github.com/opensearch-project/OpenSearch/pull/19332)) ### Dependencies - Bump `com.netflix.nebula.ospackage-base` from 12.0.0 to 12.1.0 ([#19019](https://github.com/opensearch-project/OpenSearch/pull/19019)) From 4fbfff2f63c78aafcc8f5925e30d4044a4460fbe Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Fri, 19 Sep 2025 15:01:51 -0700 Subject: [PATCH 05/15] retry workflows Signed-off-by: Anthony Leong From 84a6bdb91706583a2851953b82be88c1c0437575 Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Fri, 19 Sep 2025 22:56:02 -0700 Subject: [PATCH 06/15] retry workflows Signed-off-by: Anthony Leong From 619dd610bab203169681d2b4ae92cc7a55c52fe7 Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Sun, 21 Sep 2025 17:37:51 -0700 Subject: [PATCH 07/15] retry workflows Signed-off-by: Anthony Leong From 1db23f09a364a0b74268dfe6a96f45c9d3434bc2 Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Mon, 22 Sep 2025 16:01:50 -0700 Subject: [PATCH 08/15] retry workflows Signed-off-by: Anthony Leong From b043506cdc3a323f50e7502040e4a085469c7abd Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Wed, 24 Sep 2025 13:07:57 -0700 Subject: [PATCH 09/15] retry workflows Signed-off-by: Anthony Leong From 17e59cdae2c611fd06df686ff016aee85a3b782a Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Wed, 24 Sep 2025 13:08:19 -0700 Subject: [PATCH 10/15] retry workflows Signed-off-by: Anthony Leong From 8a4197be1b6e14e2e3dfaf5d8beb4b2284aceba0 Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Wed, 24 Sep 2025 20:49:50 -0700 Subject: [PATCH 11/15] retry workflows Signed-off-by: Anthony Leong From 445ec1f65a4226db677f8c1643db17640447eb1c Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Wed, 24 Sep 2025 21:02:33 -0700 Subject: [PATCH 12/15] retry workflows Signed-off-by: Anthony Leong From 89705bbd7cb60869ec6c2b8cb318d5b444aebe6b Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Wed, 24 Sep 2025 22:30:21 -0700 Subject: [PATCH 13/15] retry workflows Signed-off-by: Anthony Leong From 7d1319a77674494169502e37fd54e168413ca3a8 Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Wed, 24 Sep 2025 22:58:36 -0700 Subject: [PATCH 14/15] retry workflows Signed-off-by: Anthony Leong From 9854648de6c29009dcac359070ef18170edfd7c6 Mon Sep 17 00:00:00 2001 From: Anthony Leong Date: Wed, 24 Sep 2025 23:45:18 -0700 Subject: [PATCH 15/15] retry workflows Signed-off-by: Anthony Leong