/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*-------------------------------------------------------------------------
 *
 * user.c
 *	  Commands for manipulating roles (formerly called users).
 *
 * Portions Copyright (c) 2005-2010, Greenplum inc
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.174.2.1 2010/03/25 14:45:21 alvherre Exp $
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/genam.h"
#include "access/heapam.h"
#include "access/xact.h"
#include "catalog/catquery.h"
#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/indexing.h"
#include "catalog/pg_auth_time_constraint.h"
#include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_resqueue.h"
#include "commands/comment.h"
#include "commands/user.h"
#include "libpq/auth.h"
#include "libpq/password_hash.h"
#include "libpq/md5.h"
#include "libpq/pg_sha2.h"
#include "miscadmin.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/flatfiles.h"
#include "utils/fmgroids.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"

#include "executor/execdesc.h"
#include "utils/resscheduler.h"
#include "utils/syscache.h"

#include "cdb/cdbdisp.h"
#include "cdb/cdbsrlz.h"
#include "cdb/cdbvars.h"
#include "cdb/cdbcat.h"
#include "cdb/dispatcher.h"

#include "resourcemanager/communication/rmcomm_QD2RM.h"
#include "resourcemanager/errorcode.h"

typedef struct genericPair
{
	char* key1;
	char* val1;
	char* key2;
	char* val2;
	
} genericPair;

typedef struct extAuthPair
{
	char* protocol;
	char* type;

} extAuthPair;

extern bool Password_encryption;

static List *roleNamesToIds(List *memberNames);
static void AddRoleMems(const char *rolename, Oid roleid,
			List *memberNames, List *memberIds,
			Oid grantorId, bool admin_opt);
static void DelRoleMems(const char *rolename, Oid roleid,
			List *memberNames, List *memberIds,
			bool admin_opt);
static void TransformExttabAuthClause(DefElem *defel, 
			extAuthPair *extauth);
static void SetCreateExtTableForRole(List* allow, 
			List* disallow, bool* createrextgpfd,
			bool* createrexthttp, bool* createwextgpfd,
			bool* createrexthdfs, bool* createwexthdfs);

static char *daysofweek[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
							 "Thursday", "Friday", "Saturday"};
static int16 ExtractAuthInterpretDay(Value * day);
static void ExtractAuthIntervalClause(DefElem *defel,
			authInterval *authInterval);
static void AddRoleDenials(const char *rolename, Oid roleid,
			List *addintervals); 
static void DelRoleDenials(const char *rolename, Oid roleid, 
			List *dropintervals);
static bool resourceQueueIsBranch(Oid queueid);

/* Check if current user has createrole privileges */
static bool
have_createrole_privilege(void)
{
	bool		result = false;
	cqContext  *pcqCtx, cqc;
	HeapTuple	utup;

	/* Superusers can always do everything */
	if (superuser())
		return true;

	pcqCtx = 
			caql_beginscan(
					cqclr(&cqc),
					cql("SELECT * FROM pg_authid "
						" WHERE oid = :1 ",
						ObjectIdGetDatum(GetUserId())));

	if (HeapTupleIsValid(utup = caql_getnext(pcqCtx)))
	{
		result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
	}
	caql_endscan(pcqCtx);

	return result;
}

/*
 * If a resource queue(oid) is a branch
 */
static bool resourceQueueIsBranch(Oid queueid)
{
	HeapTuple		tuple = NULL;
	cqContext		cqc;
	cqContext  		*pcqCtx;
	Relation		pg_resqueue_rel;
	bool			res = false;
	Datum           status;
	bool            isNull = false;

	Assert(queueid != InvalidOid);
	pg_resqueue_rel = heap_open(ResQueueRelationId, RowExclusiveLock);
	pcqCtx = caql_addrel(cqclr(&cqc), pg_resqueue_rel);

	tuple = caql_getfirst(pcqCtx,
				  cql("SELECT * FROM pg_resqueue WHERE oid = :1",
					   ObjectIdGetDatum(queueid)));

	Assert(tuple != NULL);

	status = heap_getattr(tuple, Anum_pg_resqueue_status, RelationGetDescr(pg_resqueue_rel), &isNull);
	if (!isNull && strncmp(TextDatumGetCString(status), "branch", strlen("branch")) == 0)
		res = true;

	heap_close(pg_resqueue_rel, NoLock);
	return res;
}

/*
 * CREATE ROLE
 */
