diff options
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 123 |
1 files changed, 36 insertions, 87 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index aafa7b539ff..286ded8ef38 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.237 2008/01/01 19:45:50 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.238 2008/04/13 19:18:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -47,13 +47,12 @@ static Plan *create_unique_plan(PlannerInfo *root, UniquePath *best_path); static SeqScan *create_seqscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses); static IndexScan *create_indexscan_plan(PlannerInfo *root, IndexPath *best_path, - List *tlist, List *scan_clauses, - List **nonlossy_clauses); + List *tlist, List *scan_clauses); static BitmapHeapScan *create_bitmap_scan_plan(PlannerInfo *root, BitmapHeapPath *best_path, List *tlist, List *scan_clauses); static Plan *create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, - List **qual, List **indexqual); + List **qual); static TidScan *create_tidscan_plan(PlannerInfo *root, TidPath *best_path, List *tlist, List *scan_clauses); static SubqueryScan *create_subqueryscan_plan(PlannerInfo *root, Path *best_path, @@ -70,7 +69,6 @@ static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path, Plan *outer_plan, Plan *inner_plan); static void fix_indexqual_references(List *indexquals, IndexPath *index_path, List **fixed_indexquals, - List **nonlossy_indexquals, List **indexstrategy, List **indexsubtype); static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, @@ -239,8 +237,7 @@ create_scan_plan(PlannerInfo *root, Path *best_path) plan = (Plan *) create_indexscan_plan(root, (IndexPath *) best_path, tlist, - scan_clauses, - NULL); + scan_clauses); break; case T_BitmapHeapScan: @@ -840,16 +837,12 @@ create_seqscan_plan(PlannerInfo *root, Path *best_path, * The indexquals list of the path contains implicitly-ANDed qual conditions. * The list can be empty --- then no index restrictions will be applied during * the scan. - * - * If nonlossy_clauses isn't NULL, *nonlossy_clauses receives a list of the - * nonlossy indexquals. */ static IndexScan * create_indexscan_plan(PlannerInfo *root, IndexPath *best_path, List *tlist, - List *scan_clauses, - List **nonlossy_clauses) + List *scan_clauses) { List *indexquals = best_path->indexquals; Index baserelid = best_path->path.parent->relid; @@ -857,7 +850,6 @@ create_indexscan_plan(PlannerInfo *root, List *qpqual; List *stripped_indexquals; List *fixed_indexquals; - List *nonlossy_indexquals; List *indexstrategy; List *indexsubtype; ListCell *l; @@ -876,18 +868,13 @@ create_indexscan_plan(PlannerInfo *root, /* * The executor needs a copy with the indexkey on the left of each clause * and with index attr numbers substituted for table ones. This pass also - * gets strategy info and looks for "lossy" operators. + * gets strategy info. */ fix_indexqual_references(indexquals, best_path, &fixed_indexquals, - &nonlossy_indexquals, &indexstrategy, &indexsubtype); - /* pass back nonlossy quals if caller wants 'em */ - if (nonlossy_clauses) - *nonlossy_clauses = nonlossy_indexquals; - /* * If this is an innerjoin scan, the indexclauses will contain join * clauses that are not present in scan_clauses (since the passed-in value @@ -907,9 +894,8 @@ create_indexscan_plan(PlannerInfo *root, * by the index. All the predicates in the indexquals will be checked * (either by the index itself, or by nodeIndexscan.c), but if there are * any "special" operators involved then they must be included in qpqual. - * Also, any lossy index operators must be rechecked in the qpqual. The - * upshot is that qpqual must contain scan_clauses minus whatever appears - * in nonlossy_indexquals. + * The upshot is that qpqual must contain scan_clauses minus whatever + * appears in indexquals. * * In normal cases simple pointer equality checks will be enough to spot * duplicate RestrictInfos, so we try that first. In some situations @@ -932,13 +918,13 @@ create_indexscan_plan(PlannerInfo *root, Assert(IsA(rinfo, RestrictInfo)); if (rinfo->pseudoconstant) continue; /* we may drop pseudoconstants here */ - if (list_member_ptr(nonlossy_indexquals, rinfo)) + if (list_member_ptr(indexquals, rinfo)) continue; if (!contain_mutable_functions((Node *) rinfo->clause)) { List *clausel = list_make1(rinfo->clause); - if (predicate_implied_by(clausel, nonlossy_indexquals)) + if (predicate_implied_by(clausel, indexquals)) continue; if (best_path->indexinfo->indpred) { @@ -990,7 +976,6 @@ create_bitmap_scan_plan(PlannerInfo *root, Index baserelid = best_path->path.parent->relid; Plan *bitmapqualplan; List *bitmapqualorig; - List *indexquals; List *qpqual; ListCell *l; BitmapHeapScan *scan_plan; @@ -999,9 +984,9 @@ create_bitmap_scan_plan(PlannerInfo *root, Assert(baserelid > 0); Assert(best_path->path.parent->rtekind == RTE_RELATION); - /* Process the bitmapqual tree into a Plan tree and qual lists */ + /* Process the bitmapqual tree into a Plan tree and qual list */ bitmapqualplan = create_bitmap_subplan(root, best_path->bitmapqual, - &bitmapqualorig, &indexquals); + &bitmapqualorig); /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */ scan_clauses = extract_actual_clauses(scan_clauses, false); @@ -1023,9 +1008,9 @@ create_bitmap_scan_plan(PlannerInfo *root, * The qpqual list must contain all restrictions not automatically handled * by the index. All the predicates in the indexquals will be checked * (either by the index itself, or by nodeBitmapHeapscan.c), but if there - * are any "special" or lossy operators involved then they must be added - * to qpqual. The upshot is that qpqual must contain scan_clauses minus - * whatever appears in indexquals. + * are any "special" operators involved then they must be added to qpqual. + * The upshot is that qpqual must contain scan_clauses minus whatever + * appears in bitmapqualorig. * * In normal cases simple equal() checks will be enough to spot duplicate * clauses, so we try that first. In some situations (particularly with @@ -1037,22 +1022,22 @@ create_bitmap_scan_plan(PlannerInfo *root, * * Unlike create_indexscan_plan(), we need take no special thought here * for partial index predicates; this is because the predicate conditions - * are already listed in bitmapqualorig and indexquals. Bitmap scans have - * to do it that way because predicate conditions need to be rechecked if - * the scan becomes lossy. + * are already listed in bitmapqualorig. Bitmap scans have to do it that + * way because predicate conditions need to be rechecked if the scan's + * bitmap becomes lossy. */ qpqual = NIL; foreach(l, scan_clauses) { Node *clause = (Node *) lfirst(l); - if (list_member(indexquals, clause)) + if (list_member(bitmapqualorig, clause)) continue; if (!contain_mutable_functions(clause)) { List *clausel = list_make1(clause); - if (predicate_implied_by(clausel, indexquals)) + if (predicate_implied_by(clausel, bitmapqualorig)) continue; } qpqual = lappend(qpqual, clause); @@ -1062,7 +1047,7 @@ create_bitmap_scan_plan(PlannerInfo *root, qpqual = order_qual_clauses(root, qpqual); /* - * When dealing with special or lossy operators, we will at this point + * When dealing with special operators, we will at this point * have duplicate clauses in qpqual and bitmapqualorig. We may as well * drop 'em from bitmapqualorig, since there's no point in making the * tests twice. @@ -1086,19 +1071,19 @@ create_bitmap_scan_plan(PlannerInfo *root, /* * Given a bitmapqual tree, generate the Plan tree that implements it * - * As byproducts, we also return in *qual and *indexqual the qual lists - * (in implicit-AND form, without RestrictInfos) describing the original index - * conditions and the generated indexqual conditions. The latter is made to - * exclude lossy index operators. Both lists include partial-index predicates, - * because we have to recheck predicates as well as index conditions if the - * bitmap scan becomes lossy. + * As a byproduct, we also return in *qual a qual list (in implicit-AND + * form, without RestrictInfos) describing the generated indexqual + * conditions, as needed for rechecking heap tuples in lossy cases. + * This list also includes partial-index predicates, because we have to + * recheck predicates as well as index conditions if the scan's bitmap + * becomes lossy. * * Note: if you find yourself changing this, you probably need to change * make_restrictinfo_from_bitmapqual too. */ static Plan * create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, - List **qual, List **indexqual) + List **qual) { Plan *plan; @@ -1107,7 +1092,6 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, BitmapAndPath *apath = (BitmapAndPath *) bitmapqual; List *subplans = NIL; List *subquals = NIL; - List *subindexquals = NIL; ListCell *l; /* @@ -1121,13 +1105,11 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, { Plan *subplan; List *subqual; - List *subindexqual; subplan = create_bitmap_subplan(root, (Path *) lfirst(l), - &subqual, &subindexqual); + &subqual); subplans = lappend(subplans, subplan); subquals = list_concat_unique(subquals, subqual); - subindexquals = list_concat_unique(subindexquals, subindexqual); } plan = (Plan *) make_bitmap_and(subplans); plan->startup_cost = apath->path.startup_cost; @@ -1136,16 +1118,13 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, clamp_row_est(apath->bitmapselectivity * apath->path.parent->tuples); plan->plan_width = 0; /* meaningless */ *qual = subquals; - *indexqual = subindexquals; } else if (IsA(bitmapqual, BitmapOrPath)) { BitmapOrPath *opath = (BitmapOrPath *) bitmapqual; List *subplans = NIL; List *subquals = NIL; - List *subindexquals = NIL; bool const_true_subqual = false; - bool const_true_subindexqual = false; ListCell *l; /* @@ -1161,21 +1140,15 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, { Plan *subplan; List *subqual; - List *subindexqual; subplan = create_bitmap_subplan(root, (Path *) lfirst(l), - &subqual, &subindexqual); + &subqual); subplans = lappend(subplans, subplan); if (subqual == NIL) const_true_subqual = true; else if (!const_true_subqual) subquals = lappend(subquals, make_ands_explicit(subqual)); - if (subindexqual == NIL) - const_true_subindexqual = true; - else if (!const_true_subindexqual) - subindexquals = lappend(subindexquals, - make_ands_explicit(subindexqual)); } /* @@ -1207,23 +1180,15 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, *qual = subquals; else *qual = list_make1(make_orclause(subquals)); - if (const_true_subindexqual) - *indexqual = NIL; - else if (list_length(subindexquals) <= 1) - *indexqual = subindexquals; - else - *indexqual = list_make1(make_orclause(subindexquals)); } else if (IsA(bitmapqual, IndexPath)) { IndexPath *ipath = (IndexPath *) bitmapqual; IndexScan *iscan; - List *nonlossy_clauses; ListCell *l; /* Use the regular indexscan plan build machinery... */ - iscan = create_indexscan_plan(root, ipath, NIL, NIL, - &nonlossy_clauses); + iscan = create_indexscan_plan(root, ipath, NIL, NIL); /* then convert to a bitmap indexscan */ plan = (Plan *) make_bitmap_indexscan(iscan->scan.scanrelid, iscan->indexid, @@ -1237,7 +1202,6 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, clamp_row_est(ipath->indexselectivity * ipath->path.parent->tuples); plan->plan_width = 0; /* meaningless */ *qual = get_actual_clauses(ipath->indexclauses); - *indexqual = get_actual_clauses(nonlossy_clauses); foreach(l, ipath->indexinfo->indpred) { Expr *pred = (Expr *) lfirst(l); @@ -1249,10 +1213,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, * generating redundant conditions. */ if (!predicate_implied_by(list_make1(pred), ipath->indexclauses)) - { *qual = lappend(*qual, pred); - *indexqual = lappend(*indexqual, pred); - } } } else @@ -1794,9 +1755,9 @@ create_hashjoin_plan(PlannerInfo *root, /* * fix_indexqual_references * Adjust indexqual clauses to the form the executor's indexqual - * machinery needs, and check for recheckable (lossy) index conditions. + * machinery needs. * - * We have five tasks here: + * We have four tasks here: * * Remove RestrictInfo nodes from the input clauses. * * Index keys must be represented by Var nodes with varattno set to the * index's attribute number, not the attribute number in the original rel. @@ -1804,24 +1765,18 @@ create_hashjoin_plan(PlannerInfo *root, * left. * * We must construct lists of operator strategy numbers and subtypes * for the top-level operators of each index clause. - * * We must detect any lossy index operators. The API is that we return - * a list of the input clauses whose operators are NOT lossy. * * fixed_indexquals receives a modified copy of the indexquals list --- the * original is not changed. Note also that the copy shares no substructure * with the original; this is needed in case there is a subplan in it (we need * two separate copies of the subplan tree, or things will go awry). * - * nonlossy_indexquals receives a list of the original input clauses (with - * RestrictInfos) that contain non-lossy operators. - * * indexstrategy receives an integer list of strategy numbers. * indexsubtype receives an OID list of strategy subtypes. */ static void fix_indexqual_references(List *indexquals, IndexPath *index_path, List **fixed_indexquals, - List **nonlossy_indexquals, List **indexstrategy, List **indexsubtype) { @@ -1829,7 +1784,6 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, ListCell *l; *fixed_indexquals = NIL; - *nonlossy_indexquals = NIL; *indexstrategy = NIL; *indexsubtype = NIL; @@ -1837,7 +1791,7 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, * For each qual clause, commute if needed to put the indexkey operand on * the left, and then fix its varattno. (We do not need to change the * other side of the clause.) Then determine the operator's strategy - * number and subtype number, and check for lossy index behavior. + * number and subtype number. */ foreach(l, indexquals) { @@ -1848,7 +1802,6 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, int stratno; Oid stratlefttype; Oid stratrighttype; - bool recheck; bool is_null_op = false; Assert(IsA(rinfo, RestrictInfo)); @@ -1961,8 +1914,6 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, /* IS NULL doesn't have a clause_op */ stratno = InvalidStrategy; stratrighttype = InvalidOid; - /* We assume it's non-lossy ... might need more work someday */ - recheck = false; } else { @@ -1971,6 +1922,8 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, * to get its strategy number and the recheck indicator. This also * double-checks that we found an operator matching the index. */ + bool recheck; + get_op_opfamily_properties(clause_op, opfamily, &stratno, &stratlefttype, @@ -1980,10 +1933,6 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, *indexstrategy = lappend_int(*indexstrategy, stratno); *indexsubtype = lappend_oid(*indexsubtype, stratrighttype); - - /* If it's not lossy, add to nonlossy_indexquals */ - if (!recheck) - *nonlossy_indexquals = lappend(*nonlossy_indexquals, rinfo); } } |