summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/transam/xact.c17
-rw-r--r--src/backend/commands/comment.c42
-rw-r--r--src/backend/commands/copy.c6
-rw-r--r--src/backend/commands/schemacmds.c3
-rw-r--r--src/backend/commands/tablecmds.c117
-rw-r--r--src/backend/optimizer/plan/createplan.c10
-rw-r--r--src/backend/pgxc/plan/planner.c46
-rw-r--r--src/backend/pgxc/pool/execRemote.c63
-rw-r--r--src/backend/pgxc/pool/poolmgr.c186
-rw-r--r--src/backend/tcop/utility.c557
-rw-r--r--src/include/commands/comment.h4
-rw-r--r--src/include/commands/tablecmds.h8
-rw-r--r--src/include/pgxc/execRemote.h2
-rw-r--r--src/include/pgxc/planner.h5
-rw-r--r--src/include/pgxc/poolmgr.h25
-rw-r--r--src/test/regress/expected/cluster_1.out18
-rw-r--r--src/test/regress/expected/combocid_1.out76
-rw-r--r--src/test/regress/expected/copy2_1.out83
-rw-r--r--src/test/regress/expected/domain_1.out49
-rw-r--r--src/test/regress/expected/foreign_key_1.out28
-rw-r--r--src/test/regress/expected/functional_deps_1.out30
-rw-r--r--src/test/regress/expected/guc_1.out12
-rw-r--r--src/test/regress/expected/polymorphism_1.out263
-rw-r--r--src/test/regress/expected/returning_1.out12
-rw-r--r--src/test/regress/expected/rowtypes_1.out181
-rw-r--r--src/test/regress/expected/select_1.out247
-rw-r--r--src/test/regress/expected/select_distinct_on_1.out3
-rw-r--r--src/test/regress/expected/sequence_2.out6
-rw-r--r--src/test/regress/expected/temp_1.out106
-rw-r--r--src/test/regress/expected/transactions_1.out15
-rw-r--r--src/test/regress/expected/xc_temp.out952
-rw-r--r--src/test/regress/serial_schedule2
-rw-r--r--src/test/regress/sql/cluster.sql2
-rw-r--r--src/test/regress/sql/rowtypes.sql3
-rw-r--r--src/test/regress/sql/xc_temp.sql138
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;