void
CreateRole(CreateRoleStmt *stmt)
{
	Relation	pg_authid_rel;
	HeapTuple	tuple;
	Datum		new_record[Natts_pg_authid];
	bool		new_record_nulls[Natts_pg_authid];
	Oid			roleid;
	ListCell   *item;
	ListCell   *option;
	char	   *password = NULL;	/* user password */
	bool		encrypt_password = Password_encryption; /* encrypt password? */
	char		encrypted_password[MAX_PASSWD_HASH_LEN + 1];
	bool		issuper = false;	/* Make the user a superuser? */
	bool		inherit = true; /* Auto inherit privileges? */
	bool		createrole = false;		/* Can this user create roles? */
	bool		createdb = false;		/* Can the user create databases? */
	bool		canlogin = false;		/* Can this user login? */
	bool		createrextgpfd = false; /* Can create readable gpfdist exttab? */
	bool		createrexthttp = false; /* Can create readable http exttab? */
	bool		createwextgpfd = false; /* Can create writable gpfdist exttab? */
	bool		createrexthdfs = false; /* Can create readable gphdfs exttab? */
	bool		createwexthdfs = false; /* Can create writable gphdfs exttab? */
	int			connlimit = -1; /* maximum connections allowed */
	List	   *addroleto = NIL;	/* roles to make this a member of */
	List	   *rolemembers = NIL;		/* roles to be members of this role */
	List	   *adminmembers = NIL;		/* roles to be admins of this role */
	List	   *exttabcreate = NIL;		/* external table create privileges being added  */
	List	   *exttabnocreate = NIL;	/* external table create privileges being removed */
	char	   *validUntil = NULL;		/* time the login is valid until */
	char	   *resqueue = NULL;		/* resource queue for this role */
	List	   *addintervals = NIL;	/* list of time intervals for which login should be denied */
	DefElem    *dpassword = NULL;
	DefElem    *dresqueue = NULL;
	DefElem    *dissuper = NULL;
	DefElem    *dinherit = NULL;
	DefElem    *dcreaterole = NULL;
	DefElem    *dcreatedb = NULL;
	DefElem    *dcanlogin = NULL;
	DefElem    *dconnlimit = NULL;
	DefElem    *daddroleto = NULL;
	DefElem    *drolemembers = NULL;
	DefElem    *dadminmembers = NULL;
	DefElem    *dvalidUntil = NULL;
	cqContext	cqc;
	cqContext	cqc2;
	cqContext  *pcqCtx;
	Oid		queueid = InvalidOid;

	int  		res 		= FUNC_RETURN_OK;
	static char errorbuf[1024] = "";

	/* The defaults can vary depending on the original statement type */
	switch (stmt->stmt_type)
	{
		case ROLESTMT_ROLE:
			break;
		case ROLESTMT_USER:
			canlogin = true;
			/* may eventually want inherit to default to false here */
			break;
		case ROLESTMT_GROUP:
			break;
	}

	/* Extract options from the statement node tree */
	foreach(option, stmt->options)
	{
		DefElem    *defel = (DefElem *) lfirst(option);

		if (strcmp(defel->defname, "password") == 0 ||
			strcmp(defel->defname, "encryptedPassword") == 0 ||
			strcmp(defel->defname, "unencryptedPassword") == 0)
		{
			if (dpassword)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			dpassword = defel;
			if (strcmp(defel->defname, "encryptedPassword") == 0)
				encrypt_password = true;
			else if (strcmp(defel->defname, "unencryptedPassword") == 0)
				encrypt_password = false;
		}
		else if (strcmp(defel->defname, "sysid") == 0)
		{
			if (Gp_role != GP_ROLE_EXECUTE)
			ereport(NOTICE,
					(errmsg("SYSID can no longer be specified")));
		}
		else if (strcmp(defel->defname, "superuser") == 0)
		{
			if (dissuper)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			dissuper = defel;
		}
		else if (strcmp(defel->defname, "inherit") == 0)
		{
			if (dinherit)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			dinherit = defel;
		}
		else if (strcmp(defel->defname, "createrole") == 0)
		{
			if (dcreaterole)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			dcreaterole = defel;
		}
		else if (strcmp(defel->defname, "createdb") == 0)
		{
			if (dcreatedb)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			dcreatedb = defel;
		}
		else if (strcmp(defel->defname, "canlogin") == 0)
		{
			if (dcanlogin)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			dcanlogin = defel;
		}
		else if (strcmp(defel->defname, "connectionlimit") == 0)
		{
			if (dconnlimit)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			dconnlimit = defel;
		}
		else if (strcmp(defel->defname, "addroleto") == 0)
		{
			if (daddroleto)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			daddroleto = defel;
		}
		else if (strcmp(defel->defname, "rolemembers") == 0)
		{
			if (drolemembers)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			drolemembers = defel;
		}
		else if (strcmp(defel->defname, "adminmembers") == 0)
		{
			if (dadminmembers)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			dadminmembers = defel;
		}
		else if (strcmp(defel->defname, "validUntil") == 0)
		{
			if (dvalidUntil)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			dvalidUntil = defel;
		}
		else if (strcmp(defel->defname, "resourceQueue") == 0)
		{
			if (dresqueue)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options")));
			dresqueue = defel;
		}
		else if (strcmp(defel->defname, "exttabauth") == 0)
		{
			extAuthPair *extauth = (extAuthPair *) palloc0 (2 * sizeof(char *));
			
			TransformExttabAuthClause(defel, extauth);
			
			/* now actually append our transformed key value pairs to the list */
			exttabcreate = lappend(exttabcreate, extauth);			
		}			  
		else if (strcmp(defel->defname, "exttabnoauth") == 0)
		{
			extAuthPair *extauth = (extAuthPair *) palloc0 (2 * sizeof(char *));
			
			TransformExttabAuthClause(defel, extauth);
			
			/* now actually append our transformed key value pairs to the list */
			exttabnocreate = lappend(exttabnocreate, extauth);
		}
		else if (strcmp(defel->defname, "deny") == 0) 
		{
			authInterval *interval = (authInterval *) palloc0(sizeof(authInterval));

			ExtractAuthIntervalClause(defel, interval);

			addintervals = lappend(addintervals, interval);
		}
		else
			elog(ERROR, "option \"%s\" not recognized",
				 defel->defname);
	}

	if (dpassword && dpassword->arg)
		password = strVal(dpassword->arg);
	if (dissuper)
		issuper = intVal(dissuper->arg) != 0;
	if (dinherit)
		inherit = intVal(dinherit->arg) != 0;
	if (dcreaterole)
		createrole = intVal(dcreaterole->arg) != 0;
	if (dcreatedb)
		createdb = intVal(dcreatedb->arg) != 0;
	if (dcanlogin)
		canlogin = intVal(dcanlogin->arg) != 0;
	if (dconnlimit)
		connlimit = intVal(dconnlimit->arg);
	if (daddroleto)
		addroleto = (List *) daddroleto->arg;
	if (drolemembers)
		rolemembers = (List *) drolemembers->arg;
	if (dadminmembers)
		adminmembers = (List *) dadminmembers->arg;
	if (dvalidUntil)
		validUntil = strVal(dvalidUntil->arg);
	if (dresqueue)
		resqueue = strVal(linitial((List *) dresqueue->arg));
	else
	{
		/* MPP-6926: resource queue required -- use default queue  */
		if (Gp_role == GP_ROLE_DISPATCH)
		{
			/* MPP-7587: don't complain if you CREATE a superuser,
			 * who doesn't use the queue 
			 */
			if (!issuper)
				ereport(NOTICE,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("resource queue required -- "
								"using default resource queue \"%s\"",
								GP_DEFAULT_RESOURCE_QUEUE_NAME)));
		}

		resqueue = pstrdup(GP_DEFAULT_RESOURCE_QUEUE_NAME);
	}

	/* Check some permissions first */
	if (issuper)
	{
		if (!superuser())
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must be superuser to create superusers")));
	}
	else
	{
		if (!have_createrole_privilege())
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("permission denied to create role")));
	}

	if (strcmp(stmt->role, "public") == 0 ||
		strcmp(stmt->role, "none") == 0)
		ereport(ERROR,
				(errcode(ERRCODE_RESERVED_NAME),
				 errmsg("role name \"%s\" is reserved",
						stmt->role)));

	/* Create a new resource context to manipulate role in resource manager. */
	int resourceid = 0;
	res = createNewResourceContext(&resourceid);
	if (res != FUNC_RETURN_OK) {
		Assert( res == COMM2RM_CLIENT_FULL_RESOURCECONTEXT );
		ereport(ERROR,
				(errcode(ERRCODE_INTERNAL_ERROR),
						 errmsg("Can not apply CREATE ROLE. "
								"Because too many resource contexts were created.")));
	}

	/* Here, using user oid is more convenient. */
	res = registerConnectionInRMByOID(resourceid,
									  GetUserId(),
									  errorbuf,
									  sizeof(errorbuf));
	if (res != FUNC_RETURN_OK)
	{
		releaseResourceContextWithErrorReport(resourceid);
		ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("%s", errorbuf)));
	}

	/*
	 * Check the pg_authid relation to be certain the role doesn't already
	 * exist.
	 */
	pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);

	pcqCtx = 
			caql_beginscan(
					caql_addrel(cqclr(&cqc), pg_authid_rel),
					cql("INSERT INTO pg_authid ",
						NULL));

	if (caql_getcount(
				caql_addrel(cqclr(&cqc2), pg_authid_rel),
				cql("SELECT COUNT(*) FROM pg_authid "
					" WHERE rolname = :1 ",
					PointerGetDatum(stmt->role)))) {
		unregisterConnectionInRMWithErrorReport(resourceid);
		releaseResourceContextWithErrorReport(resourceid);
		ereport(ERROR,
				(errcode(ERRCODE_DUPLICATE_OBJECT),
				 errmsg("role \"%s\" already exists",
						stmt->role)));
	}

	/*
	 * Build a tuple to insert
	 */
	MemSet(new_record, 0, sizeof(new_record));
	MemSet(new_record_nulls, false, sizeof(new_record_nulls));

	new_record[Anum_pg_authid_rolname - 1] =
		DirectFunctionCall1(namein, CStringGetDatum(stmt->role));

	new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper);
	new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit);
	new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole);
	new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb);
	/* superuser gets catupdate right by default */
	new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper);
	new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin);
	new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit);

	/* Set the CREATE EXTERNAL TABLE permissions for this role */
	if (exttabcreate || exttabnocreate)
		SetCreateExtTableForRole(exttabcreate, exttabnocreate, &createrextgpfd,
								 &createrexthttp, &createwextgpfd,
								 &createrexthdfs, &createwexthdfs);

	new_record[Anum_pg_authid_rolcreaterextgpfd - 1] = BoolGetDatum(createrextgpfd);
	new_record[Anum_pg_authid_rolcreaterexthttp - 1] = BoolGetDatum(createrexthttp);
	new_record[Anum_pg_authid_rolcreatewextgpfd - 1] = BoolGetDatum(createwextgpfd);
	new_record[Anum_pg_authid_rolcreaterexthdfs - 1] = BoolGetDatum(createrexthdfs);
	new_record[Anum_pg_authid_rolcreatewexthdfs - 1] = BoolGetDatum(createwexthdfs);
	
	if (password)
	{
		if (!encrypt_password || isHashedPasswd(password))
			new_record[Anum_pg_authid_rolpassword - 1] =
				CStringGetTextDatum(password);
		else
		{
			if (!hash_password(password, stmt->role, strlen(stmt->role),
							   encrypted_password))
			{
				elog(ERROR, "password encryption failed");
			}

			new_record[Anum_pg_authid_rolpassword - 1] =
				CStringGetTextDatum(encrypted_password);
		}
	}
	else
		new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;

	if (validUntil)
		new_record[Anum_pg_authid_rolvaliduntil - 1] =
			DirectFunctionCall3(timestamptz_in,
								CStringGetDatum(validUntil),
								ObjectIdGetDatum(InvalidOid),
								Int32GetDatum(-1));

	else
		new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = true;

	if (resqueue)
	{
		if (strcmp(resqueue, "none") == 0)
		{
			unregisterConnectionInRMWithErrorReport(resourceid);
			releaseResourceContextWithErrorReport(resourceid);
			ereport(ERROR,
					(errcode(ERRCODE_RESERVED_NAME),
					 errmsg("resource queue name \"%s\" is reserved",
							resqueue), errOmitLocation(true)));
		}

		queueid = GetResQueueIdForName(resqueue);
		if (queueid == InvalidOid)
		{
			unregisterConnectionInRMWithErrorReport(resourceid);
			releaseResourceContextWithErrorReport(resourceid);
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("resource queue \"%s\" does not exist",
							resqueue), errOmitLocation(true)));
		}

		if(resourceQueueIsBranch(queueid))
		{
			unregisterConnectionInRMWithErrorReport(resourceid);
			releaseResourceContextWithErrorReport(resourceid);
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("cannot assign non-leaf resource queue \"%s\" to role",
							resqueue), errOmitLocation(true)));
		}

		new_record[Anum_pg_authid_rolresqueue - 1] = 
		ObjectIdGetDatum(queueid);
	}
	else
		new_record_nulls[Anum_pg_authid_rolresqueue - 1] = true;

	new_record_nulls[Anum_pg_authid_rolconfig - 1] = true;

	tuple = caql_form_tuple(pcqCtx, new_record, new_record_nulls);


	if (stmt->roleOid != InvalidOid)
		/* force tuple to have the desired OID */
		HeapTupleSetOid(tuple, stmt->roleOid);
	
	/*
	 * Insert new record in the pg_authid table
	 */
	roleid = caql_insert(pcqCtx, tuple); /* implicit update of index as well */
	stmt->roleOid = roleid;

	/*
	 * send RPC: notify RM to update
	 */
	if (resqueue && queueid != InvalidOid)
	{
		res = manipulateRoleForResourceQueue(resourceid,
											 roleid,
											 queueid,
											 MANIPULATE_ROLE_RESQUEUE_CREATE,
											 issuper,
											 stmt->role,
											 errorbuf,
											 sizeof(errorbuf));
	}

	/* We always unregister connection. */
	unregisterConnectionInRMWithErrorReport(resourceid);

	/* We always release resource context. */
	releaseResourceContextWithErrorReport(resourceid);

	if (resqueue && queueid != InvalidOid)
	{
		if ( res != FUNC_RETURN_OK )
		{
			ereport(ERROR,
					(errcode(IS_TO_RM_RPC_ERROR(res) ?
							 ERRCODE_INTERNAL_ERROR :
							 ERRCODE_INVALID_OBJECT_DEFINITION),
					 errmsg("cannot apply CREATE ROLE because of %s", errorbuf)));
		}
	}

	/*
	 * Advance command counter so we can see new record; else tests in
	 * AddRoleMems may fail.
	 */
	if (addroleto || adminmembers || rolemembers)
		CommandCounterIncrement();

	/*
	 * Add the new role to the specified existing roles.
	 */
	foreach(item, addroleto)
	{
		char	   *oldrolename = strVal(lfirst(item));
		Oid			oldroleid = get_roleid_checked(oldrolename);

		AddRoleMems(oldrolename, oldroleid,
					list_make1(makeString(stmt->role)),
					list_make1_oid(roleid),
					GetUserId(), false);
	}

	/*
	 * Add the specified members to this new role. adminmembers get the admin
	 * option, rolemembers don't.
	 */
	AddRoleMems(stmt->role, roleid,
				adminmembers, roleNamesToIds(adminmembers),
				GetUserId(), true);
	AddRoleMems(stmt->role, roleid,
				rolemembers, roleNamesToIds(rolemembers),
				GetUserId(), false);

	/*
	 * Populate pg_auth_time_constraint with intervals for which this 
	 * particular role should be denied access.
	 */
	if (addintervals)
	{
		if (issuper)
			ereport(ERROR,
					(errmsg("cannot create superuser with DENY rules")));
		AddRoleDenials(stmt->role, roleid, addintervals);
	}

	/*
	 * Close pg_authid, but keep lock till commit (this is important to
	 * prevent any risk of deadlock failure while updating flat file)
	 */
	caql_endscan(pcqCtx);
	heap_close(pg_authid_rel, NoLock);

	/*
	 * Set flag to update flat auth file at commit.
	 */
	auth_file_update_needed();

	if (Gp_role == GP_ROLE_DISPATCH)
	{
		Assert(stmt->type == T_CreateRoleStmt);
		Assert(stmt->type < 1000);
		/* GPSQL: no dispatch to segments */
		/* CdbDispatchUtilityStatement((Node *) stmt, "CreateRole"); */

		/* MPP-6929: metadata tracking */
		MetaTrackAddObject(AuthIdRelationId,
						   roleid,
						   GetUserId(),
						   "CREATE", "ROLE"
				);
	}
}


/*
 * ALTER ROLE
 *
 * Note: the rolemembers option accepted here is intended to support the
 * backwards-compatible ALTER GROUP syntax.  Although it will work to say
 * "ALTER ROLE role ROLE rolenames", we don't document it.
 */
