I have the following test index in Couchbase 7.2.2:
CREATE INDEX `test_index`
ON `test_bucket`(`sort`)
WHERE ((`type` = "type1") OR (`type` = "type2"))
with the following query:
SELECT META().`id`
FROM `test_bucket`
WHERE (`sort` IS VALUED)
AND ((`type` = "type1") OR (`type` = "type2"))
This combination requires a fetch after after pulling from the index (the query plan is at the end of the post).
Why does this require the fetch to apply the filter?
More specifically, if you drop the OR from index filter you’ll see that there is no longer a fetch and the query plan includes “filter_covers” for the index filter. But with the addition of the OR there is no longer a “filter_covers” clause.
So maybe the better question should be why the OR kills the covered filter?
The query plan with the OR follows:
{
"plan": {
"#operator": "Sequence",
"~children": [
{
"#operator": "IndexScan3",
"index": "test_index",
"index_id": "f32d68da4b75baa3",
"index_projection": {
"primary_key": true
},
"keyspace": "test_bucket",
"namespace": "default",
"spans": [
{
"exact": true,
"range": [
{
"inclusion": 0,
"index_key": "`sort`",
"low": "null"
}
]
}
],
"using": "gsi"
},
{
"#operator": "Fetch",
"keyspace": "test_bucket",
"namespace": "default"
},
{
"#operator": "Parallel",
"~child": {
"#operator": "Sequence",
"~children": [
{
"#operator": "Filter",
"condition": "(((`test_bucket`.`sort`) is valued) and (((`test_bucket`.`type`) = \"type1\") or ((`test_bucket`.`type`) = \"type2\")))"
},
{
"#operator": "InitialProject",
"discard_original": true,
"result_terms": [
{
"expr": "(meta(`test_bucket`).`id`)"
}
]
}
]
}
}
]
}
}