diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2013-03-21 19:43:59 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2013-03-21 19:44:32 -0400 |
commit | 9cbc4b80ddc10b36c64514104caa69747c386dcf (patch) | |
tree | 56ff643469573d7f83c9bbc89ab44b797ab988cd /src/backend/optimizer/path/equivclass.c | |
parent | 08af1a0a2ae8fbbd9949d9fa0f7583f6c09cf4ec (diff) |
Redo postgres_fdw's planner code so it can handle parameterized paths.
I wasn't going to ship this without having at least some example of how
to do that. This version isn't terribly bright; in particular it won't
consider any combinations of multiple join clauses. Given the cost of
executing a remote EXPLAIN, I'm not sure we want to be very aggressive
about doing that, anyway.
In support of this, refactor generate_implied_equalities_for_indexcol
so that it can be used to extract equivalence clauses that aren't
necessarily tied to an index.
Diffstat (limited to 'src/backend/optimizer/path/equivclass.c')
-rw-r--r-- | src/backend/optimizer/path/equivclass.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c index e2df448db6c..5c4ac066a52 100644 --- a/src/backend/optimizer/path/equivclass.c +++ b/src/backend/optimizer/path/equivclass.c @@ -512,7 +512,7 @@ add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids, * be more than one EC that matches the expression; if so it's order-dependent * which one you get. This is annoying but it only happens in corner cases, * so for now we live with just reporting the first match. See also - * generate_implied_equalities_for_indexcol and match_pathkeys_to_index.) + * generate_implied_equalities_for_column and match_pathkeys_to_index.) * * If create_it is TRUE, we'll build a new EquivalenceClass when there is no * match. If create_it is FALSE, we just return NULL when no match. @@ -2013,15 +2013,21 @@ mutate_eclass_expressions(PlannerInfo *root, /* - * generate_implied_equalities_for_indexcol - * Create EC-derived joinclauses usable with a specific index column. + * generate_implied_equalities_for_column + * Create EC-derived joinclauses usable with a specific column. * - * We assume that any given index column could appear in only one EC. + * This is used by indxpath.c to extract potentially indexable joinclauses + * from ECs, and can be used by foreign data wrappers for similar purposes. + * We assume that only expressions in Vars of a single table are of interest, + * but the caller provides a callback function to identify exactly which + * such expressions it would like to know about. + * + * We assume that any given table/index column could appear in only one EC. * (This should be true in all but the most pathological cases, and if it * isn't, we stop on the first match anyway.) Therefore, what we return - * is a redundant list of clauses equating the index column to each of + * is a redundant list of clauses equating the table/index column to each of * the other-relation values it is known to be equal to. Any one of - * these clauses can be used to create a parameterized indexscan, and there + * these clauses can be used to create a parameterized path, and there * is no value in using more than one. (But it *is* worthwhile to create * a separate parameterized path for each one, since that leads to different * join orders.) @@ -2030,13 +2036,13 @@ mutate_eclass_expressions(PlannerInfo *root, * to, so as to save the work of creating useless clauses. */ List * -generate_implied_equalities_for_indexcol(PlannerInfo *root, - IndexOptInfo *index, - int indexcol, - Relids prohibited_rels) +generate_implied_equalities_for_column(PlannerInfo *root, + RelOptInfo *rel, + ec_matches_callback_type callback, + void *callback_arg, + Relids prohibited_rels) { List *result = NIL; - RelOptInfo *rel = index->rel; bool is_child_rel = (rel->reloptkind == RELOPT_OTHER_MEMBER_REL); Index parent_relid; ListCell *lc1; @@ -2069,11 +2075,11 @@ generate_implied_equalities_for_indexcol(PlannerInfo *root, continue; /* - * Scan members, looking for a match to the indexable column. Note + * Scan members, looking for a match to the target column. Note * that child EC members are considered, but only when they belong to * the target relation. (Unlike regular members, the same expression * could be a child member of more than one EC. Therefore, it's - * potentially order-dependent which EC a child relation's index + * potentially order-dependent which EC a child relation's target * column gets matched to. This is annoying but it only happens in * corner cases, so for now we live with just reporting the first * match. See also get_eclass_for_sort_expr.) @@ -2083,8 +2089,7 @@ generate_implied_equalities_for_indexcol(PlannerInfo *root, { cur_em = (EquivalenceMember *) lfirst(lc2); if (bms_equal(cur_em->em_relids, rel->relids) && - eclass_member_matches_indexcol(cur_ec, cur_em, - index, indexcol)) + callback(root, rel, cur_ec, cur_em, callback_arg)) break; cur_em = NULL; } |