void
AlterRole(AlterRoleStmt *stmt)
{
	Datum		 new_record[Natts_pg_authid];
	bool		 new_record_nulls[Natts_pg_authid];
	bool		 new_record_repl[Natts_pg_authid];
	Relation	 pg_authid_rel;
	TupleDesc	 pg_authid_dsc;
	HeapTuple	 tuple,
				 new_tuple;
	ListCell	*option;
	char		*password	   = NULL;	/* user password */
	bool		 encrypt_password 
							   = Password_encryption;	/* encrypt password? */
	char		 encrypted_password[MAX_PASSWD_HASH_LEN + 1];
	int			 issuper	   = -1;	/* Make the user a superuser? */
	int			 inherit	   = -1;	/* Auto inherit privileges? */
	int			 createrole	   = -1;	/* Can this user create roles? */
	int			 createdb	   = -1;	/* Can the user create databases? */
	int			 canlogin	   = -1;	/* Can this user login? */
	int			 connlimit	   = -1;	/* maximum connections allowed */
	char		*resqueue	   = NULL;	/* resource queue for this role */
	List		*rolemembers   = NIL;	/* roles to be added/removed */
	List	    *exttabcreate  = NIL;	/* external table create privileges being added  */
	List	    *exttabnocreate = NIL;	/* external table create privileges being removed */
	char		*validUntil	   = NULL;	/* time the login is valid until */
	DefElem		*dpassword	   = NULL;
	DefElem		*dresqueue	   = NULL;
	DefElem		*dissuper	   = NULL;
	DefElem		*dinherit	   = NULL;
	DefElem		*dcreaterole   = NULL;
	DefElem		*dcreatedb	   = NULL;
	DefElem		*dcanlogin	   = NULL;
	DefElem		*dconnlimit	   = NULL;
	DefElem		*drolemembers  = NULL;
	DefElem		*dvalidUntil   = NULL;
	Oid			 roleid;
	bool		 bWas_super	   = false;	/* Was the user a superuser? */
	int			 numopts	   = 0;
	char		*alter_subtype = "";	/* metadata tracking: kind of
										   redundant to say "role" */
	bool		 createrextgpfd;
	bool 		 createrexthttp;
	bool		 createwextgpfd;
	bool 		 createrexthdfs;
	bool		 createwexthdfs;
	List		*addintervals = NIL;    /* list of time intervals for which login should be denied */
	List		*dropintervals = NIL;    /* list of time intervals for which matching rules should be dropped */

	cqContext	 cqc;
	cqContext	*pcqCtx;
	Oid			 queueid = InvalidOid;

	int  		 res 			= FUNC_RETURN_OK;
	static char  errorbuf[1024] = "";

	numopts = list_length(stmt->options);

	if (numopts > 1)
	{
		char allopts[NAMEDATALEN];

		sprintf(allopts, "%d OPTIONS", numopts);

		alter_subtype = pstrdup(allopts);
	}
	else if (0 == numopts)
	{
		alter_subtype = "0 OPTIONS";
	}

	/* Extract options from the statement node tree */
	foreach(option, stmt->options)
	{
		DefElem    *defel = (DefElem *) lfirst(option);

		if (strcmp(defel->defname, "password") == 0 ||
			strcmp(defel->defname, "encryptedPassword") == 0 ||
			strcmp(defel->defname, "unencryptedPassword") == 0)
		{
			if (dpassword)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options"),
								   errOmitLocation(true)));
			dpassword = defel;
			if (strcmp(defel->defname, "encryptedPassword") == 0)
				encrypt_password = true;
			else if (strcmp(defel->defname, "unencryptedPassword") == 0)
				encrypt_password = false;

			if (1 == numopts) alter_subtype = "PASSWORD";
		}
		else if (strcmp(defel->defname, "superuser") == 0)
		{
			if (dissuper)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options"),
								   errOmitLocation(true)));
			dissuper = defel;
			if (1 == numopts) alter_subtype = "SUPERUSER";
		}
		else if (strcmp(defel->defname, "inherit") == 0)
		{
			if (dinherit)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options"),
								   errOmitLocation(true)));
			dinherit = defel;
			if (1 == numopts) alter_subtype = "INHERIT";
		}
		else if (strcmp(defel->defname, "createrole") == 0)
		{
			if (dcreaterole)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options"),
								   errOmitLocation(true)));
			dcreaterole = defel;
			if (1 == numopts) alter_subtype = "CREATEROLE";
		}
		else if (strcmp(defel->defname, "createdb") == 0)
		{
			if (dcreatedb)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options"),
								   errOmitLocation(true)));
			dcreatedb = defel;
			if (1 == numopts) alter_subtype = "CREATEDB";
		}
		else if (strcmp(defel->defname, "canlogin") == 0)
		{
			if (dcanlogin)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options"),
								   errOmitLocation(true)));
			dcanlogin = defel;
			if (1 == numopts) alter_subtype = "LOGIN";
		}
		else if (strcmp(defel->defname, "connectionlimit") == 0)
		{
			if (dconnlimit)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options"),
								   errOmitLocation(true)));
			dconnlimit = defel;
			if (1 == numopts) alter_subtype = "CONNECTION LIMIT";
		}
		else if (strcmp(defel->defname, "rolemembers") == 0 &&
				 stmt->action != 0)
		{
			if (drolemembers)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options"),
								   errOmitLocation(true)));
			drolemembers = defel;
			if (1 == numopts) alter_subtype = "ROLE";
		}
		else if (strcmp(defel->defname, "validUntil") == 0)
		{
			if (dvalidUntil)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options"),
								   errOmitLocation(true)));
			dvalidUntil = defel;
			if (1 == numopts) alter_subtype = "VALID UNTIL";
		}
		else if (strcmp(defel->defname, "resourceQueue") == 0)
		{
			if (dresqueue)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("conflicting or redundant options"),
								   errOmitLocation(true)));
			dresqueue = defel;
			if (1 == numopts) alter_subtype = "RESOURCE QUEUE";
		}
		else if (strcmp(defel->defname, "exttabauth") == 0)
		{
			extAuthPair *extauth = (extAuthPair *) palloc0 (2 * sizeof(char *));
			
			TransformExttabAuthClause(defel, extauth);
			
			/* now actually append our transformed key value pairs to the list */
			exttabcreate = lappend(exttabcreate, extauth);	
			
			if (1 == numopts) alter_subtype = "CREATEEXTTABLE";
		}			  
		else if (strcmp(defel->defname, "exttabnoauth") == 0)
		{
			extAuthPair *extauth = (extAuthPair *) palloc0 (2 * sizeof(char *));
			
			TransformExttabAuthClause(defel, extauth);
			
			/* now actually append our transformed key value pairs to the list */
			exttabnocreate = lappend(exttabnocreate, extauth);
			
			if (1 == numopts) alter_subtype = "NO CREATEEXTTABLE";
		}
		else if (strcmp(defel->defname, "deny") == 0)
		{
			authInterval *interval = (authInterval *) palloc0(sizeof(authInterval));

			ExtractAuthIntervalClause(defel, interval);

			addintervals = lappend(addintervals, interval);
		}
		else if (strcmp(defel->defname, "drop_deny") == 0)
		{
			authInterval *interval = (authInterval *) palloc0(sizeof(authInterval));
		
			ExtractAuthIntervalClause(defel, interval);
	
			dropintervals = lappend(dropintervals, interval);
		}
		else
			elog(ERROR, "option \"%s\" not recognized",
				 defel->defname);
	}

	if (dpassword && dpassword->arg)
		password = strVal(dpassword->arg);
	if (dissuper)
		issuper = intVal(dissuper->arg);
	if (dinherit)
		inherit = intVal(dinherit->arg);
	if (dcreaterole)
		createrole = intVal(dcreaterole->arg);
	if (dcreatedb)
		createdb = intVal(dcreatedb->arg);
	if (dcanlogin)
		canlogin = intVal(dcanlogin->arg);
	if (dconnlimit)
		connlimit = intVal(dconnlimit->arg);
	if (drolemembers)
		rolemembers = (List *) drolemembers->arg;
	if (dvalidUntil)
		validUntil = strVal(dvalidUntil->arg);
	if (dresqueue)
		resqueue = strVal(linitial((List *) dresqueue->arg));

	/*
	 * create a new context
	 */
	int resourceid = 0;
    res = createNewResourceContext(&resourceid);
    if ( res != FUNC_RETURN_OK )
    {
    	Assert( res == COMM2RM_CLIENT_FULL_RESOURCECONTEXT );
    	ereport(ERROR,
    			(errcode(ERRCODE_INTERNAL_ERROR),
    			         errmsg("too many existing resource context.")));
    }

	/* Here, using user oid is more convenient. */
	res = registerConnectionInRMByOID(resourceid,
									  GetUserId(),
									  errorbuf,
									  sizeof(errorbuf));
	if (res != FUNC_RETURN_OK)
	{
		releaseResourceContextWithErrorReport(resourceid);
		ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("%s", errorbuf)));
	}

	/*
	 * Scan the pg_authid relation to be certain the user exists.
	 */
	pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
	pg_authid_dsc = RelationGetDescr(pg_authid_rel);

	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), pg_authid_rel),
			cql("SELECT * FROM pg_authid "
				" WHERE rolname = :1 "
				" FOR UPDATE ",
				PointerGetDatum(stmt->role)));

	tuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tuple)) {
		releaseResourceContextWithErrorReport(resourceid);
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("role \"%s\" does not exist", stmt->role)));
	}

	roleid = HeapTupleGetOid(tuple);

	/*
	 * To mess with a superuser you gotta be superuser; else you need
	 * createrole, or just want to change your own password
	 */

	bWas_super = ((Form_pg_authid) GETSTRUCT(tuple))->rolsuper;

	if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper || issuper >= 0)
	{
		if (!superuser()) {
			releaseResourceContextWithErrorReport(resourceid);
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must be superuser to alter superusers")));
		}
	}
	else if (!have_createrole_privilege())
	{
		bool is_createrol_required = !(inherit < 0 &&
									   createrole < 0 &&
									   createdb < 0 &&
									   canlogin < 0 &&
									   !dconnlimit &&
									   !rolemembers &&
									   !validUntil &&
									   dpassword &&
									   !exttabcreate &&
									   !exttabnocreate &&
									   roleid == GetUserId());
		
		if (is_createrol_required) {
			releaseResourceContextWithErrorReport(resourceid);
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("permission denied"),
							   errOmitLocation(true)));
		}
	}

	/*
	 * Build an updated tuple, perusing the information just obtained
	 */
	MemSet(new_record, 0, sizeof(new_record));
	MemSet(new_record_nulls, false, sizeof(new_record_nulls));
	MemSet(new_record_repl, false, sizeof(new_record_repl));

	/*
	 * issuper/createrole/catupdate/etc
	 *
	 * XXX It's rather unclear how to handle catupdate.  It's probably best to
	 * keep it equal to the superuser status, otherwise you could end up with
	 * a situation where no existing superuser can alter the catalogs,
	 * including pg_authid!
	 */
	if (issuper >= 0)
	{
		new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper > 0);
		new_record_repl[Anum_pg_authid_rolsuper - 1] = true;

		new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper > 0);
		new_record_repl[Anum_pg_authid_rolcatupdate - 1] = true;

		bWas_super = (issuper > 0); /* get current superuser status */
	}

	if (inherit >= 0)
	{
		new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit > 0);
		new_record_repl[Anum_pg_authid_rolinherit - 1] = true;
	}

	if (createrole >= 0)
	{
		new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole > 0);
		new_record_repl[Anum_pg_authid_rolcreaterole - 1] = true;
	}

	if (createdb >= 0)
	{
		new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb > 0);
		new_record_repl[Anum_pg_authid_rolcreatedb - 1] = true;
	}

	if (canlogin >= 0)
	{
		new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin > 0);
		new_record_repl[Anum_pg_authid_rolcanlogin - 1] = true;
	}

	if (dconnlimit)
	{
		new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit);
		new_record_repl[Anum_pg_authid_rolconnlimit - 1] = true;
	}

	/* password */
	if (password)
	{
		if (!encrypt_password || isHashedPasswd(password))
			new_record[Anum_pg_authid_rolpassword - 1] =
				CStringGetTextDatum(password);
		else
		{
			
			if (!hash_password(password, stmt->role, strlen(stmt->role),
							   encrypted_password))
				elog(ERROR, "password encryption failed");

			new_record[Anum_pg_authid_rolpassword - 1] =
				CStringGetTextDatum(encrypted_password);
		}
		new_record_repl[Anum_pg_authid_rolpassword - 1] = true;
	}

	/* unset password */
	if (dpassword && dpassword->arg == NULL)
	{
		new_record_repl[Anum_pg_authid_rolpassword - 1] = true;
		new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
	}

	/* valid until */
	if (validUntil)
	{
		new_record[Anum_pg_authid_rolvaliduntil - 1] =
			DirectFunctionCall3(timestamptz_in,
								CStringGetDatum(validUntil),
								ObjectIdGetDatum(InvalidOid),
								Int32GetDatum(-1));
		new_record_repl[Anum_pg_authid_rolvaliduntil - 1] = true;
	}

	/* Set the CREATE EXTERNAL TABLE permissions for this role, if specified in ALTER */	
	if (exttabcreate || exttabnocreate)
	{
		bool	isnull;
		Datum 	dcreaterextgpfd;
		Datum 	dcreaterexthttp;
		Datum 	dcreatewextgpfd;
		Datum 	dcreaterexthdfs;
		Datum 	dcreatewexthdfs;

		/* 
		 * get bool values from catalog. we don't ever expect a NULL value, but just
		 * in case it is there (perhaps after an upgrade) we treat it as 'false'.
		 */
		dcreaterextgpfd = heap_getattr(tuple, Anum_pg_authid_rolcreaterextgpfd, pg_authid_dsc, &isnull);
		createrextgpfd = (isnull ? false : DatumGetBool(dcreaterextgpfd));
		dcreaterexthttp = heap_getattr(tuple, Anum_pg_authid_rolcreaterexthttp, pg_authid_dsc, &isnull);
		createrexthttp = (isnull ? false : DatumGetBool(dcreaterexthttp));
		dcreatewextgpfd = heap_getattr(tuple, Anum_pg_authid_rolcreatewextgpfd, pg_authid_dsc, &isnull);
		createwextgpfd = (isnull ? false : DatumGetBool(dcreatewextgpfd));
		dcreaterexthdfs = heap_getattr(tuple, Anum_pg_authid_rolcreaterexthdfs, pg_authid_dsc, &isnull);
		createrexthdfs = (isnull ? false : DatumGetBool(dcreaterexthdfs));
		dcreatewexthdfs = heap_getattr(tuple, Anum_pg_authid_rolcreatewexthdfs, pg_authid_dsc, &isnull);
		createwexthdfs = (isnull ? false : DatumGetBool(dcreatewexthdfs));
		
		SetCreateExtTableForRole(exttabcreate, exttabnocreate, &createrextgpfd,
								 &createrexthttp, &createwextgpfd,
								 &createrexthdfs, &createwexthdfs);

		new_record[Anum_pg_authid_rolcreaterextgpfd - 1] = BoolGetDatum(createrextgpfd);
		new_record_repl[Anum_pg_authid_rolcreaterextgpfd - 1] = true;
		new_record[Anum_pg_authid_rolcreaterexthttp - 1] = BoolGetDatum(createrexthttp);
		new_record_repl[Anum_pg_authid_rolcreaterexthttp - 1] = true;
		new_record[Anum_pg_authid_rolcreatewextgpfd - 1] = BoolGetDatum(createwextgpfd);
		new_record_repl[Anum_pg_authid_rolcreatewextgpfd - 1] = true;
		new_record[Anum_pg_authid_rolcreaterexthdfs - 1] = BoolGetDatum(createrexthdfs);
		new_record_repl[Anum_pg_authid_rolcreaterexthdfs - 1] = true;
		new_record[Anum_pg_authid_rolcreatewexthdfs - 1] = BoolGetDatum(createwexthdfs);
		new_record_repl[Anum_pg_authid_rolcreatewexthdfs - 1] = true;
	}

	/* resource queue */
	if (resqueue)
	{

		/* MPP-6926: NONE not supported -- use default queue  */
		if (
/*			( 0 == pg_strcasecmp(resqueue,"none"))) */
			( 0 == strcmp(resqueue,"none")))
		{
			/* MPP-7587: don't complain if you ALTER a superuser,
			 * who doesn't use the queue 
			 */
			if (Gp_role == GP_ROLE_DISPATCH)
			{
				if (!bWas_super)
						ereport(NOTICE,
								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("resource queue required -- "
										"using default resource queue \"%s\"",
										GP_DEFAULT_RESOURCE_QUEUE_NAME)));
			}
			
			resqueue = pstrdup(GP_DEFAULT_RESOURCE_QUEUE_NAME);
		}

		if ( strcmp(resqueue, "none") == 0)
		{
			new_record_nulls[Anum_pg_authid_rolresqueue - 1] = true;
		}
		else
		{
			queueid = GetResQueueIdForName(resqueue);
			if (queueid == InvalidOid) {
				releaseResourceContextWithErrorReport(resourceid);
				ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("resource queue \"%s\" does not exist",
							resqueue),
									   errOmitLocation(true)));
			}

			if(resourceQueueIsBranch(queueid)) {
				releaseResourceContextWithErrorReport(resourceid);
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
						 errmsg("cannot assign non-leaf resource queue \"%s\" to role",
								resqueue),
										   errOmitLocation(true)));
			}
			new_record[Anum_pg_authid_rolresqueue - 1] = 
			ObjectIdGetDatum(GetResQueueIdForName(resqueue));
		}
		new_record_repl[Anum_pg_authid_rolresqueue - 1] = true;
	}


	new_tuple = caql_modify_current(pcqCtx, new_record,
									new_record_nulls, new_record_repl);
	caql_update_current(pcqCtx, new_tuple);
	/* and Update indexes (implicit) */

	caql_endscan(pcqCtx);
	heap_freetuple(new_tuple);

	/*
	 * send RPC: notify RM to update
	 */
	if (resqueue && queueid != InvalidOid)
	{
		res = manipulateRoleForResourceQueue (resourceid,
											  roleid,
											  queueid,
											  MANIPULATE_ROLE_RESQUEUE_ALTER,
											  issuper,
											  stmt->role,
											  errorbuf,
											  sizeof(errorbuf));
	}

	/* We always unregister connection. */
	unregisterConnectionInRMWithErrorReport(resourceid);

	/* We always release resource context. */
	releaseResourceContextWithErrorReport(resourceid);

	if (resqueue && queueid != InvalidOid)
	{
		if ( res != FUNC_RETURN_OK )
		{

			ereport(ERROR,
					(errcode(IS_TO_RM_RPC_ERROR(res) ?
							 ERRCODE_INTERNAL_ERROR :
							 ERRCODE_INVALID_OBJECT_DEFINITION),
					 errmsg("cannot apply ALTER ROLE because of %s", errorbuf)));
		}
	}

	/*
	 * Advance command counter so we can see new record; else tests in
	 * AddRoleMems may fail.
	 */
	if (rolemembers)
		CommandCounterIncrement();

	if (stmt->action == +1)		/* add members to role */
	{
		if (rolemembers)
			alter_subtype = "ADD USER";
		AddRoleMems(stmt->role, roleid,
					rolemembers, roleNamesToIds(rolemembers),
					GetUserId(), false);
	}
	else if (stmt->action == -1)	/* drop members from role */
	{
		if (rolemembers)
			alter_subtype = "DROP USER";
		DelRoleMems(stmt->role, roleid,
					rolemembers, roleNamesToIds(rolemembers),
					false);
	}

	if (bWas_super)
	{
		if (addintervals)
			ereport(ERROR,
					(errmsg("cannot alter superuser with DENY rules")));
		else
			DelRoleDenials(stmt->role, roleid, NIL);	/* drop all preexisting constraints, if any. */
	}

	/*
	 * Disallow the use of DENY and DROP DENY fragments in the same query.
	 *
	 * We do this to prevent commands with unusual behavior.
	 * e.g. consider "ALTER ROLE foo DENY DAY 0 DROP DENY FOR DAY 1 DENY DAY 1 DENY DAY 2"
	 * In the manner that this is currently coded, because all DENY fragments are interpreted
	 * first, this actually becomes equivalent to you "ALTER ROLE foo DENY DAY 0 DENY DAY 2".
	 * 
	 * Instead, we could honor the order in which the fragments are presented, but still that
	 * allows users to contradict themselves, as in the example given.
	 */
	if (addintervals && dropintervals)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("conflicting or redundant options"),
				 errhint("DENY and DROP DENY cannot be used in the same ALTER ROLE statement.")));

	/*
	 * Populate pg_auth_time_constraint with the new intervals for which this 
	 * particular role should be denied access.
	 */
	if (addintervals)
		AddRoleDenials(stmt->role, roleid, addintervals);

	/*
	 * Remove pg_auth_time_constraint entries that overlap with the 
	 * intervals given by the user.
	 */
	if (dropintervals)
		DelRoleDenials(stmt->role, roleid, dropintervals);

	/* MPP-6929: metadata tracking */
	if (Gp_role == GP_ROLE_DISPATCH)
		MetaTrackUpdObject(AuthIdRelationId,
						   roleid,
						   GetUserId(),
						   "ALTER", alter_subtype
				);

	/*
	 * Close pg_authid, but keep lock till commit (this is important to
	 * prevent any risk of deadlock failure while updating flat file)
	 */
	heap_close(pg_authid_rel, NoLock);

	/*
	 * Set flag to update flat auth file at commit.
	 */
	auth_file_update_needed();

	if (Gp_role == GP_ROLE_DISPATCH)
	{
		/* GPSQL: no dispatch to segments */
		/*CdbDispatchUtilityStatement((Node *) stmt, "AlterRole");*/
	}
}


