summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshutosh Bapat2013-02-21 09:49:53 +0000
committerAshutosh Bapat2013-02-21 09:49:53 +0000
commit8476398f0d8f2cfd869605acadfd380aea37287b (patch)
treeae77ce4a6b67997bdd516b4dc4a8cd76c7652b90
parent194f26c762b1e7c081a9c6742e6727d61c9d5f8a (diff)
Refactor GetRelationNodes with following changes
1. Instead of using lappend(NULL, ...) or list_concat(NULL, ...) use list_make1_int() and list_copy resp. 2. For replicated nodes, return all the nodes for read access. While finalising the RemoteQuery plans, one of the nodes (preferably preferred one) is picked from the list of nodes. 3. Remote LOCATOR_TYPE_SINGLE; there is no clue why this locator was added and it's not used anywhere.
-rw-r--r--src/backend/optimizer/path/pgxcpath.c15
-rw-r--r--src/backend/optimizer/util/pgxcship.c18
-rw-r--r--src/backend/pgxc/locator/locator.c96
-rw-r--r--src/include/pgxc/locator.h1
4 files changed, 31 insertions, 99 deletions
diff --git a/src/backend/optimizer/path/pgxcpath.c b/src/backend/optimizer/path/pgxcpath.c
index 6f12d0c7cf..00d90a5751 100644
--- a/src/backend/optimizer/path/pgxcpath.c
+++ b/src/backend/optimizer/path/pgxcpath.c
@@ -110,7 +110,6 @@ create_remotequery_path(PlannerInfo *root, RelOptInfo *rel, ExecNodes *exec_node
extern bool
create_plainrel_rqpath(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
{
- RelationLocInfo *rel_loc_info;
List *quals;
ExecNodes *exec_nodes;
@@ -122,26 +121,12 @@ create_plainrel_rqpath(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
if (!IS_PGXC_COORDINATOR || IsConnFromCoord() || root->parse->is_local)
return false;
- rel_loc_info = GetRelationLocInfo(rte->relid);
quals = extract_actual_clauses(rel->baserestrictinfo, false);
exec_nodes = GetRelationNodesByQuals(rte->relid, rel->relid,
(Node *)quals,
RELATION_ACCESS_READ);
if (!exec_nodes)
return false;
- /*
- * If the table is replicated, we need to get all the node, and let the
- * JOIN reduction pick up the appropriate.
- * PGXC_TODO: This code is duplicated in
- * pgxc_FQS_get_relation_nodes(). We need to move it inside
- * GetRelationNodes().
- * create_remotequery_plan would reduce the number of nodes to 1.
- */
- if (IsRelationReplicated(rel_loc_info))
- {
- list_free(exec_nodes->nodeList);
- exec_nodes->nodeList = list_copy(rel_loc_info->nodeList);
- }
/* We don't have subpaths for a plain base relation */
add_path(rel, (Path *)create_remotequery_path(root, rel, exec_nodes,
diff --git a/src/backend/optimizer/util/pgxcship.c b/src/backend/optimizer/util/pgxcship.c
index cd9cd86907..f83c0be16b 100644
--- a/src/backend/optimizer/util/pgxcship.c
+++ b/src/backend/optimizer/util/pgxcship.c
@@ -479,20 +479,8 @@ pgxc_FQS_get_relation_nodes(RangeTblEntry *rte, Index varno, Query *query)
if (!rel_exec_nodes)
return NULL;
- rel_exec_nodes->accesstype = rel_access;
- /*
- * If we are reading a replicated table, pick all the nodes where it
- * resides. If the query has JOIN, it helps picking up a matching set of
- * Datanodes for that JOIN. FQS planner will ultimately pick up one node if
- * the JOIN is replicated.
- */
- if (rel_access == RELATION_ACCESS_READ &&
- IsRelationReplicated(rel_loc_info))
- {
- list_free(rel_exec_nodes->nodeList);
- rel_exec_nodes->nodeList = list_copy(rel_loc_info->nodeList);
- }
- else if (rel_access == RELATION_ACCESS_INSERT &&
+
+ if (rel_access == RELATION_ACCESS_INSERT &&
IsRelationDistributedByValue(rel_loc_info))
{
ListCell *lc;
@@ -1778,7 +1766,6 @@ pgxc_check_index_shippability(RelationLocInfo *relLocInfo,
/* Those types are not supported yet */
case LOCATOR_TYPE_RANGE:
- case LOCATOR_TYPE_SINGLE:
case LOCATOR_TYPE_NONE:
case LOCATOR_TYPE_DISTRIBUTED:
case LOCATOR_TYPE_CUSTOM:
@@ -1897,7 +1884,6 @@ pgxc_check_fk_shippability(RelationLocInfo *parentLocInfo,
break;
case LOCATOR_TYPE_RANGE:
- case LOCATOR_TYPE_SINGLE:
case LOCATOR_TYPE_NONE:
case LOCATOR_TYPE_DISTRIBUTED:
case LOCATOR_TYPE_CUSTOM:
diff --git a/src/backend/pgxc/locator/locator.c b/src/backend/pgxc/locator/locator.c
index 0d5b633482..432ae502be 100644
--- a/src/backend/pgxc/locator/locator.c
+++ b/src/backend/pgxc/locator/locator.c
@@ -417,7 +417,6 @@ GetRelationNodes(RelationLocInfo *rel_loc_info, Datum valueForDistCol,
long hashValue;
int modulo;
int nodeIndex;
- int k;
if (rel_loc_info == NULL)
return NULL;
@@ -430,10 +429,18 @@ GetRelationNodes(RelationLocInfo *rel_loc_info, Datum valueForDistCol,
{
case LOCATOR_TYPE_REPLICATED:
+ /*
+ * When intention is to read from replicated table, return all the
+ * nodes so that planner can choose one depending upon the rest of
+ * the JOIN tree. But while reading with update lock, we need to
+ * read from the primary node (if exists) so as to avoid the
+ * deadlock.
+ * For write access set primary node (if exists).
+ */
+ exec_nodes->nodeList = list_copy(rel_loc_info->nodeList);
if (accessType == RELATION_ACCESS_UPDATE || accessType == RELATION_ACCESS_INSERT)
{
/* we need to write to all synchronously */
- exec_nodes->nodeList = list_concat(exec_nodes->nodeList, rel_loc_info->nodeList);
/*
* Write to primary node first, to reduce chance of a deadlock
@@ -443,57 +450,22 @@ GetRelationNodes(RelationLocInfo *rel_loc_info, Datum valueForDistCol,
&& exec_nodes->nodeList
&& list_length(exec_nodes->nodeList) > 1) /* make sure more than 1 */
{
- exec_nodes->primarynodelist = lappend_int(NULL,
- PGXCNodeGetNodeId(primary_data_node, PGXC_NODE_DATANODE));
- list_delete_int(exec_nodes->nodeList,
- PGXCNodeGetNodeId(primary_data_node, PGXC_NODE_DATANODE));
+ exec_nodes->primarynodelist = list_make1_int(PGXCNodeGetNodeId(primary_data_node,
+ PGXC_NODE_DATANODE));
+ exec_nodes->nodeList = list_delete_int(exec_nodes->nodeList,
+ PGXCNodeGetNodeId(primary_data_node,
+ PGXC_NODE_DATANODE));
}
}
- else
+ else if (accessType == RELATION_ACCESS_READ_FOR_UPDATE &&
+ IsTableDistOnPrimary(rel_loc_info))
{
/*
- * In case there are nodes defined in location info, initialize node list
- * with a default node being the first node in list.
- * This node list may be changed if a better one is found afterwards.
+ * We should ensure row is locked on the primary node to
+ * avoid distributed deadlock if updating the same row
+ * concurrently
*/
- if (rel_loc_info->nodeList)
- exec_nodes->nodeList = lappend_int(NULL,
- linitial_int(rel_loc_info->nodeList));
-
- if (accessType == RELATION_ACCESS_READ_FOR_UPDATE &&
- IsTableDistOnPrimary(rel_loc_info))
- {
- /*
- * We should ensure row is locked on the primary node to
- * avoid distributed deadlock if updating the same row
- * concurrently
- */
- exec_nodes->nodeList = lappend_int(NULL,
- PGXCNodeGetNodeId(primary_data_node, PGXC_NODE_DATANODE));
- }
- else if (num_preferred_data_nodes > 0)
- {
- ListCell *item;
-
- foreach(item, rel_loc_info->nodeList)
- {
- for (k = 0; k < num_preferred_data_nodes; k++)
- {
- if (PGXCNodeGetNodeId(preferred_data_node[k],
- PGXC_NODE_DATANODE) == lfirst_int(item))
- {
- exec_nodes->nodeList = lappend_int(NULL,
- lfirst_int(item));
- break;
- }
- }
- }
- }
-
- /* If nothing found just read from one of them. Use round robin mechanism */
- if (exec_nodes->nodeList == NULL)
- exec_nodes->nodeList = lappend_int(NULL,
- GetRoundRobinNode(rel_loc_info->relid));
+ exec_nodes->nodeList = list_make1_int(PGXCNodeGetNodeId(primary_data_node, PGXC_NODE_DATANODE));
}
break;
@@ -505,37 +477,27 @@ GetRelationNodes(RelationLocInfo *rel_loc_info, Datum valueForDistCol,
rel_loc_info->locatorType);
modulo = compute_modulo(abs(hashValue), list_length(rel_loc_info->nodeList));
nodeIndex = get_node_from_modulo(modulo, rel_loc_info->nodeList);
- exec_nodes->nodeList = lappend_int(NULL, nodeIndex);
+ exec_nodes->nodeList = list_make1_int(nodeIndex);
}
else
{
if (accessType == RELATION_ACCESS_INSERT)
/* Insert NULL to first node*/
- exec_nodes->nodeList = lappend_int(NULL, linitial_int(rel_loc_info->nodeList));
+ exec_nodes->nodeList = list_make1_int(linitial_int(rel_loc_info->nodeList));
else
- exec_nodes->nodeList = list_concat(exec_nodes->nodeList, rel_loc_info->nodeList);
+ exec_nodes->nodeList = list_copy(rel_loc_info->nodeList);
}
break;
- case LOCATOR_TYPE_SINGLE:
- /* just return first (there should only be one) */
- exec_nodes->nodeList = list_concat(exec_nodes->nodeList,
- rel_loc_info->nodeList);
- break;
-
case LOCATOR_TYPE_RROBIN:
- /* round robin, get next one */
+ /*
+ * round robin, get next one in case of insert. If not insert, all
+ * node needed
+ */
if (accessType == RELATION_ACCESS_INSERT)
- {
- /* write to just one of them */
- exec_nodes->nodeList = lappend_int(NULL, GetRoundRobinNode(rel_loc_info->relid));
- }
+ exec_nodes->nodeList = list_make1_int(GetRoundRobinNode(rel_loc_info->relid));
else
- {
- /* we need to read from all */
- exec_nodes->nodeList = list_concat(exec_nodes->nodeList,
- rel_loc_info->nodeList);
- }
+ exec_nodes->nodeList = list_copy(rel_loc_info->nodeList);
break;
/* PGXCTODO case LOCATOR_TYPE_RANGE: */
diff --git a/src/include/pgxc/locator.h b/src/include/pgxc/locator.h
index aaef9079ef..43ee425c25 100644
--- a/src/include/pgxc/locator.h
+++ b/src/include/pgxc/locator.h
@@ -16,7 +16,6 @@
#define LOCATOR_TYPE_REPLICATED 'R'
#define LOCATOR_TYPE_HASH 'H'
#define LOCATOR_TYPE_RANGE 'G'
-#define LOCATOR_TYPE_SINGLE 'S'
#define LOCATOR_TYPE_RROBIN 'N'
#define LOCATOR_TYPE_CUSTOM 'C'
#define LOCATOR_TYPE_MODULO 'M'