diff options
Diffstat (limited to 'src/backend/optimizer/path/indxpath.c')
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index ece326d8850..940efb38b66 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -48,9 +48,9 @@ /* Whether to use ScalarArrayOpExpr to build index qualifications */ typedef enum { - SAOP_FORBID, /* Do not use ScalarArrayOpExpr */ - SAOP_ALLOW, /* OK to use ScalarArrayOpExpr */ - SAOP_REQUIRE /* Require ScalarArrayOpExpr */ + SAOP_PER_AM, /* Use ScalarArrayOpExpr if amsearcharray */ + SAOP_ALLOW, /* Use ScalarArrayOpExpr for all indexes */ + SAOP_REQUIRE /* Require ScalarArrayOpExpr to be used */ } SaOpControl; /* Whether we are looking for plain indexscan, bitmap scan, or either */ @@ -196,7 +196,7 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel) */ indexpaths = find_usable_indexes(root, rel, rel->baserestrictinfo, NIL, - true, NULL, SAOP_FORBID, ST_ANYSCAN); + true, NULL, SAOP_PER_AM, ST_ANYSCAN); /* * Submit all the ones that can form plain IndexScan plans to add_path. @@ -233,8 +233,9 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel) bitindexpaths = list_concat(bitindexpaths, indexpaths); /* - * Likewise, generate paths using ScalarArrayOpExpr clauses; these can't - * be simple indexscans but they can be used in bitmap scans. + * Likewise, generate paths using executor-managed ScalarArrayOpExpr + * clauses; these can't be simple indexscans but they can be used in + * bitmap scans. */ indexpaths = find_saop_paths(root, rel, rel->baserestrictinfo, NIL, @@ -338,6 +339,14 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel, } /* + * If we're doing find_saop_paths(), we can skip indexes that support + * ScalarArrayOpExpr natively. We already generated all the potential + * indexpaths for them, so no need to do anything more. + */ + if (saop_control == SAOP_REQUIRE && index->amsearcharray) + continue; + + /* * Ignore partial indexes that do not match the query. If a partial * index is marked predOK then we know it's OK; otherwise, if we are * at top level we know it's not OK (since predOK is exactly whether @@ -492,10 +501,10 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel, /* * find_saop_paths - * Find all the potential indexpaths that make use of ScalarArrayOpExpr - * clauses. The executor only supports these in bitmap scans, not - * plain indexscans, so we need to segregate them from the normal case. - * Otherwise, same API as find_usable_indexes(). + * Find all the potential indexpaths that make use of executor-managed + * ScalarArrayOpExpr clauses. The executor only supports these in bitmap + * scans, not plain indexscans, so we need to segregate them from the + * normal case. Otherwise, same API as find_usable_indexes(). * Returns a list of IndexPaths. */ static List * @@ -1287,9 +1296,10 @@ group_clauses_by_indexkey(IndexOptInfo *index, * expand_indexqual_rowcompare(). * * It is also possible to match ScalarArrayOpExpr clauses to indexes, when - * the clause is of the form "indexkey op ANY (arrayconst)". Since the - * executor can only handle these in the context of bitmap index scans, - * our caller specifies whether to allow these or not. + * the clause is of the form "indexkey op ANY (arrayconst)". Since not + * all indexes handle these natively, and the executor implements them + * only in the context of bitmap index scans, our caller specifies whether + * to allow these or not. * * For boolean indexes, it is also possible to match the clause directly * to the indexkey; or perhaps the clause is (NOT indexkey). @@ -1357,8 +1367,8 @@ match_clause_to_indexcol(IndexOptInfo *index, expr_coll = ((OpExpr *) clause)->inputcollid; plain_op = true; } - else if (saop_control != SAOP_FORBID && - clause && IsA(clause, ScalarArrayOpExpr)) + else if (clause && IsA(clause, ScalarArrayOpExpr) && + (index->amsearcharray || saop_control != SAOP_PER_AM)) { ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause; @@ -2089,12 +2099,12 @@ best_inner_indexscan(PlannerInfo *root, RelOptInfo *rel, /* * Find all the index paths that are usable for this join, except for - * stuff involving OR and ScalarArrayOpExpr clauses. + * stuff involving OR and executor-managed ScalarArrayOpExpr clauses. */ allindexpaths = find_usable_indexes(root, rel, clause_list, NIL, false, outer_rel, - SAOP_FORBID, + SAOP_PER_AM, ST_ANYSCAN); /* @@ -2123,8 +2133,9 @@ best_inner_indexscan(PlannerInfo *root, RelOptInfo *rel, outer_rel)); /* - * Likewise, generate paths using ScalarArrayOpExpr clauses; these can't - * be simple indexscans but they can be used in bitmap scans. + * Likewise, generate paths using executor-managed ScalarArrayOpExpr + * clauses; these can't be simple indexscans but they can be used in + * bitmap scans. */ bitindexpaths = list_concat(bitindexpaths, find_saop_paths(root, rel, |