/*
 * ALTER ROLE ... SET
 */
void
AlterRoleSet(AlterRoleSetStmt *stmt)
{
	char	   *valuestr;
	HeapTuple	oldtuple,
				newtuple;
	Datum		repl_val[Natts_pg_authid];
	bool		repl_null[Natts_pg_authid];
	bool		repl_repl[Natts_pg_authid];
	char	   *alter_subtype = "SET"; /* metadata tracking */
	cqContext  *pcqCtx;

	valuestr = flatten_set_variable_args(stmt->variable, stmt->value);

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_authid "
				" WHERE rolname = :1 "
				" FOR UPDATE ",
				PointerGetDatum(stmt->role)));

	oldtuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(oldtuple))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("role \"%s\" does not exist", stmt->role),
						   errOmitLocation(true)));

	/*
	 * To mess with a superuser you gotta be superuser; else you need
	 * createrole, or just want to change your own settings
	 */
	if (((Form_pg_authid) GETSTRUCT(oldtuple))->rolsuper)
	{
		if (!superuser())
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must be superuser to alter superusers"),
							   errOmitLocation(true)));
	}
	else
	{
		if (!have_createrole_privilege() &&
			HeapTupleGetOid(oldtuple) != GetUserId())
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("permission denied"),
							   errOmitLocation(true)));
	}

	memset(repl_repl, false, sizeof(repl_repl));
	repl_repl[Anum_pg_authid_rolconfig - 1] = true;

	if (strcmp(stmt->variable, "all") == 0 && valuestr == NULL)
	{
		alter_subtype = "RESET ALL";

		ArrayType  *new = NULL;
		Datum		datum;
		bool		isnull;

		/*
		 * in RESET ALL, request GUC to reset the settings array; if none
		 * left, we can set rolconfig to null; otherwise use the returned
		 * array
		 */
		datum = caql_getattr(pcqCtx,
							 Anum_pg_authid_rolconfig, &isnull);
		if (!isnull)
			new = GUCArrayReset(DatumGetArrayTypeP(datum));
		if (new)
		{
			repl_val[Anum_pg_authid_rolconfig - 1] = PointerGetDatum(new);
			repl_null[Anum_pg_authid_rolconfig - 1] = false;
		}
		else
		{
			repl_null[Anum_pg_authid_rolconfig - 1] = true;
			repl_val[Anum_pg_authid_rolconfig - 1] = (Datum) 0;
		}
	}
	else
	{
		Datum		datum;
		bool		isnull;
		ArrayType  *array;

		repl_null[Anum_pg_authid_rolconfig - 1] = false;

		/* Extract old value of rolconfig */
		datum = caql_getattr(pcqCtx,
							 Anum_pg_authid_rolconfig, &isnull);
		array = isnull ? NULL : DatumGetArrayTypeP(datum);

		/* Update (valuestr is NULL in RESET cases) */
		if (valuestr)
			array = GUCArrayAdd(array, stmt->variable, valuestr);
		else
		{
			alter_subtype = "RESET";
			array = GUCArrayDelete(array, stmt->variable);
		}

		if (array)
			repl_val[Anum_pg_authid_rolconfig - 1] = PointerGetDatum(array);
		else
			repl_null[Anum_pg_authid_rolconfig - 1] = true;
	}

	newtuple = caql_modify_current(pcqCtx, 
								   repl_val, repl_null, repl_repl);

	caql_update_current(pcqCtx, newtuple);
	/* and Update indexes (implicit) */

	if (Gp_role == GP_ROLE_DISPATCH)
		/* MPP-6929: metadata tracking */
		MetaTrackUpdObject(AuthIdRelationId,
						   HeapTupleGetOid(oldtuple),
						   GetUserId(),
						   "ALTER", alter_subtype
				);

	caql_endscan(pcqCtx);
	/* needn't keep lock since we won't be updating the flat file */

}


