diff options
| author | Michael P | 2011-04-18 05:51:14 +0000 |
|---|---|---|
| committer | Pavan Deolasee | 2011-05-24 10:33:29 +0000 |
| commit | 57ff3183c379a4629b9d215731daf1bb84fdb36d (patch) | |
| tree | 98fc87e860d162697be80faefc59211a0614696d /src/backend | |
| parent | e389cedc177bd2f6c3192aa765477d9e9685b121 (diff) | |
Fix for bug 3167720: join optimizer error
When running a query on multiple tables, if a constant
expression was contained in WHERE clause, XC planner
examined the constant expression all the time and checked
if it was possible to avoid multiple node operation
if the constant expression depended on a distributed table.
This commits adds a check to verify in the case of multiple tables
used in FROM clause if query can be safely pushed down to one
target node on depending on the distribution type of each table.
If SELECT clause is used on one distributed table and several
replicated tables, this can be safely pushed down to a target node
but in the case of multiple distributed tables used, all the nodes
have to be targetted.
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/pgxc/plan/planner.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/backend/pgxc/plan/planner.c b/src/backend/pgxc/plan/planner.c index fc1ee04e76..d386ded941 100644 --- a/src/backend/pgxc/plan/planner.c +++ b/src/backend/pgxc/plan/planner.c @@ -1084,6 +1084,46 @@ examine_conditions_walker(Node *expr_node, XCWalkerContext *context) if (!rel_loc_info1) return true; + /* Check if this constant expression is targetting multiple tables */ + if (list_length(context->query->rtable) > 1) + { + ListCell *lc; + RangeTblEntry *save_rte = NULL; + RelationLocInfo *save_loc_info; + + foreach(lc, context->query->rtable) + { + RangeTblEntry *rte = lfirst(lc); + + if (!save_rte) + { + save_rte = rte; + save_loc_info = GetRelationLocInfo(save_rte->relid); + } + else + { + /* + * If there are two distributed tables at least + * among the multiple tables, push down the query to all nodes. + */ + if (save_rte->relid != rte->relid) + { + RelationLocInfo *loc_info = GetRelationLocInfo(rte->relid); + + if (loc_info->locatorType != LOCATOR_TYPE_REPLICATED && + save_loc_info->locatorType != LOCATOR_TYPE_REPLICATED) + return true; + if (loc_info->locatorType != LOCATOR_TYPE_REPLICATED && + save_loc_info->locatorType == LOCATOR_TYPE_REPLICATED) + { + save_rte = rte; + save_loc_info = loc_info; + } + } + } + } + } + /* If hash or modulo partitioned, check if the part column was used */ if (IsHashColumn(rel_loc_info1, column_base->colname) || IsModuloColumn(rel_loc_info1, column_base->colname)) |
