summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorMichael P2011-04-18 05:51:14 +0000
committerPavan Deolasee2011-05-24 10:33:29 +0000
commit57ff3183c379a4629b9d215731daf1bb84fdb36d (patch)
tree98fc87e860d162697be80faefc59211a0614696d /src/backend
parente389cedc177bd2f6c3192aa765477d9e9685b121 (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.c40
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))