/*
 * DROP ROLE
 */
void
DropRole(DropRoleStmt *stmt)
{
	Relation	pg_authid_rel,
				pg_auth_members_rel;
	ListCell   *item;

	int  		res			   = FUNC_RETURN_OK;
	static char errorbuf[1024] = "";

	if (!have_createrole_privilege())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("permission denied to drop role"),
						   errOmitLocation(true)));
	/*
	 * Scan the pg_authid relation to find the Oid of the role(s) to be
	 * deleted.
	 */
	pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
	pg_auth_members_rel = heap_open(AuthMemRelationId, RowExclusiveLock);

	foreach(item, stmt->roles)
	{
		const char *role = strVal(lfirst(item));
		HeapTuple	tuple;
		char	   *detail;
		Oid			roleid;
		cqContext	cqc;
		cqContext  *pcqCtx;

		pcqCtx = caql_beginscan(
				caql_addrel(cqclr(&cqc), pg_authid_rel),
				cql("SELECT * FROM pg_authid "
					" WHERE rolname = :1 "
					" FOR UPDATE ",
					PointerGetDatum((char *) role)));

		tuple = caql_getnext(pcqCtx);

		if (!HeapTupleIsValid(tuple))
		{
			if (!stmt->missing_ok)
			{
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
						 errmsg("role \"%s\" does not exist", role),
								   errOmitLocation(true)));
			}
			else
			{
				ereport(NOTICE,
						(errmsg("role \"%s\" does not exist, skipping",
								role),
										   errOmitLocation(true)));
			}

			continue;
		}

		roleid = HeapTupleGetOid(tuple);

		if (roleid == GetUserId())
			ereport(ERROR,
					(errcode(ERRCODE_OBJECT_IN_USE),
					 errmsg("current user cannot be dropped"),
							   errOmitLocation(true)));
		if (roleid == GetOuterUserId())
			ereport(ERROR,
					(errcode(ERRCODE_OBJECT_IN_USE),
					 errmsg("current user cannot be dropped"),
							   errOmitLocation(true)));
		if (roleid == GetSessionUserId())
			ereport(ERROR,
					(errcode(ERRCODE_OBJECT_IN_USE),
					 errmsg("session user cannot be dropped"),
							   errOmitLocation(true)));

		/*
		 * For safety's sake, we allow createrole holders to drop ordinary
		 * roles but not superuser roles.  This is mainly to avoid the
		 * scenario where you accidentally drop the last superuser.
		 */
		if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper &&
			!superuser())
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must be superuser to drop superusers")));

		/*
		 * Lock the role, so nobody can add dependencies to her while we drop
		 * her.  We keep the lock until the end of transaction.
		 */
		LockSharedObject(AuthIdRelationId, roleid, 0, AccessExclusiveLock);

		/* Check for pg_shdepend entries depending on this role */
		if ((detail = checkSharedDependencies(AuthIdRelationId, roleid)) != NULL)
			ereport(ERROR,
					(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
					 errmsg("role \"%s\" cannot be dropped because some objects depend on it",
							role),
					 errdetail("%s", detail),
					 errOmitLocation(true)));

		/*
		 * Remove the role from the pg_authid table
		 */
		caql_delete_current(pcqCtx);

		caql_endscan(pcqCtx);

		/* Create a new resource context to manipulate role in resource manager. */
		int resourceid = 0;
		res = createNewResourceContext(&resourceid);
		if ( res != FUNC_RETURN_OK ) {
			Assert( res == COMM2RM_CLIENT_FULL_RESOURCECONTEXT );
			ereport(ERROR,
					(errcode(ERRCODE_INTERNAL_ERROR),
							 errmsg("cannot apply DROP ROLE. "
									"Because too many resource contexts were created.")));
		}

		/* Here, using user oid is more convenient. */
		res = registerConnectionInRMByOID(resourceid,
										  GetUserId(),
										  errorbuf,
										  sizeof(errorbuf));
		if (res != FUNC_RETURN_OK)
		{
			releaseResourceContextWithErrorReport(resourceid);
			ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("%s", errorbuf)));
		}

		/* Notify resource manager to drop role. */
		res = manipulateRoleForResourceQueue (resourceid,
											  roleid,
											  0, 		// not used when drop role
											  MANIPULATE_ROLE_RESQUEUE_DROP,
											  0,		// not used when drop role
											  (char*)role,
											  errorbuf,
											  sizeof(errorbuf));
		/* We always unregister connection. */
		unregisterConnectionInRMWithErrorReport(resourceid);

		/* We always release resource context. */
		releaseResourceContextWithErrorReport(resourceid);

		if ( res != FUNC_RETURN_OK )
		{
			ereport(ERROR,
					(errcode(IS_TO_RM_RPC_ERROR(res) ?
							 ERRCODE_INTERNAL_ERROR :
							 ERRCODE_INVALID_OBJECT_DEFINITION),
					 errmsg("cannot apply DROP ROLE because of %s", errorbuf)));
		}

		/*
		 * Remove role from the pg_auth_members table.	We have to remove all
		 * tuples that show it as either a role or a member.
		 *
		 * XXX what about grantor entries?	Maybe we should do one heap scan.
		 */
		{
			int numDel;
			cqContext cqc2;

			numDel = 
					caql_getcount(
							caql_addrel(cqclr(&cqc2), pg_auth_members_rel),
							cql("DELETE FROM pg_auth_members "
								" WHERE roleid = :1 ",
								ObjectIdGetDatum(roleid)));

			numDel = 
					caql_getcount(
							caql_addrel(cqclr(&cqc2), pg_auth_members_rel),
							cql("DELETE FROM pg_auth_members "
								" WHERE member = :1 ",
								ObjectIdGetDatum(roleid)));

		}

		/*
		 * Remove any time constraints on this role.
		 */
		DelRoleDenials(role, roleid, NIL);

		/*
		 * Remove any comments on this role.
		 */
		DeleteSharedComments(roleid, AuthIdRelationId);

		/* MPP-6929: metadata tracking */
		if (Gp_role == GP_ROLE_DISPATCH)
			MetaTrackDropObject(AuthIdRelationId,
								roleid);
		/*
		 * Advance command counter so that later iterations of this loop will
		 * see the changes already made.  This is essential if, for example,
		 * we are trying to drop both a role and one of its direct members ---
		 * we'll get an error if we try to delete the linking pg_auth_members
		 * tuple twice.  (We do not need a CCI between the two delete loops
		 * above, because it's not allowed for a role to directly contain
		 * itself.)
		 */
		CommandCounterIncrement();
	}

	/*
	 * Now we can clean up; but keep locks until commit (to avoid possible
	 * deadlock failure while updating flat file)
	 */
	heap_close(pg_auth_members_rel, NoLock);
	heap_close(pg_authid_rel, NoLock);

	/*
	 * Set flag to update flat auth file at commit.
	 */
	auth_file_update_needed();

	if (Gp_role == GP_ROLE_DISPATCH)
	{
		/* GPSQL: no dispatch to segments */
		/* CdbDispatchUtilityStatement((Node *) stmt, "DropRole"); */

	}
}

/*
 * Rename role
 */
