diff options
Diffstat (limited to 'src/mongo/db/query/query_planner_test.cpp')
-rw-r--r-- | src/mongo/db/query/query_planner_test.cpp | 389 |
1 files changed, 0 insertions, 389 deletions
diff --git a/src/mongo/db/query/query_planner_test.cpp b/src/mongo/db/query/query_planner_test.cpp index 417081795a6..58645fc9efc 100644 --- a/src/mongo/db/query/query_planner_test.cpp +++ b/src/mongo/db/query/query_planner_test.cpp @@ -5687,395 +5687,6 @@ TEST_F(QueryPlannerTest, SolutionSetStableWhenOrEnumerationLimitIsReached) { "1}}}}}]}}"); } -// Test that we enumerate the expected plans with the special parameter set. In this test we have -// two branches of an $or, each with two possible indexed solutions. -TEST_F(QueryPlannerTest, LockstepOrEnumerationSanityCheckTwoChildrenTwoIndexesEach) { - params.options = - QueryPlannerParams::NO_TABLE_SCAN | QueryPlannerParams::ENUMERATE_OR_CHILDREN_LOCKSTEP; - addIndex(BSON("a" << 1 << "b" << 1)); - addIndex(BSON("a" << 1 << "c" << 1)); - - runQueryAsCommand( - fromjson("{find: 'testns', filter: {a: 1, $or: [{b: 1, c: 1}, {b: 2, c: 2}]}}")); - - assertNumSolutions(6U); - - assertSolutionExists( - "{or: {nodes: [{fetch: {filter: {c: {$eq: 1} }, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}]}}"); - assertSolutionExists( - "{or: {nodes: [{fetch: {filter: {b: {$eq: 1} }, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}]}}"); - assertSolutionExists( - "{or: {nodes: [{fetch: {filter: {c: {$eq: 1} }, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}]}}"); - assertSolutionExists( - "{or: {nodes: [{fetch: {filter: {b: {$eq: 1} }, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}]}}"); - assertSolutionExists( - "{fetch: {filter: {$or: [{b: {$eq: 1}, c: {$eq: 1}}, {b: {$eq: 2}, c: {$eq: 2}}]}, node: " - "{ixscan: {pattern: {a: 1, b: 1}}}}}}}"); - assertSolutionExists( - "{fetch: {filter: {$or: [{b: {$eq: 1}, c: {$eq: 1}}, {b: {$eq: 2}, c: {$eq: 2}}]}, node: " - "{ixscan: {pattern: {a: 1, c: 1}}}}}}}"); -} - -// Test that we enumerate the expected plans with the special parameter set. In this test we have -// two branches of an $or, each with one possible indexed solution. -TEST_F(QueryPlannerTest, LockstepOrEnumerationSanityCheckTwoChildrenOneIndexEach) { - params.options = - QueryPlannerParams::NO_TABLE_SCAN | QueryPlannerParams::ENUMERATE_OR_CHILDREN_LOCKSTEP; - addIndex(BSON("a" << 1 << "b" << 1)); - addIndex(BSON("a" << 1 << "c" << 1)); - - runQueryAsCommand(fromjson("{find: 'testns', filter: {a: 1, $or: [{b: 1}, {c: 2}]}}")); - - assertNumSolutions(3U); - - assertSolutionExists( - "{fetch: {filter: null, node: {or: {nodes: [{ixscan: {pattern: {a: 1, b: 1}}}, {ixscan: " - "{pattern: {a: 1, c: 1}}}]}}}}"); - assertSolutionExists( - "{fetch: {filter: {$or: [{b: {$eq: 1}}, {c: {$eq: 2}}]}, node: {ixscan: {pattern: {a: 1, " - "b: 1}}}}}}}"); - assertSolutionExists( - "{fetch: {filter: {$or: [{b: {$eq: 1}}, {c: {$eq: 2}}]}, node: {ixscan: {pattern: {a: 1, " - "c: 1}}}}}}}"); -} - -// Test that we enumerate the expected plans with the special parameter set. In this test we have -// two branches of an $or, one with one possible indexed solution, the other with two possible -// indexed solutions. -TEST_F(QueryPlannerTest, LockstepOrEnumerationSanityCheckTwoChildrenDifferentNumSolutions) { - params.options = - QueryPlannerParams::NO_TABLE_SCAN | QueryPlannerParams::ENUMERATE_OR_CHILDREN_LOCKSTEP; - addIndex(BSON("a" << 1 << "b" << 1)); - addIndex(BSON("a" << 1 << "c" << 1)); - - runQueryAsCommand(fromjson("{find: 'testns', filter: {a: 1, $or: [{b: 1}, {b: 2, c: 2}]}}")); - - assertNumSolutions(4U); - - assertSolutionExists( - "{fetch: {filter: null, node: {or: {nodes: [{ixscan: {pattern: {a: 1, b: 1}}}, {fetch: " - "{filter: {c: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}]}}}}"); - assertSolutionExists( - "{fetch: {filter: null, node: {or: {nodes: [{ixscan: {pattern: {a: 1, b: 1}}}, {fetch: " - "{filter: {b: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}]}}}}"); - assertSolutionExists( - "{fetch: {filter: {$or: [{b: {$eq: 1}}, {b: {$eq: 2}, c: {$eq: 2}}]}, node: {ixscan: " - "{pattern: {a: 1, b: 1}}}}}}}"); - assertSolutionExists( - "{fetch: {filter: {$or: [{b: {$eq: 1}}, {b: {$eq: 2}, c: {$eq: 2}}]}, node: {ixscan: " - "{pattern: {a: 1, c: 1}}}}}}}"); -} - -// Test that the special parameter does in fact impact the order of enumeration. Here we rely on the -// cap of number of or enumerations to prove that the plans we're interested in are enumerated -// before we hit the limit. -TEST_F(QueryPlannerTest, NormalOrEnumerationDoesNotPrioritizeLockstepIteration) { - params.options = QueryPlannerParams::NO_TABLE_SCAN; - ASSERT_EQ(internalQueryEnumerationMaxOrSolutions.load(), 10); - addIndex(BSON("a" << 1 << "b" << 1)); - addIndex(BSON("a" << 1 << "c" << 1)); - addIndex(BSON("a" << 1 << "d" << 1)); - - // For this query and the above indexes, each clause of the $or has three options to choose - // from, for a total of 3 * 3 * 3 = 27 possible enumerations for just that $or sub-branch. - runQueryAsCommand( - fromjson("{find: 'testns', filter: {a: 1, $or: [{b: 1, c: 1, d: 1}, {b: 2, c: 2, d: 2}, " - "{b: 3, c: 3, d: 3}]}}")); - - // The $or enumeration is limited to 10, and then we have three plans where just the {a: 1} - // predicate is indexed. - assertNumSolutions(13U); - - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {c: {$eq: 1}, d: {$eq: 1}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 2}, d: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 3}, d: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}} " - "]}}"); - // Because we did not set the 'ENUMERATE_OR_CHILDREN_LOCKSTEP' flag, we don't expect this - // solution to be generated. This is in contrast to the next test case. - ASSERT_THROWS( - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {b: {$eq: 1}, c: {$eq: 1}}, node: {ixscan: {pattern: {a: 1, d: " - "1}}}}}, " - "{fetch: {filter: {b: {$eq: 2}, c: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, d: " - "1}}}}}, " - "{fetch: {filter: {b: {$eq: 3}, c: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, d: " - "1}}}}} " - "]}}"), - unittest::TestAssertionFailureException); - - // We still expect to generate the solutions which don't index the $or. - assertSolutionExists( - "{fetch: {filter: {$or: [" - "{b: {$eq: 1}, c: {$eq: 1}, d: {$eq: 1}}, " - "{b: {$eq: 2}, c: {$eq: 2}, d: {$eq: 2}}, " - "{b: {$eq: 3}, c: {$eq: 3}, d: {$eq: 3}} " - "]}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}}"); -} - -TEST_F(QueryPlannerTest, LockstepOrEnumerationDoesPrioritizeLockstepIteration) { - params.options = - QueryPlannerParams::NO_TABLE_SCAN | QueryPlannerParams::ENUMERATE_OR_CHILDREN_LOCKSTEP; - ASSERT_EQ(internalQueryEnumerationMaxOrSolutions.load(), 10); - addIndex(BSON("a" << 1 << "b" << 1)); - addIndex(BSON("a" << 1 << "c" << 1)); - addIndex(BSON("a" << 1 << "d" << 1)); - - // For this query and the above indexes, each clause of the $or has three options to choose - // from, for a total of 3 * 3 * 3 = 27 possible enumerations for just that $or sub-branch. - runQueryAsCommand( - fromjson("{find: 'testns', filter: {a: 1, $or: [{b: 1, c: 1, d: 1}, {b: 2, c: 2, d: 2}, " - "{b: 3, c: 3, d: 3}]}}")); - - // The $or enumeration is limited to 10, and then we have three plans where just the {a: 1} - // predicate is indexed. - assertNumSolutions(13U); - - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {c: {$eq: 1}, d: {$eq: 1}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 2}, d: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 3}, d: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}} " - "]}}"); - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {b: {$eq: 1}, d: {$eq: 1}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 2}, d: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 3}, d: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}} " - "]}}"); - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {b: {$eq: 1}, c: {$eq: 1}}, node: {ixscan: {pattern: {a: 1, d: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 2}, c: {$eq: 2}}, node: {ixscan: {pattern: {a: 1, d: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 3}, c: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, d: 1}}}}} " - "]}}"); - assertSolutionExists( - "{fetch: {filter: {$or: [" - "{b: {$eq: 1}, c: {$eq: 1}, d: {$eq: 1}}, " - "{b: {$eq: 2}, c: {$eq: 2}, d: {$eq: 2}}, " - "{b: {$eq: 3}, c: {$eq: 3}, d: {$eq: 3}} " - "]}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}}"); -} - -TEST_F(QueryPlannerTest, LockstepOrEnumerationDoesPrioritizeLockstepIterationMixedChildren) { - params.options = - QueryPlannerParams::NO_TABLE_SCAN | QueryPlannerParams::ENUMERATE_OR_CHILDREN_LOCKSTEP; - ASSERT_EQ(internalQueryEnumerationMaxOrSolutions.load(), 10); - addIndex(BSON("a" << 1 << "b" << 1)); - addIndex(BSON("a" << 1 << "c" << 1)); - addIndex(BSON("a" << 1 << "d" << 1)); - addIndex(BSON("a" << 1 << "e" << 1)); - - // For this query and the above indexes, each clause of the $or has a varying number options to - // choose from, for a total of 2 * 3 * 4 * 2 = 48 possible enumerations for just that $or - // sub-branch. - runQueryAsCommand( - fromjson("{find: 'testns', filter: {" - " a: 1," - " $or: [" - " {b: 2.1, c: 2.1}," - " {b: 3, c: 3, d: 3}," - " {b: 4, c: 4, d: 4, e: 4}," - " {b: 2.2, c: 2.2}" - "]}}")); - - // The $or enumeration is limited to 10, and then we have four plans where just the {a: 1} - // predicate is indexed. - assertNumSolutions(14U); - - // Lockstep enumerations. Definitely expected. - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {c: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 3}, d: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 4}, d: {$eq: 4}, e: {$eq: 4}}," - " node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}" - "]}}"); - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {b: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 3}, d: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 4}, d: {$eq: 4}, e: {$eq: 4}}," - " node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}" - "]}}"); - // Everyone advances one more time, no longer lock step. - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {c: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 3}, c: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, d: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 4}, c: {$eq: 4}, e: {$eq: 4}}," - " node: {ixscan: {pattern: {a: 1, d: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}" - "]}}"); - // Normal enumeration. Here we observe an interesting phenomena. Before we get into plan - // enumeration, the query is parsed and "normalized". This process involves putting the query in - // a canonical order, in part so that similar queries can be recognized as such for caching. In - // this case, it orders the $or children by their respective number of children. So our original - // query will be enumerated as if it were typed in this order: - // {a: 1, - // $or: [ - // {b: 2.1, c: 2.1}, - // {b: 2.2, c: 2.2}, - // {b: 3, c: 3, d: 3}, - // {b: 4, c: 4, d: 4, e: 4} - // ] - // } - // Here are the exact plans: - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {b: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 3}, c: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, d: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 4}, c: {$eq: 4}, e: {$eq: 4}}," - " node: {ixscan: {pattern: {a: 1, d: 1}}}}}" - "]}}"); - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {c: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 3}, c: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, d: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 4}, c: {$eq: 4}, e: {$eq: 4}}," - " node: {ixscan: {pattern: {a: 1, d: 1}}}}}" - "]}}"); - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {b: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 3}, c: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, d: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 4}, c: {$eq: 4}, e: {$eq: 4}}," - " node: {ixscan: {pattern: {a: 1, d: 1}}}}}" - "]}}"); - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {c: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 3}, d: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 4}, c: {$eq: 4}, d: {$eq: 4}}," - " node: {ixscan: {pattern: {a: 1, e: 1}}}}}" - "]}}"); - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {b: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 3}, d: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 4}, c: {$eq: 4}, d: {$eq: 4}}," - " node: {ixscan: {pattern: {a: 1, e: 1}}}}}" - "]}}"); - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {c: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 3}, d: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 4}, c: {$eq: 4}, d: {$eq: 4}}," - " node: {ixscan: {pattern: {a: 1, e: 1}}}}}" - "]}}"); - assertSolutionExists( - "{or: {nodes: [" - "{fetch: {filter: {b: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - "{fetch: {filter: {c: {$eq: 3}, d: {$eq: 3}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - "{fetch: {filter: {b: {$eq: 4}, c: {$eq: 4}, d: {$eq: 4}}," - " node: {ixscan: {pattern: {a: 1, e: 1}}}}}" - "]}}"); - - // Now to the solutions which don't index the $or. - assertSolutionExists( - "{fetch: {filter: {$or: [" - "{b: {$eq: 2.1}, c: {$eq: 2.1}}, " - "{b: {$eq: 2.2}, c: {$eq: 2.2}}, " - "{b: {$eq: 3}, c: {$eq: 3}, d: {$eq: 3}}, " - "{b: {$eq: 4}, c: {$eq: 4}, d: {$eq: 4}, e: {$eq: 4}} " - "]}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}}"); - assertSolutionExists( - "{fetch: {filter: {$or: [" - "{b: {$eq: 2.1}, c: {$eq: 2.1}}, " - "{b: {$eq: 2.2}, c: {$eq: 2.2}}, " - "{b: {$eq: 3}, c: {$eq: 3}, d: {$eq: 3}}, " - "{b: {$eq: 4}, c: {$eq: 4}, d: {$eq: 4}, e: {$eq: 4}} " - "]}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}}"); - assertSolutionExists( - "{fetch: {filter: {$or: [" - "{b: {$eq: 2.1}, c: {$eq: 2.1}}, " - "{b: {$eq: 2.2}, c: {$eq: 2.2}}, " - "{b: {$eq: 3}, c: {$eq: 3}, d: {$eq: 3}}, " - "{b: {$eq: 4}, c: {$eq: 4}, d: {$eq: 4}, e: {$eq: 4}} " - "]}, node: {ixscan: {pattern: {a: 1, d: 1}}}}}}"); - assertSolutionExists( - "{fetch: {filter: {$or: [" - "{b: {$eq: 2.1}, c: {$eq: 2.1}}, " - "{b: {$eq: 2.2}, c: {$eq: 2.2}}, " - "{b: {$eq: 3}, c: {$eq: 3}, d: {$eq: 3}}, " - "{b: {$eq: 4}, c: {$eq: 4}, d: {$eq: 4}, e: {$eq: 4}} " - "]}, node: {ixscan: {pattern: {a: 1, e: 1}}}}}}"); -} - -TEST_F(QueryPlannerTest, LockstepOrEnumerationApplysToEachOrInTree) { - params.options = - QueryPlannerParams::NO_TABLE_SCAN | QueryPlannerParams::ENUMERATE_OR_CHILDREN_LOCKSTEP; - ASSERT_EQ(internalQueryEnumerationMaxOrSolutions.load(), 10); - addIndex(BSON("a" << 1 << "b" << 1)); - addIndex(BSON("a" << 1 << "c" << 1)); - addIndex(BSON("a" << 1 << "x" << 1)); - addIndex(BSON("a" << 1 << "y" << 1)); - - // For this query and the above indexes, each clause of the $or has 2 indexes to choose from, - // for a total of 2 * 2 * 2 * 2 = 16 possible enumerations for just that $or sub-branch. - runQueryAsCommand( - fromjson("{find: 'testns', filter: {" - " a: 1," - " $or: [" - " {b: 2.1, c: 2.1}," - " {b: 2.2, c: 2.2}," - " {$and: [" - " {unindexed: 'thisPredicateToEnsureNestedOrsAreNotCombined'}," - " {$or: [" - " {x: 3.0, y: 3.0}," - " {x: 3.1, y: 3.1}" - " ]}" - " ]}" - "]}}")); - - // The $or enumeration is limited to 10, and then we have 4 plans where just the {a: 1} - // predicate is indexed. - assertNumSolutions(14U); - - // Both lockstep enumerations should be present. - assertSolutionExists( - "{or: {nodes: [" - " {fetch: {filter: {c: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - " {fetch: {filter: {c: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, b: 1}}}}}, " - " {fetch: {" - " filter: {unindexed: {$eq: 'thisPredicateToEnsureNestedOrsAreNotCombined'}}," - " node: {" - " or: {nodes: [" - " {fetch: {filter: {y: {$eq: 3.0}}, node: {ixscan: {pattern: {a: 1, x: 1}}}}}," - " {fetch: {filter: {y: {$eq: 3.1}}, node: {ixscan: {pattern: {a: 1, x: 1}}}}}" - " ]}}" - " }}" - "]}}"); - assertSolutionExists( - "{or: {nodes: [" - " {fetch: {filter: {b: {$eq: 2.1}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - " {fetch: {filter: {b: {$eq: 2.2}}, node: {ixscan: {pattern: {a: 1, c: 1}}}}}, " - " {fetch: {" - " filter: {unindexed: {$eq: 'thisPredicateToEnsureNestedOrsAreNotCombined'}}," - " node: {" - " or: {nodes: [" - " {fetch: {filter: {x: {$eq: 3.0}}, node: {ixscan: {pattern: {a: 1, y: 1}}}}}," - " {fetch: {filter: {x: {$eq: 3.1}}, node: {ixscan: {pattern: {a: 1, y: 1}}}}}" - " ]}}" - " }}" - "]}}"); -} - TEST_F(QueryPlannerTest, InvalidUtf8CodePointDoesNotLeadToInvalidIndexBoundsInvariantFailure) { params.options &= ~QueryPlannerParams::INCLUDE_COLLSCAN; addIndex(BSON("a" << 1)); |