You can subscribe to this list here.
2010 |
Jan
|
Feb
|
Mar
|
Apr
(4) |
May
(28) |
Jun
(12) |
Jul
(11) |
Aug
(12) |
Sep
(5) |
Oct
(19) |
Nov
(14) |
Dec
(12) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2011 |
Jan
(18) |
Feb
(30) |
Mar
(115) |
Apr
(89) |
May
(50) |
Jun
(44) |
Jul
(22) |
Aug
(13) |
Sep
(11) |
Oct
(30) |
Nov
(28) |
Dec
(39) |
2012 |
Jan
(38) |
Feb
(18) |
Mar
(43) |
Apr
(91) |
May
(108) |
Jun
(46) |
Jul
(37) |
Aug
(44) |
Sep
(33) |
Oct
(29) |
Nov
(36) |
Dec
(15) |
2013 |
Jan
(35) |
Feb
(611) |
Mar
(5) |
Apr
(55) |
May
(30) |
Jun
(28) |
Jul
(458) |
Aug
(34) |
Sep
(9) |
Oct
(39) |
Nov
(22) |
Dec
(32) |
2014 |
Jan
(16) |
Feb
(16) |
Mar
(42) |
Apr
(179) |
May
(7) |
Jun
(6) |
Jul
(9) |
Aug
|
Sep
(4) |
Oct
|
Nov
(3) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
|
|
|
1
|
2
|
3
|
4
|
5
|
6
(1) |
7
|
8
|
9
|
10
|
11
|
12
|
13
|
14
(1) |
15
|
16
|
17
|
18
|
19
|
20
|
21
|
22
(1) |
23
|
24
|
25
|
26
(1) |
27
(1) |
28
|
29
|
30
|
|
|
From: mason_s <ma...@us...> - 2010-09-26 07:51:36
|
Project "Postgres-XC". The branch, master has been updated via c3e87d496dbf75651197f03b36d1cf0ba4ea7f0c (commit) from ac66a8c598dfc601e64df04dba73dc6d99f78272 (commit) - Log ----------------------------------------------------------------- commit c3e87d496dbf75651197f03b36d1cf0ba4ea7f0c Author: Mason Sharp <ma...@us...> Date: Sun Sep 26 16:47:36 2010 +0900 Initial support for cursors (DECLARE, FETCH). This initial version implements support by creating them on the Coordinator only; they are not created on the data nodes. Not yet supported is UPDATE / DELETE WHERE CURRENT OF, but basic read-only cursor capability works, including SCROLL cursors. Written by Andrei Martsinchyk diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c index eab1bd0..63031a7 100644 --- a/src/backend/access/common/heaptuple.c +++ b/src/backend/access/common/heaptuple.c @@ -1194,8 +1194,17 @@ slot_deform_datarow(TupleTableSlot *slot) errmsg("Tuple does not match the descriptor"))); if (slot->tts_attinmeta == NULL) + { + /* + * Ensure info about input functions is available as long as slot lives + */ + MemoryContext oldcontext = MemoryContextSwitchTo(slot->tts_mcxt); + slot->tts_attinmeta = TupleDescGetAttInMetadata(slot->tts_tupleDescriptor); + MemoryContextSwitchTo(oldcontext); + } + buffer = makeStringInfo(); for (i = 0; i < attnum; i++) { diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 657413a..772a6f7 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -847,7 +847,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString) int num_phys_attrs; uint64 processed; #ifdef PGXC - Exec_Nodes *exec_nodes = NULL; + ExecNodes *exec_nodes = NULL; #endif /* Allocate workspace and zero all fields */ @@ -1138,7 +1138,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString) { char *hash_att; - exec_nodes = (Exec_Nodes *) palloc0(sizeof(Exec_Nodes)); + exec_nodes = makeNode(ExecNodes); /* * If target table does not exists on nodes (e.g. system table) diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 151fe33..c58e2a0 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -25,6 +25,10 @@ #include "nodes/plannodes.h" #include "nodes/relation.h" +#ifdef PGXC +#include "pgxc/locator.h" +#include "pgxc/planner.h" +#endif #include "utils/datum.h" @@ -809,6 +813,124 @@ _copyPlanInvalItem(PlanInvalItem *from) return newnode; } +#ifdef PGXC +/* + * _copyRemoteQuery + */ +static RemoteQuery * +_copyRemoteQuery(RemoteQuery *from) +{ + RemoteQuery *newnode = makeNode(RemoteQuery); + + /* + * copy node superclass fields + */ + CopyScanFields((Scan *) from, (Scan *) newnode); + + /* + * copy remainder of node + */ + COPY_SCALAR_FIELD(is_single_step); + COPY_STRING_FIELD(sql_statement); + COPY_NODE_FIELD(exec_nodes); + COPY_SCALAR_FIELD(combine_type); + COPY_NODE_FIELD(simple_aggregates); + COPY_NODE_FIELD(sort); + COPY_NODE_FIELD(distinct); + COPY_SCALAR_FIELD(read_only); + COPY_SCALAR_FIELD(force_autocommit); + + return newnode; +} + +/* + * _copyExecNodes + */ +static ExecNodes * +_copyExecNodes(ExecNodes *from) +{ + ExecNodes *newnode = makeNode(ExecNodes); + + COPY_NODE_FIELD(primarynodelist); + COPY_NODE_FIELD(nodelist); + COPY_SCALAR_FIELD(baselocatortype); + COPY_SCALAR_FIELD(tableusagetype); + + return newnode; +} + +/* + * _copySimpleAgg + */ +static SimpleAgg * +_copySimpleAgg(SimpleAgg *from) +{ + SimpleAgg *newnode = makeNode(SimpleAgg); + + COPY_SCALAR_FIELD(column_pos); + COPY_NODE_FIELD(aggref); + COPY_SCALAR_FIELD(transfn_oid); + COPY_SCALAR_FIELD(finalfn_oid); + COPY_SCALAR_FIELD(arginputfn); + COPY_SCALAR_FIELD(argioparam); + COPY_SCALAR_FIELD(resoutputfn); + COPY_SCALAR_FIELD(transfn); + COPY_SCALAR_FIELD(finalfn); + if (!from->initValueIsNull) + newnode->initValue = datumCopy(from->initValue, from->transtypeByVal, + from->transtypeLen); + COPY_SCALAR_FIELD(initValueIsNull); + COPY_SCALAR_FIELD(inputtypeLen); + COPY_SCALAR_FIELD(resulttypeLen); + COPY_SCALAR_FIELD(transtypeLen); + COPY_SCALAR_FIELD(inputtypeByVal); + COPY_SCALAR_FIELD(resulttypeByVal); + COPY_SCALAR_FIELD(transtypeByVal); + /* No need to copy runtime info, just init */ + newnode->collectValueNull = true; + initStringInfo(&newnode->valuebuf); + + return newnode; +} + +/* + * _copySimpleSort + */ +static SimpleSort * +_copySimpleSort(SimpleSort *from) +{ + SimpleSort *newnode = makeNode(SimpleSort); + + COPY_SCALAR_FIELD(numCols); + if (from->numCols > 0) + { + COPY_POINTER_FIELD(sortColIdx, from->numCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(sortOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(nullsFirst, from->numCols * sizeof(bool)); + } + + return newnode; +} + +/* + * _copySimpleDistinct + */ +static SimpleDistinct * +_copySimpleDistinct(SimpleDistinct *from) +{ + SimpleDistinct *newnode = makeNode(SimpleDistinct); + + COPY_SCALAR_FIELD(numCols); + if (from->numCols > 0) + { + COPY_POINTER_FIELD(uniqColIdx, from->numCols * sizeof(AttrNumber)); + COPY_POINTER_FIELD(eqOperators, from->numCols * sizeof(Oid)); + } + + return newnode; +} +#endif + /* **************************************************************** * primnodes.h copy functions * **************************************************************** @@ -3554,7 +3676,26 @@ copyObject(void *from) case T_PlanInvalItem: retval = _copyPlanInvalItem(from); break; - +#ifdef PGXC + /* + * PGXC SPECIFIC NODES + */ + case T_RemoteQuery: + retval = _copyRemoteQuery(from); + break; + case T_ExecNodes: + retval = _copyExecNodes(from); + break; + case T_SimpleAgg: + retval = _copySimpleAgg(from); + break; + case T_SimpleSort: + retval = _copySimpleSort(from); + break; + case T_SimpleDistinct: + retval = _copySimpleDistinct(from); + break; +#endif /* * PRIMITIVE NODES */ diff --git a/src/backend/pgxc/locator/locator.c b/src/backend/pgxc/locator/locator.c index 63c6359..debbc77 100644 --- a/src/backend/pgxc/locator/locator.c +++ b/src/backend/pgxc/locator/locator.c @@ -279,18 +279,18 @@ GetRoundRobinNode(Oid relid) * * The returned List is a copy, so it should be freed when finished. */ -Exec_Nodes * +ExecNodes * GetRelationNodes(RelationLocInfo *rel_loc_info, long *partValue, int isRead) { ListCell *prefItem; ListCell *stepItem; - Exec_Nodes *exec_nodes; + ExecNodes *exec_nodes; if (rel_loc_info == NULL) return NULL; - exec_nodes = (Exec_Nodes *) palloc0(sizeof(Exec_Nodes)); + exec_nodes = makeNode(ExecNodes); exec_nodes->baselocatortype = rel_loc_info->locatorType; switch (rel_loc_info->locatorType) diff --git a/src/backend/pgxc/plan/planner.c b/src/backend/pgxc/plan/planner.c index 7fedbfb..a7bc0ab 100644 --- a/src/backend/pgxc/plan/planner.c +++ b/src/backend/pgxc/plan/planner.c @@ -20,6 +20,7 @@ #include "catalog/pg_namespace.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" +#include "executor/executor.h" #include "lib/stringinfo.h" #include "nodes/nodeFuncs.h" #include "nodes/nodes.h" @@ -120,7 +121,7 @@ typedef struct XCWalkerContext { Query *query; bool isRead; - Exec_Nodes *exec_nodes; /* resulting execution nodes */ + ExecNodes *exec_nodes; /* resulting execution nodes */ Special_Conditions *conditions; bool multilevel_join; List *rtables; /* a pointer to a list of rtables */ @@ -139,7 +140,7 @@ bool StrictStatementChecking = true; bool StrictSelectChecking = false; -static Exec_Nodes *get_plan_nodes(Query *query, bool isRead); +static ExecNodes *get_plan_nodes(Query *query, bool isRead); static bool get_plan_nodes_walker(Node *query_node, XCWalkerContext *context); static bool examine_conditions_walker(Node *expr_node, XCWalkerContext *context); static int handle_limit_offset(RemoteQuery *query_step, Query *query, PlannedStmt *plan_stmt); @@ -402,13 +403,13 @@ get_base_var(Var *var, XCWalkerContext *context) /* * get_plan_nodes_insert - determine nodes on which to execute insert. */ -static Exec_Nodes * +static ExecNodes * get_plan_nodes_insert(Query *query) { RangeTblEntry *rte; RelationLocInfo *rel_loc_info; Const *constant; - Exec_Nodes *exec_nodes; + ExecNodes *exec_nodes; ListCell *lc; long part_value; long *part_value_ptr = NULL; @@ -786,7 +787,7 @@ examine_conditions_walker(Node *expr_node, XCWalkerContext *context) bool is_multilevel; int save_parent_child_count = 0; SubLink *sublink = (SubLink *) expr_node; - Exec_Nodes *save_exec_nodes = context->exec_nodes; /* Save old exec_nodes */ + ExecNodes *save_exec_nodes = context->exec_nodes; /* Save old exec_nodes */ /* save parent-child count */ if (context->exec_nodes) @@ -940,9 +941,9 @@ get_plan_nodes_walker(Node *query_node, XCWalkerContext *context) ListCell *lc, *item; RelationLocInfo *rel_loc_info; - Exec_Nodes *test_exec_nodes = NULL; - Exec_Nodes *current_nodes = NULL; - Exec_Nodes *from_query_nodes = NULL; + ExecNodes *test_exec_nodes = NULL; + ExecNodes *current_nodes = NULL; + ExecNodes *from_query_nodes = NULL; TableUsageType table_usage_type = TABLE_USAGE_TYPE_NO_TABLE; TableUsageType current_usage_type = TABLE_USAGE_TYPE_NO_TABLE; int from_subquery_count = 0; @@ -972,7 +973,7 @@ get_plan_nodes_walker(Node *query_node, XCWalkerContext *context) if (contains_only_pg_catalog (query->rtable)) { /* just pg_catalog tables */ - context->exec_nodes = (Exec_Nodes *) palloc0(sizeof(Exec_Nodes)); + context->exec_nodes = makeNode(ExecNodes); context->exec_nodes->tableusagetype = TABLE_USAGE_TYPE_PGCATALOG; context->exec_on_coord = true; return false; @@ -991,7 +992,7 @@ get_plan_nodes_walker(Node *query_node, XCWalkerContext *context) if (rte->rtekind == RTE_SUBQUERY) { - Exec_Nodes *save_exec_nodes = context->exec_nodes; + ExecNodes *save_exec_nodes = context->exec_nodes; Special_Conditions *save_conditions = context->conditions; /* Save old conditions */ List *current_rtable = rte->subquery->rtable; @@ -1089,7 +1090,7 @@ get_plan_nodes_walker(Node *query_node, XCWalkerContext *context) /* If we are just dealing with pg_catalog, just return */ if (table_usage_type == TABLE_USAGE_TYPE_PGCATALOG) { - context->exec_nodes = (Exec_Nodes *) palloc0(sizeof(Exec_Nodes)); + context->exec_nodes = makeNode(ExecNodes); context->exec_nodes->tableusagetype = TABLE_USAGE_TYPE_PGCATALOG; context->exec_on_coord = true; return false; @@ -1255,10 +1256,10 @@ get_plan_nodes_walker(Node *query_node, XCWalkerContext *context) * Top level entry point before walking query to determine plan nodes * */ -static Exec_Nodes * +static ExecNodes * get_plan_nodes(Query *query, bool isRead) { - Exec_Nodes *result_nodes = NULL; + ExecNodes *result_nodes = NULL; XCWalkerContext context; @@ -1293,10 +1294,10 @@ get_plan_nodes(Query *query, bool isRead) * * return NULL if it is not safe to be done in a single step. */ -static Exec_Nodes * +static ExecNodes * get_plan_nodes_command(Query *query) { - Exec_Nodes *exec_nodes = NULL; + ExecNodes *exec_nodes = NULL; switch (query->commandType) { @@ -1384,7 +1385,7 @@ get_simple_aggregates(Query * query) *finalfnexpr; Datum textInitVal; - simple_agg = (SimpleAgg *) palloc0(sizeof(SimpleAgg)); + simple_agg = makeNode(SimpleAgg); simple_agg->column_pos = column_pos; initStringInfo(&simple_agg->valuebuf); simple_agg->aggref = aggref; @@ -1759,7 +1760,7 @@ make_simple_sort_from_sortclauses(Query *query, RemoteQuery *step) nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool)); numsortkeys = 0; - sort = (SimpleSort *) palloc(sizeof(SimpleSort)); + sort = makeNode(SimpleSort); if (sortcls) { @@ -1908,7 +1909,7 @@ make_simple_sort_from_sortclauses(Query *query, RemoteQuery *step) * extra_distincts list */ - distinct = (SimpleDistinct *) palloc(sizeof(SimpleDistinct)); + distinct = makeNode(SimpleDistinct); /* * We will need at most list_length(distinctcls) sort columns @@ -2093,12 +2094,50 @@ pgxc_planner(Query *query, int cursorOptions, ParamListInfo boundParams) query_step = makeNode(RemoteQuery); query_step->is_single_step = false; - query_step->sql_statement = pstrdup(query->sql_statement); + /* + * Declare Cursor case: + * We should leave as a step query only SELECT statement + * Further if we need refer source statement for planning we should take + * the truncated string + */ + if (query->utilityStmt && + IsA(query->utilityStmt, DeclareCursorStmt)) + { + + char *src = query->sql_statement; + char str[strlen(src) + 1]; /* mutable copy */ + char *dst = str; + + cursorOptions |= ((DeclareCursorStmt *) query->utilityStmt)->options; + + /* + * Initialize mutable copy, converting letters to uppercase and + * various witespace characters to spaces + */ + while (*src) + { + if (isspace(*src)) + { + src++; + *dst++ = ' '; + } + else + *dst++ = toupper(*src++); + } + *dst = '\0'; + /* search for SELECT keyword in the normalized string */ + dst = strstr(str, " SELECT "); + /* Take substring of the original string using found offset */ + query_step->sql_statement = pstrdup(query->sql_statement + (dst - str + 1)); + } + else + query_step->sql_statement = pstrdup(query->sql_statement); + query_step->exec_nodes = NULL; query_step->combine_type = COMBINE_TYPE_NONE; query_step->simple_aggregates = NULL; /* Optimize multi-node handling */ - query_step->read_only = query->nodeTag == T_SelectStmt; + query_step->read_only = query->commandType == CMD_SELECT; query_step->force_autocommit = false; result->planTree = (Plan *) query_step; @@ -2108,20 +2147,20 @@ pgxc_planner(Query *query, int cursorOptions, ParamListInfo boundParams) * level, Data Nodes, or both. By default we choose both. We should be * able to quickly expand this for more commands. */ - switch (query->nodeTag) + switch (query->commandType) { - case T_SelectStmt: + case CMD_SELECT: /* Perform some checks to make sure we can support the statement */ if (query->intoClause) ereport(ERROR, (errcode(ERRCODE_STATEMENT_TOO_COMPLEX), (errmsg("INTO clause not yet supported")))); /* fallthru */ - case T_InsertStmt: - case T_UpdateStmt: - case T_DeleteStmt: + case CMD_INSERT: + case CMD_UPDATE: + case CMD_DELETE: /* Set result relations */ - if (query->nodeTag != T_SelectStmt) + if (query->commandType != CMD_SELECT) result->resultRelations = list_make1_int(query->resultRelation); query_step->exec_nodes = get_plan_nodes_command(query); @@ -2129,7 +2168,7 @@ pgxc_planner(Query *query, int cursorOptions, ParamListInfo boundParams) if (query_step->exec_nodes == NULL) { /* Do not yet allow multi-node correlated UPDATE or DELETE */ - if ((query->nodeTag == T_UpdateStmt || query->nodeTag == T_DeleteStmt)) + if (query->commandType == CMD_UPDATE || query->commandType == CMD_DELETE) { ereport(ERROR, (errcode(ERRCODE_STATEMENT_TOO_COMPLEX), @@ -2144,15 +2183,16 @@ pgxc_planner(Query *query, int cursorOptions, ParamListInfo boundParams) return result; } - if ((query->nodeTag == T_UpdateStmt || query->nodeTag == T_DeleteStmt) + /* Do not yet allow multi-node correlated UPDATE or DELETE */ + if ((query->commandType == CMD_UPDATE || query->commandType == CMD_DELETE) && !query_step->exec_nodes && list_length(query->rtable) > 1) { - result = standard_planner(query, cursorOptions, boundParams); - return result; + result = standard_planner(query, cursorOptions, boundParams); + return result; } - /* + /* * Use standard plan if we have more than one data node with either * group by, hasWindowFuncs, or hasRecursive */ @@ -2161,13 +2201,13 @@ pgxc_planner(Query *query, int cursorOptions, ParamListInfo boundParams) * group by expression is the partitioning column, in which * case it is ok to treat as a single step. */ - if (query->nodeTag == T_SelectStmt + if (query->commandType == CMD_SELECT && query_step->exec_nodes && list_length(query_step->exec_nodes->nodelist) > 1 && (query->groupClause || query->hasWindowFuncs || query->hasRecursive)) { - result = standard_planner(query, cursorOptions, boundParams); - return result; + result = standard_planner(query, cursorOptions, boundParams); + return result; } query_step->is_single_step = true; @@ -2191,9 +2231,9 @@ pgxc_planner(Query *query, int cursorOptions, ParamListInfo boundParams) query, query_step->exec_nodes->baselocatortype); /* Set up simple aggregates */ - /* PGXCTODO - we should detect what types of aggregates are used. + /* PGXCTODO - we should detect what types of aggregates are used. * in some cases we can avoid the final step and merely proxy results - * (when there is only one data node involved) instead of using + * (when there is only one data node involved) instead of using * coordinator consolidation. At the moment this is needed for AVG() */ query_step->simple_aggregates = get_simple_aggregates(query); @@ -2224,6 +2264,16 @@ pgxc_planner(Query *query, int cursorOptions, ParamListInfo boundParams) result->planTree = standardPlan; } + /* + * If creating a plan for a scrollable cursor, make sure it can run + * backwards on demand. Add a Material node at the top at need. + */ + if (cursorOptions & CURSOR_OPT_SCROLL) + { + if (!ExecSupportsBackwardScan(result->planTree)) + result->planTree = materialize_finished_plan(result->planTree); + } + return result; } diff --git a/src/backend/pgxc/pool/execRemote.c b/src/backend/pgxc/pool/execRemote.c index e7ac601..16d2f6b 100644 --- a/src/backend/pgxc/pool/execRemote.c +++ b/src/backend/pgxc/pool/execRemote.c @@ -1990,7 +1990,7 @@ DataNodeCopyBegin(const char *query, List *nodelist, Snapshot snapshot, bool is_ * Send a data row to the specified nodes */ int -DataNodeCopyIn(char *data_row, int len, Exec_Nodes *exec_nodes, DataNodeHandle** copy_connections) +DataNodeCopyIn(char *data_row, int len, ExecNodes *exec_nodes, DataNodeHandle** copy_connections) { DataNodeHandle *primary_handle = NULL; ListCell *nodeitem; @@ -2143,7 +2143,7 @@ DataNodeCopyIn(char *data_row, int len, Exec_Nodes *exec_nodes, DataNodeHandle** } uint64 -DataNodeCopyOut(Exec_Nodes *exec_nodes, DataNodeHandle** copy_connections, FILE* copy_file) +DataNodeCopyOut(ExecNodes *exec_nodes, DataNodeHandle** copy_connections, FILE* copy_file) { RemoteQueryState *combiner; int conn_count = list_length(exec_nodes->nodelist) == 0 ? NumDataNodes : list_length(exec_nodes->nodelist); @@ -2436,7 +2436,7 @@ copy_slot(RemoteQueryState *node, TupleTableSlot *src, TupleTableSlot *dst) } static void -get_exec_connections(Exec_Nodes *exec_nodes, +get_exec_connections(ExecNodes *exec_nodes, int *regular_conn_count, int *total_conn_count, DataNodeHandle ***connections, diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 84c70c6..528e4e1 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -658,7 +658,6 @@ pg_analyze_and_rewrite(Node *parsetree, const char *query_string, { Query *query = (Query *) lfirst(lc); query->sql_statement = pstrdup(query_string); - query->nodeTag = nodeTag(parsetree); } } #endif @@ -1318,7 +1317,6 @@ exec_parse_message(const char *query_string, /* string to execute */ { Query *query = (Query *) lfirst(lc); query->sql_statement = pstrdup(query_string); - query->nodeTag = nodeTag(raw_parse_tree); } } #endif diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 91456c4..db11abe 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -62,7 +62,7 @@ #include "pgxc/pgxc.h" #include "pgxc/planner.h" -static void ExecUtilityStmtOnNodes(const char *queryString, Exec_Nodes *nodes, +static void ExecUtilityStmtOnNodes(const char *queryString, ExecNodes *nodes, bool force_autocommit); #endif @@ -1367,7 +1367,7 @@ ProcessUtility(Node *parsetree, #ifdef PGXC static void -ExecUtilityStmtOnNodes(const char *queryString, Exec_Nodes *nodes, +ExecUtilityStmtOnNodes(const char *queryString, ExecNodes *nodes, bool force_autocommit) { RemoteQuery *step = makeNode(RemoteQuery); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index a466239..8bb49c6 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -73,6 +73,13 @@ typedef enum NodeTag T_SetOp, T_Limit, #ifdef PGXC + /* + * TAGS FOR PGXC NODES (planner.h, locator.h) + */ + T_ExecNodes, + T_SimpleAgg, + T_SimpleSort, + T_SimpleDistinct, T_RemoteQuery, #endif /* this one isn't a subclass of Plan: */ diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index a367a6b..5fb2a2b 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -149,7 +149,6 @@ typedef struct Query #ifdef PGXC /* need this info for PGXC Planner, may be temporary */ char *sql_statement; /* original query */ - NodeTag nodeTag; /* node tag of top node of parse tree */ #endif } Query; diff --git a/src/include/pgxc/execRemote.h b/src/include/pgxc/execRemote.h index e2aebef..5ba8fff 100644 --- a/src/include/pgxc/execRemote.h +++ b/src/include/pgxc/execRemote.h @@ -85,8 +85,8 @@ extern void DataNodeRollbackPrepared(char *gid); extern void DataNodeCommitPrepared(char *gid); extern DataNodeHandle** DataNodeCopyBegin(const char *query, List *nodelist, Snapshot snapshot, bool is_from); -extern int DataNodeCopyIn(char *data_row, int len, Exec_Nodes *exec_nodes, DataNodeHandle** copy_connections); -extern uint64 DataNodeCopyOut(Exec_Nodes *exec_nodes, DataNodeHandle** copy_connections, FILE* copy_file); +extern int DataNodeCopyIn(char *data_row, int len, ExecNodes *exec_nodes, DataNodeHandle** copy_connections); +extern uint64 DataNodeCopyOut(ExecNodes *exec_nodes, DataNodeHandle** copy_connections, FILE* copy_file); extern void DataNodeCopyFinish(DataNodeHandle** copy_connections, int primary_data_node, CombineType combine_type); extern int ExecCountSlotsRemoteQuery(RemoteQuery *node); diff --git a/src/include/pgxc/locator.h b/src/include/pgxc/locator.h index 7ae0474..233bf26 100644 --- a/src/include/pgxc/locator.h +++ b/src/include/pgxc/locator.h @@ -61,11 +61,12 @@ typedef enum */ typedef struct { + NodeTag type; List *primarynodelist; List *nodelist; char baselocatortype; TableUsageType tableusagetype; /* track pg_catalog usage */ -} Exec_Nodes; +} ExecNodes; extern char *PreferredDataNodes; @@ -77,7 +78,7 @@ extern char ConvertToLocatorType(int disttype); extern char *GetRelationHashColumn(RelationLocInfo *rel_loc_info); extern RelationLocInfo *GetRelationLocInfo(Oid relid); extern RelationLocInfo *CopyRelationLocInfo(RelationLocInfo *src_info); -extern Exec_Nodes *GetRelationNodes(RelationLocInfo *rel_loc_info, long *partValue, +extern ExecNodes *GetRelationNodes(RelationLocInfo *rel_loc_info, long *partValue, int isRead); extern bool IsHashColumn(RelationLocInfo *rel_loc_info, char *part_col_name); extern bool IsHashColumnForRelId(Oid relid, char *part_col_name); diff --git a/src/include/pgxc/planner.h b/src/include/pgxc/planner.h index 346dd65..548e4cd 100644 --- a/src/include/pgxc/planner.h +++ b/src/include/pgxc/planner.h @@ -38,6 +38,7 @@ typedef enum */ typedef struct { + NodeTag type; int numCols; /* number of sort-key columns */ AttrNumber *sortColIdx; /* their indexes in the target list */ Oid *sortOperators; /* OIDs of operators to sort them by */ @@ -47,6 +48,7 @@ typedef struct /* For returning distinct results from the RemoteQuery*/ typedef struct { + NodeTag type; int numCols; /* number of sort-key columns */ AttrNumber *uniqColIdx; /* their indexes in the target list */ Oid *eqOperators; /* OIDs of operators to equate them by */ @@ -61,7 +63,7 @@ typedef struct Scan scan; bool is_single_step; /* special case, skip extra work */ char *sql_statement; - Exec_Nodes *exec_nodes; + ExecNodes *exec_nodes; CombineType combine_type; List *simple_aggregates; /* simple aggregate to combine on this step */ SimpleSort *sort; @@ -87,6 +89,7 @@ typedef enum /* For handling simple aggregates */ typedef struct { + NodeTag type; int column_pos; /* Only use 1 for now */ Aggref *aggref; Oid transfn_oid; ----------------------------------------------------------------------- Summary of changes: src/backend/access/common/heaptuple.c | 9 ++ src/backend/commands/copy.c | 4 +- src/backend/nodes/copyfuncs.c | 143 ++++++++++++++++++++++++++++++++- src/backend/pgxc/locator/locator.c | 6 +- src/backend/pgxc/plan/planner.c | 122 ++++++++++++++++++++-------- src/backend/pgxc/pool/execRemote.c | 6 +- src/backend/tcop/postgres.c | 2 - src/backend/tcop/utility.c | 4 +- src/include/nodes/nodes.h | 7 ++ src/include/nodes/parsenodes.h | 1 - src/include/pgxc/execRemote.h | 4 +- src/include/pgxc/locator.h | 5 +- src/include/pgxc/planner.h | 5 +- 13 files changed, 263 insertions(+), 55 deletions(-) hooks/post-receive -- Postgres-XC |