void
RenameRole(const char *oldname, const char *newname)
{
	HeapTuple	oldtuple,
				newtuple;
	TupleDesc	dsc;
	Relation	rel;
	Datum		datum;
	bool		isnull;
	Datum		repl_val[Natts_pg_authid];
	bool		repl_null[Natts_pg_authid];
	bool		repl_repl[Natts_pg_authid];
	int			i;
	Oid			roleid;
	cqContext	cqc;
	cqContext	cqc2;
	cqContext  *pcqCtx;

	rel = heap_open(AuthIdRelationId, RowExclusiveLock);
	dsc = RelationGetDescr(rel);

	pcqCtx = caql_beginscan(
			caql_addrel(cqclr(&cqc), rel),
			cql("SELECT * FROM pg_authid "
				" WHERE rolname = :1 "
				" FOR UPDATE ",
				CStringGetDatum((char *) oldname)));

	oldtuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(oldtuple))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("role \"%s\" does not exist", oldname),
				 errOmitLocation(true)));

	/*
	 * XXX Client applications probably store the session user somewhere, so
	 * renaming it could cause confusion.  On the other hand, there may not be
	 * an actual problem besides a little confusion, so think about this and
	 * decide.	Same for SET ROLE ... we don't restrict renaming the current
	 * effective userid, though.
	 */

	roleid = HeapTupleGetOid(oldtuple);

	if (roleid == GetSessionUserId())
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("session user cannot be renamed")));
	if (roleid == GetOuterUserId())
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("current user cannot be renamed")));

	/* make sure the new name doesn't exist */
	if (caql_getcount(
				caql_addrel(cqclr(&cqc2), rel),
				cql("SELECT COUNT(*) FROM pg_authid "
					" WHERE rolname = :1 ",
					CStringGetDatum((char *) newname))))
		ereport(ERROR,
				(errcode(ERRCODE_DUPLICATE_OBJECT),
				 errmsg("role \"%s\" already exists", newname)));

	if (strcmp(newname, "public") == 0 ||
		strcmp(newname, "none") == 0)
		ereport(ERROR,
				(errcode(ERRCODE_RESERVED_NAME),
				 errmsg("role name \"%s\" is reserved",
						newname)));

	/*
	 * createrole is enough privilege unless you want to mess with a superuser
	 */
	if (((Form_pg_authid) GETSTRUCT(oldtuple))->rolsuper)
	{
		if (!superuser())
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must be superuser to rename superusers")));
	}
	else
	{
		if (!have_createrole_privilege())
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("permission denied to rename role")));
	}

	/* OK, construct the modified tuple */
	for (i = 0; i < Natts_pg_authid; i++)
		repl_repl[i] = false;

	repl_repl[Anum_pg_authid_rolname - 1] = true;
	repl_val[Anum_pg_authid_rolname - 1] = DirectFunctionCall1(namein,
												   CStringGetDatum((char *) newname));
	repl_null[Anum_pg_authid_rolname - 1] = false;

	datum = heap_getattr(oldtuple, Anum_pg_authid_rolpassword, dsc, &isnull);

	if (!isnull && isMD5(TextDatumGetCString(datum)))
	{
		/* MD5 uses the username as salt, so just clear it on a rename */
		repl_repl[Anum_pg_authid_rolpassword - 1] = true;
		repl_null[Anum_pg_authid_rolpassword - 1] = true;

		if (Gp_role != GP_ROLE_EXECUTE)
		ereport(NOTICE,
				(errmsg("MD5 password cleared because of role rename")));
	}

	newtuple = caql_modify_current(pcqCtx, repl_val, repl_null, repl_repl);
	caql_update_current(pcqCtx, newtuple); 
	/* and Update indexes (implicit) */

	caql_endscan(pcqCtx);

	/*
	 * Close pg_authid, but keep lock till commit (this is important to
	 * prevent any risk of deadlock failure while updating flat file)
	 */
	heap_close(rel, NoLock);

	/*
	 * Set flag to update flat auth file at commit.
	 */
	auth_file_update_needed();

	/* MPP-6929: metadata tracking */
	if (Gp_role == GP_ROLE_DISPATCH)
		MetaTrackUpdObject(AuthIdRelationId,
						   roleid,
						   GetUserId(),
						   "ALTER", "RENAME"
				);

}

/*
 * GrantRoleStmt
 *
 * Grant/Revoke roles to/from roles
 */
void
GrantRole(GrantRoleStmt *stmt)
{
	Relation	 pg_authid_rel;
	Oid			 grantor;
	List		*grantee_ids;
	ListCell	*item;

	if (stmt->grantor)
		grantor = get_roleid_checked(stmt->grantor);
	else
		grantor = GetUserId();

	grantee_ids = roleNamesToIds(stmt->grantee_roles);

	/* AccessShareLock is enough since we aren't modifying pg_authid */
	pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock);

	/*
	 * Step through all of the granted roles and add/remove entries for the
	 * grantees, or, if admin_opt is set, then just add/remove the admin
	 * option.
	 *
	 * Note: Permissions checking is done by AddRoleMems/DelRoleMems
	 */
	foreach(item, stmt->granted_roles)
	{
		char	   *rolename = strVal(lfirst(item));
		Oid			roleid = get_roleid_checked(rolename);

		if (stmt->is_grant)
		{
			AddRoleMems(rolename, roleid,
						stmt->grantee_roles, grantee_ids,
						grantor, stmt->admin_opt);
		}
		else
		{
			DelRoleMems(rolename, roleid,
						stmt->grantee_roles, grantee_ids,
						stmt->admin_opt);
		}

		/* MPP-6929: metadata tracking */
		if (Gp_role == GP_ROLE_DISPATCH)
				MetaTrackUpdObject(AuthIdRelationId,
								   roleid,
								   GetUserId(),
								   "PRIVILEGE", 
								   (stmt->is_grant) ? "GRANT" : "REVOKE"
						);

	}

	/*
	 * Close pg_authid, but keep lock till commit (this is important to
	 * prevent any risk of deadlock failure while updating flat file)
	 */
	heap_close(pg_authid_rel, NoLock);

	/*
	 * Set flag to update flat auth file at commit.
	 */
	auth_file_update_needed();
}

/*
 * DropOwnedObjects
 *
 * Drop the objects owned by a given list of roles.
 */
void
DropOwnedObjects(DropOwnedStmt *stmt)
{
	List	   *role_ids = roleNamesToIds(stmt->roles);
	ListCell   *cell;

	/* Check privileges */
	foreach(cell, role_ids)
	{
		Oid			roleid = lfirst_oid(cell);

		if (!has_privs_of_role(GetUserId(), roleid))
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("permission denied to drop objects"),
					 errOmitLocation(true)));
	}
	
	/*
	if (Gp_role == GP_ROLE_DISPATCH)
    {
        CdbDispatchUtilityStatement((Node *) stmt, "DropOwnedObjects");
    }
	*/
    
	/* Ok, do it */
	shdepDropOwned(role_ids, stmt->behavior);
}

/*
 * ReassignOwnedObjects
 *
 * Give the objects owned by a given list of roles away to another user.
 */
void
ReassignOwnedObjects(ReassignOwnedStmt *stmt)
{
	List	   *role_ids = roleNamesToIds(stmt->roles);
	ListCell   *cell;
	Oid			newrole;

	/* Check privileges */
	foreach(cell, role_ids)
	{
		Oid			roleid = lfirst_oid(cell);

		if (!has_privs_of_role(GetUserId(), roleid))
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("permission denied to reassign objects"),
					 errOmitLocation(true)));
	}

	/* Must have privileges on the receiving side too */
	newrole = get_roleid_checked(stmt->newrole);

	if (!has_privs_of_role(GetUserId(), newrole))
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("permission denied to reassign objects"),
				 errOmitLocation(true)));
				 
	/*
	if (Gp_role == GP_ROLE_DISPATCH)
    {
        CdbDispatchUtilityStatement((Node *) stmt, "ReassignOwnedObjects");
    }
	*/

	/* Ok, do it */
	shdepReassignOwned(role_ids, newrole);
}

/*
 * roleNamesToIds
 *
 * Given a list of role names (as String nodes), generate a list of role OIDs
 * in the same order.
 */
static List *
roleNamesToIds(List *memberNames)
{
	List	   *result = NIL;
	ListCell   *l;

	foreach(l, memberNames)
	{
		char	   *rolename = strVal(lfirst(l));
		Oid			roleid = get_roleid_checked(rolename);

		result = lappend_oid(result, roleid);
	}
	return result;
}

/*
 * AddRoleMems -- Add given members to the specified role
 *
 * rolename: name of role to add to (used only for error messages)
 * roleid: OID of role to add to
 * memberNames: list of names of roles to add (used only for error messages)
 * memberIds: OIDs of roles to add
 * grantorId: who is granting the membership
 * admin_opt: granting admin option?
 *
 * Note: caller is responsible for calling auth_file_update_needed().
 */
static void
AddRoleMems(const char *rolename, Oid roleid,
			List *memberNames, List *memberIds,
			Oid grantorId, bool admin_opt)
{
	Relation	pg_authmem_rel;
	TupleDesc	pg_authmem_dsc;
	ListCell   *nameitem;
	ListCell   *iditem;

	Assert(list_length(memberNames) == list_length(memberIds));

	/* Skip permission check if nothing to do */
	if (!memberIds)
		return;

	/*
	 * Check permissions: must have createrole or admin option on the role to
	 * be changed.	To mess with a superuser role, you gotta be superuser.
	 */
	if (superuser_arg(roleid))
	{
		if (!superuser())
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must be superuser to alter superusers")));
	}
	else
	{
		if (!have_createrole_privilege() &&
			!is_admin_of_role(grantorId, roleid))
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must have admin option on role \"%s\"",
							rolename)));
	}

	/* XXX not sure about this check */
	if (grantorId != GetUserId() && !superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("must be superuser to set grantor")));

	pg_authmem_rel = heap_open(AuthMemRelationId, RowExclusiveLock);
	pg_authmem_dsc = RelationGetDescr(pg_authmem_rel);

	forboth(nameitem, memberNames, iditem, memberIds)
	{
		const char *membername = strVal(lfirst(nameitem));
		Oid			memberid = lfirst_oid(iditem);
		HeapTuple	authmem_tuple;
		HeapTuple	tuple;
		Datum		new_record[Natts_pg_auth_members];
		bool		new_record_nulls[Natts_pg_auth_members];
		bool		new_record_repl[Natts_pg_auth_members];
		cqContext	cqc;
		cqContext  *pcqCtx;

		/*
		 * Refuse creation of membership loops, including the trivial case
		 * where a role is made a member of itself.  We do this by checking to
		 * see if the target role is already a member of the proposed member
		 * role.  We have to ignore possible superuserness, however, else we
		 * could never grant membership in a superuser-privileged role.
		 */
		if (is_member_of_role_nosuper(roleid, memberid))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_GRANT_OPERATION),
					 (errmsg("role \"%s\" is a member of role \"%s\"",
							 rolename, membername))));

		/*
		 * Check if entry for this role/member already exists; if so, give
		 * warning unless we are adding admin option.
		 */
		pcqCtx = caql_beginscan(
				caql_addrel(cqclr(&cqc), pg_authmem_rel),
				cql("SELECT * FROM pg_auth_members "
					" WHERE roleid = :1 "
					" AND member = :2 "
					" FOR UPDATE ",
					ObjectIdGetDatum(roleid),
					ObjectIdGetDatum(memberid)));

		authmem_tuple = caql_getnext(pcqCtx);

		if (HeapTupleIsValid(authmem_tuple) &&
			(!admin_opt ||
			 ((Form_pg_auth_members) GETSTRUCT(authmem_tuple))->admin_option))
		{
			if (Gp_role != GP_ROLE_EXECUTE)
			ereport(NOTICE,
					(errmsg("role \"%s\" is already a member of role \"%s\"",
							membername, rolename)));
			caql_endscan(pcqCtx);
			continue;
		}

		/* Build a tuple to insert or update */
		MemSet(new_record, 0, sizeof(new_record));
		MemSet(new_record_nulls, false, sizeof(new_record_nulls));
		MemSet(new_record_repl, false, sizeof(new_record_repl));

		new_record[Anum_pg_auth_members_roleid - 1] = ObjectIdGetDatum(roleid);
		new_record[Anum_pg_auth_members_member - 1] = ObjectIdGetDatum(memberid);
		new_record[Anum_pg_auth_members_grantor - 1] = ObjectIdGetDatum(grantorId);
		new_record[Anum_pg_auth_members_admin_option - 1] = BoolGetDatum(admin_opt);

		if (HeapTupleIsValid(authmem_tuple))
		{
			new_record_repl[Anum_pg_auth_members_grantor - 1] = true;
			new_record_repl[Anum_pg_auth_members_admin_option - 1] = true;
			tuple = caql_modify_current(pcqCtx,
										new_record,
										new_record_nulls, new_record_repl);
			caql_update_current(pcqCtx, tuple);
			/* and Update indexes (implicit) */

			caql_endscan(pcqCtx);
		}
		else
		{
			pcqCtx = caql_beginscan(
					caql_addrel(cqclr(&cqc), pg_authmem_rel),
					cql("INSERT INTO pg_auth_members ",
						NULL));

			tuple = caql_form_tuple(pcqCtx, new_record, new_record_nulls);

			/* Insert tuple into the relation */
			caql_insert(pcqCtx, tuple);  /* implicit update of index as well */

			caql_endscan(pcqCtx);
		}

		/* CCI after each change, in case there are duplicates in list */
		CommandCounterIncrement();
	}

	/*
	 * Close pg_authmem, but keep lock till commit (this is important to
	 * prevent any risk of deadlock failure while updating flat file)
	 */
	heap_close(pg_authmem_rel, NoLock);

}

