diff options
| author | Abbas | 2011-05-24 12:06:30 +0000 |
|---|---|---|
| committer | Michael P | 2011-05-26 00:56:39 +0000 |
| commit | eb593761cb84d35e63ee4af4adb804735e083ffa (patch) | |
| tree | d17fb5232cfe902d7e2b511f5d495adf121cc2fc /src/backend | |
| parent | c51655e2648efaaef0b9e73a11b3af56aef0c031 (diff) | |
This patch adds support for the following data types to be used as distribution key
INT8, INT2, OID, INT4, BOOL, INT2VECTOR, OIDVECTOR
CHAR, NAME, TEXT, BPCHAR, BYTEA, VARCHAR
FLOAT4, FLOAT8, NUMERIC, CASH
ABSTIME, RELTIME, DATE, TIME, TIMESTAMP, TIMESTAMPTZ, INTERVAL, TIMETZ
A new function compute_hash is added in the system which is used to
compute hash of a any of the supported data types.
The computed hash is used in the function GetRelationNodes to
find the targeted data node.
EXPLAIN for RemoteQuery has been modified to show the number of
data nodes targeted for a certain query. This is essential
to spot bugs in the optimizer in case it is targeting all nodes
by mistake.
In case of optimisations where comparison with a constant leads
the optimiser to point to a single data node, there were a couple
of mistakes in examine_conditions_walker.
First it was not supporting RelabelType, which represents a "dummy"
type coercion between two binary compatible datatypes.
This was resulting in the optimization not working for varchar
type for example.
Secondly it was not catering for the case where the user specifies the
condition such that the constant expression is written towards LHS and the
variable towards the RHS of the = operator.
i.e. 23 = a
A number of test cases have been added in regression to make sure
further enhancements do not break this functionality.
This change has a sizeable impact on current regression tests in the following manner.
1. horology test case crashes the server and has been commented out in serial_schedule.
2. In money test case the planner optimizer wrongly kicks in to optimize this query
SELECT m = '$123.01' FROM money_data;
to point to a single data node.
3. There were a few un-necessary EXPLAINs in create_index test case.
Since we have added support in EXPLAIN to show the number of
data nodes targeted for RemoteQuery, this test case was producing
output dependent on the cluster configuration.
4. In guc test case
DROP ROLE temp_reset_user;
results in
ERROR: permission denied to drop role
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/access/hash/hashfunc.c | 95 | ||||
| -rw-r--r-- | src/backend/commands/copy.c | 31 | ||||
| -rw-r--r-- | src/backend/commands/explain.c | 22 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/createplan.c | 7 | ||||
| -rw-r--r-- | src/backend/pgxc/locator/locator.c | 74 | ||||
| -rw-r--r-- | src/backend/pgxc/plan/planner.c | 96 | ||||
| -rw-r--r-- | src/backend/pgxc/pool/execRemote.c | 8 | ||||
| -rw-r--r-- | src/backend/tcop/postgres.c | 26 |
8 files changed, 264 insertions, 95 deletions
diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c index 872c9f0f26..6b99acff88 100644 --- a/src/backend/access/hash/hashfunc.c +++ b/src/backend/access/hash/hashfunc.c @@ -28,6 +28,13 @@ #include "access/hash.h" +#ifdef PGXC +#include "catalog/pg_type.h" +#include "utils/builtins.h" +#include "utils/timestamp.h" +#include "utils/date.h" +#include "utils/nabstime.h" +#endif /* Note: this is used for both "char" and boolean datatypes */ Datum @@ -521,3 +528,91 @@ hash_uint32(uint32 k) /* report the result */ return UInt32GetDatum(c); } + +#ifdef PGXC +/* + * compute_hash() -- Generaic hash function for all datatypes + * + */ + +Datum +compute_hash(Oid type, Datum value, int *pErr) +{ + Assert(pErr); + + *pErr = 0; + + if (value == NULL) + { + *pErr = 1; + return 0; + } + + switch(type) + { + case INT8OID: + /* This gives added advantage that + * a = 8446744073709551359 + * and a = 8446744073709551359::int8 both work*/ + return DatumGetInt32(value); + case INT2OID: + return DatumGetInt16(value); + case OIDOID: + return DatumGetObjectId(value); + case INT4OID: + return DatumGetInt32(value); + case BOOLOID: + return DatumGetBool(value); + + case CHAROID: + return DirectFunctionCall1(hashchar, value); + case NAMEOID: + return DirectFunctionCall1(hashname, value); + case INT2VECTOROID: + return DirectFunctionCall1(hashint2vector, value); + + case VARCHAROID: + case TEXTOID: + return DirectFunctionCall1(hashtext, value); + + case OIDVECTOROID: + return DirectFunctionCall1(hashoidvector, value); + case FLOAT4OID: + return DirectFunctionCall1(hashfloat4, value); + case FLOAT8OID: + return DirectFunctionCall1(hashfloat8, value); + + case ABSTIMEOID: + return DatumGetAbsoluteTime(value); + case RELTIMEOID: + return DatumGetRelativeTime(value); + case CASHOID: + return DirectFunctionCall1(hashint8, value); + + case BPCHAROID: + return DirectFunctionCall1(hashbpchar, value); + case BYTEAOID: + return DirectFunctionCall1(hashvarlena, value); + + case DATEOID: + return DatumGetDateADT(value); + case TIMEOID: + return DirectFunctionCall1(time_hash, value); + case TIMESTAMPOID: + return DirectFunctionCall1(timestamp_hash, value); + case TIMESTAMPTZOID: + return DirectFunctionCall1(timestamp_hash, value); + case INTERVALOID: + return DirectFunctionCall1(interval_hash, value); + case TIMETZOID: + return DirectFunctionCall1(timetz_hash, value); + + case NUMERICOID: + return DirectFunctionCall1(hash_numeric, value); + default: + *pErr = 1; + return 0; + } +} + +#endif diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 0a6f6051ba..77b82db102 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -1643,14 +1643,14 @@ CopyTo(CopyState cstate) } #ifdef PGXC - if (IS_PGXC_COORDINATOR && cstate->rel_loc) + if (IS_PGXC_COORDINATOR && cstate->rel_loc) { cstate->processed = DataNodeCopyOut( - GetRelationNodes(cstate->rel_loc, NULL, RELATION_ACCESS_READ), + GetRelationNodes(cstate->rel_loc, 0, UNKNOWNOID, RELATION_ACCESS_READ), cstate->connections, cstate->copy_file); } - else + else { #endif @@ -2415,15 +2415,18 @@ CopyFrom(CopyState cstate) #ifdef PGXC if (IS_PGXC_COORDINATOR && cstate->rel_loc) { - Datum *dist_col_value = NULL; + Datum dist_col_value; + Oid dist_col_type = UNKNOWNOID; if (cstate->idx_dist_by_col >= 0 && !nulls[cstate->idx_dist_by_col]) - dist_col_value = &values[cstate->idx_dist_by_col]; + { + dist_col_value = values[cstate->idx_dist_by_col]; + dist_col_type = attr[cstate->idx_dist_by_col]->atttypid; + } if (DataNodeCopyIn(cstate->line_buf.data, cstate->line_buf.len, - GetRelationNodes(cstate->rel_loc, (long *)dist_col_value, - RELATION_ACCESS_INSERT), + GetRelationNodes(cstate->rel_loc, dist_col_value, dist_col_type, RELATION_ACCESS_INSERT), cstate->connections)) ereport(ERROR, (errcode(ERRCODE_CONNECTION_EXCEPTION), @@ -4035,7 +4038,8 @@ DoInsertSelectCopy(EState *estate, TupleTableSlot *slot) HeapTuple tuple; Datum *values; bool *nulls; - Datum *dist_col_value = NULL; + Datum dist_col_value; + Oid dist_col_type; MemoryContext oldcontext; CopyState cstate; @@ -4080,6 +4084,11 @@ DoInsertSelectCopy(EState *estate, TupleTableSlot *slot) cstate->fe_msgbuf = makeStringInfo(); attr = cstate->tupDesc->attrs; + if (cstate->idx_dist_by_col >= 0) + dist_col_type = attr[cstate->idx_dist_by_col]->atttypid; + else + dist_col_type = UNKNOWNOID; + /* Get info about the columns we need to process. */ cstate->out_functions = (FmgrInfo *) palloc(cstate->tupDesc->natts * sizeof(FmgrInfo)); foreach(lc, cstate->attnumlist) @@ -4150,12 +4159,14 @@ DoInsertSelectCopy(EState *estate, TupleTableSlot *slot) /* Get dist column, if any */ if (cstate->idx_dist_by_col >= 0 && !nulls[cstate->idx_dist_by_col]) - dist_col_value = &values[cstate->idx_dist_by_col]; + dist_col_value = values[cstate->idx_dist_by_col]; + else + dist_col_type = UNKNOWNOID; /* Send item to the appropriate data node(s) (buffer) */ if (DataNodeCopyIn(cstate->fe_msgbuf->data, cstate->fe_msgbuf->len, - GetRelationNodes(cstate->rel_loc, (long *)dist_col_value, RELATION_ACCESS_INSERT), + GetRelationNodes(cstate->rel_loc, dist_col_value, dist_col_type, RELATION_ACCESS_INSERT), cstate->connections)) ereport(ERROR, (errcode(ERRCODE_CONNECTION_EXCEPTION), diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index da5fdbc368..5d2cb5cb9f 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -851,8 +851,28 @@ ExplainNode(Plan *plan, PlanState *planstate, case T_WorkTableScan: #ifdef PGXC case T_RemoteQuery: + { + RemoteQuery *remote_query = (RemoteQuery *) plan; + int pnc, nc; + + pnc = 0; + nc = 0; + if (remote_query->exec_nodes != NULL) + { + if (remote_query->exec_nodes->primarynodelist != NULL) + { + pnc = list_length(remote_query->exec_nodes->primarynodelist); + appendStringInfo(es->str, " (Primary Node Count [%d])", pnc); + } + if (remote_query->exec_nodes->nodelist) + { + nc = list_length(remote_query->exec_nodes->nodelist); + appendStringInfo(es->str, " (Node Count [%d])", nc); + } + } #endif - ExplainScanTarget((Scan *) plan, es); + ExplainScanTarget((Scan *) plan, es); + } break; case T_BitmapIndexScan: { diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 4dd1f51d62..efd89fb8b3 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -2418,9 +2418,7 @@ create_remotequery_plan(PlannerInfo *root, Path *best_path, scan_plan->exec_nodes->baselocatortype = rel_loc_info->locatorType; else scan_plan->exec_nodes->baselocatortype = '\0'; - scan_plan->exec_nodes = GetRelationNodes(rel_loc_info, - NULL, - RELATION_ACCESS_READ); + scan_plan->exec_nodes = GetRelationNodes(rel_loc_info, 0, UNKNOWNOID, RELATION_ACCESS_READ); copy_path_costsize(&scan_plan->scan.plan, best_path); /* PGXCTODO - get better estimates */ @@ -5024,8 +5022,7 @@ create_remotedelete_plan(PlannerInfo *root, Plan *topplan) fstep->sql_statement = pstrdup(buf->data); fstep->combine_type = COMBINE_TYPE_SAME; fstep->read_only = false; - fstep->exec_nodes = GetRelationNodes(rel_loc_info, NULL, - RELATION_ACCESS_UPDATE); + fstep->exec_nodes = GetRelationNodes(rel_loc_info, 0, UNKNOWNOID, RELATION_ACCESS_UPDATE); } else { diff --git a/src/backend/pgxc/locator/locator.c b/src/backend/pgxc/locator/locator.c index 1eff17cb18..1539bd9c86 100644 --- a/src/backend/pgxc/locator/locator.c +++ b/src/backend/pgxc/locator/locator.c @@ -41,7 +41,7 @@ #include "catalog/pgxc_class.h" #include "catalog/namespace.h" - +#include "access/hash.h" /* * PGXCTODO For prototype, relations use the same hash mapping table. @@ -206,7 +206,32 @@ char *pColName; bool IsHashDistributable(Oid col_type) { - if (col_type == INT4OID || col_type == INT2OID) + if(col_type == INT8OID + || col_type == INT2OID + || col_type == OIDOID + || col_type == INT4OID + || col_type == BOOLOID + || col_type == CHAROID + || col_type == NAMEOID + || col_type == INT2VECTOROID + || col_type == TEXTOID + || col_type == OIDVECTOROID + || col_type == FLOAT4OID + || col_type == FLOAT8OID + || col_type == ABSTIMEOID + || col_type == RELTIMEOID + || col_type == CASHOID + || col_type == BPCHAROID + || col_type == BYTEAOID + || col_type == VARCHAROID + || col_type == DATEOID + || col_type == TIMEOID + || col_type == TIMESTAMPOID + || col_type == TIMESTAMPTZOID + || col_type == INTERVALOID + || col_type == TIMETZOID + || col_type == NUMERICOID + ) return true; return false; @@ -296,7 +321,32 @@ RelationLocInfo *rel_loc_info; bool IsModuloDistributable(Oid col_type) { - if (col_type == INT4OID || col_type == INT2OID) + if(col_type == INT8OID + || col_type == INT2OID + || col_type == OIDOID + || col_type == INT4OID + || col_type == BOOLOID + || col_type == CHAROID + || col_type == NAMEOID + || col_type == INT2VECTOROID + || col_type == TEXTOID + || col_type == OIDVECTOROID + || col_type == FLOAT4OID + || col_type == FLOAT8OID + || col_type == ABSTIMEOID + || col_type == RELTIMEOID + || col_type == CASHOID + || col_type == BPCHAROID + || col_type == BYTEAOID + || col_type == VARCHAROID + || col_type == DATEOID + || col_type == TIMEOID + || col_type == TIMESTAMPOID + || col_type == TIMESTAMPTZOID + || col_type == INTERVALOID + || col_type == TIMETZOID + || col_type == NUMERICOID + ) return true; return false; @@ -409,13 +459,13 @@ GetRoundRobinNode(Oid relid) * The returned List is a copy, so it should be freed when finished. */ ExecNodes * -GetRelationNodes(RelationLocInfo *rel_loc_info, long *partValue, - RelationAccessType accessType) +GetRelationNodes(RelationLocInfo *rel_loc_info, Datum valueForDistCol, Oid typeOfValueForDistCol, RelationAccessType accessType) { ListCell *prefItem; ListCell *stepItem; ExecNodes *exec_nodes; - + long hashValue; + int nError; if (rel_loc_info == NULL) return NULL; @@ -480,10 +530,10 @@ GetRelationNodes(RelationLocInfo *rel_loc_info, long *partValue, break; case LOCATOR_TYPE_HASH: - - if (partValue != NULL) + hashValue = compute_hash(typeOfValueForDistCol, valueForDistCol, &nError); + if (nError == 0) /* in prototype, all partitioned tables use same map */ - exec_nodes->nodelist = lappend_int(NULL, get_node_from_hash(hash_range_int(*partValue))); + exec_nodes->nodelist = lappend_int(NULL, get_node_from_hash(hash_range_int(hashValue))); else if (accessType == RELATION_ACCESS_INSERT) /* Insert NULL to node 1 */ @@ -494,9 +544,10 @@ GetRelationNodes(RelationLocInfo *rel_loc_info, long *partValue, break; case LOCATOR_TYPE_MODULO: - if (partValue != NULL) + hashValue = compute_hash(typeOfValueForDistCol, valueForDistCol, &nError); + if (nError == 0) /* in prototype, all partitioned tables use same map */ - exec_nodes->nodelist = lappend_int(NULL, get_node_from_modulo(compute_modulo(*partValue))); + exec_nodes->nodelist = lappend_int(NULL, get_node_from_modulo(compute_modulo(hashValue))); else if (accessType == RELATION_ACCESS_INSERT) /* Insert NULL to node 1 */ @@ -750,7 +801,6 @@ RelationLocInfo * GetRelationLocInfo(Oid relid) { RelationLocInfo *ret_loc_info = NULL; - char *namespace; Relation rel = relation_open(relid, AccessShareLock); diff --git a/src/backend/pgxc/plan/planner.c b/src/backend/pgxc/plan/planner.c index 2da079fcbc..652008b5ec 100644 --- a/src/backend/pgxc/plan/planner.c +++ b/src/backend/pgxc/plan/planner.c @@ -43,20 +43,23 @@ #include "utils/lsyscache.h" #include "utils/portal.h" #include "utils/syscache.h" - +#include "utils/numeric.h" +#include "access/hash.h" +#include "utils/timestamp.h" +#include "utils/date.h" /* * Convenient format for literal comparisons * - * PGXCTODO - make constant type Datum, handle other types */ typedef struct { - Oid relid; - RelationLocInfo *rel_loc_info; - Oid attrnum; - char *col_name; - long constant; /* assume long PGXCTODO - should be Datum */ + Oid relid; + RelationLocInfo *rel_loc_info; + Oid attrnum; + char *col_name; + Datum constValue; + Oid constType; } Literal_Comparison; /* @@ -471,15 +474,12 @@ get_base_var(Var *var, XCWalkerContext *context) static void get_plan_nodes_insert(PlannerInfo *root, RemoteQuery *step) { - Query *query = root->parse; - RangeTblEntry *rte; - RelationLocInfo *rel_loc_info; - Const *constant; - ListCell *lc; - long part_value; - long *part_value_ptr = NULL; - Expr *eval_expr = NULL; - + Query *query = root->parse; + RangeTblEntry *rte; + RelationLocInfo *rel_loc_info; + Const *constant; + ListCell *lc; + Expr *eval_expr = NULL; step->exec_nodes = NULL; @@ -568,7 +568,7 @@ get_plan_nodes_insert(PlannerInfo *root, RemoteQuery *step) if (!lc) { /* Skip rest, handle NULL */ - step->exec_nodes = GetRelationNodes(rel_loc_info, NULL, RELATION_ACCESS_INSERT); + step->exec_nodes = GetRelationNodes(rel_loc_info, 0, UNKNOWNOID, RELATION_ACCESS_INSERT); return; } @@ -650,21 +650,11 @@ get_plan_nodes_insert(PlannerInfo *root, RemoteQuery *step) } constant = (Const *) checkexpr; - - if (constant->consttype == INT4OID || - constant->consttype == INT2OID || - constant->consttype == INT8OID) - { - part_value = (long) constant->constvalue; - part_value_ptr = &part_value; - } - /* PGXCTODO - handle other data types */ } } /* single call handles both replicated and partitioned types */ - step->exec_nodes = GetRelationNodes(rel_loc_info, part_value_ptr, - RELATION_ACCESS_INSERT); + step->exec_nodes = GetRelationNodes(rel_loc_info, constant->constvalue, constant->consttype, RELATION_ACCESS_INSERT); if (eval_expr) pfree(eval_expr); @@ -1048,6 +1038,28 @@ examine_conditions_walker(Node *expr_node, XCWalkerContext *context) { Expr *arg1 = linitial(opexpr->args); Expr *arg2 = lsecond(opexpr->args); + RelabelType *rt; + Expr *targ; + + if (IsA(arg1, RelabelType)) + { + rt = arg1; + arg1 = rt->arg; + } + + if (IsA(arg2, RelabelType)) + { + rt = arg2; + arg2 = rt->arg; + } + + /* Handle constant = var */ + if (IsA(arg2, Var)) + { + targ = arg1; + arg1 = arg2; + arg2 = targ; + } /* Look for a table */ if (IsA(arg1, Var)) @@ -1135,7 +1147,8 @@ examine_conditions_walker(Node *expr_node, XCWalkerContext *context) lit_comp->relid = column_base->relid; lit_comp->rel_loc_info = rel_loc_info1; lit_comp->col_name = column_base->colname; - lit_comp->constant = constant->constvalue; + lit_comp->constValue = constant->constvalue; + lit_comp->constType = constant->consttype; context->conditions->partitioned_literal_comps = lappend( context->conditions->partitioned_literal_comps, @@ -1743,9 +1756,7 @@ get_plan_nodes_walker(Node *query_node, XCWalkerContext *context) if (rel_loc_info->locatorType != LOCATOR_TYPE_HASH && rel_loc_info->locatorType != LOCATOR_TYPE_MODULO) /* do not need to determine partitioning expression */ - context->query_step->exec_nodes = GetRelationNodes(rel_loc_info, - NULL, - context->accessType); + context->query_step->exec_nodes = GetRelationNodes(rel_loc_info, 0, UNKNOWNOID, context->accessType); /* Note replicated table usage for determining safe queries */ if (context->query_step->exec_nodes) @@ -1801,9 +1812,7 @@ get_plan_nodes_walker(Node *query_node, XCWalkerContext *context) { Literal_Comparison *lit_comp = (Literal_Comparison *) lfirst(lc); - test_exec_nodes = GetRelationNodes( - lit_comp->rel_loc_info, &(lit_comp->constant), - RELATION_ACCESS_READ); + test_exec_nodes = GetRelationNodes(lit_comp->rel_loc_info, lit_comp->constValue, lit_comp->constType, RELATION_ACCESS_READ); test_exec_nodes->tableusagetype = table_usage_type; if (context->query_step->exec_nodes == NULL) @@ -1829,9 +1838,7 @@ get_plan_nodes_walker(Node *query_node, XCWalkerContext *context) parent_child = (Parent_Child_Join *) linitial(context->conditions->partitioned_parent_child); - context->query_step->exec_nodes = GetRelationNodes(parent_child->rel_loc_info1, - NULL, - context->accessType); + context->query_step->exec_nodes = GetRelationNodes(parent_child->rel_loc_info1, 0, UNKNOWNOID, context->accessType); context->query_step->exec_nodes->tableusagetype = table_usage_type; } @@ -3379,8 +3386,6 @@ GetHashExecNodes(RelationLocInfo *rel_loc_info, ExecNodes **exec_nodes, const Ex Expr *checkexpr; Expr *eval_expr = NULL; Const *constant; - long part_value; - long *part_value_ptr = NULL; eval_expr = (Expr *) eval_const_expressions(NULL, (Node *)expr); checkexpr = get_numeric_constant(eval_expr); @@ -3390,17 +3395,8 @@ GetHashExecNodes(RelationLocInfo *rel_loc_info, ExecNodes **exec_nodes, const Ex constant = (Const *) checkexpr; - if (constant->consttype == INT4OID || - constant->consttype == INT2OID || - constant->consttype == INT8OID) - { - part_value = (long) constant->constvalue; - part_value_ptr = &part_value; - } - /* single call handles both replicated and partitioned types */ - *exec_nodes = GetRelationNodes(rel_loc_info, part_value_ptr, - RELATION_ACCESS_INSERT); + *exec_nodes = GetRelationNodes(rel_loc_info, constant->constvalue, constant->consttype, RELATION_ACCESS_INSERT); if (eval_expr) pfree(eval_expr); diff --git a/src/backend/pgxc/pool/execRemote.c b/src/backend/pgxc/pool/execRemote.c index 335c05f7c4..0a2e6deca8 100644 --- a/src/backend/pgxc/pool/execRemote.c +++ b/src/backend/pgxc/pool/execRemote.c @@ -1061,7 +1061,8 @@ BufferConnection(PGXCNodeHandle *conn) RemoteQueryState *combiner = conn->combiner; MemoryContext oldcontext; - Assert(conn->state == DN_CONNECTION_STATE_QUERY && combiner); + if (combiner == NULL || conn->state != DN_CONNECTION_STATE_QUERY) + return; /* * When BufferConnection is invoked CurrentContext is related to other @@ -3076,9 +3077,8 @@ get_exec_connections(RemoteQueryState *planstate, if (!isnull) { RelationLocInfo *rel_loc_info = GetRelationLocInfo(exec_nodes->relid); - ExecNodes *nodes = GetRelationNodes(rel_loc_info, - (long *) &partvalue, - exec_nodes->accesstype); + /* PGXCTODO what is the type of partvalue here*/ + ExecNodes *nodes = GetRelationNodes(rel_loc_info, partvalue, UNKNOWNOID, exec_nodes->accesstype); if (nodes) { nodelist = nodes->nodelist; diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 6dc98a03d3..16998f966a 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -664,18 +664,18 @@ pg_analyze_and_rewrite(Node *parsetree, const char *query_string, querytree_list = pg_rewrite_query(query); #ifdef PGXC - if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) - { - ListCell *lc; - - foreach(lc, querytree_list) - { - Query *query = (Query *) lfirst(lc); - - if (query->sql_statement == NULL) - query->sql_statement = pstrdup(query_string); - } - } + if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) + { + ListCell *lc; + + foreach(lc, querytree_list) + { + Query *query = (Query *) lfirst(lc); + + if (query->sql_statement == NULL) + query->sql_statement = pstrdup(query_string); + } + } #endif TRACE_POSTGRESQL_QUERY_REWRITE_DONE(query_string); @@ -1036,7 +1036,7 @@ exec_simple_query(const char *query_string) querytree_list = pg_analyze_and_rewrite(parsetree, query_string, NULL, 0); - + plantree_list = pg_plan_queries(querytree_list, 0, NULL); /* Done with the snapshot used for parsing/planning */ |
