diff options
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 */ |