/*
 * CheckKeywordIsValid
 * 
 * check that string in 'keyword' is included in set of strings in 'arr'
 */
static void CheckKeywordIsValid(char *keyword, const char **arr, const int arrsize)
{
	int 	i = 0;
	bool	ok = false;
	
	for(i = 0 ; i < arrsize ; i++)
	{
		if(strcasecmp(keyword, arr[i]) == 0)
			ok = true;
	}
	
	if(!ok)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("invalid [NO]CREATEEXTTABLE option \"%s\"", keyword)));				

}

/*
 * CheckValueBelongsToKey
 * 
 * check that value (e.g 'gpfdist') belogs to the key it was defined for (e.g 'protocol').
 * error out otherwise (for example, [protocol='writable'] includes valid keywords, but makes
 * no sense.
 */
static void CheckValueBelongsToKey(char *key, char *val, const char **keys, const char **vals)
{
	if(strcasecmp(key, keys[0]) == 0)
	{
		if(strcasecmp(val, vals[0]) != 0 && 
		   strcasecmp(val, vals[1]) != 0)
			
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("invalid %s value \"%s\"", key, val)));	
	}
	else /* keys[1] */
	{
		if (strcasecmp(val, "gphdfs") == 0 && Gp_role == GP_ROLE_DISPATCH)
			ereport(WARNING,
					(errmsg("GRANT/REVOKE on gphdfs is deprecated"),
					 errhint("Issue the GRANT or REVOKE on the protocol itself"),
					 errOmitLocation(true)));

		if(strcasecmp(val, "gpfdist") != 0 && 
		   strcasecmp(val, "gpfdists") != 0 &&
		   strcasecmp(val, "http") != 0 &&
		   strcasecmp(val, "gphdfs") != 0&&
		   strcasecmp(val, "hdfs") != 0)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("invalid %s value \"%s\"", key, val)));
	}
	
}

/*
 * TransformExttabAuthClause
 * 
 * Given a set of key value pairs, take them apart, fill in any default
 * values, and validate that pairs are legal and make sense.
 * 
 * defaults are: 
 *   - 'readable' when no type defined, 
 *   - 'gpfdist' when no protocol defined,
 *   - 'readable' + ' gpfdist' if both type and protocol aren't defined.
 * 
 */
static void TransformExttabAuthClause(DefElem *defel, extAuthPair *extauth)
{
	ListCell   	*lc;
	List	   	*l = (List *) defel->arg;
	DefElem 	*d1 = NULL, 
				*d2 = NULL;
	genericPair *genpair = (genericPair *) palloc0 (4 * sizeof(char *));
	
	const int	numkeys = 2;
	const int	numvals = 6;
	const char *keys[] = { "type", "protocol"};	 /* order matters for validation. don't change! */
	const char *vals[] = { /* types     */ "readable", "writable", 
						   /* protocols */ "gpfdist", "gpfdists" , "http", "gphdfs", "hdfs"};

	if(list_length(l) > 2)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("invalid [NO]CREATEEXTTABLE specification. too many values")));				

		
	if(list_length(l) == 2)
	{
		/* both a protocol and type specification */
		
		lc = list_head(l); 
		d1 = (DefElem *) lfirst(lc);
		genpair->key1 = pstrdup(d1->defname);
		genpair->val1 = pstrdup(strVal(d1->arg));
		
		lc = lnext(lc);
		d2 = (DefElem *) lfirst(lc);
		genpair->key2 = pstrdup(d2->defname);
		genpair->val2 = pstrdup(strVal(d2->arg));
	}
	else if(list_length(l) == 1)
	{
		/* either a protocol or type specification */
		
		lc = list_head(l); 
		d1 = (DefElem *) lfirst(lc);
		genpair->key1 = pstrdup(d1->defname);
		genpair->val1 = pstrdup(strVal(d1->arg));
		
		if(strcasecmp(genpair->key1, "type") == 0)
		{
			/* default value for missing protocol */
			genpair->key2 = pstrdup("protocol");
			genpair->val2 = pstrdup("gpfdist");
		}
		else
		{
			/* default value for missing type */
			genpair->key2 = pstrdup("type");
			genpair->val2 = pstrdup("readable");
		}
	}
	else
	{
		/* none specified. use global default */
		
		genpair->key1 = pstrdup("protocol");
		genpair->val1 = pstrdup("gpfdist");
		genpair->key2 = pstrdup("type");
		genpair->val2 = pstrdup("readable");
	}
	
	/* check all keys and values are legal */
	CheckKeywordIsValid(genpair->key1, keys, numkeys);
	CheckKeywordIsValid(genpair->key2, keys, numkeys);
	CheckKeywordIsValid(genpair->val1, vals, numvals);
	CheckKeywordIsValid(genpair->val2, vals, numvals);
		
	/* check all values are of the proper key */
	CheckValueBelongsToKey(genpair->key1, genpair->val1, keys, vals);
	CheckValueBelongsToKey(genpair->key2, genpair->val2, keys, vals);

	if(strcasecmp(genpair->key1, genpair->key2) == 0)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("redundant option for \"%s\"", genpair->key1)));
	
	/* now set values in extauth, which is the result returned */
	if(strcasecmp(genpair->key1, "protocol") == 0)
	{
		extauth->protocol = pstrdup(genpair->val1);
		extauth->type = pstrdup(genpair->val2);
	}
	else
	{
		extauth->protocol = pstrdup(genpair->val2);
		extauth->type = pstrdup(genpair->val1);
	}
	
	pfree(genpair->key1);
	pfree(genpair->key2);
	pfree(genpair->val1);
	pfree(genpair->val2);
	pfree(genpair);
}

/*
 * SetCreateExtTableForRole
 * 
 * Given the allow list (permissions to add) and disallow (permissions
 * to take away) consolidate this information into the 3 catalog
 * boolean columns that will need to get updated. While at it we check
 * that all the options are valid and don't conflict with each other.
 * 
 */
static void SetCreateExtTableForRole(List* allow, 
									 List* disallow,
									 bool* createrextgpfd,
									 bool* createrexthttp, 
									 bool* createwextgpfd,
									 bool* createrexthdfs,
									 bool* createwexthdfs)
{
	ListCell*	lc;
	bool		createrextgpfd_specified = false;
	bool		createwextgpfd_specified = false;
	bool		createrexthttp_specified = false;
	bool		createrexthdfs_specified = false;
	bool		createwexthdfs_specified = false;
	
	if(list_length(allow) > 0)
	{
		/* examine key value pairs */
		foreach(lc, allow)
		{
			extAuthPair* extauth = (extAuthPair*) lfirst(lc);
			
			/* we use the same privilege for gpfdist and gpfdists */
			if ((strcasecmp(extauth->protocol, "gpfdist") == 0) ||
			    (strcasecmp(extauth->protocol, "gpfdists") == 0))
			{
				if(strcasecmp(extauth->type, "readable") == 0)
				{
					*createrextgpfd = true;
					createrextgpfd_specified = true; 
				}
				else
				{
					*createwextgpfd = true;
					createwextgpfd_specified = true;
				}
			}
			else if(strcasecmp(extauth->protocol, "gphdfs") == 0)
			{
				if(strcasecmp(extauth->type, "readable") == 0)
				{
					*createrexthdfs = true;
					createrexthdfs_specified = true;
				}
				else
				{
					*createwexthdfs = true;
					createwexthdfs_specified = true;
				}
			}
			else if(strcasecmp(extauth->protocol, "hdfs") == 0)
			{
				if(strcasecmp(extauth->type, "readable") == 0)
				{
					*createrexthdfs = true;
					createrexthdfs_specified = true;
				}
				else
				{
					*createwexthdfs = true;
					createwexthdfs_specified = true;
				}
			}
			else /* http */
			{
				if(strcasecmp(extauth->type, "readable") == 0)
				{
					*createrexthttp = true;
					createrexthttp_specified = true;
				}
				else
				{
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("invalid CREATEEXTTABLE specification. writable http external tables do not exist")));
				}
			}			
		}
	}	
	
	/*
	 * go over the disallow list.
	 * if we're in CREATE ROLE, check that we don't negate something from the 
	 * allow list. error out with conflicting options if we do. 
	 * if we're in ALTER ROLE, just set the flags accordingly.
	 */
	if(list_length(disallow) > 0)
	{
		bool conflict = false;
		
		/* examine key value pairs */
		foreach(lc, disallow)
		{
			extAuthPair* extauth = (extAuthPair*) lfirst(lc);
			
			/* we use the same privilege for gpfdist and gpfdists */
			if ((strcasecmp(extauth->protocol, "gpfdist") == 0) ||
				(strcasecmp(extauth->protocol, "gpfdists") == 0))
			{
				if(strcasecmp(extauth->type, "readable") == 0)
				{
					if(createrextgpfd_specified)
						conflict = true;
						
					*createrextgpfd = false;
				}
				else
				{
					if(createwextgpfd_specified)
						conflict = true;

					*createwextgpfd = false;
				}
			}
			else if(strcasecmp(extauth->protocol, "gphdfs") == 0)
			{
				if(strcasecmp(extauth->type, "readable") == 0)
				{
					if(createrexthdfs_specified)
						conflict = true;

					*createrexthdfs = false;
				}
				else
				{
					if(createwexthdfs_specified)
						conflict = true;

					*createwexthdfs = false;
				}
			}
			else if(strcasecmp(extauth->protocol, "hdfs") == 0)
			{
				if(strcasecmp(extauth->type, "readable") == 0)
				{
					if(createrexthdfs_specified)
						conflict = true;

					*createrexthdfs = false;
				}
				else
				{
					if(createwexthdfs_specified)
						conflict = true;

					*createwexthdfs = false;
				}
			}
			else /* http */
			{
				if(strcasecmp(extauth->type, "readable") == 0)
				{
					if(createrexthttp_specified)
						conflict = true;

					*createrexthttp = false;
				}
				else
				{
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("invalid NOCREATEEXTTABLE specification. writable http external tables do not exist")));
				}
			}			
		}
		
		if(conflict)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("conflicting specifications in CREATEEXTTABLE and NOCREATEEXTTABLE")));
			
	}	

}

/*
 * DelRoleMems -- Remove given members from the specified role
 *
 * rolename: name of role to del from (used only for error messages)
 * roleid: OID of role to del from
 * memberNames: list of names of roles to del (used only for error messages)
 * memberIds: OIDs of roles to del
 * admin_opt: remove admin option only?
 *
 * Note: caller is responsible for calling auth_file_update_needed().
 */
