diff options
author | Michael P | 2012-01-10 03:05:43 +0000 |
---|---|---|
committer | Michael P | 2012-01-10 03:05:43 +0000 |
commit | 52d80a9ee69b94e7be5850a449b5ff9c041eea67 (patch) | |
tree | 0e2b83966633fcb4aefe58fda9593c7f8621232f /src | |
parent | c461c74182e6ca61f0c13779f1a3b821e111d888 (diff) |
Support for EXPLAIN with remote DML planning
When running an explain query with DML that need Coordinator to
be generated, additional remote query plans in ModifyTable are
printed. Those plans are created by create_remoteinsert_plan,
create_remoteupdate_plan and create_remotedelete_plan in createplan.c
This commit also includes a fix for remote DML plans related to the scan
relation ID used. The relation ID was used but the correct way is to
use its Index when referring to the table list in Scan plan.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/explain.c | 149 | ||||
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 11 |
2 files changed, 98 insertions, 62 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 31205fccdb..9c9dc9ed91 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -99,6 +99,10 @@ static void ExplainCloseGroup(const char *objtype, const char *labelname, bool labeled, ExplainState *es); static void ExplainDummyGroup(const char *objtype, const char *labelname, ExplainState *es); +#ifdef PGXC +static void ExplainExecNodes(ExecNodes *en, ExplainState *es); +static void ExplainRemoteQuery(RemoteQuery *plan, ExplainState *es); +#endif static void ExplainXMLTag(const char *tagname, int flags, ExplainState *es); static void ExplainJSONLineEnding(ExplainState *es); static void ExplainYAMLLineStarting(ExplainState *es); @@ -858,20 +862,8 @@ ExplainNode(PlanState *planstate, List *ancestors, break; #ifdef PGXC case T_RemoteQuery: - if (es->num_nodes) - { - ExecNodes *en = ((RemoteQuery *)plan)->exec_nodes; - int primary_node_count = en ? list_length(en->primarynodelist) : 0; - int node_count = en ? list_length(en->nodeList) : 0; - if (es->format == EXPLAIN_FORMAT_TEXT) - appendStringInfo(es->str, " (primary node count=%d, node count=%d)", - primary_node_count, node_count); - else - { - ExplainPropertyInteger("Primary node count", primary_node_count, es); - ExplainPropertyInteger("Node count", node_count, es); - } - } + /* Emit node execution list */ + ExplainExecNodes(((RemoteQuery *)plan)->exec_nodes, es); ExplainScanTarget((Scan *) plan, es); break; #endif @@ -1048,46 +1040,18 @@ ExplainNode(PlanState *planstate, List *ancestors, "Index Cond", planstate, ancestors, es); break; #ifdef PGXC - case T_RemoteQuery: + case T_ModifyTable: { - RemoteQuery *remote_query = (RemoteQuery *) plan; - /* add names of the nodes if they exist */ - if (remote_query->exec_nodes && es->nodes) - { - StringInfo node_names = makeStringInfo(); - ListCell *lcell; - char *sep; - int node_no; - if (remote_query->exec_nodes->primarynodelist) - { - sep = ""; - foreach(lcell, remote_query->exec_nodes->primarynodelist) - { - node_no = lfirst_int(lcell); - appendStringInfo(node_names, "%s%s", sep, - get_pgxc_nodename(PGXCNodeGetNodeOid(node_no, PGXC_NODE_DATANODE))); - sep = ", "; - } - ExplainPropertyText("Primary node/s", node_names->data, es); - } - if (remote_query->exec_nodes->nodeList) - { - resetStringInfo(node_names); - sep = ""; - foreach(lcell, remote_query->exec_nodes->nodeList) - { - node_no = lfirst_int(lcell); - appendStringInfo(node_names, "%s%s", sep, - get_pgxc_nodename(PGXCNodeGetNodeOid(node_no, PGXC_NODE_DATANODE))); - sep = ", "; - } - ExplainPropertyText("Node/s", node_names->data, es); - } - } + /* Remote query planning on DMLs */ + ModifyTable *mt = (ModifyTable *)plan; + ListCell *elt; + foreach(elt, mt->remote_plans) + ExplainRemoteQuery((RemoteQuery *) lfirst(elt), es); } - if (es->verbose) - ExplainPropertyText("Remote query", - ((RemoteQuery *)plan)->sql_statement, es); + break; + case T_RemoteQuery: + /* Remote query */ + ExplainRemoteQuery((RemoteQuery *)plan, es); show_scan_qual(plan->qual, "Coordinator quals", planstate, ancestors, es); break; #endif @@ -1637,8 +1601,7 @@ ExplainScanTarget(Scan *plan, ExplainState *es) { #ifdef PGXC if (plan->scanrelid <= 0 || - es->rtable == NULL || - plan->scanrelid > es->rtable->length) + list_length(es->rtable) == 0) return; #endif @@ -2210,6 +2173,84 @@ ExplainSeparatePlans(ExplainState *es) } } +#ifdef PGXC +/* + * Emit execution node list number. + */ +static void +ExplainExecNodes(ExecNodes *en, ExplainState *es) +{ + int primary_node_count = en ? list_length(en->primarynodelist) : 0; + int node_count = en ? list_length(en->nodeList) : 0; + + if (!es->num_nodes) + return; + + if (es->format == EXPLAIN_FORMAT_TEXT) + { + appendStringInfo(es->str, " (primary node count=%d, node count=%d)", + primary_node_count, node_count); + } + else + { + ExplainPropertyInteger("Primary node count", primary_node_count, es); + ExplainPropertyInteger("Node count", node_count, es); + } +} + +/* + * Emit remote query planning details + */ +static void +ExplainRemoteQuery(RemoteQuery *plan, ExplainState *es) +{ + /* Add names of the nodes if they exist */ + if (plan->exec_nodes && es->nodes) + { + StringInfo node_names = makeStringInfo(); + ListCell *lcell; + char *sep; + int node_no; + + /* Primary node(s) name(s) */ + if (plan->exec_nodes->primarynodelist) + { + sep = ""; + foreach(lcell, plan->exec_nodes->primarynodelist) + { + node_no = lfirst_int(lcell); + appendStringInfo(node_names, "%s%s", sep, + get_pgxc_nodename(PGXCNodeGetNodeOid(node_no, + PGXC_NODE_DATANODE))); + sep = ", "; + } + ExplainPropertyText("Primary node/s", node_names->data, es); + } + + /* Other node(s) name(s) */ + if (plan->exec_nodes->nodeList) + { + resetStringInfo(node_names); + sep = ""; + foreach(lcell, plan->exec_nodes->nodeList) + { + node_no = lfirst_int(lcell); + appendStringInfo(node_names, "%s%s", sep, + get_pgxc_nodename(PGXCNodeGetNodeOid(node_no, + PGXC_NODE_DATANODE))); + sep = ", "; + } + ExplainPropertyText("Node/s", node_names->data, es); + } + } + + /* Remote query statement */ + if (es->verbose) + ExplainPropertyText("Remote query", + plan->sql_statement, es); +} +#endif + /* * Emit opening or closing XML tag. * diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 8a57816bd8..e32a9b578e 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -5394,7 +5394,6 @@ create_remoteinsert_plan(PlannerInfo *root, Plan *topplan) Var *var; Oid *att_types; - ttab = rt_fetch(resultRelationIndex, root->parse->rtable); /* Bad relation ? */ @@ -5423,7 +5422,7 @@ create_remoteinsert_plan(PlannerInfo *root, Plan *topplan) appendStringInfo(buf, "INSERT INTO %s.%s (", quote_identifier(nspname), quote_identifier(ttab->relname)); - fstep = make_remotequery(NIL, ttab, NIL, ttab->relid); + fstep = make_remotequery(NIL, ttab, NIL, resultRelationIndex); fstep->is_temp = IsTempTable(ttab->relid); natts = get_relnatts(ttab->relid); @@ -5751,7 +5750,7 @@ create_remoteupdate_plan(PlannerInfo *root, Plan *topplan) appendStringInfo(buf, "%s", buf2->data); /* Finally build the final UPDATE step */ - fstep = make_remotequery(tlist, ttab, NIL, ttab->relid); + fstep = make_remotequery(tlist, ttab, NIL, resultRelationIndex); fstep->is_temp = IsTempTable(ttab->relid); fstep->sql_statement = pstrdup(buf->data); fstep->combine_type = COMBINE_TYPE_NONE; @@ -5761,8 +5760,6 @@ create_remoteupdate_plan(PlannerInfo *root, Plan *topplan) fstep->exec_nodes = GetRelationNodes(rel_loc_info, 0, UNKNOWNOID, RELATION_ACCESS_UPDATE); fstep->exec_nodes->baselocatortype = rel_loc_info->locatorType; fstep->exec_nodes->tableusagetype = TABLE_USAGE_TYPE_USER; - fstep->exec_nodes->primarynodelist = NULL; - fstep->exec_nodes->nodeList = NULL; fstep->exec_nodes->en_relid = ttab->relid; fstep->exec_nodes->accesstype = RELATION_ACCESS_UPDATE; SetRemoteStatementName((Plan *) fstep, NULL, natts + 1, att_types, 0); @@ -5870,7 +5867,7 @@ create_remotedelete_plan(PlannerInfo *root, Plan *topplan) } /* Finish by building the plan step */ - fstep = make_remotequery(parse->targetList, ttab, NIL, ttab->relid); + fstep = make_remotequery(parse->targetList, ttab, NIL, resultRelationIndex); fstep->is_temp = IsTempTable(ttab->relid); fstep->sql_statement = pstrdup(buf->data); fstep->combine_type = COMBINE_TYPE_NONE; @@ -5880,8 +5877,6 @@ create_remotedelete_plan(PlannerInfo *root, Plan *topplan) fstep->exec_nodes = GetRelationNodes(rel_loc_info, 0, UNKNOWNOID, RELATION_ACCESS_UPDATE); fstep->exec_nodes->baselocatortype = rel_loc_info->locatorType; fstep->exec_nodes->tableusagetype = TABLE_USAGE_TYPE_USER; - fstep->exec_nodes->primarynodelist = NULL; - fstep->exec_nodes->nodeList = NULL; fstep->exec_nodes->en_relid = ttab->relid; fstep->exec_nodes->accesstype = RELATION_ACCESS_UPDATE; SetRemoteStatementName((Plan *) fstep, NULL, nparams, param_types, 0); |