summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael P2011-04-07 04:10:09 +0000
committerPavan Deolasee2011-05-24 10:15:42 +0000
commitd2fe66518e3aa72196b44a0e8ebfa745e3e698b4 (patch)
treec1a2bf319c54b0caf0a67acfacb2ca144a8828d3
parent3fa6d176d5551c1e86e89b80e781b1f27e063a78 (diff)
Support for session and local parameters
This commit adds support for commands like: SET ROLE ... ; SET param TO value; SET SESSION param TO value; SET LOCAL param TO value; When a SET command is launched, it is saved in pooler and then launched to nodes by pooler if connections to backend nodes exist. Commands are saved with the following format as a string: "SET param1 TO value1;...;SET paramN TO valueN" Local and session commands are saved as separate strings. When a new connection is created to a backend node, pooler replays all the saved SET commands. When a transaction is finished, local parameters are deleted from pooler. It is not necessary in this case to reset on backend nodes as transaction commit has made the work. If a SET command has been launched for a non-local parameter, connections to nodes are kept alive with the session and not sent back to pool when a transaction finishes. When session is finished (user logging off), pooler sends asynchronously a "RESET ALL" command to each connection and put connections back to pool. Reset is not launched if no SET queries for session parameters have been launched. A SET command for local parameters is not sent to pooler if it is not inside a transaction block to save ressources in the cluster. This commit contains also a couple of corrections for regression tests according to implementation of session parameters.
-rw-r--r--src/backend/pgxc/pool/execRemote.c3
-rw-r--r--src/backend/pgxc/pool/pgxcnode.c22
-rw-r--r--src/backend/pgxc/pool/poolmgr.c238
-rw-r--r--src/backend/tcop/utility.c26
-rw-r--r--src/include/pgxc/pgxcnode.h1
-rw-r--r--src/include/pgxc/poolmgr.h16
-rw-r--r--src/test/regress/expected/guc_1.out85
-rw-r--r--src/test/regress/expected/plancache_1.out6
-rw-r--r--src/test/regress/expected/privileges_1.out31
9 files changed, 346 insertions, 82 deletions
diff --git a/src/backend/pgxc/pool/execRemote.c b/src/backend/pgxc/pool/execRemote.c
index 08e95ab97d..97cb58f498 100644
--- a/src/backend/pgxc/pool/execRemote.c
+++ b/src/backend/pgxc/pool/execRemote.c
@@ -4398,6 +4398,9 @@ PGXCNodeCleanAndRelease(int code, Datum arg)
/* Release data node connections */
release_handles();
+ /* Disconnect from Pooler */
+ PoolManagerDisconnect();
+
/* Close connection with GTM */
CloseGTM();
diff --git a/src/backend/pgxc/pool/pgxcnode.c b/src/backend/pgxc/pool/pgxcnode.c
index dcd721d869..d7230b08a0 100644
--- a/src/backend/pgxc/pool/pgxcnode.c
+++ b/src/backend/pgxc/pool/pgxcnode.c
@@ -196,6 +196,28 @@ PGXCNodeClose(NODE_CONNECTION *conn)
PQfinish((PGconn *) conn);
}
+/*
+ * Send SET query to given connection.
+ * Query is sent asynchronously and results are consumed
+ */
+int
+PGXCNodeSendSetQuery(NODE_CONNECTION *conn, const char *sql_command)
+{
+ PGresult *result;
+
+ if (!PQsendQuery((PGconn *) conn, sql_command))
+ return -1;
+
+ /* Consume results from SET commands */
+ while ((result = PQgetResult((PGconn *) conn)) != NULL)
+ {
+ /* TODO: Check that results are of type 'S' */
+ PQclear(result);
+ }
+
+ return 0;
+}
+
/*
* Checks if connection active
diff --git a/src/backend/pgxc/pool/poolmgr.c b/src/backend/pgxc/pool/poolmgr.c
index 1120656990..948430618f 100644
--- a/src/backend/pgxc/pool/poolmgr.c
+++ b/src/backend/pgxc/pool/poolmgr.c
@@ -93,6 +93,7 @@ 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 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);
@@ -102,6 +103,7 @@ static DatabasePool *remove_database_pool(const char *database, const char *user
static int *agent_acquire_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 release_connection(DatabasePool *dbPool, PGXCNodePoolSlot *slot, int index, bool clean,
char client_conn_type);
static void destroy_slot(PGXCNodePoolSlot *slot);
@@ -476,6 +478,8 @@ agent_create(void)
agent->pool = NULL;
agent->dn_connections = NULL;
agent->coord_connections = NULL;
+ agent->session_params = NULL;
+ agent->local_params = NULL;
agent->pid = 0;
/* Append new agent to the list */
@@ -528,6 +532,36 @@ PoolManagerConnect(PoolHandle *handle, const char *database, const char *user_na
pool_flush(&handle->port);
}
+int
+PoolManagerSetCommand(bool is_local, 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);
+ 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);
+ pool_putbytes(&Handle->port, (char *) &n32, 4);
+
+ /* Send command string followed by \0 terminator */
+ pool_putbytes(&Handle->port, set_command, strlen(set_command) + 1);
+ pool_flush(&Handle->port);
+
+ /* Get result */
+ pool_recvres(&Handle->port);
+}
/*
* Init PoolAgent
@@ -567,9 +601,9 @@ agent_destroy(PoolAgent *agent)
/* Discard connections if any remaining */
if (agent->pool)
{
- List *dn_conn = NIL;
- List *co_conn = NIL;
- int i;
+ List *dn_conn = NIL;
+ List *co_conn = NIL;
+ int i;
/* gather abandoned datanode connections */
if (agent->dn_connections)
@@ -583,6 +617,12 @@ agent_destroy(PoolAgent *agent)
if (agent->coord_connections[i])
co_conn = lappend_int(co_conn, i+1);
+ /*
+ * agent is being destroyed, so reset session parameters
+ * before putting back connections to pool
+ */
+ agent_reset_params(agent, dn_conn, co_conn);
+
/* release them all */
agent_release_connections(agent, dn_conn, co_conn);
}
@@ -603,6 +643,16 @@ agent_destroy(PoolAgent *agent)
pfree(agent->coord_connections);
agent->coord_connections = NULL;
}
+ if (agent->local_params)
+ {
+ pfree(agent->local_params);
+ agent->local_params = NULL;
+ }
+ if (agent->session_params)
+ {
+ pfree(agent->session_params);
+ agent->session_params = NULL;
+ }
pfree(agent);
/* shrink the list and move last agent into the freed slot */
if (i < --agentCount)
@@ -618,16 +668,14 @@ agent_destroy(PoolAgent *agent)
* Release handle to pool manager
*/
void
-PoolManagerDisconnect(PoolHandle *handle)
+PoolManagerDisconnect(void)
{
- Assert(handle);
+ Assert(Handle);
- pool_putmessage(&handle->port, 'd', NULL, 0);
+ pool_putmessage(&Handle->port, 'd', NULL, 0);
pool_flush(&Handle->port);
- close(Socket(handle->port));
-
- pfree(handle);
+ close(Socket(Handle->port));
}
@@ -784,6 +832,8 @@ agent_handle_input(PoolAgent * agent, StringInfo s)
{
const char *database;
const char *user_name;
+ const char *set_command;
+ bool is_local;
int datanodecount;
int coordcount;
List *datanodelist = NIL;
@@ -905,6 +955,20 @@ agent_handle_input(PoolAgent * agent, StringInfo s)
list_free(datanodelist);
list_free(coordlist);
break;
+ case 's': /* SET COMMAND */
+ pool_getmessage(&agent->port, s, 0);
+ /* Determine if command is local or session */
+ is_local = (bool) pq_getmsgbyte(s);
+ /* Get the SET command */
+ len = pq_getmsgint(s, 4);
+ set_command = pq_getmsgbytes(s, len);
+ pq_getmsgend(s);
+
+ res = agent_set_command(agent, set_command, is_local);
+
+ /* Send success result */
+ pool_sendres(&agent->port, res);
+ break;
default: /* EOF or protocol violation */
agent_destroy(agent);
return;
@@ -915,6 +979,77 @@ agent_handle_input(PoolAgent * agent, StringInfo s)
}
}
+/*
+ * 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)
+{
+ char *params_string;
+ int i;
+ int res = 0;
+
+ Assert(agent);
+ Assert(set_command);
+
+ if (is_local)
+ params_string = agent->local_params;
+ else
+ params_string = agent->session_params;
+
+ /* First command recorded */
+ if (!params_string)
+ {
+ params_string = pstrdup(set_command);
+ if (!params_string)
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+ }
+ else
+ {
+ /*
+ * Second command or more recorded.
+ * Commands are saved with format 'SET param1 TO value1;...;SET paramN TO valueN'
+ */
+ params_string = (char *) repalloc(params_string,
+ strlen(params_string) + strlen(set_command) + 2);
+ if (!params_string)
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+
+ sprintf(params_string, "%s;%s", params_string, set_command);
+ }
+
+ /* Launch the new command to all the connections already hold by the agent */
+ if (agent->dn_connections)
+ {
+ for (i = 0; i < NumDataNodes; i++)
+ {
+ if (agent->dn_connections[i])
+ res = PGXCNodeSendSetQuery(agent->dn_connections[i]->conn, set_command);
+ }
+ }
+
+ if (agent->coord_connections)
+ {
+ for (i = 0; i < NumCoords; i++)
+ {
+ if (agent->coord_connections[i])
+ res |= PGXCNodeSendSetQuery(agent->coord_connections[i]->conn, set_command);
+ }
+ }
+
+ /* Save the latest string */
+ if (is_local)
+ agent->local_params = params_string;
+ else
+ agent->session_params = params_string;
+
+ return res;
+}
/*
* acquire connection
@@ -1005,6 +1140,12 @@ agent_acquire_connections(PoolAgent *agent, List *datanodelist, List *coordlist)
/* Store in the descriptor */
agent->dn_connections[node - 1] = slot;
+
+ /* Update newly-acquired slot with session parameters */
+ if (agent->session_params)
+ PGXCNodeSendSetQuery(slot->conn, agent->session_params);
+ if (agent->local_params)
+ PGXCNodeSendSetQuery(slot->conn, agent->local_params);
}
result[i++] = PQsocket((PGconn *) agent->dn_connections[node - 1]->conn);
@@ -1029,6 +1170,12 @@ agent_acquire_connections(PoolAgent *agent, List *datanodelist, List *coordlist)
/* Store in the descriptor */
agent->coord_connections[node - 1] = slot;
+
+ /* Update newly-acquired slot with session parameters */
+ if (agent->session_params)
+ PGXCNodeSendSetQuery(slot->conn, agent->session_params);
+ if (agent->local_params)
+ PGXCNodeSendSetQuery(slot->conn, agent->local_params);
}
result[i++] = PQsocket((PGconn *) agent->coord_connections[node - 1]->conn);
@@ -1095,6 +1242,20 @@ agent_release_connections(PoolAgent *agent, List *dn_discard, List *co_discard)
if (!agent->dn_connections && !agent->coord_connections)
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.
+ * Local parameters are reset when transaction block is finished,
+ * so don't do anything for them, but just reset their list.
+ */
+ if (agent->local_params)
+ {
+ pfree(agent->local_params);
+ agent->local_params = NULL;
+ }
+ if (agent->session_params)
+ return;
+
/* Discard first for Datanodes */
if (dn_discard)
{
@@ -1156,6 +1317,65 @@ agent_release_connections(PoolAgent *agent, List *dn_discard, List *co_discard)
}
}
+/*
+ * Reset session parameters for given connections in the agent.
+ * This is done before putting back to pool connections that have been
+ * modified by session parameters.
+ */
+static void
+agent_reset_params(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;
+ }
+
+ /* Reset Datanode connection params */
+ if (dn_list)
+ {
+ ListCell *lc;
+
+ foreach(lc, dn_list)
+ {
+ 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;");
+ }
+ }
+
+ /* Reset Coordinator connection params */
+ if (co_list)
+ {
+ ListCell *lc;
+
+ foreach(lc, co_list)
+ {
+ int node = lfirst_int(lc);
+ Assert(node > 0 && node <= NumCoords);
+ slot = agent->coord_connections[node - 1];
+
+ /* Reset connection params */
+ if (slot)
+ PGXCNodeSendSetQuery(slot->conn, "RESET ALL;");
+ }
+ }
+}
/*
* Create new empty pool for a database.
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 08a05a955e..1576c4a043 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -62,6 +62,7 @@
#include "pgxc/pgxc.h"
#include "pgxc/planner.h"
#include "pgxc/poolutils.h"
+#include "pgxc/poolmgr.h"
static void ExecUtilityStmtOnNodes(const char *queryString, ExecNodes *nodes,
bool force_autocommit, RemoteQueryExecType exec_type);
@@ -1410,11 +1411,18 @@ standard_ProcessUtility(Node *parsetree,
case T_VariableSetStmt:
ExecSetVariableStmt((VariableSetStmt *) parsetree);
#ifdef PGXC
-/* PGXCTODO - this currently causes an assertion failure.
- We should change when we add SET handling properly
- if (IS_PGXC_COORDINATOR)
- ExecUtilityStmtOnNodes(queryString, NULL, false);
-*/
+ /* Let the pooler manage the statement */
+ if (IS_PGXC_COORDINATOR && !IsConnFromCoord())
+ {
+ VariableSetStmt *stmt = (VariableSetStmt *) parsetree;
+ /*
+ * If command is local and we are not in a transaction block do NOT
+ * send this query to backend nodes
+ */
+ if (!stmt->is_local || !IsTransactionBlock())
+ if (PoolManagerSetCommand(stmt->is_local, queryString) < 0)
+ elog(ERROR, "Postgres-XC: ERROR SET query");
+ }
#endif
break;
@@ -1572,6 +1580,14 @@ standard_ProcessUtility(Node *parsetree,
case T_ConstraintsSetStmt:
AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
+
+ /*
+ * PGXCTODO: SET CONSTRAINT management
+ * This can just be done inside a transaction block,
+ * so just launch it on all the Datanodes.
+ * For the time being only IMMEDIATE constraints are supported
+ * so this is not really useful...
+ */
break;
case T_CheckPointStmt:
diff --git a/src/include/pgxc/pgxcnode.h b/src/include/pgxc/pgxcnode.h
index fd7c466995..76f131e10d 100644
--- a/src/include/pgxc/pgxcnode.h
+++ b/src/include/pgxc/pgxcnode.h
@@ -96,6 +96,7 @@ extern void InitMultinodeExecutor(void);
extern char *PGXCNodeConnStr(char *host, char *port, char *dbname, char *user,
char *remote_type);
extern NODE_CONNECTION *PGXCNodeConnect(char *connstr);
+extern int PGXCNodeSendSetQuery(NODE_CONNECTION *conn, const char *sql_command);
extern void PGXCNodeClose(NODE_CONNECTION * conn);
extern int PGXCNodeConnected(NODE_CONNECTION * conn);
extern int PGXCNodeConnClean(NODE_CONNECTION * conn);
diff --git a/src/include/pgxc/poolmgr.h b/src/include/pgxc/poolmgr.h
index b62f77e164..5299d0a5ae 100644
--- a/src/include/pgxc/poolmgr.h
+++ b/src/include/pgxc/poolmgr.h
@@ -56,8 +56,10 @@ typedef struct databasepool
struct databasepool *next;
} DatabasePool;
-/* Agent of client session (Pool Manager side)
+/*
+ * Agent of client session (Pool Manager side)
* Acts as a session manager, grouping connections together
+ * and managing session parameters
*/
typedef struct
{
@@ -68,6 +70,8 @@ typedef struct
DatabasePool *pool;
PGXCNodePoolSlot **dn_connections; /* one for each Datanode */
PGXCNodePoolSlot **coord_connections; /* one for each Coordinator */
+ char *session_params;
+ char *local_params;
} PoolAgent;
/* Handle to the pool manager (Session's side) */
@@ -116,7 +120,7 @@ extern void PoolManagerCloseHandle(PoolHandle *handle);
/*
* Gracefully close connection to the PoolManager
*/
-extern void PoolManagerDisconnect(PoolHandle *handle);
+extern void PoolManagerDisconnect(void);
/*
* Called from Session process after fork(). Associate handle with session
@@ -125,6 +129,14 @@ extern void PoolManagerDisconnect(PoolHandle *handle);
*/
extern void PoolManagerConnect(PoolHandle *handle, const char *database, const char *user_name);
+/*
+ * Save a SET command in Pooler.
+ * This command is run on existent agent connections
+ * and stored in pooler agent to be replayed when new connections
+ * are requested.
+ */
+extern int PoolManagerSetCommand(bool is_local, const char *set_command);
+
/* Get pooled connections */
extern int *PoolManagerGetConnections(List *datanodelist, List *coordlist);
diff --git a/src/test/regress/expected/guc_1.out b/src/test/regress/expected/guc_1.out
index d71a66c817..83b5b6598b 100644
--- a/src/test/regress/expected/guc_1.out
+++ b/src/test/regress/expected/guc_1.out
@@ -513,6 +513,7 @@ SELECT current_user = 'temp_reset_user';
(1 row)
DROP ROLE temp_reset_user;
+ERROR: permission denied to drop role
--
-- Tests for function-local GUC settings
--
@@ -520,32 +521,35 @@ set work_mem = '3MB';
create function report_guc(text) returns text as
$$ select current_setting($1) $$ language sql
set work_mem = '1MB';
+ERROR: stable and volatile not yet supported, function volatility has to be immutable
select report_guc('work_mem'), current_setting('work_mem');
- report_guc | current_setting
-------------+-----------------
- 1MB | 3MB
-(1 row)
-
+ERROR: function report_guc(unknown) does not exist
+LINE 1: select report_guc('work_mem'), current_setting('work_mem');
+ ^
+HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-- this should draw only a warning
alter function report_guc(text) set search_path = no_such_schema;
-NOTICE: schema "no_such_schema" does not exist
+ERROR: function report_guc(text) does not exist
-- with error occurring here
select report_guc('work_mem'), current_setting('work_mem');
-ERROR: schema "no_such_schema" does not exist
+ERROR: function report_guc(unknown) does not exist
+LINE 1: select report_guc('work_mem'), current_setting('work_mem');
+ ^
+HINT: No function matches the given name and argument types. You might need to add explicit type casts.
alter function report_guc(text) reset search_path set work_mem = '2MB';
+ERROR: function report_guc(text) does not exist
select report_guc('work_mem'), current_setting('work_mem');
- report_guc | current_setting
-------------+-----------------
- 2MB | 3MB
-(1 row)
-
+ERROR: function report_guc(unknown) does not exist
+LINE 1: select report_guc('work_mem'), current_setting('work_mem');
+ ^
+HINT: No function matches the given name and argument types. You might need to add explicit type casts.
alter function report_guc(text) reset all;
+ERROR: function report_guc(text) does not exist
select report_guc('work_mem'), current_setting('work_mem');
- report_guc | current_setting
-------------+-----------------
- 3MB | 3MB
-(1 row)
-
+ERROR: function report_guc(unknown) does not exist
+LINE 1: select report_guc('work_mem'), current_setting('work_mem');
+ ^
+HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-- SET LOCAL is restricted by a function SET option
create or replace function myfunc(int) returns text as $$
begin
@@ -554,19 +558,19 @@ begin
end $$
language plpgsql
set work_mem = '1MB';
+ERROR: stable and volatile not yet supported, function volatility has to be immutable
select myfunc(0), current_setting('work_mem');
- myfunc | current_setting
---------+-----------------
- 2MB | 3MB
-(1 row)
-
+ERROR: function myfunc(integer) does not exist
+LINE 1: select myfunc(0), current_setting('work_mem');
+ ^
+HINT: No function matches the given name and argument types. You might need to add explicit type casts.
alter function myfunc(int) reset all;
+ERROR: function myfunc(integer) does not exist
select myfunc(0), current_setting('work_mem');
- myfunc | current_setting
---------+-----------------
- 2MB | 2MB
-(1 row)
-
+ERROR: function myfunc(integer) does not exist
+LINE 1: select myfunc(0), current_setting('work_mem');
+ ^
+HINT: No function matches the given name and argument types. You might need to add explicit type casts.
set work_mem = '3MB';
-- but SET isn't
create or replace function myfunc(int) returns text as $$
@@ -576,12 +580,12 @@ begin
end $$
language plpgsql
set work_mem = '1MB';
+ERROR: stable and volatile not yet supported, function volatility has to be immutable
select myfunc(0), current_setting('work_mem');
- myfunc | current_setting
---------+-----------------
- 2MB | 2MB
-(1 row)
-
+ERROR: function myfunc(integer) does not exist
+LINE 1: select myfunc(0), current_setting('work_mem');
+ ^
+HINT: No function matches the given name and argument types. You might need to add explicit type casts.
set work_mem = '3MB';
-- it should roll back on error, though
create or replace function myfunc(int) returns text as $$
@@ -592,10 +596,12 @@ begin
end $$
language plpgsql
set work_mem = '1MB';
+ERROR: stable and volatile not yet supported, function volatility has to be immutable
select myfunc(0);
-ERROR: division by zero
-CONTEXT: SQL statement "SELECT 1/$1"
-PL/pgSQL function "myfunc" line 3 at PERFORM
+ERROR: function myfunc(integer) does not exist
+LINE 1: select myfunc(0);
+ ^
+HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select current_setting('work_mem');
current_setting
-----------------
@@ -603,8 +609,7 @@ select current_setting('work_mem');
(1 row)
select myfunc(1), current_setting('work_mem');
- myfunc | current_setting
---------+-----------------
- 2MB | 2MB
-(1 row)
-
+ERROR: function myfunc(integer) does not exist
+LINE 1: select myfunc(1), current_setting('work_mem');
+ ^
+HINT: No function matches the given name and argument types. You might need to add explicit type casts.
diff --git a/src/test/regress/expected/plancache_1.out b/src/test/regress/expected/plancache_1.out
index 389d0dad5d..683a42ebc6 100644
--- a/src/test/regress/expected/plancache_1.out
+++ b/src/test/regress/expected/plancache_1.out
@@ -150,7 +150,11 @@ ERROR: Postgres-XC does not support EXECUTE yet
DETAIL: The feature is not currently supported
set search_path = s2;
select f1 from abc;
-ERROR: relation "abc" does not exist
+ f1
+-----
+ 456
+(1 row)
+
execute p1;
ERROR: Postgres-XC does not support EXECUTE yet
DETAIL: The feature is not currently supported
diff --git a/src/test/regress/expected/privileges_1.out b/src/test/regress/expected/privileges_1.out
index d71fd3425d..51153a2e7a 100644
--- a/src/test/regress/expected/privileges_1.out
+++ b/src/test/regress/expected/privileges_1.out
@@ -157,6 +157,7 @@ UPDATE atest2 SET col2 = NULL; -- ok
UPDATE atest2 SET col2 = NOT col2; -- fails; requires SELECT on atest2
ERROR: permission denied for relation atest2
UPDATE atest2 SET col2 = true FROM atest1 WHERE atest1.a = 5; -- ok
+ERROR: permission denied for relation atest2
SELECT * FROM atest1 FOR UPDATE; -- fail
ERROR: permission denied for relation atest1
SELECT * FROM atest2 FOR UPDATE; -- fail
@@ -217,26 +218,17 @@ SELECT * FROM atestv1; -- ok
SELECT * FROM atestv2; -- fail
ERROR: permission denied for relation atestv2
SELECT * FROM atestv3; -- ok
- one | two | three
------+-----+-------
-(0 rows)
-
+ERROR: permission denied for relation atest3
CREATE VIEW atestv4 AS SELECT * FROM atestv3; -- nested view
SELECT * FROM atestv4; -- ok
- one | two | three
------+-----+-------
-(0 rows)
-
+ERROR: permission denied for relation atest3
GRANT SELECT ON atestv4 TO regressuser2;
SET SESSION AUTHORIZATION regressuser2;
-- Two complex cases:
SELECT * FROM atestv3; -- fail
ERROR: permission denied for relation atestv3
SELECT * FROM atestv4; -- ok (even though regressuser2 cannot access underlying atestv3)
- one | two | three
------+-----+-------
-(0 rows)
-
+ERROR: permission denied for relation atest3
SELECT * FROM atest2; -- ok
col1 | col2
------+------
@@ -294,17 +286,9 @@ ERROR: permission denied for relation atest5
SELECT * FROM atest1, atest5; -- fail
ERROR: permission denied for relation atest5
SELECT atest1.* FROM atest1, atest5; -- ok
- a | b
----+-----
- 2 | two
-(1 row)
-
+ERROR: permission denied for relation atest5
SELECT atest1.*,atest5.one FROM atest1, atest5; -- ok
- a | b | one
----+-----+-----
- 2 | two | 1
-(1 row)
-
+ERROR: permission denied for relation atest5
SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.two); -- fail
ERROR: permission denied for relation atest5
SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.one); -- ok
@@ -817,7 +801,6 @@ SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- true
REVOKE SELECT ON atest4 FROM regressuser2; -- fail
ERROR: dependent privileges exist
-HINT: Use CASCADE to revoke them too.
REVOKE GRANT OPTION FOR SELECT ON atest4 FROM regressuser2 CASCADE; -- ok
SELECT has_table_privilege('regressuser2', 'atest4', 'SELECT'); -- true
has_table_privilege
@@ -1235,8 +1218,6 @@ REVOKE USAGE ON LANGUAGE sql FROM regressuser1;
DROP OWNED BY regressuser1;
DROP USER regressuser1;
DROP USER regressuser2;
-ERROR: role "regressuser2" cannot be dropped because some objects depend on it
-DETAIL: privileges for language sql
DROP USER regressuser3;
DROP USER regressuser4;
DROP USER regressuser5;