static void
DelRoleMems(const char *rolename, Oid roleid,
			List *memberNames, List *memberIds,
			bool admin_opt)
{
	Relation	pg_authmem_rel;
	ListCell   *nameitem;
	ListCell   *iditem;

	Assert(list_length(memberNames) == list_length(memberIds));

	/* Skip permission check if nothing to do */
	if (!memberIds)
		return;

	/*
	 * Check permissions: must have createrole or admin option on the role to
	 * be changed.	To mess with a superuser role, you gotta be superuser.
	 */
	if (superuser_arg(roleid))
	{
		if (!superuser())
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must be superuser to alter superusers")));
	}
	else
	{
		if (!have_createrole_privilege() &&
			!is_admin_of_role(GetUserId(), roleid))
			ereport(ERROR,
					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
					 errmsg("must have admin option on role \"%s\"",
							rolename)));
	}

	pg_authmem_rel = heap_open(AuthMemRelationId, RowExclusiveLock);

	forboth(nameitem, memberNames, iditem, memberIds)
	{
		const char *membername = strVal(lfirst(nameitem));
		Oid			memberid = lfirst_oid(iditem);
		HeapTuple	authmem_tuple;
		cqContext	cqc;
		cqContext  *pcqCtx;

		/*
		 * Find entry for this role/member
		 */
		pcqCtx = caql_beginscan(
				caql_addrel(cqclr(&cqc), pg_authmem_rel),
				cql("SELECT * FROM pg_auth_members "
					" WHERE roleid = :1 "
					" AND member = :2 "
					" FOR UPDATE ",
					ObjectIdGetDatum(roleid),
					ObjectIdGetDatum(memberid)));

		authmem_tuple = caql_getnext(pcqCtx);

		if (!HeapTupleIsValid(authmem_tuple))
		{
			ereport(WARNING,
					(errmsg("role \"%s\" is not a member of role \"%s\"",
							membername, rolename)));
			continue;
		}

		if (!admin_opt)
		{
			/* Remove the entry altogether */
			caql_delete_current(pcqCtx);
		}
		else
		{
			/* Just turn off the admin option */
			HeapTuple	tuple;
			Datum		new_record[Natts_pg_auth_members];
			bool		new_record_nulls[Natts_pg_auth_members];
			bool		new_record_repl[Natts_pg_auth_members];

			/* Build a tuple to update with */
			MemSet(new_record, 0, sizeof(new_record));
			MemSet(new_record_nulls, false, sizeof(new_record_nulls));
			MemSet(new_record_repl, false, sizeof(new_record_repl));

			new_record[Anum_pg_auth_members_admin_option - 1] = BoolGetDatum(false);
			new_record_repl[Anum_pg_auth_members_admin_option - 1] = true;

			tuple = caql_modify_current(pcqCtx,
										new_record,
										new_record_nulls, new_record_repl);
			caql_update_current(pcqCtx, tuple);
			/* and Update indexes (implicit) */
		}

		caql_endscan(pcqCtx);

		/* CCI after each change, in case there are duplicates in list */
		CommandCounterIncrement();
	}

	/*
	 * Close pg_authmem, but keep lock till commit (this is important to
	 * prevent any risk of deadlock failure while updating flat file)
	 */
	heap_close(pg_authmem_rel, NoLock);
}

/*
 * ExtractAuthIntervalClause
 * 
 * Build an authInterval struct (defined above) from given input
 */
static void 
ExtractAuthIntervalClause(DefElem *defel, authInterval *interval)
{
	DenyLoginPoint *start = NULL, *end = NULL;
	char	*temp;
	if (IsA(defel->arg, DenyLoginInterval))
	{
		DenyLoginInterval *span = (DenyLoginInterval *)defel->arg;
		start = span->start;
		end = span->end;
	} 
	else 
	{
		Assert(IsA(defel->arg, DenyLoginPoint));
		start = (DenyLoginPoint *)defel->arg;
		end = start;
	}
	interval->start.day = ExtractAuthInterpretDay(start->day);
	temp = start->time != NULL ? strVal(start->time) : "00:00:00";
	interval->start.time = DatumGetTimeADT(DirectFunctionCall1(time_in, CStringGetDatum(temp)));
	interval->end.day = ExtractAuthInterpretDay(end->day);
	temp = end->time != NULL ? strVal(end->time) : "24:00:00";
	interval->end.time = DatumGetTimeADT(DirectFunctionCall1(time_in, CStringGetDatum(temp)));
	if (point_cmp(&interval->start, &interval->end) > 0)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("time interval must not wrap around"))); 
}

/*
 * TransferAuthInterpretDay -- Interpret day of week from parse node
 *
 * day: node which dictates a day of week;
 *		may be either an integer in [0, 6] 
 *		or a string giving name of day in English
 */
static int16 
ExtractAuthInterpretDay(Value * day) 
{
	int16   ret;
	if (day->type == T_Integer) 
	{
		ret = intVal(day);
		if (ret < 0 || ret > 6)
			ereport(ERROR,
					 (errcode(ERRCODE_SYNTAX_ERROR),
					  errmsg("numeric day of week must be between 0 and 6")));
	} 
	else 
	{
		int16		 elems = 7;
		char		*target = strVal(day);
		for (ret = 0; ret < elems; ret++) 
			if (strcasecmp(target, daysofweek[ret]) == 0)
				break;
		if (ret == elems)
			ereport(ERROR,
					 (errcode(ERRCODE_SYNTAX_ERROR),
					  errmsg("invalid weekday name \"%s\"", target),
					  errhint("Day of week must be one of 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'.")));
	}
	return ret;
}

/*
 * AddRoleDenials -- Populate pg_auth_time_constraint
 *
 * rolename: name of role to add to (used only for error messages)
 * roleid: OID of role to add to
 * addintervals: list of authInterval structs dictating when
 *				  this particular role should be denied access
 *
 * Note: caller is reponsible for checking permissions to edit the given role.
 */
static void
AddRoleDenials(const char *rolename, Oid roleid, List *addintervals) {
	Relation	pg_auth_time_rel;
	ListCell   *intervalitem;
	cqContext	cqc;
	cqContext  *pcqCtx;

	pg_auth_time_rel = heap_open(AuthTimeConstraintRelationId, RowExclusiveLock);

	pcqCtx = caql_beginscan(
				caql_addrel(cqclr(&cqc), pg_auth_time_rel),
				cql("INSERT INTO pg_auth_time_constraint ",
					NULL));

	foreach(intervalitem, addintervals)
	{
		authInterval 	*interval = (authInterval *)lfirst(intervalitem);
		HeapTuple   tuple;
		Datum		new_record[Natts_pg_auth_time_constraint];
		bool		new_record_nulls[Natts_pg_auth_time_constraint];

		/* Build a tuple to insert or update */
		MemSet(new_record, 0, sizeof(new_record));
		MemSet(new_record_nulls, false, sizeof(new_record_nulls));

		new_record[Anum_pg_auth_time_constraint_authid - 1] = ObjectIdGetDatum(roleid);
		new_record[Anum_pg_auth_time_constraint_start_day - 1] = Int16GetDatum(interval->start.day);
		new_record[Anum_pg_auth_time_constraint_start_time - 1] = TimeADTGetDatum(interval->start.time);
		new_record[Anum_pg_auth_time_constraint_end_day - 1] = Int16GetDatum(interval->end.day);
		new_record[Anum_pg_auth_time_constraint_end_time - 1] = TimeADTGetDatum(interval->end.time);

		tuple = caql_form_tuple(pcqCtx, new_record, new_record_nulls);
		
		/* Insert tuple into the relation */
		caql_insert(pcqCtx, tuple); /* implicit update of index as well */

	}

	CommandCounterIncrement();

	/*
	 * Close pg_auth_time_constraint, but keep lock till commit (this is important to
	 * prevent any risk of deadlock failure while updating flat file)
	 */
	caql_endscan(pcqCtx);
	heap_close(pg_auth_time_rel, NoLock);

	/*
	 * Set flag to update flat auth time constraint file at commit.
	 */
	auth_time_file_update_needed();
}

/*
 * DelRoleDenials -- Trim pg_auth_time_constraint
 *
 * rolename: name of role to edit (used only for error messages)
 * roleid: OID of role to edit
 * dropintervals: list of authInterval structs dictating which
 *                existing rules should be dropped. Here, NIL will mean
 *                remove all constraints for the given role.
 *
 * Note: caller is reponsible for checking permissions to edit the given role.
 */
static void
DelRoleDenials(const char *rolename, Oid roleid, List *dropintervals) 
{
	Relation    pg_auth_time_rel;
	ListCell	*intervalitem;
	bool		dropped_matching_interval = false; 

	HeapTuple 	tmp_tuple;
	cqContext	cqc;
	cqContext  *pcqCtx;

	pg_auth_time_rel = heap_open(AuthTimeConstraintRelationId, RowExclusiveLock);

	pcqCtx = 
			caql_beginscan(
					caql_addrel(cqclr(&cqc), pg_auth_time_rel),
					cql("SELECT * FROM pg_auth_time_constraint "
						" WHERE authid = :1 "
						" FOR UPDATE ",
						ObjectIdGetDatum(roleid)));

	while (HeapTupleIsValid(tmp_tuple = caql_getnext(pcqCtx)))
	{
		if (dropintervals != NIL) 
		{
			Form_pg_auth_time_constraint obj = (Form_pg_auth_time_constraint) GETSTRUCT(tmp_tuple);
			authInterval *interval, *existing = (authInterval *) palloc0(sizeof(authInterval));
			existing->start.day = obj->start_day;
			existing->start.time = obj->start_time;
			existing->end.day = obj->end_day;
			existing->end.time = obj->end_time;
			foreach(intervalitem, dropintervals) 
			{
				interval = (authInterval *)lfirst(intervalitem);
				if (interval_overlap(existing, interval))
				{
					if (Gp_role == GP_ROLE_DISPATCH)
						ereport(NOTICE,
								(errmsg("dropping DENY rule for \"%s\" between %s %s and %s %s",
										rolename, 
										daysofweek[existing->start.day],
										DatumGetCString(DirectFunctionCall1(time_out, TimeADTGetDatum(existing->start.time))),
										daysofweek[existing->end.day],
										DatumGetCString(DirectFunctionCall1(time_out, TimeADTGetDatum(existing->end.time))))));
					caql_delete_current(pcqCtx);
					dropped_matching_interval = true;
					break;
				}
			}
		} 
		else
			caql_delete_current(pcqCtx);
	}

	/* if intervals were specified and none was found, raise error */
	if (dropintervals && !dropped_matching_interval)
		ereport(ERROR, 
				(errmsg("cannot find matching DENY rules for \"%s\"", rolename)));

	caql_endscan(pcqCtx);

	/*
	 * Close pg_auth_time_constraint, but keep lock till commit (this is important to
	 * prevent any risk of deadlock failure while updating flat file)
	 */
	heap_close(pg_auth_time_rel, NoLock);

	/*
	 * Set flag to update flat auth time constraint file at commit.
	 */
	auth_time_file_update_needed();
}
