summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/clausesel.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-11-25 19:47:50 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-11-25 19:47:50 +0000
commit290166f93404d8759f4bf60ef1732c8ba9a52785 (patch)
treeb7b9b00e3b3c1defea0e78b4f9b982e21963aa0f /src/backend/optimizer/path/clausesel.c
parentdab52ab13d3d3cce26e9bcc3193eb285c195d430 (diff)
Teach planner and executor to handle ScalarArrayOpExpr as an indexable
qualification when the underlying operator is indexable and useOr is true. That is, indexkey op ANY (ARRAY[...]) is effectively translated into an OR combination of one indexscan for each array element. This only works for bitmap index scans, of course, since regular indexscans no longer support OR'ing of scans. There are still some loose ends to clean up before changing 'x IN (list)' to translate as a ScalarArrayOpExpr; for instance predtest.c ought to be taught about it. But this gets the basic functionality in place.
Diffstat (limited to 'src/backend/optimizer/path/clausesel.c')
-rw-r--r--src/backend/optimizer/path/clausesel.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index 9a4990898e9..eba6bf1d148 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.75 2005/10/15 02:49:19 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.76 2005/11/25 19:47:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -624,12 +624,45 @@ clause_selectivity(PlannerInfo *root,
*/
s1 = (Selectivity) 0.5;
}
- else if (IsA(clause, DistinctExpr) ||
- IsA(clause, ScalarArrayOpExpr))
+ else if (IsA(clause, DistinctExpr))
{
/* can we do better? */
s1 = (Selectivity) 0.5;
}
+ else if (IsA(clause, ScalarArrayOpExpr))
+ {
+ /* First, decide if it's a join clause, same as for OpExpr */
+ bool is_join_clause;
+
+ if (varRelid != 0)
+ {
+ /*
+ * If we are considering a nestloop join then all clauses are
+ * restriction clauses, since we are only interested in the one
+ * relation.
+ */
+ is_join_clause = false;
+ }
+ else
+ {
+ /*
+ * Otherwise, it's a join if there's more than one relation used.
+ * We can optimize this calculation if an rinfo was passed.
+ */
+ if (rinfo)
+ is_join_clause = (bms_membership(rinfo->clause_relids) ==
+ BMS_MULTIPLE);
+ else
+ is_join_clause = (NumRelids(clause) > 1);
+ }
+
+ /* Use node specific selectivity calculation function */
+ s1 = scalararraysel(root,
+ (ScalarArrayOpExpr *) clause,
+ is_join_clause,
+ varRelid,
+ jointype);
+ }
else if (IsA(clause, NullTest))
{
/* Use node specific selectivity calculation function */