[SERVER-71489] tassert tripped when using a cached ixscan plan involving a partialFilterExpression with $or and non-simple collation Created: 18/Nov/22  Updated: 13/Jan/23  Resolved: 13/Jan/23

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Nicholas Zolnierz Assignee: Nicholas Zolnierz
Resolution: Duplicate Votes: 0
Labels: query-director-triage
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
Duplicate
duplicates SERVER-68434 Equality to null can incorrectly use ... Closed
Related
related to SERVER-68434 Equality to null can incorrectly use ... Closed
Assigned Teams:
Query Optimization
Operating System: ALL
Steps To Reproduce:

(function() {
"use strict";
 
db.test.drop();
 
const indexList = [
    {
        "obj.array": 1,
    },
    {
        "obj.array": -1,
    },
];
 
const indexOptions = [
    {
        partialFilterExpression: {$or: [{"obj.array": {$exists: true}}, {"obj.array": 5}]},
        collation: {
            locale: 'ko',
            strength: 5,
        },
    },
    {},
];
 
const documentList = [
    {
        _id: 1,
        "obj.array": ["some", "string"],
    },
    {
        _id: 2,
        "obj.array": ["some", "other", "string"],
    },
];
 
assert.commandWorked(db.test.insert(documentList));
 
for (let i = 0; i < indexList.length; i++) {
    db.test.createIndex(indexList[i], indexOptions[i]);
}
 
// Run a few aggregations to get a cached entry for {obj.array: {$in: [...]}}
const aggregationList = [
    {$match: {"obj.array": {$in: [1, 2]}}},
    {$match: {"obj.array": {$in: [1, 2]}}},
    {$match: {"obj.array": {$in: ["Small Analyst", "parsing Zambia Metal"]}}},  // THIS ONE TASSERTS
];
for (let i = 0; i < aggregationList.length; i++) {
    db.test.aggregate(aggregationList[i]).toArray();
}
})();

Participants:
Linked BF Score: 16

 Description   

A tassert can be tripped when using a plan cache entry that performs an index scan over a partial index with a filter containing $or and a non-simple collation. The bounds validity check fails when checking whether intervals are ordered correctly.

Theoretically the query that causes the tassert should not be eligible for the plan cache entry, since it contains a collation-sensitive string value in the predicate.



 Comments   
Comment by Nicholas Zolnierz [ 04/Jan/23 ]

I've confirmed that the plan cache key's are identical for the collation-sensitive query and the collation-insensitive query, even though the filter on the partial index has a competing collation. This is because the discriminator for the partial index is 0 (ineligible) for both the {$in: [1, 2]} as well as the {$in: ["Small Analyst", "parsing Zambia Metal"]} predicates, even though the first should be eligible.

It's worth noting that although the plan cache key indicates that the index is not compatible with the query, the planner uses a different set of logic which is actually correct for the collation-insensitive case. I believe that SERVER-68434 will change the plan cache key encoding to be correct, and thus the collation-sensitive query will not use the cached IXSCAN entry. Will test as part of SERVER-68434 before closing this ticket.

Comment by David Storch [ 16/Dec/22 ]

Flagging for re-scheduling as maybe this slipped through the cracks. I would think that we should generally put in the effort to fix tassert() failures.

Comment by Nicholas Zolnierz [ 18/Nov/22 ]

Marking as related-to SERVER-68434 as the root cause may be the same however the symptoms are slightly different. CC joel.redman@mongodb.com 

Generated at Thu Feb 08 06:19:09 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.