diff options
35 files changed, 2549 insertions, 768 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 1a199789b1..e3e0e0f9aa 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -1962,6 +1962,14 @@ CommitTransaction(bool contact_gtm) char implicitgid[256]; TransactionId xid = InvalidTransactionId; + /* + * Check if there are any On Commit actions and force temporary object flag. + * This is possible in the case of a session using ON COMMIT DELETE ROWS. + * It is essential to do this check *before* calling PGXCNodeIsImplicit2PC. + */ + if (IsOnCommitActions()) + ExecSetTempObjectIncluded(); + if (IS_PGXC_COORDINATOR && !IsConnFromCoord() && contact_gtm) PreparePGXCNodes = PGXCNodeIsImplicit2PC(&PrepareLocalCoord); @@ -2330,6 +2338,15 @@ PrepareTransaction(void) ShowTransactionState("PrepareTransaction"); +#ifdef PGXC + /* + * Check if there are any On Commit actions and force temporary object flag. + * This is possible in the case of a session using ON COMMIT DELETE ROWS. + */ + if (IsOnCommitActions()) + ExecSetTempObjectIncluded(); +#endif + /* * check the current transaction state */ diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index d09bef0682..f18a132219 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -4,7 +4,8 @@ * * PostgreSQL object comments utility code. * - * Copyright (c) 1996-2011, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2011 Nippon Telegraph and Telephone Corporation * * IDENTIFICATION * src/backend/commands/comment.c @@ -460,3 +461,42 @@ GetComment(Oid oid, Oid classoid, int32 subid) return comment; } + + +#ifdef PGXC +/* + * GetCommentObjectId + * + * Return Object ID of object commented + * Note: This function uses portions of the code of CommentObject, + * even if this code is duplicated this is done like this to facilitate + * merges with PostgreSQL head. + */ +Oid +GetCommentObjectId(CommentStmt *stmt) +{ + ObjectAddress address; + Relation relation; + + if (stmt->objtype == OBJECT_DATABASE && list_length(stmt->objname) == 1) + { + char *database = strVal(linitial(stmt->objname)); + + if (!OidIsValid(get_database_oid(database, true))) + { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_DATABASE), + errmsg("database \"%s\" does not exist", database))); + return InvalidOid; + } + } + + address = get_object_address(stmt->objtype, stmt->objname, stmt->objargs, + &relation, ShareUpdateExclusiveLock); + + if (relation != NULL) + relation_close(relation, NoLock); + + return address.objectId; +} +#endif diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 952b88b533..bfaf6e2860 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -918,6 +918,12 @@ DoCopy(const CopyStmt *stmt, const char *queryString) rte->relkind = rel->rd_rel->relkind; rte->requiredPerms = required_access; +#ifdef PGXC + /* In case COPY is used on a temporary table, never use 2PC for implicit commits */ + if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP) + ExecSetTempObjectIncluded(); +#endif + tupDesc = RelationGetDescr(rel); attnums = CopyGetAttnums(tupDesc, rel, stmt->attlist); foreach(cur, attnums) diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index 831886f46d..851b0dca3b 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -132,7 +132,8 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString) * Add a RemoteQuery node for a query at top level on a remote Coordinator */ if (is_top_level) - parsetree_list = AddRemoteQueryNode(parsetree_list, queryString, EXEC_ON_ALL_NODES); + parsetree_list = AddRemoteQueryNode(parsetree_list, queryString, + EXEC_ON_ALL_NODES, false); #endif /* diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 644e572934..7fe0015868 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -89,6 +89,7 @@ #include "pgxc/pgxc.h" #include "access/gtm.h" #include "commands/sequence.h" +#include "pgxc/execRemote.h" #endif /* @@ -439,20 +440,11 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) * code. This is needed because calling code might not expect untrusted * tables to appear in pg_temp at the front of its search path. */ -#ifdef PGXC - if (stmt->relation->relpersistence == RELPERSISTENCE_TEMP && - IsUnderPostmaster && - relkind != RELKIND_SEQUENCE) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("PG-XC does not yet support temporary tables"))); -#else if (stmt->relation->relpersistence == RELPERSISTENCE_TEMP && InSecurityRestrictedOperation()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("cannot create temporary table within security-restricted operation"))); -#endif /* * Look up the namespace in which we are supposed to create the relation, @@ -9462,3 +9454,110 @@ AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, } } } + +#ifdef PGXC +/* + * IsTempTable + * + * Check if given table Oid is temporary. + */ +bool +IsTempTable(Oid relid) +{ + Relation rel; + bool res; + /* + * PGXCTODO: Is it correct to open without locks? + * we just check if this table is temporary though... + */ + rel = relation_open(relid, NoLock); + res = rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP; + relation_close(rel, NoLock); + return res; +} + +/* + * IsIndexUsingTemp + * + * Check if given index relation uses temporary tables. + */ +bool +IsIndexUsingTempTable(Oid relid) +{ + bool res = false; + HeapTuple tuple; + Oid parent_id = InvalidOid; + + tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(relid)); + if (HeapTupleIsValid(tuple)) + { + Form_pg_index index = (Form_pg_index) GETSTRUCT(tuple); + parent_id = index->indrelid; + + /* Release system cache BEFORE looking at the parent table */ + ReleaseSysCache(tuple); + + res = IsTempTable(parent_id); + } + else + res = false; /* Default case */ + + return res; +} + +/* + * IsOnCommitDeleteRows + * + * Check if there are any on-commit actions activated + * This is possible in the case of ON COMMIT DELETE ROWS for example. + * In this case 2PC cannot be used. + */ +bool +IsOnCommitActions(void) +{ + return list_length(on_commits) > 0; +} + +/* + * DropTableThrowErrorExternal + * + * Error interface for DROP when looking for execution node type. + */ +void +DropTableThrowErrorExternal(RangeVar *relation, ObjectType removeType, bool missing_ok) +{ + char relkind; + + /* Determine required relkind */ + switch (removeType) + { + case OBJECT_TABLE: + relkind = RELKIND_RELATION; + break; + + case OBJECT_INDEX: + relkind = RELKIND_INDEX; + break; + + case OBJECT_SEQUENCE: + relkind = RELKIND_SEQUENCE; + break; + + case OBJECT_VIEW: + relkind = RELKIND_VIEW; + break; + + case OBJECT_FOREIGN_TABLE: + relkind = RELKIND_FOREIGN_TABLE; + break; + + default: + elog(ERROR, "unrecognized drop object type: %d", + (int) removeType); + relkind = 0; /* keep compiler quiet */ + break; + } + + DropErrorMsgNonExistent(relation->relname, relkind, missing_ok); +} +#endif diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index d3b5c7793b..bc32049b87 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -47,6 +47,7 @@ #include "catalog/pg_type.h" #include "executor/executor.h" #include "rewrite/rewriteManip.h" +#include "commands/tablecmds.h" #endif #include "utils/lsyscache.h" @@ -2601,8 +2602,15 @@ create_remotequery_plan(PlannerInfo *root, Path *best_path, /* * XXX: should use GENERIC OPTIONS like 'foreign_relname' or something for * the foreign table name instead of the local name ? + * + * A temporary table does not use namespace as it may not be + * consistent among nodes cluster. Relation name is sufficient. */ - appendStringInfo(&sql, "%s.%s %s", nspname_q, relname_q, aliasname_q); + if (IsTempTable(rte->relid)) + appendStringInfo(&sql, "%s %s", relname_q, aliasname_q); + else + appendStringInfo(&sql, "%s.%s %s", nspname_q, relname_q, aliasname_q); + pfree(nspname); pfree(relname); if (nspname_q != nspname_q) diff --git a/src/backend/pgxc/plan/planner.c b/src/backend/pgxc/plan/planner.c index 7da7f848af..e3499134db 100644 --- a/src/backend/pgxc/plan/planner.c +++ b/src/backend/pgxc/plan/planner.c @@ -46,6 +46,7 @@ #include "utils/syscache.h" #include "utils/numeric.h" #include "access/hash.h" +#include "commands/tablecmds.h" #include "utils/timestamp.h" #include "utils/date.h" @@ -171,7 +172,8 @@ static int handle_limit_offset(RemoteQuery *query_step, Query *query, PlannedStm static void InitXCWalkerContext(XCWalkerContext *context); static RemoteQuery *makeRemoteQuery(void); static void validate_part_col_updatable(const Query *query); - +static bool contains_temp_tables(List *rtable); +static bool contains_only_pg_catalog(List *rtable); /* * Find position of specified substring in the string @@ -1403,7 +1405,7 @@ examine_conditions_fromlist(Node *treenode, XCWalkerContext *context) * only contain pg_catalog entries. */ static bool -contains_only_pg_catalog (List *rtable) +contains_only_pg_catalog(List *rtable) { ListCell *item; @@ -1416,13 +1418,39 @@ contains_only_pg_catalog (List *rtable) { if (get_rel_namespace(rte->relid) != PG_CATALOG_NAMESPACE) return false; - } else if (rte->rtekind == RTE_SUBQUERY && - !contains_only_pg_catalog (rte->subquery->rtable)) + } + else if (rte->rtekind == RTE_SUBQUERY && + !contains_only_pg_catalog(rte->subquery->rtable)) return false; } return true; } +/* + * Returns true if at least one temporary table is in use + * in query (and its subqueries) + */ +static bool +contains_temp_tables(List *rtable) +{ + ListCell *item; + + foreach(item, rtable) + { + RangeTblEntry *rte = (RangeTblEntry *) lfirst(item); + + if (rte->rtekind == RTE_RELATION) + { + if (IsTempTable(rte->relid)) + return true; + } + else if (rte->rtekind == RTE_SUBQUERY && + contains_temp_tables(rte->subquery->rtable)) + return true; + } + + return false; +} /* * get_plan_nodes - determine the nodes to execute the command on. @@ -1934,6 +1962,7 @@ makeRemoteQuery(void) result->paramval_data = NULL; result->paramval_len = 0; result->exec_direct_type = EXEC_DIRECT_NONE; + result->is_temp = false; result->relname = NULL; result->remotejoin = false; @@ -2737,12 +2766,16 @@ pgxc_planner(Query *query, int cursorOptions, ParamListInfo boundParams) if (query->commandType != CMD_SELECT) result->resultRelations = list_make1_int(query->resultRelation); - if (contains_only_pg_catalog (query->rtable)) + if (contains_only_pg_catalog(query->rtable)) { result = standard_planner(query, cursorOptions, boundParams); return result; } + /* Check if temporary tables are in use in target list */ + if (contains_temp_tables(query->rtable)) + query_step->is_temp = true; + if (query_step->exec_nodes == NULL) get_plan_nodes_command(query_step, root); @@ -3184,7 +3217,7 @@ GetHashExecNodes(RelationLocInfo *rel_loc_info, ExecNodes **exec_nodes, const Ex * duplicated queries on Datanodes. */ List * -AddRemoteQueryNode(List *stmts, const char *queryString, RemoteQueryExecType remoteExecType) +AddRemoteQueryNode(List *stmts, const char *queryString, RemoteQueryExecType remoteExecType, bool is_temp) { List *result = stmts; @@ -3199,6 +3232,7 @@ AddRemoteQueryNode(List *stmts, const char *queryString, RemoteQueryExecType rem step->combine_type = COMBINE_TYPE_SAME; step->sql_statement = queryString; step->exec_type = remoteExecType; + step->is_temp = is_temp; result = lappend(result, step); } diff --git a/src/backend/pgxc/pool/execRemote.c b/src/backend/pgxc/pool/execRemote.c index 1efb364333..121245d696 100644 --- a/src/backend/pgxc/pool/execRemote.c +++ b/src/backend/pgxc/pool/execRemote.c @@ -52,6 +52,7 @@ static bool autocommit = true; static bool is_ddl = false; static bool implicit_force_autocommit = false; +static bool temp_object_included = false; static PGXCNodeHandle **write_node_list = NULL; static int write_node_count = 0; static char *begin_string = NULL; @@ -1536,11 +1537,27 @@ finish: if (res != 0) { - ereport(ERROR, - (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("Could not prepare transaction on data nodes"))); + + /* In case transaction has operated on temporary objects */ + if (temp_object_included) + { + /* Reset temporary object flag */ + temp_object_included = false; + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("cannot PREPARE a transaction that has operated on temporary tables"))); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("Could not prepare transaction on data nodes"))); + } } + /* Reset temporary object flag */ + temp_object_included = false; + return local_operation; } @@ -1824,6 +1841,9 @@ finish: is_ddl = false; clear_write_node_list(); + /* Reset temporary object flag */ + temp_object_included = false; + /* Clean up connections */ pfree_pgxc_all_handles(pgxc_connections); @@ -1973,6 +1993,9 @@ finish: is_ddl = false; clear_write_node_list(); + /* Reset temporary object flag */ + temp_object_included = false; + /* Free node list taken from GTM */ if (datanodes && datanodecnt != 0) free(datanodes); @@ -2113,6 +2136,9 @@ finish: is_ddl = false; clear_write_node_list(); + /* Reset temporary object flag */ + temp_object_included = false; + /* Free node list taken from GTM */ if (datanodes) free(datanodes); @@ -2210,6 +2236,9 @@ finish: is_ddl = false; clear_write_node_list(); + /* Reset temporary object flag */ + temp_object_included = false; + /* Clean up connections */ pfree_pgxc_all_handles(pgxc_connections); if (res != 0) @@ -2284,6 +2313,9 @@ finish: is_ddl = false; clear_write_node_list(); + /* Reset temporary object flag */ + temp_object_included = false; + /* Clean up connections */ pfree_pgxc_all_handles(pgxc_connections); return res; @@ -3217,6 +3249,10 @@ do_query(RemoteQueryState *node) bool need_tran; PGXCNodeAllHandles *pgxc_connections; + /* Be sure to set temporary object flag if necessary */ + if (step->is_temp) + temp_object_included = true; + /* * Get connections for Datanodes only, utilities and DDLs * are launched in ExecRemoteUtility @@ -4033,6 +4069,9 @@ ExecRemoteUtility(RemoteQuery *node) implicit_force_autocommit = force_autocommit; + /* A transaction using temporary objects cannot use 2PC */ + temp_object_included = node->is_temp; + remotestate = CreateResponseCombiner(0, node->combine_type); pgxc_connections = get_exec_connections(NULL, node->exec_nodes, exec_type); @@ -4516,12 +4555,14 @@ PGXCNodeIsImplicit2PC(bool *prepare_local_coord) /* * In case of an autocommit or forced autocommit transaction, 2PC is not involved - * This case happens for Utilities using force autocommit (CREATE DATABASE, VACUUM...) + * This case happens for Utilities using force autocommit (CREATE DATABASE, VACUUM...). + * For a transaction using temporary objects, 2PC is not authorized. */ - if (implicit_force_autocommit) + if (implicit_force_autocommit || temp_object_included) { *prepare_local_coord = false; implicit_force_autocommit = false; + temp_object_included = false; return false; } @@ -4622,3 +4663,15 @@ int DataNodeCopyInBinaryForAll(char *msg_buf, int len, PGXCNodeHandle** copy_con return 0; } + +/* + * ExecSetTempObjectIncluded + * + * Set Temp object flag on the fly for transactions + * This flag will be reinitialized at commit. + */ +void +ExecSetTempObjectIncluded(void) +{ + temp_object_included = true; +} diff --git a/src/backend/pgxc/pool/poolmgr.c b/src/backend/pgxc/pool/poolmgr.c index 463bd5a170..c0d8d56aab 100644 --- a/src/backend/pgxc/pool/poolmgr.c +++ b/src/backend/pgxc/pool/poolmgr.c @@ -93,7 +93,13 @@ static void agent_init(PoolAgent *agent, const char *database, const char *user_ static void agent_destroy(PoolAgent *agent); static void agent_create(void); static void agent_handle_input(PoolAgent *agent, StringInfo s); -static int agent_set_command(PoolAgent *agent, const char *set_command, bool is_local); +static int agent_session_command(PoolAgent *agent, + const char *set_command, + PoolCommandType command_type); +static int agent_set_command(PoolAgent *agent, + const char *set_command, + PoolCommandType command_type); +static int agent_temp_command(PoolAgent *agent); static DatabasePool *create_database_pool(const char *database, const char *user_name); static void insert_database_pool(DatabasePool *pool); static int destroy_database_pool(const char *database, const char *user_name); @@ -107,7 +113,7 @@ static int *agent_acquire_connections(PoolAgent *agent, List *datanodelist, List static int cancel_query_on_connections(PoolAgent *agent, List *datanodelist, List *coordlist); static PGXCNodePoolSlot *acquire_connection(DatabasePool *dbPool, int node, char client_conn_type); static void agent_release_connections(PoolAgent *agent, List *dn_discard, List *co_discard); -static void agent_reset_params(PoolAgent *agent, List *dn_list, List *co_list); +static void agent_reset_session(PoolAgent *agent, List *dn_list, List *co_list); static void release_connection(DatabasePool *dbPool, PGXCNodePoolSlot *slot, int index, bool clean, char client_conn_type); static void destroy_slot(PGXCNodePoolSlot *slot); @@ -490,6 +496,7 @@ agent_create(void) agent->coord_connections = NULL; agent->session_params = NULL; agent->local_params = NULL; + agent->is_temp = false; agent->pid = 0; /* Append new agent to the list */ @@ -543,30 +550,44 @@ PoolManagerConnect(PoolHandle *handle, const char *database, const char *user_na } int -PoolManagerSetCommand(bool is_local, const char *set_command) +PoolManagerSetCommand(PoolCommandType command_type, const char *set_command) { int n32; char msgtype = 's'; - Assert(set_command); Assert(Handle); /* Message type */ pool_putbytes(&Handle->port, &msgtype, 1); /* Message length */ - n32 = htonl(strlen(set_command) + 10); + if (set_command) + n32 = htonl(strlen(set_command) + 13); + else + n32 = htonl(12); + pool_putbytes(&Handle->port, (char *) &n32, 4); /* LOCAL or SESSION parameter ? */ - pool_putbytes(&Handle->port, (char *) &is_local, 1); - - /* Length of SET command string */ - n32 = htonl(strlen(set_command) + 1); + n32 = htonl(command_type); pool_putbytes(&Handle->port, (char *) &n32, 4); - /* Send command string followed by \0 terminator */ - pool_putbytes(&Handle->port, set_command, strlen(set_command) + 1); + if (set_command) + { + /* Length of SET command string */ + n32 = htonl(strlen(set_command) + 1); + pool_putbytes(&Handle->port, (char *) &n32, 4); + + /* Send command string followed by \0 terminator */ + pool_putbytes(&Handle->port, set_command, strlen(set_command) + 1); + } + else + { + /* Send empty command */ + n32 = htonl(0); + pool_putbytes(&Handle->port, (char *) &n32, 4); + } + pool_flush(&Handle->port); /* Get result */ @@ -628,10 +649,10 @@ agent_destroy(PoolAgent *agent) co_conn = lappend_int(co_conn, i+1); /* - * agent is being destroyed, so reset session parameters - * before putting back connections to pool + * Agent is being destroyed, so reset session parameters + * and temporary objects before putting back connections to pool. */ - agent_reset_params(agent, dn_conn, co_conn); + agent_reset_session(agent, dn_conn, co_conn); /* release them all */ agent_release_connections(agent, dn_conn, co_conn); @@ -881,8 +902,8 @@ agent_handle_input(PoolAgent * agent, StringInfo s) { const char *database = NULL; const char *user_name = NULL; - const char *set_command; - bool is_local; + const char *set_command = NULL; + PoolCommandType command_type; int datanodecount; int coordcount; List *datanodelist = NIL; @@ -1043,16 +1064,19 @@ agent_handle_input(PoolAgent * agent, StringInfo s) list_free(datanodelist); list_free(coordlist); break; - case 's': /* SET COMMAND */ + case 's': /* Session-related COMMAND */ pool_getmessage(&agent->port, s, 0); /* Determine if command is local or session */ - is_local = (bool) pq_getmsgbyte(s); - /* Get the SET command */ + command_type = (PoolCommandType) pq_getmsgint(s, 4); + /* Get the SET command if necessary */ len = pq_getmsgint(s, 4); - set_command = pq_getmsgbytes(s, len); + if (len != 0) + set_command = pq_getmsgbytes(s, len); + pq_getmsgend(s); - res = agent_set_command(agent, set_command, is_local); + /* Manage command depending on its type */ + res = agent_session_command(agent, set_command, command_type); /* Send success result */ pool_sendres(&agent->port, res); @@ -1068,11 +1092,46 @@ agent_handle_input(PoolAgent * agent, StringInfo s) } /* + * Manage a session command for pooler + */ +static int +agent_session_command(PoolAgent *agent, const char *set_command, PoolCommandType command_type) +{ + int res; + + switch (command_type) + { + case POOL_CMD_LOCAL_SET: + case POOL_CMD_GLOBAL_SET: + res = agent_set_command(agent, set_command, command_type); + break; + case POOL_CMD_TEMP: + res = agent_temp_command(agent); + break; + default: + res = -1; + break; + } + + return res; +} + +/* + * Set agent flag that a temporary object is in use. + */ +static int +agent_temp_command(PoolAgent *agent) +{ + agent->is_temp = true; + return 0; +} + +/* * Save a SET command and distribute it to the agent connections * already in use. */ static int -agent_set_command(PoolAgent *agent, const char *set_command, bool is_local) +agent_set_command(PoolAgent *agent, const char *set_command, PoolCommandType command_type) { char *params_string; int i; @@ -1080,11 +1139,16 @@ agent_set_command(PoolAgent *agent, const char *set_command, bool is_local) Assert(agent); Assert(set_command); + Assert(command_type == POOL_CMD_LOCAL_SET || command_type == POOL_CMD_GLOBAL_SET); - if (is_local) + if (command_type == POOL_CMD_LOCAL_SET) params_string = agent->local_params; - else + else if (command_type == POOL_CMD_GLOBAL_SET) params_string = agent->session_params; + else + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("Set command process failed"))); /* First command recorded */ if (!params_string) @@ -1131,9 +1195,9 @@ agent_set_command(PoolAgent *agent, const char *set_command, bool is_local) } /* Save the latest string */ - if (is_local) + if (command_type == POOL_CMD_LOCAL_SET) agent->local_params = params_string; - else + else if (command_type == POOL_CMD_GLOBAL_SET) agent->session_params = params_string; return res; @@ -1278,7 +1342,6 @@ agent_acquire_connections(PoolAgent *agent, List *datanodelist, List *coordlist) static int cancel_query_on_connections(PoolAgent *agent, List *datanodelist, List *coordlist) { - int i; ListCell *nodelist_item; char errbuf[256]; int nCount; @@ -1435,8 +1498,9 @@ agent_release_connections(PoolAgent *agent, List *dn_discard, List *co_discard) return; /* - * If there are some session parameters, do not put back connections to pool - * disconnection will be made when session is cut for this user. + * If there are some session parameters or temporary objects, + * do not put back connections to pool. + * Disconnection will be made when session is cut for this user. * Local parameters are reset when transaction block is finished, * so don't do anything for them, but just reset their list. */ @@ -1445,7 +1509,8 @@ agent_release_connections(PoolAgent *agent, List *dn_discard, List *co_discard) pfree(agent->local_params); agent->local_params = NULL; } - if (agent->session_params) + if (agent->session_params || + agent->is_temp) return; /* Discard first for Datanodes */ @@ -1515,50 +1580,61 @@ agent_release_connections(PoolAgent *agent, List *dn_discard, List *co_discard) * modified by session parameters. */ static void -agent_reset_params(PoolAgent *agent, List *dn_list, List *co_list) +agent_reset_session(PoolAgent *agent, List *dn_list, List *co_list) { - PGXCNodePoolSlot *slot; if (!agent->dn_connections && !agent->coord_connections) return; - /* Parameters are reset, so free commands */ - if (agent->session_params) - { - pfree(agent->session_params); - agent->session_params = NULL; - } - if (agent->local_params) - { - pfree(agent->local_params); - agent->local_params = NULL; - } + if (!agent->session_params && !agent->local_params && !agent->is_temp) + return; - /* Reset Datanode connection params */ - if (dn_list) + /* + * Reset Datanode connection params. + * Discard is only done for Datanodes as Temporary objects are never created + * to other Coordinators in a session. + */ + if (dn_list && + (agent->session_params || agent->local_params || agent->is_temp)) { ListCell *lc; foreach(lc, dn_list) { + PGXCNodePoolSlot *slot; int node = lfirst_int(lc); + Assert(node > 0 && node <= NumDataNodes); slot = agent->dn_connections[node - 1]; /* Reset connection params */ if (slot) - PGXCNodeSendSetQuery(slot->conn, "RESET ALL;"); + { + if (agent->session_params || agent->local_params) + PGXCNodeSendSetQuery(slot->conn, "RESET ALL;"); + + /* + * Discard queries cannot be sent as multiple-queries, + * so do it separately. It is OK to use this slow process + * as session is ending. + */ + if (agent->is_temp) + PGXCNodeSendSetQuery(slot->conn, "DISCARD ALL;"); + } } } /* Reset Coordinator connection params */ - if (co_list) + if (co_list && + (agent->session_params || agent->local_params)) { ListCell *lc; foreach(lc, co_list) { + PGXCNodePoolSlot *slot; int node = lfirst_int(lc); + Assert(node > 0 && node <= NumCoords); slot = agent->coord_connections[node - 1]; @@ -1567,6 +1643,19 @@ agent_reset_params(PoolAgent *agent, List *dn_list, List *co_list) PGXCNodeSendSetQuery(slot->conn, "RESET ALL;"); } } + + /* Parameters are reset, so free commands */ + if (agent->session_params) + { + pfree(agent->session_params); + agent->session_params = NULL; + } + if (agent->local_params) + { + pfree(agent->local_params); + agent->local_params = NULL; + } + agent->is_temp = false; } /* @@ -2070,6 +2159,9 @@ grow_pool(DatabasePool * dbPool, int index, char client_conn_type) errmsg("out of memory"))); } + /* If connection fails, be sure that slot is destroyed cleanly */ + slot->xc_cancelConn = NULL; + /* Establish connection */ slot->conn = PGXCNodeConnect(nodePool->connstr); if (!PGXCNodeConnected(slot->conn)) diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index e4e6ed55b4..9e88b268b2 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -7,6 +7,7 @@ * * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California + * Portions Copyright (c) 2010-2011 Nippon Telegraph and Telephone Corporation * * * IDENTIFICATION @@ -68,12 +69,15 @@ #include "pgxc/planner.h" #include "pgxc/poolutils.h" #include "pgxc/poolmgr.h" +#include "utils/lsyscache.h" static void ExecUtilityStmtOnNodes(const char *queryString, ExecNodes *nodes, - bool force_autocommit, RemoteQueryExecType exec_type); -static RemoteQueryExecType ExecUtilityFindNodes(const char *queryString, - ObjectType objectType, - Oid relid); + bool force_autocommit, RemoteQueryExecType exec_type, + bool is_temp); +static RemoteQueryExecType ExecUtilityFindNodes(ObjectType objectType, + Oid relid, + bool *is_temp); +static RemoteQueryExecType ExecUtilityFindNodesRelkind(Oid relid, bool *is_temp); #endif @@ -653,17 +657,77 @@ standard_ProcessUtility(Node *parsetree, List *stmts; ListCell *l; Oid relOid; +#ifdef PGXC + bool is_temp = false; +#endif /* Run parse analysis ... */ stmts = transformCreateStmt((CreateStmt *) parsetree, queryString); - #ifdef PGXC + if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) + { + /* + * Scan the list of objects. + * Temporary tables are created on Datanodes only. + * Non-temporary objects are created on all nodes. + * In case temporary and non-temporary objects are mized return an error. + */ + bool is_first = true; + + foreach(l, stmts) + { + Node *stmt = (Node *) lfirst(l); + + if (IsA(stmt, CreateStmt)) + { + CreateStmt *stmt_loc = (CreateStmt *) stmt; + bool is_object_temp = stmt_loc->relation->relpersistence == RELPERSISTENCE_TEMP; + + if (is_first) + { + is_first = false; + if (is_object_temp) + is_temp = true; + } + else + { + if (is_object_temp != is_temp) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE not supported for TEMP and non-TEMP objects"), + errdetail("You should separate TEMP and non-TEMP objects"))); + } + } + else if (IsA(stmt, CreateForeignTableStmt)) + { + /* There are no temporary foreign tables */ + if (is_first) + { + is_first = false; + } + else + { + if (!is_temp) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE not supported for TEMP and non-TEMP objects"), + errdetail("You should separate TEMP and non-TEMP objects"))); + } + } + } + } + /* * Add a RemoteQuery node for a query at top level on a remote Coordinator */ if (isTopLevel) - stmts = AddRemoteQueryNode(stmts, queryString, EXEC_ON_ALL_NODES); + { + if (is_temp) + stmts = AddRemoteQueryNode(stmts, queryString, EXEC_ON_DATANODES, is_temp); + else + stmts = AddRemoteQueryNode(stmts, queryString, EXEC_ON_ALL_NODES, is_temp); + } #endif /* ... and do it */ @@ -676,6 +740,12 @@ standard_ProcessUtility(Node *parsetree, Datum toast_options; static char *validnsps[] = HEAP_RELOPT_NAMESPACES; +#ifdef PGXC + /* Set temporary object object flag in pooler */ + if (is_temp) + PoolManagerSetCommand(POOL_CMD_TEMP, NULL); +#endif + /* Create the table itself */ relOid = DefineRelation((CreateStmt *) stmt, RELKIND_RELATION, @@ -798,6 +868,7 @@ standard_ProcessUtility(Node *parsetree, DropStmt *stmt = (DropStmt *) parsetree; #ifdef PGXC bool is_temp = false; + RemoteQueryExecType exec_type = EXEC_ON_ALL_NODES; /* * We need to check details of the objects being dropped and @@ -806,41 +877,75 @@ standard_ProcessUtility(Node *parsetree, */ if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) { - /* - * Check the list of sequences/tables going to be dropped. - * XC does not allow yet to mix drop of temporary and - * non-temporary objects because this involves to rewrite - * query to process for tables and stop remote query process - * for sequences. - * PGXCTODO: For the time being this is just checked for - * sequences but should also be done for tables - */ - - if (stmt->removeType == OBJECT_SEQUENCE) + switch (stmt->removeType) { - ListCell *cell; - bool is_first = true; - - foreach(cell, stmt->objects) - { - RangeVar *rel = makeRangeVarFromNameList((List *) lfirst(cell)); - Oid relid; - - relid = RangeVarGetRelid(rel, false); - if (is_first) + case OBJECT_TABLE: + case OBJECT_SEQUENCE: + case OBJECT_VIEW: + case OBJECT_INDEX: { - is_temp = IsTempSequence(relid); - is_first = false; - } - else - { - if (IsTempSequence(relid) != is_temp) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("DROP SEQUENCE not supported for TEMP and non-TEMP sequences"), - errdetail("DROP can be done if TEMP and non-TEMP objects are separated"))); + /* + * Check the list of objects going to be dropped. + * XC does not allow yet to mix drop of temporary and + * non-temporary objects because this involves to rewrite + * query to process for tables. + */ + ListCell *cell; + bool is_first = true; + + foreach(cell, stmt->objects) + { + RangeVar *rel = makeRangeVarFromNameList((List *) lfirst(cell)); + Oid relid; + + /* + * Do not print result at all, error is thrown + * after if necessary + */ + relid = RangeVarGetRelid(rel, true); + + /* + * In case this relation ID is incorrect throw + * a correct DROP error. + */ + if (!OidIsValid(relid) && !stmt->missing_ok) + DropTableThrowErrorExternal(rel, + stmt->removeType, + stmt->missing_ok); + + /* In case of DROP ... IF EXISTS bypass */ + if (!OidIsValid(relid) && stmt->missing_ok) + continue; + + if (is_first) + { + exec_type = ExecUtilityFindNodes(stmt->removeType, + relid, + &is_temp); + is_first = false; + } + else + { + RemoteQueryExecType exec_type_loc; + bool is_temp_loc; + exec_type_loc = ExecUtilityFindNodes(stmt->removeType, + relid, + &is_temp_loc); + if (exec_type_loc != exec_type || + is_temp_loc != is_temp) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("DROP not supported for TEMP and non-TEMP objects"), + errdetail("You should separate TEMP and non-TEMP objects"))); + } + } } - } + break; + + default: + is_temp = false; + exec_type = EXEC_ON_ALL_NODES; + break; } } #endif @@ -898,20 +1003,9 @@ standard_ProcessUtility(Node *parsetree, } #ifdef PGXC - /* - * Drop can be done on non-temporary objects and temporary objects - * if they are not mixed up. - * PGXCTODO: This should be extended to tables - */ - if (IS_PGXC_COORDINATOR && !IsConnFromCoord() && !is_temp) - { - /* Sequence and views exists only on Coordinators */ - if (stmt->removeType == OBJECT_SEQUENCE || - stmt->removeType == OBJECT_VIEW) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_COORDS); - else - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); - } + /* DROP is done depending on the object type and its temporary type */ + if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) + ExecUtilityStmtOnNodes(queryString, NULL, false, exec_type, is_temp); #endif } break; @@ -920,12 +1014,31 @@ standard_ProcessUtility(Node *parsetree, ExecuteTruncate((TruncateStmt *) parsetree); #ifdef PGXC /* - * PGXCTODO - * We may need to check details of the object being truncated and - * run command on correct nodes + * Check details of the object being truncated. + * If at least one temporary table is truncated truncate cannot use 2PC + * at commit. */ - if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) + { + bool is_temp = false; + ListCell *cell; + TruncateStmt *stmt = (TruncateStmt *) parsetree; + + foreach(cell, stmt->relations) + { + Oid relid; + RangeVar *rel = (RangeVar *) lfirst(cell); + + relid = RangeVarGetRelid(rel, true); + if (IsTempTable(relid)) + { + is_temp = true; + break; + } + } + + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_DATANODES, is_temp); + } #endif break; @@ -933,13 +1046,23 @@ standard_ProcessUtility(Node *parsetree, CommentObject((CommentStmt *) parsetree); #ifdef PGXC - /* - * PGXCTODO - * Comments on temporary objects need special handling - * depending on their types. - */ + /* Comment objects depending on their object and temporary types */ if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_COORDS); + { + bool is_temp = false; + RemoteQueryExecType exec_type = EXEC_ON_ALL_NODES; + CommentStmt *stmt = (CommentStmt *) parsetree; + Oid relid = GetCommentObjectId(stmt); + + /* Commented object may not have a valid object ID, so move to default */ + if (OidIsValid(relid)) + { + exec_type = ExecUtilityFindNodes(stmt->objtype, + relid, + &is_temp); + } + ExecUtilityStmtOnNodes(queryString, NULL, false, exec_type, is_temp); + } #endif break; @@ -981,19 +1104,21 @@ standard_ProcessUtility(Node *parsetree, { RenameStmt *stmt = (RenameStmt *) parsetree; RemoteQueryExecType exec_type; + bool is_temp = false; /* Relation is not set for a schema */ if (stmt->relation) - exec_type = ExecUtilityFindNodes(queryString, - stmt->renameType, - RangeVarGetRelid(stmt->relation, false)); + exec_type = ExecUtilityFindNodes(stmt->renameType, + RangeVarGetRelid(stmt->relation, false), + &is_temp); else exec_type = EXEC_ON_ALL_NODES; ExecUtilityStmtOnNodes(queryString, NULL, false, - exec_type); + exec_type, + is_temp); } #endif ExecRenameStmt((RenameStmt *) parsetree); @@ -1004,19 +1129,21 @@ standard_ProcessUtility(Node *parsetree, if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) { AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree; - RemoteQueryExecType exec_type; + bool is_temp = false; + if (stmt->relation) - exec_type = ExecUtilityFindNodes(queryString, - stmt->objectType, - RangeVarGetRelid(stmt->relation, false)); + exec_type = ExecUtilityFindNodes(stmt->objectType, + RangeVarGetRelid(stmt->relation, false), + &is_temp); else exec_type = EXEC_ON_ALL_NODES; ExecUtilityStmtOnNodes(queryString, NULL, false, - exec_type); + exec_type, + is_temp); } #endif ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree); @@ -1027,7 +1154,7 @@ standard_ProcessUtility(Node *parsetree, #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1045,12 +1172,14 @@ standard_ProcessUtility(Node *parsetree, */ if (isTopLevel) { + bool is_temp = false; AlterTableStmt *stmt = (AlterTableStmt *) parsetree; - RemoteQueryExecType exec_type = ExecUtilityFindNodes(queryString, - stmt->relkind, - RangeVarGetRelid(stmt->relation, false)); + RemoteQueryExecType exec_type; + exec_type = ExecUtilityFindNodes(stmt->relkind, + RangeVarGetRelid(stmt->relation, false), + &is_temp); - stmts = AddRemoteQueryNode(stmts, queryString, exec_type); + stmts = AddRemoteQueryNode(stmts, queryString, exec_type, is_temp); } #endif @@ -1126,7 +1255,7 @@ standard_ProcessUtility(Node *parsetree, } #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1136,6 +1265,7 @@ standard_ProcessUtility(Node *parsetree, { RemoteQueryExecType remoteExecType = EXEC_ON_ALL_NODES; GrantStmt *stmt = (GrantStmt *) parsetree; + bool is_temp = false; /* Launch GRANT on Coordinator if object is a sequence */ if ((stmt->objtype == ACL_OBJECT_RELATION && @@ -1156,22 +1286,9 @@ standard_ProcessUtility(Node *parsetree, RangeVar *relvar = (RangeVar *) lfirst(cell); Oid relid = RangeVarGetRelid(relvar, false); - if (get_rel_relkind(relid) == RELKIND_SEQUENCE || - get_rel_relkind(relid) == RELKIND_VIEW) - { - /* PGXCTODO: extend that for temporary views and tables */ - if (get_rel_relkind(relid) == RELKIND_SEQUENCE && - IsTempSequence(relid)) - remoteExecType = EXEC_ON_NONE; - else - remoteExecType = EXEC_ON_COORDS; - } - else - { - remoteExecType = EXEC_ON_ALL_NODES; - } + remoteExecType = ExecUtilityFindNodesRelkind(relid, &is_temp); - /* Check if objects can be launched at the same place as 1st one */ + /* Check if object node type corresponds to the first one */ if (first) { type_local = remoteExecType; @@ -1183,11 +1300,11 @@ standard_ProcessUtility(Node *parsetree, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("PGXC does not support GRANT on multiple object types"), - errdetail("Grant VIEW/SEQUENCE and relations on separate queries"))); + errdetail("Grant VIEW/SEQUENCE/TABLE with separate queries"))); } } } - ExecUtilityStmtOnNodes(queryString, NULL, false, remoteExecType); + ExecUtilityStmtOnNodes(queryString, NULL, false, remoteExecType, is_temp); } #endif ExecuteGrantStmt((GrantStmt *) parsetree); @@ -1198,7 +1315,7 @@ standard_ProcessUtility(Node *parsetree, #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1207,7 +1324,7 @@ standard_ProcessUtility(Node *parsetree, #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1260,7 +1377,7 @@ standard_ProcessUtility(Node *parsetree, } #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1272,7 +1389,7 @@ standard_ProcessUtility(Node *parsetree, } #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1280,7 +1397,7 @@ standard_ProcessUtility(Node *parsetree, DefineEnum((CreateEnumStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1299,7 +1416,16 @@ standard_ProcessUtility(Node *parsetree, DefineView((ViewStmt *) parsetree, queryString); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_COORDS); + { + /* + * If view is temporary, no need to send this query to other + * remote Coordinators + */ + ViewStmt *stmt = (ViewStmt *) parsetree; + + if (stmt->view->relpersistence != RELPERSISTENCE_TEMP) + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_COORDS, false); + } #endif break; @@ -1307,7 +1433,7 @@ standard_ProcessUtility(Node *parsetree, CreateFunction((CreateFunctionStmt *) parsetree, queryString); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1315,7 +1441,7 @@ standard_ProcessUtility(Node *parsetree, AlterFunction((AlterFunctionStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1324,6 +1450,10 @@ standard_ProcessUtility(Node *parsetree, IndexStmt *stmt = (IndexStmt *) parsetree; #ifdef PGXC + Oid relid; + bool is_temp = false; + RemoteQueryExecType exec_type = EXEC_ON_ALL_NODES; + if (stmt->concurrent) { ereport(ERROR, @@ -1331,6 +1461,11 @@ standard_ProcessUtility(Node *parsetree, errmsg("PGXC does not support concurrent INDEX yet"), errdetail("The feature is not currently supported"))); } + + /* INDEX on a temporary table cannot use 2PC at commit */ + relid = RangeVarGetRelid(stmt->relation, true); + if (OidIsValid(relid)) + exec_type = ExecUtilityFindNodes(OBJECT_TABLE, relid, &is_temp); #endif if (stmt->concurrent) @@ -1365,7 +1500,7 @@ standard_ProcessUtility(Node *parsetree, #ifdef PGXC if (IS_PGXC_COORDINATOR && !stmt->isconstraint && !IsConnFromCoord()) ExecUtilityStmtOnNodes(queryString, NULL, - stmt->concurrent, EXEC_ON_ALL_NODES); + stmt->concurrent, exec_type, is_temp); #endif } break; @@ -1377,14 +1512,11 @@ standard_ProcessUtility(Node *parsetree, if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) { RemoteQueryExecType remoteExecType; + bool is_temp; Oid relid = RangeVarGetRelid(((RuleStmt *) parsetree)->relation, false); - if (get_rel_relkind(relid) == RELKIND_VIEW) - remoteExecType = EXEC_ON_COORDS; - else - remoteExecType = EXEC_ON_ALL_NODES; - - ExecUtilityStmtOnNodes(queryString, NULL, false, remoteExecType); + remoteExecType = ExecUtilityFindNodesRelkind(relid, &is_temp); + ExecUtilityStmtOnNodes(queryString, NULL, false, remoteExecType, is_temp); } #endif break; @@ -1400,9 +1532,8 @@ standard_ProcessUtility(Node *parsetree, */ CreateSeqStmt *stmt = (CreateSeqStmt *) parsetree; - if (stmt->sequence->relpersistence == RELPERSISTENCE_PERMANENT || - stmt->sequence->relpersistence == RELPERSISTENCE_UNLOGGED) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_COORDS); + if (stmt->sequence->relpersistence != RELPERSISTENCE_TEMP) + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_COORDS, false); } #endif break; @@ -1420,7 +1551,7 @@ standard_ProcessUtility(Node *parsetree, Oid relid = RangeVarGetRelid(stmt->sequence, false); if (!IsTempSequence(relid)) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_COORDS); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_COORDS, false); } #endif break; @@ -1448,7 +1579,7 @@ standard_ProcessUtility(Node *parsetree, } #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1461,7 +1592,7 @@ standard_ProcessUtility(Node *parsetree, createdb((CreatedbStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_ALL_NODES, false); #endif break; @@ -1469,7 +1600,7 @@ standard_ProcessUtility(Node *parsetree, AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1477,7 +1608,7 @@ standard_ProcessUtility(Node *parsetree, AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1495,7 +1626,7 @@ standard_ProcessUtility(Node *parsetree, /* Clean also remote Coordinators */ sprintf(query, "CLEAN CONNECTION TO ALL FOR DATABASE %s;", stmt->dbname); - ExecUtilityStmtOnNodes(query, NULL, true, EXEC_ON_COORDS); + ExecUtilityStmtOnNodes(query, NULL, true, EXEC_ON_COORDS, false); } #endif @@ -1504,7 +1635,7 @@ standard_ProcessUtility(Node *parsetree, } #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_ALL_NODES, false); #endif break; @@ -1551,7 +1682,7 @@ standard_ProcessUtility(Node *parsetree, } #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_DATANODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_DATANODES, false); #endif break; @@ -1561,7 +1692,7 @@ standard_ProcessUtility(Node *parsetree, cluster((ClusterStmt *) parsetree, isTopLevel); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_DATANODES); + ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_DATANODES, false); #endif break; @@ -1574,7 +1705,7 @@ standard_ProcessUtility(Node *parsetree, * vacuum() pops active snapshot and we can not send it to nodes */ if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_DATANODES); + ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_DATANODES, false); #endif vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false, isTopLevel); @@ -1596,8 +1727,16 @@ standard_ProcessUtility(Node *parsetree, * send this query to backend nodes */ if (!stmt->is_local || !IsTransactionBlock()) - if (PoolManagerSetCommand(stmt->is_local, queryString) < 0) + { + PoolCommandType command_type; + if (stmt->is_local) + command_type = POOL_CMD_LOCAL_SET; + else + command_type = POOL_CMD_GLOBAL_SET; + + if (PoolManagerSetCommand(command_type, queryString) < 0) elog(ERROR, "Postgres-XC: ERROR SET query"); + } } #endif break; @@ -1623,7 +1762,7 @@ standard_ProcessUtility(Node *parsetree, * send this query to backend nodes */ if (!IsTransactionBlock()) - if (PoolManagerSetCommand(false, queryString) < 0) + if (PoolManagerSetCommand(POOL_CMD_GLOBAL_SET, queryString) < 0) elog(ERROR, "Postgres-XC: ERROR DISCARD query"); } #endif @@ -1640,7 +1779,7 @@ standard_ProcessUtility(Node *parsetree, errdetail("The feature is not currently supported"))); if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1661,15 +1800,12 @@ standard_ProcessUtility(Node *parsetree, /* If rule is defined on a view, drop it only on Coordinators */ if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) { - RemoteQueryExecType remoteExecType; + RemoteQueryExecType remoteExecType = EXEC_ON_ALL_NODES; + bool is_temp = false; Oid relid = RangeVarGetRelid(stmt->relation, false); - if (get_rel_relkind(relid) == RELKIND_VIEW) - remoteExecType = EXEC_ON_COORDS; - else - remoteExecType = EXEC_ON_ALL_NODES; - - ExecUtilityStmtOnNodes(queryString, NULL, false, remoteExecType); + remoteExecType = ExecUtilityFindNodesRelkind(relid, &is_temp); + ExecUtilityStmtOnNodes(queryString, NULL, false, remoteExecType, is_temp); } #endif break; @@ -1679,7 +1815,7 @@ standard_ProcessUtility(Node *parsetree, stmt->behavior, stmt->missing_ok); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; default: @@ -1694,7 +1830,7 @@ standard_ProcessUtility(Node *parsetree, CreateProceduralLanguage((CreatePLangStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1702,7 +1838,7 @@ standard_ProcessUtility(Node *parsetree, DropProceduralLanguage((DropPLangStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1713,7 +1849,7 @@ standard_ProcessUtility(Node *parsetree, DefineDomain((CreateDomainStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1724,7 +1860,7 @@ standard_ProcessUtility(Node *parsetree, CreateRole((CreateRoleStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1732,7 +1868,7 @@ standard_ProcessUtility(Node *parsetree, AlterRole((AlterRoleStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1740,7 +1876,7 @@ standard_ProcessUtility(Node *parsetree, AlterRoleSet((AlterRoleSetStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1748,7 +1884,7 @@ standard_ProcessUtility(Node *parsetree, DropRole((DropRoleStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1756,7 +1892,7 @@ standard_ProcessUtility(Node *parsetree, DropOwnedObjects((DropOwnedStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1764,7 +1900,7 @@ standard_ProcessUtility(Node *parsetree, ReassignOwnedObjects((ReassignOwnedStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1778,7 +1914,7 @@ standard_ProcessUtility(Node *parsetree, LockTableCommand((LockStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1810,7 +1946,7 @@ standard_ProcessUtility(Node *parsetree, (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE)); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_DATANODES); + ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_DATANODES, false); #endif break; @@ -1855,7 +1991,7 @@ standard_ProcessUtility(Node *parsetree, #ifdef PGXC if (IS_PGXC_COORDINATOR) ExecUtilityStmtOnNodes(queryString, NULL, - stmt->kind == OBJECT_DATABASE, EXEC_ON_ALL_NODES); + stmt->kind == OBJECT_DATABASE, EXEC_ON_ALL_NODES, false); #endif break; } @@ -1865,7 +2001,7 @@ standard_ProcessUtility(Node *parsetree, CreateConversionCommand((CreateConversionStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1873,7 +2009,7 @@ standard_ProcessUtility(Node *parsetree, CreateCast((CreateCastStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1881,7 +2017,7 @@ standard_ProcessUtility(Node *parsetree, DropCast((DropCastStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1889,7 +2025,7 @@ standard_ProcessUtility(Node *parsetree, DefineOpClass((CreateOpClassStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1897,7 +2033,7 @@ standard_ProcessUtility(Node *parsetree, DefineOpFamily((CreateOpFamilyStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1905,7 +2041,7 @@ standard_ProcessUtility(Node *parsetree, AlterOpFamily((AlterOpFamilyStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1913,7 +2049,7 @@ standard_ProcessUtility(Node *parsetree, RemoveOpClass((RemoveOpClassStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1921,7 +2057,7 @@ standard_ProcessUtility(Node *parsetree, RemoveOpFamily((RemoveOpFamilyStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1929,7 +2065,7 @@ standard_ProcessUtility(Node *parsetree, AlterTSDictionary((AlterTSDictionaryStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; @@ -1937,7 +2073,7 @@ standard_ProcessUtility(Node *parsetree, AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree); #ifdef PGXC if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES); + ExecUtilityStmtOnNodes(queryString, NULL, false, EXEC_ON_ALL_NODES, false); #endif break; #ifdef PGXC @@ -1956,7 +2092,7 @@ standard_ProcessUtility(Node *parsetree, CleanConnection((CleanConnStmt *) parsetree); if (IS_PGXC_COORDINATOR) - ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_COORDS); + ExecUtilityStmtOnNodes(queryString, NULL, true, EXEC_ON_COORDS, false); break; #endif default: @@ -1975,7 +2111,7 @@ standard_ProcessUtility(Node *parsetree, */ static void ExecUtilityStmtOnNodes(const char *queryString, ExecNodes *nodes, - bool force_autocommit, RemoteQueryExecType exec_type) + bool force_autocommit, RemoteQueryExecType exec_type, bool is_temp) { /* Return if query is launched on no nodes */ if (exec_type == EXEC_ON_NONE) @@ -1989,6 +2125,7 @@ ExecUtilityStmtOnNodes(const char *queryString, ExecNodes *nodes, step->sql_statement = pstrdup(queryString); step->force_autocommit = force_autocommit; step->exec_type = exec_type; + step->is_temp = is_temp; ExecRemoteUtility(step); pfree(step->sql_statement); pfree(step); @@ -2000,37 +2137,97 @@ ExecUtilityStmtOnNodes(const char *queryString, ExecNodes *nodes, * * Determine the list of nodes to launch query on. * This depends on temporary nature of object and object type. - * PGXCTODO: Extend temporary object check for tables. + * Return also a flag indicating if relation is temporary. */ static RemoteQueryExecType -ExecUtilityFindNodes(const char *queryString, - ObjectType object_type, - Oid relid) +ExecUtilityFindNodes(ObjectType object_type, + Oid relid, + bool *is_temp) { - bool is_temp = false; - RemoteQueryExecType remoteExecType = EXEC_ON_NONE; + RemoteQueryExecType exec_type; - /* Check if object is a temporary sequence */ - if (object_type == OBJECT_SEQUENCE || - (object_type == OBJECT_TABLE && - get_rel_relkind(relid) == RELKIND_SEQUENCE)) - is_temp = IsTempSequence(relid); + switch (object_type) + { + case OBJECT_SEQUENCE: + /* Check if object is a temporary sequence */ + if ((*is_temp = IsTempSequence(relid))) + exec_type = EXEC_ON_NONE; + else + exec_type = EXEC_ON_COORDS; + break; + + case OBJECT_TABLE: + /* Do the check on relation kind */ + exec_type = ExecUtilityFindNodesRelkind(relid, is_temp); + break; + + case OBJECT_VIEW: + /* Check if object is a temporary view */ + if ((*is_temp = IsTempTable(relid))) + exec_type = EXEC_ON_NONE; + else + exec_type = EXEC_ON_COORDS; + break; + + case OBJECT_INDEX: + /* Check if given index uses temporary tables */ + if ((*is_temp = IsIndexUsingTempTable(relid))) + exec_type = EXEC_ON_DATANODES; + else + exec_type = EXEC_ON_ALL_NODES; + break; + + default: + *is_temp = false; + exec_type = EXEC_ON_ALL_NODES; + break; + } + + return exec_type; +} - if (!is_temp) +/* + * ExecUtilityFindNodesRelkind + * + * Get node execution and temporary type + * for given relation depending on its relkind + */ +static RemoteQueryExecType +ExecUtilityFindNodesRelkind(Oid relid, bool *is_temp) +{ + char relkind_str = get_rel_relkind(relid); + RemoteQueryExecType exec_type; + + switch (relkind_str) { - remoteExecType = EXEC_ON_ALL_NODES; + case RELKIND_SEQUENCE: + if ((*is_temp = IsTempSequence(relid))) + exec_type = EXEC_ON_NONE; + else + exec_type = EXEC_ON_COORDS; + break; - if (object_type == OBJECT_SEQUENCE || - object_type == OBJECT_VIEW) - remoteExecType = EXEC_ON_COORDS; - else if (object_type == OBJECT_TABLE) - { - if (get_rel_relkind(relid) == RELKIND_SEQUENCE) - remoteExecType = EXEC_ON_COORDS; - } + case RELKIND_RELATION: + if ((*is_temp = IsTempTable(relid))) + exec_type = EXEC_ON_DATANODES; + else + exec_type = EXEC_ON_ALL_NODES; + break; + + case RELKIND_VIEW: + if ((*is_temp = IsTempTable(relid))) + exec_type = EXEC_ON_NONE; + else + exec_type = EXEC_ON_COORDS; + break; + + default: + *is_temp = false; + exec_type = EXEC_ON_ALL_NODES; + break; } - return remoteExecType; + return exec_type; } #endif diff --git a/src/include/commands/comment.h b/src/include/commands/comment.h index 1b12e81bdd..b3d8da156f 100644 --- a/src/include/commands/comment.h +++ b/src/include/commands/comment.h @@ -41,4 +41,8 @@ extern void CreateSharedComments(Oid oid, Oid classoid, char *comment); extern char *GetComment(Oid oid, Oid classoid, int32 subid); +#ifdef PGXC +extern Oid GetCommentObjectId(CommentStmt *stmt); +#endif + #endif /* COMMENT_H */ diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index 3f971eb218..7d46ede251 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -70,5 +70,13 @@ extern void AtEOXact_on_commit_actions(bool isCommit); extern void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid); +#ifdef PGXC +extern bool IsTempTable(Oid relid); +extern bool IsIndexUsingTempTable(Oid relid); +extern bool IsOnCommitActions(void); +extern void DropTableThrowErrorExternal(RangeVar *relation, + ObjectType removeType, + bool missing_ok); +#endif #endif /* TABLECMDS_H */ diff --git a/src/include/pgxc/execRemote.h b/src/include/pgxc/execRemote.h index 48d23ca399..cf25c2d966 100644 --- a/src/include/pgxc/execRemote.h +++ b/src/include/pgxc/execRemote.h @@ -162,5 +162,7 @@ extern int ParamListToDataRow(ParamListInfo params, char** result); extern void ExecCloseRemoteStatement(const char *stmt_name, List *nodelist); +extern void ExecSetTempObjectIncluded(void); + extern int primary_data_node; #endif diff --git a/src/include/pgxc/planner.h b/src/include/pgxc/planner.h index edb2174dbf..efba3c4e09 100644 --- a/src/include/pgxc/planner.h +++ b/src/include/pgxc/planner.h @@ -106,6 +106,8 @@ typedef struct * plan. So, don't change this once set. */ RemoteQueryExecType exec_type; + bool is_temp; /* determine if this remote node is based + * on a temporary objects (no 2PC) */ /* Support for parameters */ char *paramval_data; /* parameter data, format is like in BIND */ @@ -147,6 +149,7 @@ extern bool IsHashDistributable(Oid col_type); extern bool IsJoinReducible(RemoteQuery *innernode, RemoteQuery *outernode, List *rtable_list, JoinPath *join_path, JoinReduceInfo *join_info); -extern List *AddRemoteQueryNode(List *stmts, const char *queryString, RemoteQueryExecType remoteExecType); +extern List *AddRemoteQueryNode(List *stmts, const char *queryString, + RemoteQueryExecType remoteExecType, bool is_temp); #endif /* PGXCPLANNER_H */ diff --git a/src/include/pgxc/poolmgr.h b/src/include/pgxc/poolmgr.h index 79397687da..bf74a6eb49 100644 --- a/src/include/pgxc/poolmgr.h +++ b/src/include/pgxc/poolmgr.h @@ -23,6 +23,28 @@ #define MAX_IDLE_TIME 60 +/* + * List of flags related to pooler connection clean up when disconnecting + * a session or relaeasing handles. + * When Local SET commands (POOL_CMD_LOCAL_SET) are used, local parameter + * string is cleaned by the node commit itself. + * When global SET commands (POOL_CMD_GLOBAL_SET) are used, "RESET ALL" + * command is sent down to activated nodes to at session end. At the end + * of a transaction, connections using global SET commands are not sent + * back to pool. + * When temporary object commands are used (POOL_CMD_TEMP), "DISCARD ALL" + * query is sent down to nodes whose connection is activated at the end of + * a session. + * At the end of a transaction, a session using either temporary objects + * or global session parameters has its connections not sent back to pool. + */ +typedef enum +{ + POOL_CMD_TEMP, /* Temporary object flag */ + POOL_CMD_LOCAL_SET, /* Local SET flag */ + POOL_CMD_GLOBAL_SET /* Global SET flag */ +} PoolCommandType; + /* TODO move? */ typedef struct { @@ -73,6 +95,7 @@ typedef struct PGXCNodePoolSlot **coord_connections; /* one for each Coordinator */ char *session_params; char *local_params; + bool is_temp; /* Temporary objects used for this pool session? */ } PoolAgent; /* Handle to the pool manager (Session's side) */ @@ -136,7 +159,7 @@ extern void PoolManagerConnect(PoolHandle *handle, const char *database, const c * and stored in pooler agent to be replayed when new connections * are requested. */ -extern int PoolManagerSetCommand(bool is_local, const char *set_command); +extern int PoolManagerSetCommand(PoolCommandType command_type, const char *set_command); /* Get pooled connections */ extern int *PoolManagerGetConnections(List *datanodelist, List *coordlist); diff --git a/src/test/regress/expected/cluster_1.out b/src/test/regress/expected/cluster_1.out index 8017e1e351..f5f24ad093 100644 --- a/src/test/regress/expected/cluster_1.out +++ b/src/test/regress/expected/cluster_1.out @@ -373,19 +373,17 @@ SELECT * FROM clustertest ORDER BY 1; -- check that temp tables can be clustered create temp table clstr_temp (col1 int primary key, col2 text); -ERROR: PG-XC does not yet support temporary tables +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "clstr_temp_pkey" for table "clstr_temp" insert into clstr_temp values (2, 'two'), (1, 'one'); -ERROR: relation "clstr_temp" does not exist -LINE 1: insert into clstr_temp values (2, 'two'), (1, 'one'); - ^ cluster clstr_temp using clstr_temp_pkey; -ERROR: relation "clstr_temp" does not exist -select * from clstr_temp; -ERROR: relation "clstr_temp" does not exist -LINE 1: select * from clstr_temp; - ^ +select * from clstr_temp order by 1; + col1 | col2 +------+------ + 1 | one + 2 | two +(2 rows) + drop table clstr_temp; -ERROR: table "clstr_temp" does not exist -- clean up \c - DROP TABLE clustertest; diff --git a/src/test/regress/expected/combocid_1.out b/src/test/regress/expected/combocid_1.out index eab70859b9..dbd2dc27cb 100644 --- a/src/test/regress/expected/combocid_1.out +++ b/src/test/regress/expected/combocid_1.out @@ -2,39 +2,29 @@ -- Tests for some likely failure cases with combo cmin/cmax mechanism -- CREATE TEMP TABLE combocidtest (foobar int); -ERROR: PG-XC does not yet support temporary tables BEGIN; -- a few dummy ops to push up the CommandId counter INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: relation "combocidtest" does not exist -LINE 1: INSERT INTO combocidtest SELECT 1 LIMIT 0; - ^ INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest VALUES (1); -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest VALUES (2); -ERROR: current transaction is aborted, commands ignored until end of transaction block SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; -ERROR: current transaction is aborted, commands ignored until end of transaction block + ctid | cmin | foobar +-------+------+-------- + (0,1) | 0 | 1 + (0,1) | 0 | 2 +(2 rows) + SAVEPOINT s1; -ERROR: current transaction is aborted, commands ignored until end of transaction block +ERROR: SAVEPOINT is not yet supported. UPDATE combocidtest SET foobar = foobar + 10; ERROR: current transaction is aborted, commands ignored until end of transaction block -- here we should see only updated tuples @@ -48,57 +38,48 @@ ERROR: current transaction is aborted, commands ignored until end of transactio COMMIT; -- combo data is not there anymore, but should still see tuples SELECT ctid,cmin,* FROM combocidtest; -ERROR: relation "combocidtest" does not exist -LINE 1: SELECT ctid,cmin,* FROM combocidtest; - ^ + ctid | cmin | foobar +------+------+-------- +(0 rows) + -- Test combo cids with portals BEGIN; INSERT INTO combocidtest VALUES (333); -ERROR: relation "combocidtest" does not exist -LINE 1: INSERT INTO combocidtest VALUES (333); - ^ DECLARE c CURSOR FOR SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; -ERROR: current transaction is aborted, commands ignored until end of transaction block DELETE FROM combocidtest; -ERROR: current transaction is aborted, commands ignored until end of transaction block FETCH ALL FROM c; -ERROR: current transaction is aborted, commands ignored until end of transaction block + ctid | cmin | foobar +------+------+-------- +(0 rows) + ROLLBACK; SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; -ERROR: relation "combocidtest" does not exist -LINE 1: SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; - ^ + ctid | cmin | foobar +------+------+-------- +(0 rows) + -- check behavior with locked tuples BEGIN; -- a few dummy ops to push up the CommandId counter INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: relation "combocidtest" does not exist -LINE 1: INSERT INTO combocidtest SELECT 1 LIMIT 0; - ^ INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest SELECT 1 LIMIT 0; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO combocidtest VALUES (444); -ERROR: current transaction is aborted, commands ignored until end of transaction block SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; -ERROR: current transaction is aborted, commands ignored until end of transaction block + ctid | cmin | foobar +-------+------+-------- + (0,3) | 0 | 444 +(1 row) + SAVEPOINT s1; -ERROR: current transaction is aborted, commands ignored until end of transaction block +ERROR: SAVEPOINT is not yet supported. -- this doesn't affect cmin SELECT ctid,cmin,* FROM combocidtest FOR UPDATE; ERROR: current transaction is aborted, commands ignored until end of transaction block @@ -115,6 +96,7 @@ SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; ERROR: current transaction is aborted, commands ignored until end of transaction block COMMIT; SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; -ERROR: relation "combocidtest" does not exist -LINE 1: SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; - ^ + ctid | cmin | foobar +------+------+-------- +(0 rows) + diff --git a/src/test/regress/expected/copy2_1.out b/src/test/regress/expected/copy2_1.out index 9ff656ca33..d9b149e37f 100644 --- a/src/test/regress/expected/copy2_1.out +++ b/src/test/regress/expected/copy2_1.out @@ -167,78 +167,69 @@ CREATE TEMP TABLE y ( col1 text, col2 text ); -ERROR: PG-XC does not yet support temporary tables INSERT INTO y VALUES ('Jackson, Sam', E'\\h'); -ERROR: relation "y" does not exist -LINE 1: INSERT INTO y VALUES ('Jackson, Sam', E'\\h'); - ^ INSERT INTO y VALUES ('It is "perfect".',E'\t'); -ERROR: relation "y" does not exist -LINE 1: INSERT INTO y VALUES ('It is "perfect".',E'\t'); - ^ INSERT INTO y VALUES ('', NULL); -ERROR: relation "y" does not exist -LINE 1: INSERT INTO y VALUES ('', NULL); - ^ COPY y TO stdout WITH CSV; -ERROR: relation "y" does not exist +"Jackson, Sam",\h +"It is ""perfect"".", +"", COPY y TO stdout WITH CSV QUOTE '''' DELIMITER '|'; -ERROR: relation "y" does not exist +Jackson, Sam|\h +It is "perfect".| +''| COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE E'\\' ENCODING 'sql_ascii'; -ERROR: relation "y" does not exist +"Jackson, Sam","\\h" +"It is \"perfect\"."," " +"", COPY y TO stdout WITH CSV FORCE QUOTE *; -ERROR: relation "y" does not exist +"Jackson, Sam",\h +"It is ""perfect"".", +"", -- Repeat above tests with new 9.0 option syntax COPY y TO stdout (FORMAT CSV); -ERROR: relation "y" does not exist +"Jackson, Sam",\h +"It is ""perfect"".", +"", COPY y TO stdout (FORMAT CSV, QUOTE '''', DELIMITER '|'); -ERROR: relation "y" does not exist +Jackson, Sam|\h +It is "perfect".| +''| COPY y TO stdout (FORMAT CSV, FORCE_QUOTE (col2), ESCAPE E'\\'); -ERROR: relation "y" does not exist +"Jackson, Sam","\\h" +"It is \"perfect\"."," " +"", COPY y TO stdout (FORMAT CSV, FORCE_QUOTE *); -ERROR: relation "y" does not exist +"Jackson, Sam",\h +"It is ""perfect"".", +"", \copy y TO stdout (FORMAT CSV) -ERROR: relation "y" does not exist -\copy: ERROR: relation "y" does not exist +"Jackson, Sam",\h +"It is ""perfect"".", +"", \copy y TO stdout (FORMAT CSV, QUOTE '''', DELIMITER '|') -ERROR: relation "y" does not exist -\copy: ERROR: relation "y" does not exist +Jackson, Sam|\h +It is "perfect".| +''| \copy y TO stdout (FORMAT CSV, FORCE_QUOTE (col2), ESCAPE E'\\') -ERROR: relation "y" does not exist -\copy: ERROR: relation "y" does not exist +"Jackson, Sam","\\h" +"It is \"perfect\"."," " +"", \copy y TO stdout (FORMAT CSV, FORCE_QUOTE *) -ERROR: relation "y" does not exist -\copy: ERROR: relation "y" does not exist +"Jackson, Sam",\h +"It is ""perfect"".", +"", --test that we read consecutive LFs properly CREATE TEMP TABLE testnl (a int, b text, c int); -ERROR: PG-XC does not yet support temporary tables COPY testnl FROM stdin CSV; -ERROR: relation "testnl" does not exist -1,"a field with two LFs - -inside",2 -\. -invalid command \. -- test end of copy marker CREATE TEMP TABLE testeoc (a text); -ERROR: syntax error at or near "1" -LINE 1: 1,"a field with two LFs - ^ COPY testeoc FROM stdin CSV; -ERROR: relation "testeoc" does not exist +COPY testeoc TO stdout CSV; a\. -invalid command \. \.b -invalid command \.b c\.d -invalid command \.d "\." -\. -invalid command \. -COPY testeoc TO stdout CSV; -ERROR: syntax error at or near "a" -LINE 1: a - ^ DROP TABLE x, y; ERROR: table "x" does not exist DROP FUNCTION fn_x_before(); diff --git a/src/test/regress/expected/domain_1.out b/src/test/regress/expected/domain_1.out index 6c158f2c66..f2f45379d6 100644 --- a/src/test/regress/expected/domain_1.out +++ b/src/test/regress/expected/domain_1.out @@ -438,33 +438,18 @@ ERROR: value for domain dtop violates check constraint "dinter_check" select 'xz23'::dtop; -- fail ERROR: value for domain dtop violates check constraint "dtop_check" create temp table dtest(f1 dtop); -ERROR: PG-XC does not yet support temporary tables insert into dtest values('x123'); -ERROR: relation "dtest" does not exist -LINE 1: insert into dtest values('x123'); - ^ insert into dtest values('x1234'); -- fail, implicit coercion -ERROR: relation "dtest" does not exist -LINE 1: insert into dtest values('x1234'); - ^ +ERROR: value too long for type character varying(4) insert into dtest values('y1234'); -- fail, implicit coercion -ERROR: relation "dtest" does not exist -LINE 1: insert into dtest values('y1234'); - ^ +ERROR: value too long for type character varying(4) insert into dtest values('y123'); -- fail -ERROR: relation "dtest" does not exist -LINE 1: insert into dtest values('y123'); - ^ +ERROR: value for domain dtop violates check constraint "dinter_check" insert into dtest values('yz23'); -- fail -ERROR: relation "dtest" does not exist -LINE 1: insert into dtest values('yz23'); - ^ +ERROR: value for domain dtop violates check constraint "dinter_check" insert into dtest values('xz23'); -- fail -ERROR: relation "dtest" does not exist -LINE 1: insert into dtest values('xz23'); - ^ +ERROR: value for domain dtop violates check constraint "dtop_check" drop table dtest; -ERROR: table "dtest" does not exist drop domain vchar4 cascade; NOTICE: drop cascades to 2 other objects DETAIL: drop cascades to type dinter @@ -636,27 +621,19 @@ select array[1,2]::orderedpair; select array[2,1]::orderedpair; -- fail ERROR: value for domain orderedpair violates check constraint "orderedpair_check" create temp table op (f1 orderedpair); -ERROR: PG-XC does not yet support temporary tables insert into op values (array[1,2]); -ERROR: relation "op" does not exist -LINE 1: insert into op values (array[1,2]); - ^ insert into op values (array[2,1]); -- fail -ERROR: relation "op" does not exist -LINE 1: insert into op values (array[2,1]); - ^ +ERROR: value for domain orderedpair violates check constraint "orderedpair_check" update op set f1[2] = 3; -ERROR: relation "op" does not exist -LINE 1: update op set f1[2] = 3; - ^ +ERROR: syntax error at or near ":=" update op set f1[2] = 0; -- fail -ERROR: relation "op" does not exist -LINE 1: update op set f1[2] = 0; - ^ +ERROR: syntax error at or near ":=" select * from op; -ERROR: relation "op" does not exist -LINE 1: select * from op; - ^ + f1 +------- + {1,2} +(1 row) + create or replace function array_elem_check(int) returns int as $$ declare x orderedpair := '{1,2}'; diff --git a/src/test/regress/expected/foreign_key_1.out b/src/test/regress/expected/foreign_key_1.out index 560b5e9f70..8dc155a63a 100644 --- a/src/test/regress/expected/foreign_key_1.out +++ b/src/test/regress/expected/foreign_key_1.out @@ -1125,7 +1125,8 @@ CREATE TEMP TABLE pktable ( id3 REAL UNIQUE, UNIQUE(id1, id2, id3) ); -ERROR: PG-XC does not yet support temporary tables +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" +ERROR: Unique index of partitioned table must contain the hash/modulo distribution column. CREATE TEMP TABLE fktable ( x1 INT4 REFERENCES pktable(id1), x2 VARCHAR(4) REFERENCES pktable(id2), @@ -1197,7 +1198,7 @@ CREATE TEMP TABLE pktable ( id int primary key, other int ); -ERROR: PG-XC does not yet support temporary tables +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable" CREATE TEMP TABLE fktable ( id int primary key, fk int references pktable deferrable initially deferred @@ -1205,9 +1206,6 @@ CREATE TEMP TABLE fktable ( ERROR: Postgres-XC does not support DEFERRED constraints yet DETAIL: The feature is not currently supported INSERT INTO pktable VALUES (5, 10); -ERROR: relation "pktable" does not exist -LINE 1: INSERT INTO pktable VALUES (5, 10); - ^ BEGIN; -- doesn't match PK, but no error yet INSERT INTO fktable VALUES (0, 20); @@ -1272,26 +1270,17 @@ CREATE TEMP TABLE users ( id INT PRIMARY KEY, name VARCHAR NOT NULL ); -ERROR: PG-XC does not yet support temporary tables +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "users_pkey" for table "users" INSERT INTO users VALUES (1, 'Jozko'); -ERROR: relation "users" does not exist -LINE 1: INSERT INTO users VALUES (1, 'Jozko'); - ^ INSERT INTO users VALUES (2, 'Ferko'); -ERROR: relation "users" does not exist -LINE 1: INSERT INTO users VALUES (2, 'Ferko'); - ^ INSERT INTO users VALUES (3, 'Samko'); -ERROR: relation "users" does not exist -LINE 1: INSERT INTO users VALUES (3, 'Samko'); - ^ CREATE TEMP TABLE tasks ( id INT PRIMARY KEY, owner INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL, worker INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL, checked_by INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL ); -ERROR: relation "users" does not exist +ERROR: Hash/Modulo distributed table must include distribution column in index INSERT INTO tasks VALUES (1,1,NULL,NULL); ERROR: relation "tasks" does not exist LINE 1: INSERT INTO tasks VALUES (1,1,NULL,NULL); @@ -1309,17 +1298,12 @@ ERROR: relation "tasks" does not exist LINE 1: SELECT * FROM tasks ORDER BY 1, 2, 3,4; ^ UPDATE users SET id = 4 WHERE id = 3; -ERROR: relation "users" does not exist -LINE 1: UPDATE users SET id = 4 WHERE id = 3; - ^ +ERROR: Partition column can't be updated in current version SELECT * FROM tasks ORDER BY 1, 2, 3,4; ERROR: relation "tasks" does not exist LINE 1: SELECT * FROM tasks ORDER BY 1, 2, 3,4; ^ DELETE FROM users WHERE id = 4; -ERROR: relation "users" does not exist -LINE 1: DELETE FROM users WHERE id = 4; - ^ SELECT * FROM tasks ORDER BY 1, 2, 3,4; ERROR: relation "tasks" does not exist LINE 1: SELECT * FROM tasks ORDER BY 1, 2, 3,4; diff --git a/src/test/regress/expected/functional_deps_1.out b/src/test/regress/expected/functional_deps_1.out index 4fa16821b1..24920e72a5 100644 --- a/src/test/regress/expected/functional_deps_1.out +++ b/src/test/regress/expected/functional_deps_1.out @@ -6,14 +6,15 @@ CREATE TEMP TABLE articles ( body text UNIQUE, created date ); -ERROR: PG-XC does not yet support temporary tables +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "articles_pkey" for table "articles" +ERROR: Unique index of partitioned table must contain the hash/modulo distribution column. CREATE TEMP TABLE articles_in_category ( article_id int, category_id int, changed date, PRIMARY KEY (article_id, category_id) ); -ERROR: PG-XC does not yet support temporary tables +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "articles_in_category_pkey" for table "articles_in_category" -- test functional dependencies based on primary keys/unique constraints -- base tables -- group by primary key (OK) @@ -96,32 +97,29 @@ LINE 2: FROM articles AS a JOIN articles_in_category AS aic ON a.id ... ^ -- example from documentation CREATE TEMP TABLE products (product_id int, name text, price numeric); -ERROR: PG-XC does not yet support temporary tables CREATE TEMP TABLE sales (product_id int, units int); -ERROR: PG-XC does not yet support temporary tables -- OK SELECT product_id, p.name, (sum(s.units) * p.price) AS sales FROM products p LEFT JOIN sales s USING (product_id) GROUP BY product_id, p.name, p.price; -ERROR: relation "products" does not exist -LINE 2: FROM products p LEFT JOIN sales s USING (product_id) - ^ + product_id | name | sales +------------+------+------- +(0 rows) + -- fail SELECT product_id, p.name, (sum(s.units) * p.price) AS sales FROM products p LEFT JOIN sales s USING (product_id) GROUP BY product_id; -ERROR: relation "products" does not exist -LINE 2: FROM products p LEFT JOIN sales s USING (product_id) - ^ +ERROR: column "p.name" must appear in the GROUP BY clause or be used in an aggregate function +LINE 1: SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + ^ ALTER TABLE products ADD PRIMARY KEY (product_id); -ERROR: relation "products" does not exist +NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "products_pkey" for table "products" -- OK now SELECT product_id, p.name, (sum(s.units) * p.price) AS sales FROM products p LEFT JOIN sales s USING (product_id) GROUP BY product_id; -ERROR: relation "products" does not exist -LINE 2: FROM products p LEFT JOIN sales s USING (product_id) - ^ +ERROR: column "group_2.name_1_2_1" must appear in the GROUP BY clause or be used in an aggregate function -- Drupal example, http://drupal.org/node/555530 CREATE TEMP TABLE node ( nid SERIAL, @@ -144,7 +142,8 @@ CREATE TEMP TABLE users ( PRIMARY KEY (uid), UNIQUE (name) ); -ERROR: PG-XC does not yet support temporary tables +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "users_pkey" for table "users" +ERROR: Unique index of partitioned table must contain the hash/modulo distribution column. -- OK SELECT u.uid, u.name FROM node n INNER JOIN users u ON u.uid = n.uid @@ -195,7 +194,6 @@ LINE 3: FROM articles AS a JOIN articles_in_category AS aic ON a.id ... ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; -- fail ERROR: relation "articles" does not exist ALTER TABLE articles_in_category DROP CONSTRAINT articles_in_category_pkey RESTRICT; --fail -ERROR: relation "articles_in_category" does not exist DROP VIEW fdv2; ERROR: view "fdv2" does not exist -- nested queries diff --git a/src/test/regress/expected/guc_1.out b/src/test/regress/expected/guc_1.out index 39790cc262..42e7e37037 100644 --- a/src/test/regress/expected/guc_1.out +++ b/src/test/regress/expected/guc_1.out @@ -416,11 +416,11 @@ SELECT '2006-08-13 12:34:56'::timestamptz; -- Test DISCARD TEMP -- CREATE TEMP TABLE reset_test ( data text ) ON COMMIT DELETE ROWS; -ERROR: PG-XC does not yet support temporary tables SELECT relname FROM pg_class WHERE relname = 'reset_test'; - relname ---------- -(0 rows) + relname +------------ + reset_test +(1 row) DISCARD TEMP; SELECT relname FROM pg_class WHERE relname = 'reset_test'; @@ -437,7 +437,6 @@ PREPARE foo AS SELECT 1; LISTEN foo_event; SET vacuum_cost_delay = 13; CREATE TEMP TABLE tmp_foo (data text) ON COMMIT DELETE ROWS; -ERROR: PG-XC does not yet support temporary tables CREATE ROLE temp_reset_user; SET SESSION AUTHORIZATION temp_reset_user; -- look changes @@ -468,7 +467,8 @@ SHOW vacuum_cost_delay; SELECT relname from pg_class where relname = 'tmp_foo'; relname --------- -(0 rows) + tmp_foo +(1 row) SELECT current_user = 'temp_reset_user'; ?column? diff --git a/src/test/regress/expected/polymorphism_1.out b/src/test/regress/expected/polymorphism_1.out index d78b7ed1e9..48e4dc6824 100644 --- a/src/test/regress/expected/polymorphism_1.out +++ b/src/test/regress/expected/polymorphism_1.out @@ -344,136 +344,205 @@ CREATE AGGREGATE mysum2(anyelement,anyelement) (SFUNC = sum3, STYPE = anyelement, INITCOND = '0'); -- create test data for polymorphic aggregates create temp table t(f1 int, f2 int[], f3 text); -ERROR: PG-XC does not yet support temporary tables insert into t values(1,array[1],'a'); -ERROR: relation "t" does not exist -LINE 1: insert into t values(1,array[1],'a'); - ^ insert into t values(1,array[11],'b'); -ERROR: relation "t" does not exist -LINE 1: insert into t values(1,array[11],'b'); - ^ insert into t values(1,array[111],'c'); -ERROR: relation "t" does not exist -LINE 1: insert into t values(1,array[111],'c'); - ^ insert into t values(2,array[2],'a'); -ERROR: relation "t" does not exist -LINE 1: insert into t values(2,array[2],'a'); - ^ insert into t values(2,array[22],'b'); -ERROR: relation "t" does not exist -LINE 1: insert into t values(2,array[22],'b'); - ^ insert into t values(2,array[222],'c'); -ERROR: relation "t" does not exist -LINE 1: insert into t values(2,array[222],'c'); - ^ insert into t values(3,array[3],'a'); -ERROR: relation "t" does not exist -LINE 1: insert into t values(3,array[3],'a'); - ^ insert into t values(3,array[3],'b'); -ERROR: relation "t" does not exist -LINE 1: insert into t values(3,array[3],'b'); - ^ -- test the successfully created polymorphic aggregates select f3, myaggp01a(*) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp01a(*) from t group by f3 order by f3; - ^ + f3 | myaggp01a +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggp03a(*) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp03a(*) from t group by f3 order by f3; - ^ + f3 | myaggp03a +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggp03b(*) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp03b(*) from t group by f3 order by f3; - ^ + f3 | myaggp03b +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggp05a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp05a(f1) from t group by f3 order by f3; - ^ + f3 | myaggp05a +----+----------- + a | {3,2,1} + b | {3,2,1} + c | {1,2} +(3 rows) + select f3, myaggp06a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp06a(f1) from t group by f3 order by f3; - ^ + f3 | myaggp06a +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggp08a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp08a(f1) from t group by f3 order by f3; - ^ + f3 | myaggp08a +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggp09a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp09a(f1) from t group by f3 order by f3; - ^ + f3 | myaggp09a +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggp09b(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp09b(f1) from t group by f3 order by f3; - ^ + f3 | myaggp09b +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggp10a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp10a(f1) from t group by f3 order by f3; - ^ + f3 | myaggp10a +----+----------- + a | {3,2,1} + b | {3,2,1} + c | {1,2} +(3 rows) + select f3, myaggp10b(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp10b(f1) from t group by f3 order by f3; - ^ + f3 | myaggp10b +----+----------- + a | {3,2,1} + b | {3,2,1} + c | {1,2} +(3 rows) + select f3, myaggp20a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp20a(f1) from t group by f3 order by f3; - ^ + f3 | myaggp20a +----+----------- + a | {3,2,1} + b | {3,2,1} + c | {1,2} +(3 rows) + select f3, myaggp20b(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggp20b(f1) from t group by f3 order by f3; - ^ + f3 | myaggp20b +----+----------- + a | {3,2,1} + b | {3,2,1} + c | {1,2} +(3 rows) + select f3, myaggn01a(*) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn01a(*) from t group by f3 order by f3; - ^ + f3 | myaggn01a +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggn01b(*) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn01b(*) from t group by f3 order by f3; - ^ + f3 | myaggn01b +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggn03a(*) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn03a(*) from t group by f3 order by f3; - ^ + f3 | myaggn03a +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggn05a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn05a(f1) from t group by f3 order by f3; - ^ + f3 | myaggn05a +----+----------- + a | {3,2,1} + b | {3,2,1} + c | {1,2} +(3 rows) + select f3, myaggn05b(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn05b(f1) from t group by f3 order by f3; - ^ + f3 | myaggn05b +----+----------- + a | {3,2,1} + b | {3,2,1} + c | {1,2} +(3 rows) + select f3, myaggn06a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn06a(f1) from t group by f3 order by f3; - ^ + f3 | myaggn06a +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggn06b(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn06b(f1) from t group by f3 order by f3; - ^ + f3 | myaggn06b +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggn08a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn08a(f1) from t group by f3 order by f3; - ^ + f3 | myaggn08a +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggn08b(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn08b(f1) from t group by f3 order by f3; - ^ + f3 | myaggn08b +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggn09a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn09a(f1) from t group by f3 order by f3; - ^ + f3 | myaggn09a +----+----------- + a | {} + b | {} + c | {} +(3 rows) + select f3, myaggn10a(f1) from t group by f3 order by f3; -ERROR: relation "t" does not exist -LINE 1: select f3, myaggn10a(f1) from t group by f3 order by f3; - ^ + f3 | myaggn10a +----+----------- + a | {2,1,3} + b | {3,1,2} + c | {2,1} +(3 rows) + select mysum2(f1, f1 + 1) from t; -ERROR: relation "t" does not exist -LINE 1: select mysum2(f1, f1 + 1) from t; - ^ + mysum2 +-------- + 38 +(1 row) + -- test inlining of polymorphic SQL functions create function bleat(int) returns int as $$ begin diff --git a/src/test/regress/expected/returning_1.out b/src/test/regress/expected/returning_1.out index c620a6a233..bbf24a7db2 100644 --- a/src/test/regress/expected/returning_1.out +++ b/src/test/regress/expected/returning_1.out @@ -77,7 +77,7 @@ LINE 1: SELECT * FROM foo ORDER BY f1; ^ -- Check inheritance cases CREATE TEMP TABLE foochild (fc int) INHERITS (foo); -ERROR: PG-XC does not yet support temporary tables +ERROR: relation "foo" does not exist INSERT INTO foochild VALUES(123,'child',999,-123); ERROR: relation "foochild" does not exist LINE 1: INSERT INTO foochild VALUES(123,'child',999,-123); @@ -220,19 +220,9 @@ LINE 1: SELECT * FROM voo ORDER BY f1; ^ -- Try a join case CREATE TEMP TABLE joinme (f2j text, other int); -ERROR: PG-XC does not yet support temporary tables INSERT INTO joinme VALUES('more', 12345); -ERROR: relation "joinme" does not exist -LINE 1: INSERT INTO joinme VALUES('more', 12345); - ^ INSERT INTO joinme VALUES('zoo2', 54321); -ERROR: relation "joinme" does not exist -LINE 1: INSERT INTO joinme VALUES('zoo2', 54321); - ^ INSERT INTO joinme VALUES('other', 0); -ERROR: relation "joinme" does not exist -LINE 1: INSERT INTO joinme VALUES('other', 0); - ^ CREATE TEMP VIEW joinview AS SELECT foo.*, other FROM foo JOIN joinme ON (f2 = f2j); ERROR: relation "foo" does not exist diff --git a/src/test/regress/expected/rowtypes_1.out b/src/test/regress/expected/rowtypes_1.out index 1af80a0a62..b87c710125 100644 --- a/src/test/regress/expected/rowtypes_1.out +++ b/src/test/regress/expected/rowtypes_1.out @@ -4,7 +4,6 @@ -- Make both a standalone composite type and a table rowtype create type complex as (r float8, i float8); create temp table fullname (first text, last text); -ERROR: PG-XC does not yet support temporary tables -- Nested composite create type quad as (c1 complex, c2 complex); -- Some simple tests of I/O conversions and row construction @@ -15,111 +14,114 @@ select (1.1,2.2)::complex, row((3.3,4.4),(5.5,null))::quad; (1 row) select row('Joe', 'Blow')::fullname, '(Joe,Blow)'::fullname; -ERROR: type "fullname" does not exist -LINE 1: select row('Joe', 'Blow')::fullname, '(Joe,Blow)'::fullname; - ^ + row | fullname +------------+------------ + (Joe,Blow) | (Joe,Blow) +(1 row) + select '(Joe,von Blow)'::fullname, '(Joe,d''Blow)'::fullname; -ERROR: type "fullname" does not exist -LINE 1: select '(Joe,von Blow)'::fullname, '(Joe,d''Blow)'::fullname... - ^ + fullname | fullname +------------------+-------------- + (Joe,"von Blow") | (Joe,d'Blow) +(1 row) + select '(Joe,"von""Blow")'::fullname, E'(Joe,d\\\\Blow)'::fullname; -ERROR: type "fullname" does not exist -LINE 1: select '(Joe,"von""Blow")'::fullname, E'(Joe,d\\\\Blow)'::fu... - ^ + fullname | fullname +-------------------+----------------- + (Joe,"von""Blow") | (Joe,"d\\Blow") +(1 row) + select '(Joe,"Blow,Jr")'::fullname; -ERROR: type "fullname" does not exist -LINE 1: select '(Joe,"Blow,Jr")'::fullname; - ^ + fullname +----------------- + (Joe,"Blow,Jr") +(1 row) + select '(Joe,)'::fullname; -- ok, null 2nd column -ERROR: type "fullname" does not exist -LINE 1: select '(Joe,)'::fullname; - ^ + fullname +---------- + (Joe,) +(1 row) + select '(Joe)'::fullname; -- bad -ERROR: type "fullname" does not exist +ERROR: malformed record literal: "(Joe)" LINE 1: select '(Joe)'::fullname; - ^ + ^ +DETAIL: Too few columns. select '(Joe,,)'::fullname; -- bad -ERROR: type "fullname" does not exist +ERROR: malformed record literal: "(Joe,,)" LINE 1: select '(Joe,,)'::fullname; - ^ + ^ +DETAIL: Too many columns. create temp table quadtable(f1 int, q quad); -ERROR: PG-XC does not yet support temporary tables insert into quadtable values (1, ((3.3,4.4),(5.5,6.6))); -ERROR: relation "quadtable" does not exist -LINE 1: insert into quadtable values (1, ((3.3,4.4),(5.5,6.6))); - ^ insert into quadtable values (2, ((null,4.4),(5.5,6.6))); -ERROR: relation "quadtable" does not exist -LINE 1: insert into quadtable values (2, ((null,4.4),(5.5,6.6))); - ^ select * from quadtable order by f1, q; -ERROR: relation "quadtable" does not exist -LINE 1: select * from quadtable order by f1, q; - ^ + f1 | q +----+--------------------------- + 1 | ("(3.3,4.4)","(5.5,6.6)") + 2 | ("(,4.4)","(5.5,6.6)") +(2 rows) + select f1, q.c1 from quadtable; -- fails, q is a table reference -ERROR: relation "quadtable" does not exist +ERROR: missing FROM-clause entry for table "q" LINE 1: select f1, q.c1 from quadtable; - ^ + ^ select f1, (q).c1, (qq.q).c1.i from quadtable qq order by 1; -ERROR: relation "quadtable" does not exist -LINE 1: select f1, (q).c1, (qq.q).c1.i from quadtable qq order by 1; - ^ + f1 | c1 | i +----+-----------+----- + 1 | (3.3,4.4) | 4.4 + 2 | (,4.4) | 4.4 +(2 rows) + create temp table people (fn fullname, bd date); -ERROR: type "fullname" does not exist -LINE 1: create temp table people (fn fullname, bd date); - ^ insert into people values ('(Joe,Blow)', '1984-01-10'); -ERROR: relation "people" does not exist -LINE 1: insert into people values ('(Joe,Blow)', '1984-01-10'); - ^ select * from people; -ERROR: relation "people" does not exist -LINE 1: select * from people; - ^ + fn | bd +------------+------------ + (Joe,Blow) | 01-10-1984 +(1 row) + -- at the moment this will not work due to ALTER TABLE inadequacy: alter table fullname add column suffix text default ''; -ERROR: relation "fullname" does not exist +ERROR: cannot alter table "fullname" because column "people"."fn" uses its rowtype -- but this should work: alter table fullname add column suffix text default null; -ERROR: relation "fullname" does not exist select * from people; -ERROR: relation "people" does not exist -LINE 1: select * from people; - ^ + fn | bd +-------------+------------ + (Joe,Blow,) | 01-10-1984 +(1 row) + -- test insertion/updating of subfields update people set fn.suffix = 'Jr'; -ERROR: relation "people" does not exist -LINE 1: update people set fn.suffix = 'Jr'; - ^ select * from people; -ERROR: relation "people" does not exist -LINE 1: select * from people; - ^ -insert into quadtable (f1, q.c1.r, q.c2.i) values(44,55,66); -ERROR: relation "quadtable" does not exist -LINE 1: insert into quadtable (f1, q.c1.r, q.c2.i) values(44,55,66); - ^ + fn | bd +---------------+------------ + (Joe,Blow,Jr) | 01-10-1984 +(1 row) + +-- PGXCTODO: This test case makes a server crash due to query deparsing in planner +-- insert into quadtable (f1, q.c1.r, q.c2.i) values(44,55,66); select * from quadtable order by f1, q; -ERROR: relation "quadtable" does not exist -LINE 1: select * from quadtable order by f1, q; - ^ + f1 | q +----+--------------------------- + 1 | ("(3.3,4.4)","(5.5,6.6)") + 2 | ("(,4.4)","(5.5,6.6)") +(2 rows) + -- The object here is to ensure that toasted references inside -- composite values don't cause problems. The large f1 value will -- be toasted inside pp, it must still work after being copied to people. create temp table pp (f1 text); -ERROR: PG-XC does not yet support temporary tables insert into pp values (repeat('abcdefghijkl', 100000)); -ERROR: relation "pp" does not exist -LINE 1: insert into pp values (repeat('abcdefghijkl', 100000)); - ^ insert into people select ('Jim', f1, null)::fullname, current_date from pp; -ERROR: relation "people" does not exist -LINE 1: insert into people select ('Jim', f1, null)::fullname, curre... - ^ select (fn).first, substr((fn).last, 1, 20), length((fn).last) from people order by 1, 2; -ERROR: relation "people" does not exist -LINE 1: ... substr((fn).last, 1, 20), length((fn).last) from people ord... - ^ + first | substr | length +-------+--------+-------- + Joe | Blow | 4 +(1 row) + -- Test row comparison semantics. Prior to PG 8.2 we did this in a totally -- non-spec-compliant way. select ROW(1,2) < ROW(1,3) as true; @@ -286,19 +288,13 @@ select row(1,1.1) = any (array[ row(7,7.7), row(1,1.0), row(0,0.0) ]); -- Check behavior with a non-comparable rowtype create type cantcompare as (p point, r float8); create temp table cc (f1 cantcompare); -ERROR: PG-XC does not yet support temporary tables insert into cc values('("(1,2)",3)'); -ERROR: relation "cc" does not exist -LINE 1: insert into cc values('("(1,2)",3)'); - ^ insert into cc values('("(4,5)",6)'); -ERROR: relation "cc" does not exist -LINE 1: insert into cc values('("(4,5)",6)'); - ^ select * from cc order by f1; -- fail, but should complain about cantcompare -ERROR: relation "cc" does not exist +ERROR: could not identify an ordering operator for type cantcompare LINE 1: select * from cc order by f1; - ^ + ^ +HINT: Use an explicit ordering operator or modify the query. -- -- Test case derived from bug #5716: check multiple uses of a rowtype result -- @@ -343,21 +339,24 @@ rollback; -- the latter is too prone to be invoked unintentionally. -- select cast (fullname as text) from fullname; -ERROR: relation "fullname" does not exist -LINE 1: select cast (fullname as text) from fullname; - ^ + fullname +---------- +(0 rows) + select fullname::text from fullname; -ERROR: relation "fullname" does not exist -LINE 1: select fullname::text from fullname; - ^ + fullname +---------- +(0 rows) + select text(fullname) from fullname; -- error -ERROR: relation "fullname" does not exist +ERROR: function text(fullname) does not exist LINE 1: select text(fullname) from fullname; - ^ + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. select fullname.text from fullname; -- error -ERROR: relation "fullname" does not exist +ERROR: column fullname.text does not exist LINE 1: select fullname.text from fullname; - ^ + ^ -- same, but RECORD instead of named composite type: select cast (row('Jim', 'Beam') as text); row diff --git a/src/test/regress/expected/select_1.out b/src/test/regress/expected/select_1.out index ea438e5846..6f4fbf5e6f 100644 --- a/src/test/regress/expected/select_1.out +++ b/src/test/regress/expected/select_1.out @@ -527,91 +527,218 @@ ORDER BY column1,column2; -- Test ORDER BY options -- CREATE TEMP TABLE foo (f1 int); -ERROR: PG-XC does not yet support temporary tables INSERT INTO foo VALUES (42),(3),(10),(7),(null),(null),(1); -ERROR: relation "foo" does not exist -LINE 1: INSERT INTO foo VALUES (42),(3),(10),(7),(null),(null),(1); - ^ SELECT * FROM foo ORDER BY f1; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1; - ^ + f1 +---- + 1 + 3 + 7 + 10 + 42 + + +(7 rows) + SELECT * FROM foo ORDER BY f1 ASC; -- same thing -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 ASC; - ^ + f1 +---- + 1 + 3 + 7 + 10 + 42 + + +(7 rows) + SELECT * FROM foo ORDER BY f1 NULLS FIRST; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 NULLS FIRST; - ^ + f1 +---- + + + 1 + 3 + 7 + 10 + 42 +(7 rows) + SELECT * FROM foo ORDER BY f1 DESC; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 DESC; - ^ + f1 +---- + + + 42 + 10 + 7 + 3 + 1 +(7 rows) + SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; - ^ + f1 +---- + 42 + 10 + 7 + 3 + 1 + + +(7 rows) + -- check if indexscans do the right things CREATE INDEX fooi ON foo (f1); -ERROR: relation "foo" does not exist SET enable_sort = false; SELECT * FROM foo ORDER BY f1; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1; - ^ + f1 +---- + 1 + 3 + 7 + 10 + 42 + + +(7 rows) + SELECT * FROM foo ORDER BY f1 NULLS FIRST; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 NULLS FIRST; - ^ + f1 +---- + + + 1 + 3 + 7 + 10 + 42 +(7 rows) + SELECT * FROM foo ORDER BY f1 DESC; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 DESC; - ^ + f1 +---- + + + 42 + 10 + 7 + 3 + 1 +(7 rows) + SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; - ^ + f1 +---- + 42 + 10 + 7 + 3 + 1 + + +(7 rows) + DROP INDEX fooi; -ERROR: index "fooi" does not exist CREATE INDEX fooi ON foo (f1 DESC); -ERROR: relation "foo" does not exist SELECT * FROM foo ORDER BY f1; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1; - ^ + f1 +---- + 1 + 3 + 7 + 10 + 42 + + +(7 rows) + SELECT * FROM foo ORDER BY f1 NULLS FIRST; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 NULLS FIRST; - ^ + f1 +---- + + + 1 + 3 + 7 + 10 + 42 +(7 rows) + SELECT * FROM foo ORDER BY f1 DESC; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 DESC; - ^ + f1 +---- + + + 42 + 10 + 7 + 3 + 1 +(7 rows) + SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; - ^ + f1 +---- + 42 + 10 + 7 + 3 + 1 + + +(7 rows) + DROP INDEX fooi; -ERROR: index "fooi" does not exist CREATE INDEX fooi ON foo (f1 DESC NULLS LAST); -ERROR: relation "foo" does not exist SELECT * FROM foo ORDER BY f1; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1; - ^ + f1 +---- + 1 + 3 + 7 + 10 + 42 + + +(7 rows) + SELECT * FROM foo ORDER BY f1 NULLS FIRST; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 NULLS FIRST; - ^ + f1 +---- + + + 1 + 3 + 7 + 10 + 42 +(7 rows) + SELECT * FROM foo ORDER BY f1 DESC; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 DESC; - ^ + f1 +---- + + + 42 + 10 + 7 + 3 + 1 +(7 rows) + SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; -ERROR: relation "foo" does not exist -LINE 1: SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; - ^ + f1 +---- + 42 + 10 + 7 + 3 + 1 + + +(7 rows) + -- -- Test some corner cases that have been known to confuse the planner -- diff --git a/src/test/regress/expected/select_distinct_on_1.out b/src/test/regress/expected/select_distinct_on_1.out index 0c01725248..9f951f79a5 100644 --- a/src/test/regress/expected/select_distinct_on_1.out +++ b/src/test/regress/expected/select_distinct_on_1.out @@ -25,6 +25,5 @@ select distinct on (1) floor(random()) as r, f1 from int4_tbl order by 1,2; r | f1 ---+------------- 0 | -2147483647 - 0 | -123456 -(2 rows) +(1 row) diff --git a/src/test/regress/expected/sequence_2.out b/src/test/regress/expected/sequence_2.out index a83f486cee..562747ae99 100644 --- a/src/test/regress/expected/sequence_2.out +++ b/src/test/regress/expected/sequence_2.out @@ -153,7 +153,7 @@ ERROR: Postgres-XC does not support SERIAL yet DETAIL: The feature is not currently supported -- Both drops should fail, but with different error messages: DROP SEQUENCE t1_f1_seq; -ERROR: relation "t1_f1_seq" does not exist +ERROR: sequence "t1_f1_seq" does not exist DROP SEQUENCE myseq2; -- This however will work: DROP SEQUENCE myseq3; @@ -161,10 +161,10 @@ DROP TABLE t1; ERROR: table "t1" does not exist -- Fails because no longer existent: DROP SEQUENCE t1_f1_seq; -ERROR: relation "t1_f1_seq" does not exist +ERROR: sequence "t1_f1_seq" does not exist -- Now OK: DROP SEQUENCE myseq2; -ERROR: relation "myseq2" does not exist +ERROR: sequence "myseq2" does not exist -- -- Alter sequence -- diff --git a/src/test/regress/expected/temp_1.out b/src/test/regress/expected/temp_1.out index ef48e27b4d..2e7f73581f 100644 --- a/src/test/regress/expected/temp_1.out +++ b/src/test/regress/expected/temp_1.out @@ -6,47 +6,42 @@ CREATE TABLE temptest(col int); CREATE INDEX i_temptest ON temptest(col); CREATE TEMP TABLE temptest(tcol int); -ERROR: PG-XC does not yet support temporary tables CREATE INDEX i_temptest ON temptest(tcol); -ERROR: column "tcol" does not exist SELECT * FROM temptest; - col ------ + tcol +------ (0 rows) DROP INDEX i_temptest; DROP TABLE temptest; SELECT * FROM temptest; -ERROR: relation "temptest" does not exist -LINE 1: SELECT * FROM temptest; - ^ + col +----- +(0 rows) + DROP INDEX i_temptest; -ERROR: index "i_temptest" does not exist DROP TABLE temptest; -ERROR: table "temptest" does not exist -- test temp table selects CREATE TABLE temptest(col int); INSERT INTO temptest VALUES (1); CREATE TEMP TABLE temptest(tcol float); -ERROR: PG-XC does not yet support temporary tables INSERT INTO temptest VALUES (2.1); SELECT * FROM temptest; + tcol +------ + 2.1 +(1 row) + +DROP TABLE temptest; +SELECT * FROM temptest; col ----- 1 - 2 -(2 rows) +(1 row) DROP TABLE temptest; -SELECT * FROM temptest; -ERROR: relation "temptest" does not exist -LINE 1: SELECT * FROM temptest; - ^ -DROP TABLE temptest; -ERROR: table "temptest" does not exist -- test temp table deletion CREATE TEMP TABLE temptest(col int); -ERROR: PG-XC does not yet support temporary tables \c SELECT * FROM temptest; ERROR: relation "temptest" does not exist @@ -54,23 +49,23 @@ LINE 1: SELECT * FROM temptest; ^ -- Test ON COMMIT DELETE ROWS CREATE TEMP TABLE temptest(col int) ON COMMIT DELETE ROWS; -ERROR: PG-XC does not yet support temporary tables BEGIN; INSERT INTO temptest VALUES (1); -ERROR: relation "temptest" does not exist -LINE 1: INSERT INTO temptest VALUES (1); - ^ INSERT INTO temptest VALUES (2); -ERROR: current transaction is aborted, commands ignored until end of transaction block SELECT * FROM temptest ORDER BY 1; -ERROR: current transaction is aborted, commands ignored until end of transaction block + col +----- + 1 + 2 +(2 rows) + COMMIT; SELECT * FROM temptest; -ERROR: relation "temptest" does not exist -LINE 1: SELECT * FROM temptest; - ^ + col +----- +(0 rows) + DROP TABLE temptest; -ERROR: table "temptest" does not exist BEGIN; CREATE TEMP TABLE temptest(col) ON COMMIT DELETE ROWS AS SELECT 1; ERROR: INTO clause not yet supported @@ -86,13 +81,15 @@ ERROR: table "temptest" does not exist -- Test ON COMMIT DROP BEGIN; CREATE TEMP TABLE temptest(col int) ON COMMIT DROP; -ERROR: PG-XC does not yet support temporary tables INSERT INTO temptest VALUES (1); -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO temptest VALUES (2); -ERROR: current transaction is aborted, commands ignored until end of transaction block SELECT * FROM temptest ORDER BY 1; -ERROR: current transaction is aborted, commands ignored until end of transaction block + col +----- + 1 + 2 +(2 rows) + COMMIT; SELECT * FROM temptest; ERROR: relation "temptest" does not exist @@ -116,34 +113,34 @@ ERROR: INTO clause not yet supported -- Test foreign keys BEGIN; CREATE TEMP TABLE temptest1(col int PRIMARY KEY); -ERROR: PG-XC does not yet support temporary tables +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "temptest1_pkey" for table "temptest1" CREATE TEMP TABLE temptest2(col int REFERENCES temptest1) ON COMMIT DELETE ROWS; -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO temptest1 VALUES (1); -ERROR: current transaction is aborted, commands ignored until end of transaction block INSERT INTO temptest2 VALUES (1); -ERROR: current transaction is aborted, commands ignored until end of transaction block COMMIT; SELECT * FROM temptest1; -ERROR: relation "temptest1" does not exist -LINE 1: SELECT * FROM temptest1; - ^ + col +----- + 1 +(1 row) + SELECT * FROM temptest2; -ERROR: relation "temptest2" does not exist -LINE 1: SELECT * FROM temptest2; - ^ + col +----- +(0 rows) + BEGIN; CREATE TEMP TABLE temptest3(col int PRIMARY KEY) ON COMMIT DELETE ROWS; -ERROR: PG-XC does not yet support temporary tables +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "temptest3_pkey" for table "temptest3" CREATE TEMP TABLE temptest4(col int REFERENCES temptest3); -ERROR: current transaction is aborted, commands ignored until end of transaction block COMMIT; +ERROR: unsupported ON COMMIT and foreign key combination +DETAIL: Table "temptest4" references "temptest3", but they do not have the same ON COMMIT setting. -- Test manipulation of temp schema's placement in search path create table public.whereami (f1 text); insert into public.whereami values ('public'); create temp table whereami (f1 text); -ERROR: PG-XC does not yet support temporary tables insert into whereami values ('temp'); create function public.whoami() returns text as $$select 'public'::text$$ language sql; @@ -151,11 +148,10 @@ create function pg_temp.whoami() returns text as $$select 'temp'::text$$ language sql; -- default should have pg_temp implicitly first, but only for tables select * from whereami order by f1; - f1 --------- - public + f1 +------ temp -(2 rows) +(1 row) select whoami(); whoami @@ -166,11 +162,10 @@ select whoami(); -- can list temp first explicitly, but it still doesn't affect functions set search_path = pg_temp, public; select * from whereami order by f1; - f1 --------- - public + f1 +------ temp -(2 rows) +(1 row) select whoami(); whoami @@ -184,8 +179,7 @@ select * from whereami order by f1; f1 -------- public - temp -(2 rows) +(1 row) select whoami(); whoami diff --git a/src/test/regress/expected/transactions_1.out b/src/test/regress/expected/transactions_1.out index c30fa25a56..3cf5273814 100644 --- a/src/test/regress/expected/transactions_1.out +++ b/src/test/regress/expected/transactions_1.out @@ -43,7 +43,6 @@ SELECT * FROM aggtest order by a, b; -- Read-only tests CREATE TABLE writetest (a int); CREATE TEMPORARY TABLE temptest (a int); -ERROR: PG-XC does not yet support temporary tables BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY, DEFERRABLE; -- ok SELECT * FROM writetest; -- ok @@ -123,21 +122,17 @@ SELECT * FROM writetest; -- ok (0 rows) DELETE FROM temptest; -- ok -ERROR: relation "temptest" does not exist -LINE 1: DELETE FROM temptest; - ^ UPDATE temptest SET a = 0 FROM writetest WHERE temptest.a = 1 AND writetest.a = temptest.a; -- ok -ERROR: relation "temptest" does not exist -LINE 1: UPDATE temptest SET a = 0 FROM writetest WHERE temptest.a = ... - ^ +ERROR: Partition column can't be updated in current version PREPARE test AS UPDATE writetest SET a = 0; -- ok ERROR: Partition column can't be updated in current version EXECUTE test; -- fail ERROR: prepared statement "test" does not exist SELECT * FROM writetest, temptest; -- ok -ERROR: relation "temptest" does not exist -LINE 1: SELECT * FROM writetest, temptest; - ^ + a | a +---+--- +(0 rows) + CREATE TABLE test AS SELECT * FROM writetest; -- fail ERROR: INTO clause not yet supported START TRANSACTION READ WRITE; diff --git a/src/test/regress/expected/xc_temp.out b/src/test/regress/expected/xc_temp.out new file mode 100644 index 0000000000..7fb6df7472 --- /dev/null +++ b/src/test/regress/expected/xc_temp.out @@ -0,0 +1,952 @@ +-- +-- XC_TEMP +-- +-- Create TEMPORARY and normal tables +CREATE TABLE table_rep (a int, b_rep char(1)) DISTRIBUTE BY REPLICATION; +CREATE TABLE table_hash (a int, b_hash char(1)) DISTRIBUTE BY HASH(a); +CREATE TABLE table_rb (a int, b_rb char(1)) DISTRIBUTE BY ROUND ROBIN; +CREATE TEMP TABLE temptable_rep (a int, b_tprep char(1)) DISTRIBUTE BY REPLICATION; +CREATE TEMP TABLE temptable_hash (a int, b_tphash char(1)) DISTRIBUTE BY HASH(a); +CREATE TEMP TABLE temptable_rb (a int, b_tprb char(1)) DISTRIBUTE BY ROUND ROBIN; +INSERT INTO table_rep VALUES (1, 'a'); +INSERT INTO table_rep VALUES (2, 'b'); +INSERT INTO table_rep VALUES (3, 'c'); +INSERT INTO table_rep VALUES (4, NULL); +INSERT INTO table_rep VALUES (NULL, 'e'); +INSERT INTO table_hash VALUES (1, 'a'); +INSERT INTO table_hash VALUES (2, 'b'); +INSERT INTO table_hash VALUES (3, 'c'); +INSERT INTO table_hash VALUES (4, NULL); +INSERT INTO table_hash VALUES (NULL, 'e'); +INSERT INTO table_rb VALUES (1, 'a'); +INSERT INTO table_rb VALUES (2, 'b'); +INSERT INTO table_rb VALUES (3, 'c'); +INSERT INTO table_rb VALUES (4, NULL); +INSERT INTO table_rb VALUES (NULL, 'e'); +INSERT INTO temptable_rep VALUES (1, 'A'); +INSERT INTO temptable_rep VALUES (2, NULL); +INSERT INTO temptable_rep VALUES (3, 'C'); +INSERT INTO temptable_rep VALUES (4, 'D'); +INSERT INTO temptable_rep VALUES (NULL, 'E'); +INSERT INTO temptable_hash VALUES (1, 'A'); +INSERT INTO temptable_hash VALUES (2, 'B'); +INSERT INTO temptable_hash VALUES (3, NULL); +INSERT INTO temptable_hash VALUES (4, 'D'); +INSERT INTO temptable_hash VALUES (NULL, 'E'); +INSERT INTO temptable_rb VALUES (1, 'A'); +INSERT INTO temptable_rb VALUES (2, 'B'); +INSERT INTO temptable_rb VALUES (3, 'C'); +INSERT INTO temptable_rb VALUES (4, NULL); +INSERT INTO temptable_rb VALUES (NULL, 'E'); +-- Check global joins on each table combination +SELECT * FROM table_hash, temptable_hash ORDER BY 1,2,3,4; + a | b_hash | a | b_tphash +---+--------+---+---------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | + 1 | a | 4 | D + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | B + 2 | b | 3 | + 2 | b | 4 | D + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | B + 3 | c | 3 | + 3 | c | 4 | D + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | B + 4 | | 3 | + 4 | | 4 | D + 4 | | | E + | e | 1 | A + | e | 2 | B + | e | 3 | + | e | 4 | D + | e | | E +(25 rows) + +SELECT * FROM table_hash, temptable_rep ORDER BY 1,2,3,4; + a | b_hash | a | b_tprep +---+--------+---+--------- + 1 | a | 1 | A + 1 | a | 2 | + 1 | a | 3 | C + 1 | a | 4 | D + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | + 2 | b | 3 | C + 2 | b | 4 | D + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | + 3 | c | 3 | C + 3 | c | 4 | D + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | + 4 | | 3 | C + 4 | | 4 | D + 4 | | | E + | e | 1 | A + | e | 2 | + | e | 3 | C + | e | 4 | D + | e | | E +(25 rows) + +SELECT * FROM table_hash, temptable_rb ORDER BY 1,2,3,4; + a | b_hash | a | b_tprb +---+--------+---+-------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | C + 1 | a | 4 | + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | B + 2 | b | 3 | C + 2 | b | 4 | + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | B + 3 | c | 3 | C + 3 | c | 4 | + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | B + 4 | | 3 | C + 4 | | 4 | + 4 | | | E + | e | 1 | A + | e | 2 | B + | e | 3 | C + | e | 4 | + | e | | E +(25 rows) + +SELECT * FROM table_rep, temptable_rep ORDER BY 1,2,3,4; + a | b_rep | a | b_tprep +---+-------+---+--------- + 1 | a | 1 | A + 1 | a | 2 | + 1 | a | 3 | C + 1 | a | 4 | D + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | + 2 | b | 3 | C + 2 | b | 4 | D + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | + 3 | c | 3 | C + 3 | c | 4 | D + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | + 4 | | 3 | C + 4 | | 4 | D + 4 | | | E + | e | 1 | A + | e | 2 | + | e | 3 | C + | e | 4 | D + | e | | E +(25 rows) + +SELECT * FROM table_rep, temptable_rb ORDER BY 1,2,3,4; + a | b_rep | a | b_tprb +---+-------+---+-------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | C + 1 | a | 4 | + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | B + 2 | b | 3 | C + 2 | b | 4 | + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | B + 3 | c | 3 | C + 3 | c | 4 | + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | B + 4 | | 3 | C + 4 | | 4 | + 4 | | | E + | e | 1 | A + | e | 2 | B + | e | 3 | C + | e | 4 | + | e | | E +(25 rows) + +SELECT * FROM table_rb, temptable_rb ORDER BY 1,2,3,4; + a | b_rb | a | b_tprb +---+------+---+-------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | C + 1 | a | 4 | + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | B + 2 | b | 3 | C + 2 | b | 4 | + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | B + 3 | c | 3 | C + 3 | c | 4 | + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | B + 4 | | 3 | C + 4 | | 4 | + 4 | | | E + | e | 1 | A + | e | 2 | B + | e | 3 | C + | e | 4 | + | e | | E +(25 rows) + +-- Equi-joins +SELECT * FROM table_hash, temptable_hash WHERE table_hash.a = temptable_hash.a ORDER BY 1,2,3,4; + a | b_hash | a | b_tphash +---+--------+---+---------- + 1 | a | 1 | A + 2 | b | 2 | B + 3 | c | 3 | + 4 | | 4 | D +(4 rows) + +SELECT * FROM table_hash, temptable_rep WHERE table_hash.a = temptable_rep.a ORDER BY 1,2,3,4; + a | b_hash | a | b_tprep +---+--------+---+--------- + 1 | a | 1 | A + 2 | b | 2 | + 3 | c | 3 | C + 4 | | 4 | D +(4 rows) + +SELECT * FROM table_hash, temptable_rb WHERE table_hash.a = temptable_rb.a ORDER BY 1,2,3,4; + a | b_hash | a | b_tprb +---+--------+---+-------- + 1 | a | 1 | A + 2 | b | 2 | B + 3 | c | 3 | C + 4 | | 4 | +(4 rows) + +SELECT * FROM table_rep, temptable_rep WHERE table_rep.a = temptable_rep.a ORDER BY 1,2,3,4; + a | b_rep | a | b_tprep +---+-------+---+--------- + 1 | a | 1 | A + 2 | b | 2 | + 3 | c | 3 | C + 4 | | 4 | D +(4 rows) + +SELECT * FROM table_rep, temptable_rb WHERE table_rep.a = temptable_rb.a ORDER BY 1,2,3,4; + a | b_rep | a | b_tprb +---+-------+---+-------- + 1 | a | 1 | A + 2 | b | 2 | B + 3 | c | 3 | C + 4 | | 4 | +(4 rows) + +SELECT * FROM table_rb, temptable_rb WHERE table_rb.a = temptable_rb.a ORDER BY 1,2,3,4; + a | b_rb | a | b_tprb +---+------+---+-------- + 1 | a | 1 | A + 2 | b | 2 | B + 3 | c | 3 | C + 4 | | 4 | +(4 rows) + +-- Non equi-joins +SELECT * FROM table_hash JOIN temptable_hash ON (table_hash.a <= temptable_hash.a) ORDER BY 1,2,3,4; + a | b_hash | a | b_tphash +---+--------+---+---------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | + 1 | a | 4 | D + 2 | b | 2 | B + 2 | b | 3 | + 2 | b | 4 | D + 3 | c | 3 | + 3 | c | 4 | D + 4 | | 4 | D +(10 rows) + +SELECT * FROM table_hash JOIN temptable_rep ON (table_hash.a <= temptable_rep.a) ORDER BY 1,2,3,4; + a | b_hash | a | b_tprep +---+--------+---+--------- + 1 | a | 1 | A + 1 | a | 2 | + 1 | a | 3 | C + 1 | a | 4 | D + 2 | b | 2 | + 2 | b | 3 | C + 2 | b | 4 | D + 3 | c | 3 | C + 3 | c | 4 | D + 4 | | 4 | D +(10 rows) + +SELECT * FROM table_hash JOIN temptable_rb ON (table_hash.a <= temptable_rb.a) ORDER BY 1,2,3,4; + a | b_hash | a | b_tprb +---+--------+---+-------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | C + 1 | a | 4 | + 2 | b | 2 | B + 2 | b | 3 | C + 2 | b | 4 | + 3 | c | 3 | C + 3 | c | 4 | + 4 | | 4 | +(10 rows) + +SELECT * FROM table_rep JOIN temptable_rep ON (table_rep.a <= temptable_rep.a) ORDER BY 1,2,3,4; + a | b_rep | a | b_tprep +---+-------+---+--------- + 1 | a | 1 | A + 1 | a | 2 | + 1 | a | 3 | C + 1 | a | 4 | D + 2 | b | 2 | + 2 | b | 3 | C + 2 | b | 4 | D + 3 | c | 3 | C + 3 | c | 4 | D + 4 | | 4 | D +(10 rows) + +SELECT * FROM table_rep JOIN temptable_rb ON (table_rep.a <= temptable_rb.a) ORDER BY 1,2,3,4; + a | b_rep | a | b_tprb +---+-------+---+-------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | C + 1 | a | 4 | + 2 | b | 2 | B + 2 | b | 3 | C + 2 | b | 4 | + 3 | c | 3 | C + 3 | c | 4 | + 4 | | 4 | +(10 rows) + +SELECT * FROM table_rb JOIN temptable_rb ON (table_rb.a <= temptable_rb.a) ORDER BY 1,2,3,4; + a | b_rb | a | b_tprb +---+------+---+-------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | C + 1 | a | 4 | + 2 | b | 2 | B + 2 | b | 3 | C + 2 | b | 4 | + 3 | c | 3 | C + 3 | c | 4 | + 4 | | 4 | +(10 rows) + +-- More complicated joins +-- Hash and temp Hash +SELECT * FROM table_hash NATURAL JOIN temptable_hash ORDER BY 1,2,3; + a | b_hash | b_tphash +---+--------+---------- + 1 | a | A + 2 | b | B + 3 | c | + 4 | | D +(4 rows) + +SELECT * FROM table_hash CROSS JOIN temptable_hash ORDER BY 1,2,3,4; + a | b_hash | a | b_tphash +---+--------+---+---------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | + 1 | a | 4 | D + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | B + 2 | b | 3 | + 2 | b | 4 | D + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | B + 3 | c | 3 | + 3 | c | 4 | D + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | B + 4 | | 3 | + 4 | | 4 | D + 4 | | | E + | e | 1 | A + | e | 2 | B + | e | 3 | + | e | 4 | D + | e | | E +(25 rows) + +SELECT * FROM table_hash INNER JOIN temptable_hash USING (a) ORDER BY 1,2,3; + a | b_hash | b_tphash +---+--------+---------- + 1 | a | A + 2 | b | B + 3 | c | + 4 | | D +(4 rows) + +SELECT * FROM table_hash LEFT OUTER JOIN temptable_hash USING (a) ORDER BY 1,2,3; + a | b_hash | b_tphash +---+--------+---------- + 1 | a | A + 2 | b | B + 3 | c | + 4 | | D + | e | +(5 rows) + +SELECT * FROM table_hash RIGHT OUTER JOIN temptable_hash USING (a) ORDER BY 1,2,3; + a | b_hash | b_tphash +---+--------+---------- + 1 | a | A + 2 | b | B + 3 | c | + 4 | | D + | | E +(5 rows) + +SELECT * FROM table_hash FULL OUTER JOIN temptable_hash USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +SELECT * FROM table_hash LEFT JOIN temptable_hash USING (a) ORDER BY 1,2,3; + a | b_hash | b_tphash +---+--------+---------- + 1 | a | A + 2 | b | B + 3 | c | + 4 | | D + | e | +(5 rows) + +SELECT * FROM table_hash RIGHT JOIN temptable_hash USING (a) ORDER BY 1,2,3; + a | b_hash | b_tphash +---+--------+---------- + 1 | a | A + 2 | b | B + 3 | c | + 4 | | D + | | E +(5 rows) + +SELECT * FROM table_hash FULL JOIN temptable_hash USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +-- Hash and temp Replication +SELECT * FROM table_hash NATURAL JOIN temptable_rep ORDER BY 1,2,3; + a | b_hash | b_tprep +---+--------+--------- + 1 | a | A + 2 | b | + 3 | c | C + 4 | | D +(4 rows) + +SELECT * FROM table_hash CROSS JOIN temptable_rep ORDER BY 1,2,3,4; + a | b_hash | a | b_tprep +---+--------+---+--------- + 1 | a | 1 | A + 1 | a | 2 | + 1 | a | 3 | C + 1 | a | 4 | D + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | + 2 | b | 3 | C + 2 | b | 4 | D + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | + 3 | c | 3 | C + 3 | c | 4 | D + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | + 4 | | 3 | C + 4 | | 4 | D + 4 | | | E + | e | 1 | A + | e | 2 | + | e | 3 | C + | e | 4 | D + | e | | E +(25 rows) + +SELECT * FROM table_hash INNER JOIN temptable_rep USING (a) ORDER BY 1,2,3; + a | b_hash | b_tprep +---+--------+--------- + 1 | a | A + 2 | b | + 3 | c | C + 4 | | D +(4 rows) + +SELECT * FROM table_hash LEFT OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; + a | b_hash | b_tprep +---+--------+--------- + 1 | a | A + 2 | b | + 3 | c | C + 4 | | D + | e | +(5 rows) + +SELECT * FROM table_hash RIGHT OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; + a | b_hash | b_tprep +---+--------+--------- + 1 | a | A + 1 | | A + 2 | b | + 2 | | + 3 | c | C + 3 | | C + 4 | | D + 4 | | D + | | E + | | E +(10 rows) + +SELECT * FROM table_hash FULL OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +SELECT * FROM table_hash LEFT JOIN temptable_rep USING (a) ORDER BY 1,2,3; + a | b_hash | b_tprep +---+--------+--------- + 1 | a | A + 2 | b | + 3 | c | C + 4 | | D + | e | +(5 rows) + +SELECT * FROM table_hash RIGHT JOIN temptable_rep USING (a) ORDER BY 1,2,3; + a | b_hash | b_tprep +---+--------+--------- + 1 | a | A + 1 | | A + 2 | b | + 2 | | + 3 | c | C + 3 | | C + 4 | | D + 4 | | D + | | E + | | E +(10 rows) + +SELECT * FROM table_hash FULL JOIN temptable_rep USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +-- Hash and temp Round Robin +SELECT * FROM table_hash NATURAL JOIN temptable_rb ORDER BY 1,2,3; + a | b_hash | b_tprb +---+--------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | +(4 rows) + +SELECT * FROM table_hash CROSS JOIN temptable_rb ORDER BY 1,2,3,4; + a | b_hash | a | b_tprb +---+--------+---+-------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | C + 1 | a | 4 | + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | B + 2 | b | 3 | C + 2 | b | 4 | + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | B + 3 | c | 3 | C + 3 | c | 4 | + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | B + 4 | | 3 | C + 4 | | 4 | + 4 | | | E + | e | 1 | A + | e | 2 | B + | e | 3 | C + | e | 4 | + | e | | E +(25 rows) + +SELECT * FROM table_hash INNER JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_hash | b_tprb +---+--------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | +(4 rows) + +SELECT * FROM table_hash LEFT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_hash | b_tprb +---+--------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | + | e | +(5 rows) + +SELECT * FROM table_hash RIGHT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_hash | b_tprb +---+--------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | + | | E +(5 rows) + +SELECT * FROM table_hash FULL OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +SELECT * FROM table_hash LEFT JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_hash | b_tprb +---+--------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | + | e | +(5 rows) + +SELECT * FROM table_hash RIGHT JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_hash | b_tprb +---+--------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | + | | E +(5 rows) + +SELECT * FROM table_hash FULL JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +-- Replication and temp Replication +SELECT * FROM table_rep NATURAL JOIN temptable_rep ORDER BY 1,2,3; + a | b_rep | b_tprep +---+-------+--------- + 1 | a | A + 2 | b | + 3 | c | C + 4 | | D +(4 rows) + +SELECT * FROM table_rep CROSS JOIN temptable_rep ORDER BY 1,2,3,4; + a | b_rep | a | b_tprep +---+-------+---+--------- + 1 | a | 1 | A + 1 | a | 2 | + 1 | a | 3 | C + 1 | a | 4 | D + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | + 2 | b | 3 | C + 2 | b | 4 | D + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | + 3 | c | 3 | C + 3 | c | 4 | D + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | + 4 | | 3 | C + 4 | | 4 | D + 4 | | | E + | e | 1 | A + | e | 2 | + | e | 3 | C + | e | 4 | D + | e | | E +(25 rows) + +SELECT * FROM table_rep INNER JOIN temptable_rep USING (a) ORDER BY 1,2,3; + a | b_rep | b_tprep +---+-------+--------- + 1 | a | A + 2 | b | + 3 | c | C + 4 | | D +(4 rows) + +SELECT * FROM table_rep LEFT OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; + a | b_rep | b_tprep +---+-------+--------- + 1 | a | A + 2 | b | + 3 | c | C + 4 | | D + | e | +(5 rows) + +SELECT * FROM table_rep RIGHT OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; + a | b_rep | b_tprep +---+-------+--------- + 1 | a | A + 2 | b | + 3 | c | C + 4 | | D + | | E +(5 rows) + +SELECT * FROM table_rep FULL OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +SELECT * FROM table_rep LEFT JOIN temptable_rep USING (a) ORDER BY 1,2,3; + a | b_rep | b_tprep +---+-------+--------- + 1 | a | A + 2 | b | + 3 | c | C + 4 | | D + | e | +(5 rows) + +SELECT * FROM table_rep RIGHT JOIN temptable_rep USING (a) ORDER BY 1,2,3; + a | b_rep | b_tprep +---+-------+--------- + 1 | a | A + 2 | b | + 3 | c | C + 4 | | D + | | E +(5 rows) + +SELECT * FROM table_rep FULL JOIN temptable_rep USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +-- Replication and temp Round Robin +SELECT * FROM table_rep NATURAL JOIN temptable_rb ORDER BY 1,2,3; + a | b_rep | b_tprb +---+-------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | +(4 rows) + +SELECT * FROM table_rep CROSS JOIN temptable_rb ORDER BY 1,2,3,4; + a | b_rep | a | b_tprb +---+-------+---+-------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | C + 1 | a | 4 | + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | B + 2 | b | 3 | C + 2 | b | 4 | + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | B + 3 | c | 3 | C + 3 | c | 4 | + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | B + 4 | | 3 | C + 4 | | 4 | + 4 | | | E + | e | 1 | A + | e | 2 | B + | e | 3 | C + | e | 4 | + | e | | E +(25 rows) + +SELECT * FROM table_rep INNER JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_rep | b_tprb +---+-------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | +(4 rows) + +SELECT * FROM table_rep LEFT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_rep | b_tprb +---+-------+-------- + 1 | a | A + 1 | a | + 2 | b | B + 2 | b | + 3 | c | C + 3 | c | + 4 | | + 4 | | + | e | + | e | +(10 rows) + +SELECT * FROM table_rep RIGHT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_rep | b_tprb +---+-------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | + | | E +(5 rows) + +SELECT * FROM table_rep FULL OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +SELECT * FROM table_rep LEFT JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_rep | b_tprb +---+-------+-------- + 1 | a | A + 1 | a | + 2 | b | B + 2 | b | + 3 | c | C + 3 | c | + 4 | | + 4 | | + | e | + | e | +(10 rows) + +SELECT * FROM table_rep RIGHT JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_rep | b_tprb +---+-------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | + | | E +(5 rows) + +SELECT * FROM table_rep FULL JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +-- Round Robin and temp Round Robin +SELECT * FROM table_rb NATURAL JOIN temptable_rb ORDER BY 1,2,3; + a | b_rb | b_tprb +---+------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | +(4 rows) + +SELECT * FROM table_rb CROSS JOIN temptable_rb ORDER BY 1,2,3,4; + a | b_rb | a | b_tprb +---+------+---+-------- + 1 | a | 1 | A + 1 | a | 2 | B + 1 | a | 3 | C + 1 | a | 4 | + 1 | a | | E + 2 | b | 1 | A + 2 | b | 2 | B + 2 | b | 3 | C + 2 | b | 4 | + 2 | b | | E + 3 | c | 1 | A + 3 | c | 2 | B + 3 | c | 3 | C + 3 | c | 4 | + 3 | c | | E + 4 | | 1 | A + 4 | | 2 | B + 4 | | 3 | C + 4 | | 4 | + 4 | | | E + | e | 1 | A + | e | 2 | B + | e | 3 | C + | e | 4 | + | e | | E +(25 rows) + +SELECT * FROM table_rb INNER JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_rb | b_tprb +---+------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | +(4 rows) + +SELECT * FROM table_rb LEFT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_rb | b_tprb +---+------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | + | e | +(5 rows) + +SELECT * FROM table_rb RIGHT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_rb | b_tprb +---+------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | + | | E +(5 rows) + +SELECT * FROM table_rb FULL OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +SELECT * FROM table_rb LEFT JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_rb | b_tprb +---+------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | + | e | +(5 rows) + +SELECT * FROM table_rb RIGHT JOIN temptable_rb USING (a) ORDER BY 1,2,3; + a | b_rb | b_tprb +---+------+-------- + 1 | a | A + 2 | b | B + 3 | c | C + 4 | | + | | E +(5 rows) + +SELECT * FROM table_rb FULL JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being +ERROR: FULL JOIN clause not yet supported +-- Check that DROP with TEMP and non-TEMP tables fails correctly +DROP TABLE temptable_rep,table_rep; +ERROR: DROP not supported for TEMP and non-TEMP objects +DETAIL: You should separate TEMP and non-TEMP objects +-- Clean up everything +DROP TABLE table_rep,table_hash,table_rb; diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 66d965dcab..084f2cbb24 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -132,4 +132,4 @@ test: stats test: xc_groupby test: xc_distkey test: xc_having - +test: xc_temp diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql index 6b9855c4a4..4200c977b6 100644 --- a/src/test/regress/sql/cluster.sql +++ b/src/test/regress/sql/cluster.sql @@ -194,7 +194,7 @@ SELECT * FROM clustertest ORDER BY 1; create temp table clstr_temp (col1 int primary key, col2 text); insert into clstr_temp values (2, 'two'), (1, 'one'); cluster clstr_temp using clstr_temp_pkey; -select * from clstr_temp; +select * from clstr_temp order by 1; drop table clstr_temp; -- clean up diff --git a/src/test/regress/sql/rowtypes.sql b/src/test/regress/sql/rowtypes.sql index a8b4d4dc39..236096da74 100644 --- a/src/test/regress/sql/rowtypes.sql +++ b/src/test/regress/sql/rowtypes.sql @@ -58,7 +58,8 @@ update people set fn.suffix = 'Jr'; select * from people; -insert into quadtable (f1, q.c1.r, q.c2.i) values(44,55,66); +-- PGXCTODO: This test case makes a server crash due to query deparsing in planner +-- insert into quadtable (f1, q.c1.r, q.c2.i) values(44,55,66); select * from quadtable order by f1, q; diff --git a/src/test/regress/sql/xc_temp.sql b/src/test/regress/sql/xc_temp.sql new file mode 100644 index 0000000000..bc657d9db2 --- /dev/null +++ b/src/test/regress/sql/xc_temp.sql @@ -0,0 +1,138 @@ +-- +-- XC_TEMP +-- + +-- Create TEMPORARY and normal tables +CREATE TABLE table_rep (a int, b_rep char(1)) DISTRIBUTE BY REPLICATION; +CREATE TABLE table_hash (a int, b_hash char(1)) DISTRIBUTE BY HASH(a); +CREATE TABLE table_rb (a int, b_rb char(1)) DISTRIBUTE BY ROUND ROBIN; +CREATE TEMP TABLE temptable_rep (a int, b_tprep char(1)) DISTRIBUTE BY REPLICATION; +CREATE TEMP TABLE temptable_hash (a int, b_tphash char(1)) DISTRIBUTE BY HASH(a); +CREATE TEMP TABLE temptable_rb (a int, b_tprb char(1)) DISTRIBUTE BY ROUND ROBIN; +INSERT INTO table_rep VALUES (1, 'a'); +INSERT INTO table_rep VALUES (2, 'b'); +INSERT INTO table_rep VALUES (3, 'c'); +INSERT INTO table_rep VALUES (4, NULL); +INSERT INTO table_rep VALUES (NULL, 'e'); +INSERT INTO table_hash VALUES (1, 'a'); +INSERT INTO table_hash VALUES (2, 'b'); +INSERT INTO table_hash VALUES (3, 'c'); +INSERT INTO table_hash VALUES (4, NULL); +INSERT INTO table_hash VALUES (NULL, 'e'); +INSERT INTO table_rb VALUES (1, 'a'); +INSERT INTO table_rb VALUES (2, 'b'); +INSERT INTO table_rb VALUES (3, 'c'); +INSERT INTO table_rb VALUES (4, NULL); +INSERT INTO table_rb VALUES (NULL, 'e'); +INSERT INTO temptable_rep VALUES (1, 'A'); +INSERT INTO temptable_rep VALUES (2, NULL); +INSERT INTO temptable_rep VALUES (3, 'C'); +INSERT INTO temptable_rep VALUES (4, 'D'); +INSERT INTO temptable_rep VALUES (NULL, 'E'); +INSERT INTO temptable_hash VALUES (1, 'A'); +INSERT INTO temptable_hash VALUES (2, 'B'); +INSERT INTO temptable_hash VALUES (3, NULL); +INSERT INTO temptable_hash VALUES (4, 'D'); +INSERT INTO temptable_hash VALUES (NULL, 'E'); +INSERT INTO temptable_rb VALUES (1, 'A'); +INSERT INTO temptable_rb VALUES (2, 'B'); +INSERT INTO temptable_rb VALUES (3, 'C'); +INSERT INTO temptable_rb VALUES (4, NULL); +INSERT INTO temptable_rb VALUES (NULL, 'E'); + +-- Check global joins on each table combination +SELECT * FROM table_hash, temptable_hash ORDER BY 1,2,3,4; +SELECT * FROM table_hash, temptable_rep ORDER BY 1,2,3,4; +SELECT * FROM table_hash, temptable_rb ORDER BY 1,2,3,4; +SELECT * FROM table_rep, temptable_rep ORDER BY 1,2,3,4; +SELECT * FROM table_rep, temptable_rb ORDER BY 1,2,3,4; +SELECT * FROM table_rb, temptable_rb ORDER BY 1,2,3,4; + +-- Equi-joins +SELECT * FROM table_hash, temptable_hash WHERE table_hash.a = temptable_hash.a ORDER BY 1,2,3,4; +SELECT * FROM table_hash, temptable_rep WHERE table_hash.a = temptable_rep.a ORDER BY 1,2,3,4; +SELECT * FROM table_hash, temptable_rb WHERE table_hash.a = temptable_rb.a ORDER BY 1,2,3,4; +SELECT * FROM table_rep, temptable_rep WHERE table_rep.a = temptable_rep.a ORDER BY 1,2,3,4; +SELECT * FROM table_rep, temptable_rb WHERE table_rep.a = temptable_rb.a ORDER BY 1,2,3,4; +SELECT * FROM table_rb, temptable_rb WHERE table_rb.a = temptable_rb.a ORDER BY 1,2,3,4; + +-- Non equi-joins +SELECT * FROM table_hash JOIN temptable_hash ON (table_hash.a <= temptable_hash.a) ORDER BY 1,2,3,4; +SELECT * FROM table_hash JOIN temptable_rep ON (table_hash.a <= temptable_rep.a) ORDER BY 1,2,3,4; +SELECT * FROM table_hash JOIN temptable_rb ON (table_hash.a <= temptable_rb.a) ORDER BY 1,2,3,4; +SELECT * FROM table_rep JOIN temptable_rep ON (table_rep.a <= temptable_rep.a) ORDER BY 1,2,3,4; +SELECT * FROM table_rep JOIN temptable_rb ON (table_rep.a <= temptable_rb.a) ORDER BY 1,2,3,4; +SELECT * FROM table_rb JOIN temptable_rb ON (table_rb.a <= temptable_rb.a) ORDER BY 1,2,3,4; + +-- More complicated joins +-- Hash and temp Hash +SELECT * FROM table_hash NATURAL JOIN temptable_hash ORDER BY 1,2,3; +SELECT * FROM table_hash CROSS JOIN temptable_hash ORDER BY 1,2,3,4; +SELECT * FROM table_hash INNER JOIN temptable_hash USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash LEFT OUTER JOIN temptable_hash USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash RIGHT OUTER JOIN temptable_hash USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash FULL OUTER JOIN temptable_hash USING (a) ORDER BY 1,2,3; --Fails for the time being +SELECT * FROM table_hash LEFT JOIN temptable_hash USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash RIGHT JOIN temptable_hash USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash FULL JOIN temptable_hash USING (a) ORDER BY 1,2,3; --Fails for the time being + +-- Hash and temp Replication +SELECT * FROM table_hash NATURAL JOIN temptable_rep ORDER BY 1,2,3; +SELECT * FROM table_hash CROSS JOIN temptable_rep ORDER BY 1,2,3,4; +SELECT * FROM table_hash INNER JOIN temptable_rep USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash LEFT OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash RIGHT OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash FULL OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; --Fails for the time being +SELECT * FROM table_hash LEFT JOIN temptable_rep USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash RIGHT JOIN temptable_rep USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash FULL JOIN temptable_rep USING (a) ORDER BY 1,2,3; --Fails for the time being + +-- Hash and temp Round Robin +SELECT * FROM table_hash NATURAL JOIN temptable_rb ORDER BY 1,2,3; +SELECT * FROM table_hash CROSS JOIN temptable_rb ORDER BY 1,2,3,4; +SELECT * FROM table_hash INNER JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash LEFT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash RIGHT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash FULL OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being +SELECT * FROM table_hash LEFT JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash RIGHT JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_hash FULL JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being + +-- Replication and temp Replication +SELECT * FROM table_rep NATURAL JOIN temptable_rep ORDER BY 1,2,3; +SELECT * FROM table_rep CROSS JOIN temptable_rep ORDER BY 1,2,3,4; +SELECT * FROM table_rep INNER JOIN temptable_rep USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rep LEFT OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rep RIGHT OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rep FULL OUTER JOIN temptable_rep USING (a) ORDER BY 1,2,3; --Fails for the time being +SELECT * FROM table_rep LEFT JOIN temptable_rep USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rep RIGHT JOIN temptable_rep USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rep FULL JOIN temptable_rep USING (a) ORDER BY 1,2,3; --Fails for the time being + +-- Replication and temp Round Robin +SELECT * FROM table_rep NATURAL JOIN temptable_rb ORDER BY 1,2,3; +SELECT * FROM table_rep CROSS JOIN temptable_rb ORDER BY 1,2,3,4; +SELECT * FROM table_rep INNER JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rep LEFT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rep RIGHT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rep FULL OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being +SELECT * FROM table_rep LEFT JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rep RIGHT JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rep FULL JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being + +-- Round Robin and temp Round Robin +SELECT * FROM table_rb NATURAL JOIN temptable_rb ORDER BY 1,2,3; +SELECT * FROM table_rb CROSS JOIN temptable_rb ORDER BY 1,2,3,4; +SELECT * FROM table_rb INNER JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rb LEFT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rb RIGHT OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rb FULL OUTER JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being +SELECT * FROM table_rb LEFT JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rb RIGHT JOIN temptable_rb USING (a) ORDER BY 1,2,3; +SELECT * FROM table_rb FULL JOIN temptable_rb USING (a) ORDER BY 1,2,3; --Fails for the time being + +-- Check that DROP with TEMP and non-TEMP tables fails correctly +DROP TABLE temptable_rep,table_rep; + +-- Clean up everything +DROP TABLE table_rep,table_hash,table_rb; |