*** a/src/backend/commands/dbcommands.c
--- b/src/backend/commands/dbcommands.c
***************
*** 42,47 ****
--- 42,48 ----
  #include "commands/dbcommands.h"
  #include "commands/dbcommands_xlog.h"
  #include "commands/defrem.h"
+ #include "commands/policy.h"
  #include "commands/seclabel.h"
  #include "commands/tablespace.h"
  #include "mb/pg_wchar.h"
***************
*** 226,231 **** createdb(const CreatedbStmt *stmt)
--- 227,239 ----
  					 errmsg("LOCATION is not supported anymore"),
  					 errhint("Consider using tablespaces instead.")));
  		}
+ 		else if (strcmp(defel->defname, "catalog_security") == 0)
+ 		{
+ 			ereport(ERROR,
+                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                     errmsg("catalog security is not supported with create database command."),
+                     errdetail("Enable catalog security using Alter database command.")));
+ 		}
  		else
  			ereport(ERROR,
  					(errcode(ERRCODE_SYNTAX_ERROR),
***************
*** 519,524 **** createdb(const CreatedbStmt *stmt)
--- 527,533 ----
  	new_record[Anum_pg_database_datfrozenxid - 1] = TransactionIdGetDatum(src_frozenxid);
  	new_record[Anum_pg_database_datminmxid - 1] = TransactionIdGetDatum(src_minmxid);
  	new_record[Anum_pg_database_dattablespace - 1] = ObjectIdGetDatum(dst_deftablespace);
+ 	new_record[Anum_pg_database_datcatalogsecurity - 1] = BoolGetDatum(false);
  
  	/*
  	 * We deliberately set datacl to default (NULL), rather than copying it
***************
*** 1375,1385 **** AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
--- 1384,1397 ----
  	ListCell   *option;
  	bool		dbistemplate = false;
  	bool		dballowconnections = true;
+ 	bool		dbcatalogsecurity = false;
  	int			dbconnlimit = -1;
  	DefElem    *distemplate = NULL;
  	DefElem    *dallowconnections = NULL;
  	DefElem    *dconnlimit = NULL;
  	DefElem    *dtablespace = NULL;
+ 	DefElem    *dcatalogsecurity = NULL;
+ 	Form_pg_database pg_database_tuple;
  	Datum		new_record[Natts_pg_database];
  	bool		new_record_nulls[Natts_pg_database];
  	bool		new_record_repl[Natts_pg_database];
***************
*** 1421,1426 **** AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
--- 1433,1447 ----
  						 errmsg("conflicting or redundant options")));
  			dtablespace = defel;
  		}
+ 		else if (strcmp(defel->defname, "catalog_security") == 0)
+ 		{
+ 			if (dcatalogsecurity)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_SYNTAX_ERROR),
+ 						errmsg("conflicting or redundant options")));
+ 
+ 			dcatalogsecurity = defel;
+ 		}
  		else
  			ereport(ERROR,
  					(errcode(ERRCODE_SYNTAX_ERROR),
***************
*** 1457,1462 **** AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
--- 1478,1485 ----
  					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
  					 errmsg("invalid connection limit: %d", dbconnlimit)));
  	}
+ 	if (dcatalogsecurity && dcatalogsecurity->arg)
+ 		dbcatalogsecurity = defGetBoolean(dcatalogsecurity);
  
  	/*
  	 * Get the old tuple.  We don't need a lock on the database per se,
***************
*** 1476,1487 **** AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
--- 1499,1517 ----
  				(errcode(ERRCODE_UNDEFINED_DATABASE),
  				 errmsg("database \"%s\" does not exist", stmt->dbname)));
  
+ 	pg_database_tuple = (Form_pg_database)GETSTRUCT(tuple);
  	dboid = HeapTupleGetOid(tuple);
  
  	if (!pg_database_ownercheck(HeapTupleGetOid(tuple), GetUserId()))
  		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
  					   stmt->dbname);
  
+ 	if (dcatalogsecurity && (dboid != MyDatabaseId))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ 				errmsg("Enabling/disabling catalog security can be done"
+ 						" only to the connected database \"%s\"", stmt->dbname)));
+ 
  	/*
  	 * In order to avoid getting locked out and having to go through
  	 * standalone mode, we refuse to disallow connections to the database
***************
*** 1493,1498 **** AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
--- 1523,1539 ----
  				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
  				 errmsg("cannot disallow connections for current database")));
  
+ 	if (dcatalogsecurity && BoolGetDatum(dbcatalogsecurity) && !pg_database_tuple->datcatalogsecurity)
+ 	{
+ 		CreateCatalogPolicy();
+ 		CommandCounterIncrement();
+ 	}
+ 	else if (pg_database_tuple->datcatalogsecurity)
+ 	{
+ 		RemoveCatalogPolicy();
+ 		CommandCounterIncrement();
+ 	}
+ 
  	/*
  	 * Build an updated tuple, perusing the information just obtained
  	 */
***************
*** 1515,1520 **** AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel)
--- 1556,1566 ----
  		new_record[Anum_pg_database_datconnlimit - 1] = Int32GetDatum(dbconnlimit);
  		new_record_repl[Anum_pg_database_datconnlimit - 1] = true;
  	}
+ 	if (dcatalogsecurity)
+ 	{
+ 		new_record[Anum_pg_database_datcatalogsecurity - 1] = BoolGetDatum(dbcatalogsecurity);
+ 		new_record_repl[Anum_pg_database_datcatalogsecurity - 1] = true;
+ 	}
  
  	newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel), new_record,
  								 new_record_nulls, new_record_repl);
*** a/src/backend/commands/policy.c
--- b/src/backend/commands/policy.c
***************
*** 22,31 ****
--- 22,83 ----
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/objectaccess.h"
+ #include "catalog/pg_aggregate.h"
+ #include "catalog/pg_am.h"
+ #include "catalog/pg_amop.h"
+ #include "catalog/pg_amproc.h"
+ #include "catalog/pg_attrdef.h"
+ #include "catalog/pg_attribute.h"
+ #include "catalog/pg_auth_members.h"
  #include "catalog/pg_authid.h"
+ #include "catalog/pg_cast.h"
+ #include "catalog/pg_class.h"
+ #include "catalog/pg_collation.h"
+ #include "catalog/pg_constraint.h"
+ #include "catalog/pg_conversion.h"
+ #include "catalog/pg_database.h"
+ #include "catalog/pg_db_role_setting.h"
+ #include "catalog/pg_default_acl.h"
+ #include "catalog/pg_depend.h"
+ #include "catalog/pg_description.h"
+ #include "catalog/pg_enum.h"
+ #include "catalog/pg_event_trigger.h"
+ #include "catalog/pg_extension.h"
+ #include "catalog/pg_foreign_data_wrapper.h"
+ #include "catalog/pg_foreign_server.h"
+ #include "catalog/pg_foreign_table.h"
+ #include "catalog/pg_index.h"
+ #include "catalog/pg_inherits.h"
+ #include "catalog/pg_language.h"
+ #include "catalog/pg_largeobject.h"
+ #include "catalog/pg_largeobject_metadata.h"
+ #include "catalog/pg_namespace.h"
+ #include "catalog/pg_opclass.h"
+ #include "catalog/pg_operator.h"
+ #include "catalog/pg_opfamily.h"
+ #include "catalog/pg_pltemplate.h"
  #include "catalog/pg_policy.h"
+ #include "catalog/pg_proc.h"
+ #include "catalog/pg_range.h"
+ #include "catalog/pg_replication_origin.h"
+ #include "catalog/pg_rewrite.h"
+ #include "catalog/pg_seclabel.h"
+ #include "catalog/pg_shdepend.h"
+ #include "catalog/pg_shdescription.h"
+ #include "catalog/pg_shseclabel.h"
+ #include "catalog/pg_statistic.h"
+ #include "catalog/pg_tablespace.h"
+ #include "catalog/pg_transform.h"
+ #include "catalog/pg_trigger.h"
+ #include "catalog/pg_ts_config.h"
+ #include "catalog/pg_ts_config_map.h"
+ #include "catalog/pg_ts_dict.h"
+ #include "catalog/pg_ts_parser.h"
+ #include "catalog/pg_ts_template.h"
  #include "catalog/pg_type.h"
+ #include "catalog/pg_user_mapping.h"
  #include "commands/policy.h"
+ #include "executor/spi.h"
  #include "miscadmin.h"
  #include "nodes/makefuncs.h"
  #include "nodes/pg_list.h"
***************
*** 44,56 ****
--- 96,117 ----
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
  #include "utils/rel.h"
+ #include "utils/snapmgr.h"
  #include "utils/syscache.h"
  
+ #define CATALOG_POLICY_STRING_SIZE 2000
+ 
  static void RangeVarCallbackForPolicy(const RangeVar *rv,
  						  Oid relid, Oid oldrelid, void *arg);
  static char parse_policy_command(const char *cmd_name);
  static Datum *policy_role_list_to_array(List *roles, int *num_roles);
  
+ static bool generate_catalog_create_policy_string(HeapTuple cache_tuple, char *buf);
+ static bool generate_catalog_drop_policy_string(HeapTuple cache_tuple, char *buf);
+ 
+ /* variable to identify whether pg_policy relcache is built or not? */
+ bool policyRelcacheBuilt = false;
+ 
  /*
   * Callback to RangeVarGetRelidExtended().
   *
***************
*** 194,199 **** RelationBuildRowSecurity(Relation relation)
--- 255,272 ----
  	MemoryContext oldcxt = CurrentMemoryContext;
  	RowSecurityDesc *volatile rsdesc = NULL;
  
+ 	/* */
+ 	if (!criticalRelcachesBuilt || !criticalSharedRelcachesBuilt)
+ 		return;
+ 
+  	if (relation->rd_id == PolicyRelationId)
+ 	{
+ 		if (policyRelcacheBuilt)
+ 			return;
+ 		else
+ 			policyRelcacheBuilt = true;
+ 	}
+ 
  	/*
  	 * Create a memory context to hold everything associated with this
  	 * relation's row security policy.  This makes it easy to clean up during
***************
*** 325,330 **** RelationBuildRowSecurity(Relation relation)
--- 398,410 ----
  		/* Delete rscxt, first making sure it isn't active */
  		MemoryContextSwitchTo(oldcxt);
  		MemoryContextDelete(rscxt);
+ 		
+ 		if (relation->rd_id == PolicyRelationId)
+ 		{
+ 			Assert(policyRelcacheBuilt == true);
+ 			policyRelcacheBuilt = false;
+ 		}
+ 
  		PG_RE_THROW();
  	}
  	PG_END_TRY();
***************
*** 407,412 **** RemovePolicyById(Oid policy_id)
--- 487,1040 ----
  	heap_close(pg_policy_rel, RowExclusiveLock);
  }
  
+ static bool 
+ generate_catalog_create_policy_string(HeapTuple tuple, char *buf)
+ {
+ 	bool can_create_policy = false;
+ 	Form_pg_class pg_class_tuple;
+ 	Oid	relationid;
+ 
+ 	pg_class_tuple = (Form_pg_class)GETSTRUCT(tuple);
+ 	relationid = HeapTupleGetOid(tuple);
+ 
+ 	if (IsSharedRelation(relationid))
+ 		return can_create_policy;
+ 
+ 	switch (relationid)
+ 	{
+ 		/*
+ 		 * Following catalog tables data is accessible to all roles. 
+ 		 * So they doesn't need any speicific RLS policies on them.
+ 		 */ 
+ 		case AggregateRelationId:
+ 		case AccessMethodRelationId:
+ 		case AccessMethodOperatorRelationId:
+ 		case AccessMethodProcedureRelationId:
+ 			break;
+ 		case AttrDefaultRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" (has_column_privilege(adrelid, adnum,'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case AttributeRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" (has_column_privilege(attrelid, attnum,'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case CastRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_cast_privilege(oid, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case RelationRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_table_privilege(oid,'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case CollationRelationId:
+ 			/*sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR (pg_get_userbyid(collowner) = current_user))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;*/
+ 			break;
+ 		case ConstraintRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_constraint_privilege(oid,'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case ConversionRelationId:
+ 			/*sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR (pg_get_userbyid(conowner) = current_user))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;*/
+ 			break;
+ 		case DefaultAclRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" (pg_get_userbyid(defaclrole) = current_user)",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case DependRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((classid = 2600)"
+ 				" OR (classid = 2605 AND has_cast_privilege(objid, 'any'))"
+ 				" OR (classid = 3456)"
+ 				" OR (classid = 1249 AND has_column_privilege(objid, objsubid::smallint, 'any'))"
+ 				" OR (classid = 2606 AND has_constraint_privilege(objid, 'any'))"
+ 				" OR (classid = 2607)"
+ 				" OR (classid = 1262 AND has_database_privilege(objid, 'any'))"
+ 				" OR (classid = 1247 AND has_type_privilege(objid, 'any'))"
+ 				" OR (classid = 3079)"
+ 				" OR (classid = 3466)"
+ 				" OR (classid = 2328 AND has_foreign_data_wrapper_privilege(objid, 'any'))"
+ 				" OR (classid = 1259 AND has_table_privilege(objid,'any'))"
+ 				" OR (classid = 1255 AND has_function_privilege(objid, 'any'))"
+ 				" OR (classid = 2601)"
+ 				" OR (classid = 2602)"
+ 				" OR (classid = 2603)"
+ 				" OR (classid = 2604 AND has_column_default_privilege(objid, 'any'))"
+ 				" OR (classid = 2612 AND has_language_privilege(objid, 'any'))"
+ 				" OR (classid = 2613)"
+ 				" OR (classid = 2616)"
+ 				" OR (classid = 2617)"
+ 				" OR (classid = 2753)"
+ 				" OR (classid = 3501)"
+ 				" OR (classid = 3466)"
+ 				" OR (classid = 3079)"
+ 				" OR (classid = 3256 AND has_policy_privilege(objid, 'any'))"
+ 				" OR (classid = 1260 AND pg_has_role(objid, 'any'))"
+ 				" OR (classid = 2618)"
+ 				" OR (classid = 2615 AND has_schema_privilege(objid, 'any'))"
+ 				" OR (classid = 1417 AND has_server_privilege(objid, 'any'))"
+ 				" OR (classid = 1213 AND has_tablespace_privilege(objid, 'any'))"
+ 				" OR (classid = 3600)"
+ 				" OR (classid = 3601)"
+ 				" OR (classid = 3602)"
+ 				" OR (classid = 3764)"
+ 				" OR (classid = 3576)"
+ 				" OR (classid = 2620 AND has_trigger_privilege(objid, 'any'))"
+ 				" OR (classid = 1418 AND has_user_mapping_privilege(objid, 'any')))", 
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case DescriptionRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((classoid = 2600)"
+ 				" OR (classoid = 2605 AND has_cast_privilege(objoid, 'any'))"
+ 				" OR (classoid = 3456)"
+ 				" OR (classoid = 1249 AND has_column_privilege(objoid, objsubid::smallint, 'any'))"
+ 				" OR (classoid = 2606 AND has_constraint_privilege(objoid, 'any'))"
+ 				" OR (classoid = 2607)"
+ 				" OR (classoid = 1262 AND has_database_privilege(objoid, 'any'))"
+ 				" OR (classoid = 1247 AND has_type_privilege(objoid, 'any'))"
+ 				" OR (classoid = 3079)"
+ 				" OR (classoid = 3466)"
+ 				" OR (classoid = 2328 AND has_foreign_data_wrapper_privilege(objoid, 'any'))"
+ 				" OR (classoid = 1259 AND has_table_privilege(objoid,'any'))"
+ 				" OR (classoid = 1255 AND has_function_privilege(objoid, 'any'))"
+ 				" OR (classoid = 2613)"
+ 				" OR (classoid = 2616)"
+ 				" OR (classoid = 2617)"
+ 				" OR (classoid = 2753)"
+ 				" OR (classoid = 2995)"
+ 				" OR (classoid = 3256 AND has_policy_privilege(objoid, 'any'))"
+ 				" OR (classoid = 1260 AND pg_has_role(objoid, 'any'))"
+ 				" OR (classoid = 2618)"
+ 				" OR (classoid = 2615 AND has_schema_privilege(objoid, 'any'))"
+ 				" OR (classoid = 1417 AND has_server_privilege(objoid, 'any'))"
+ 				" OR (classoid = 1213 AND has_tablespace_privilege(objoid, 'any'))"
+ 				" OR (classoid = 3541)"
+ 				" OR (classoid = 3600)"
+ 				" OR (classoid = 3601)"
+ 				" OR (classoid = 3602)"
+ 				" OR (classoid = 3764)"
+ 				" OR (classoid = 3576)"
+ 				" OR (classoid = 2620 AND has_trigger_privilege(objoid, 'any')))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case EnumRelationId:
+ 			break;
+ 		case EventTriggerRelationId:
+ 			break;
+ 		case ExtensionRelationId:
+ 			break;
+ 		case ForeignDataWrapperRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_foreign_data_wrapper_privilege(oid,'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case ForeignServerRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_server_privilege(oid,'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case ForeignTableRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" (has_table_privilege(ftrelid, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case IndexRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" (has_table_privilege(indrelid, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case InheritsRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" (has_table_privilege(inhrelid, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case LanguageRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_language_privilege(oid, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case LargeObjectRelationId:
+ 			break;
+ 		case LargeObjectMetadataRelationId:
+ 			break;
+ 		case NamespaceRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_schema_privilege(oid, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case OperatorClassRelationId:
+ 			/*sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR (pg_get_userbyid(opcowner) = current_user))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;*/
+ 			break;
+ 		case OperatorRelationId:
+ 			/*sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR (pg_get_userbyid(oprowner) = current_user))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;*/
+ 			break;
+ 		case OperatorFamilyRelationId:
+ 			/*sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR (pg_get_userbyid(opfowner) = current_user))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;*/
+ 			break;
+ 		case PolicyRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_table_privilege(polrelid, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case ProcedureRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_function_privilege(oid, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case RangeRelationId:
+ 			break;
+ 		case RewriteRelationId:
+ 			break;
+ 		case SecLabelRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((classoid = 2600)"
+ 				" OR (classoid = 1249 AND has_column_privilege(objoid, objsubid::smallint, 'any'))"
+ 				" OR (classoid = 1262 AND has_database_privilege(objoid, 'any'))"
+ 				" OR (classoid = 1247 AND has_type_privilege(objoid, 'any'))"
+ 				" OR (classoid = 1259 AND has_table_privilege(objoid,'any'))"
+ 				" OR (classoid = 1255 AND has_function_privilege(objoid, 'any'))"
+ 				" OR (classoid = 2612 AND has_language_privilege(objoid, 'any'))"
+ 				" OR (classoid = 1260 AND pg_has_role(objoid, 'any'))"
+ 				" OR (classoid = 2613)"
+ 				" OR (classoid = 3466)"
+ 				" OR (classoid = 1213 AND has_tablespace_privilege(objoid, 'any')))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case StatisticRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((starelid < 16384) OR has_column_privilege(starelid, staattnum, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case TransformRelationId:
+ 			break;
+ 		case TriggerRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_table_privilege(tgrelid, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case TSConfigRelationId:
+ 			break;
+ 		case TSConfigMapRelationId:
+ 			break;
+ 		case TSDictionaryRelationId:
+ 			break;
+ 		case TSParserRelationId:
+ 			break;
+ 		case TSTemplateRelationId:
+ 			break;
+ 		case TypeRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR has_type_privilege(oid, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		case UserMappingRelationId:
+ 			sprintf(buf, "create policy %s_read_own_data on %s for select using"
+ 				" ((oid < 16384) OR pg_has_role(umuser, 'any')"
+ 				" OR has_server_privilege(umserver, 'any'))",
+ 				pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 			can_create_policy = true;
+ 			break;
+ 		default:
+ 			can_create_policy = false;
+ 			break;
+ 	}
+ 
+ 	return can_create_policy;
+ }
+ 
+ static bool
+ generate_catalog_drop_policy_string(HeapTuple tuple, char *buf)
+ {
+ 	bool can_create_policy = false;
+ 	Form_pg_class pg_class_tuple;
+ 	Oid	relationid;
+ 
+ 	pg_class_tuple = (Form_pg_class)GETSTRUCT(tuple);
+ 	relationid = HeapTupleGetOid(tuple);
+ 
+ 	if (IsSharedRelation(relationid))
+ 		return can_create_policy;
+ 
+ 	switch (relationid)
+ 	{
+ 		/*
+ 		* Following catalog tables data is accessible to all roles.
+ 		* So they doesn't need any speicific RLS policies on them.
+ 		*/
+ 	case AggregateRelationId:
+ 	case AccessMethodRelationId:
+ 	case AccessMethodOperatorRelationId:
+ 	case AccessMethodProcedureRelationId:
+ 	case CollationRelationId:
+ 	case ConversionRelationId:
+ 	case EnumRelationId:
+ 	case EventTriggerRelationId:
+ 	case ExtensionRelationId:
+ 	case LargeObjectRelationId:
+ 	case LargeObjectMetadataRelationId:
+ 	case OperatorClassRelationId:
+ 	case OperatorRelationId:
+ 	case OperatorFamilyRelationId:
+ 	case RangeRelationId:
+ 	case RewriteRelationId:
+ 	case TransformRelationId:
+ 	case TSConfigRelationId:
+ 	case TSConfigMapRelationId:
+ 	case TSDictionaryRelationId:
+ 	case TSParserRelationId:
+ 	case TSTemplateRelationId:
+ 		break;
+ 
+ 	case AttrDefaultRelationId:
+ 	case AttributeRelationId:
+ 	case CastRelationId:
+ 	case RelationRelationId:
+ 	case ConstraintRelationId:
+ 	case DefaultAclRelationId:
+ 	case DependRelationId:
+ 	case DescriptionRelationId:
+ 	case ForeignDataWrapperRelationId:
+ 	case ForeignServerRelationId:
+ 	case ForeignTableRelationId:
+ 	case IndexRelationId:
+ 	case InheritsRelationId:
+ 	case LanguageRelationId:
+ 	case NamespaceRelationId:
+ 	case PolicyRelationId:
+ 	case ProcedureRelationId:
+ 	case SecLabelRelationId:
+ 	case StatisticRelationId:
+ 	case TriggerRelationId:
+ 	case TypeRelationId:
+ 	case UserMappingRelationId:
+ 		sprintf(buf, "drop policy %s_read_own_data on %s",
+ 			pg_class_tuple->relname.data, pg_class_tuple->relname.data);
+ 		can_create_policy = true;
+ 		break;
+ 
+ 	default:
+ 		can_create_policy = false;
+ 		break;
+ 	}
+ 
+ 	return can_create_policy;
+ }
+ 
+ /*
+  * CreateCatalogPolicy -
+  *	 handles the execution of the ALTER DATBASE ROW LEVEL SECUTIRY = TRUE command.
+  */
+ void
+ CreateCatalogPolicy()
+ {
+ 	Relation	rel;
+ 	ScanKeyData scankey;
+ 	SysScanDesc scan;
+ 	HeapTuple	tuple;
+ 	bool allow_sytem_table_mods_old;
+ 	char *buf;
+ 
+ 	/*
+ 	 * Get all catalog relations from pg_class system table and
+ 	 * enable the row level security along with the catalog policy
+ 	 * command.
+ 	 */
+ 	SPI_connect();
+ 	PushActiveSnapshot(GetTransactionSnapshot());
+ 
+ 	rel = heap_open(RelationRelationId, RowExclusiveLock);
+ 	ScanKeyInit(&scankey,
+ 				ObjectIdAttributeNumber,
+ 				BTLessStrategyNumber, F_OIDLT,
+ 				ObjectIdGetDatum(FirstNormalObjectId));
+ 	scan = systable_beginscan(rel, ClassOidIndexId, true,
+ 								NULL, 1, &scankey);
+ 
+ 	buf = palloc(CATALOG_POLICY_STRING_SIZE);
+ 	allow_sytem_table_mods_old = allowSystemTableMods;
+ 	allowSystemTableMods = true;
+ 
+ 	PG_TRY();
+ 	{
+ 		while ((tuple = systable_getnext(scan)) != NULL)
+ 		{
+ 			int			ret;
+ 			HeapTuple	cache_tuple;
+ 			Form_pg_class pg_class_tuple;
+ 			bool can_create_policy;
+ 
+ 			pg_class_tuple = (Form_pg_class)GETSTRUCT(tuple);
+ 			if (pg_class_tuple->relkind != RELKIND_RELATION)
+ 				continue;
+ 				
+ 			cache_tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(HeapTupleGetOid(tuple)));
+ 
+ 			if (!HeapTupleIsValid(cache_tuple))
+ 				elog(ERROR, "cache lookup failed for relation %u", HeapTupleGetOid(tuple));
+ 
+ 			can_create_policy = generate_catalog_create_policy_string(cache_tuple, buf);
+ 			if (!can_create_policy)
+ 			{
+ 				heap_freetuple(cache_tuple);
+ 				continue;
+ 			}
+ 	
+ 			ret = SPI_execute(buf, false, 0);
+ 			if (ret != SPI_OK_UTILITY)
+ 				elog(ERROR, "Creating policy failed : error code %d", ret);
+ 
+ 			((Form_pg_class)GETSTRUCT(cache_tuple))->relrowsecurity = true;
+ 			heap_inplace_update(rel, cache_tuple);
+ 
+ 			heap_freetuple(cache_tuple);
+ 		}
+ 	}
+ 	PG_CATCH();
+ 	{
+ 		allowSystemTableMods = allow_sytem_table_mods_old;
+ 		PG_RE_THROW();
+ 	}
+ 	PG_END_TRY();
+ 
+ 	allowSystemTableMods = allow_sytem_table_mods_old;
+ 	pfree(buf);
+ 
+ 	systable_endscan(scan);
+ 	heap_close(rel, NoLock);
+ 
+ 	SPI_finish();
+ 	PopActiveSnapshot();
+ }
+ 
+ /*
+  * RemoveCatalogPolicy -
+  *	 handles the execution of the ALTER DATBASE ROW LEVEL SECUTIRY = FALSE command.
+  */
+ void
+ RemoveCatalogPolicy()
+ {
+ 	Relation	rel;
+ 	ScanKeyData scankey;
+ 	SysScanDesc scan;
+ 	HeapTuple	tuple;
+ 	Form_pg_class pg_class_tuple;
+ 	bool allow_sytem_table_mods_old;
+ 	char		 *buf;
+ 
+ 	/*
+ 	* Get all catalog relations from pg_class system table and
+ 	* enable the row level security along with the catalog policy
+ 	* command.
+ 	*/
+ 	SPI_connect();
+ 	PushActiveSnapshot(GetTransactionSnapshot());
+ 
+ 	rel = heap_open(RelationRelationId, RowExclusiveLock);
+ 	ScanKeyInit(&scankey,
+ 		ObjectIdAttributeNumber,
+ 		BTLessStrategyNumber, F_OIDLT,
+ 		ObjectIdGetDatum(FirstNormalObjectId));
+ 	scan = systable_beginscan(rel, ClassOidIndexId, true,
+ 		NULL, 1, &scankey);
+ 
+ 	buf = palloc(CATALOG_POLICY_STRING_SIZE);
+ 
+ 	allow_sytem_table_mods_old = allowSystemTableMods;
+ 	allowSystemTableMods = true;
+ 
+ 	PG_TRY();
+ 	{
+ 		while ((tuple = systable_getnext(scan)) != NULL)
+ 		{
+ 			int			ret;
+ 			HeapTuple	cache_tuple;
+ 			bool		can_drop_policy;
+ 
+ 			pg_class_tuple = (Form_pg_class)GETSTRUCT(tuple);
+ 			if (pg_class_tuple->relkind != RELKIND_RELATION)
+ 				continue;
+ 
+ 			cache_tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(HeapTupleGetOid(tuple)));
+ 			if (!HeapTupleIsValid(cache_tuple))
+ 				elog(ERROR, "cache lookup failed for relation %u", HeapTupleGetOid(tuple));
+ 
+ 			can_drop_policy = generate_catalog_drop_policy_string(cache_tuple, buf);
+ 			if (!can_drop_policy)
+ 			{
+ 				heap_freetuple(cache_tuple);
+ 				continue;
+ 			}			
+ 
+ 			ret = SPI_execute(buf, false, 0);
+ 			if (ret != SPI_OK_UTILITY)
+ 				elog(ERROR, "Creating policy failed : error code %d", ret);
+ 
+ 			((Form_pg_class)GETSTRUCT(cache_tuple))->relrowsecurity = false;
+ 			heap_inplace_update(rel, cache_tuple);
+ 
+ 			heap_freetuple(cache_tuple);
+ 		}
+ 	}
+ 	PG_CATCH();
+ 	{
+ 		allowSystemTableMods = allow_sytem_table_mods_old;
+ 		PG_RE_THROW();
+ 	}
+ 	PG_END_TRY();
+ 
+ 	allowSystemTableMods = allow_sytem_table_mods_old;
+ 
+ 	pfree(buf);
+ 	systable_endscan(scan);
+ 	heap_close(rel, NoLock);
+ 
+ 	SPI_finish();
+ 	PopActiveSnapshot();
+ }
+ 
  /*
   * CreatePolicy -
   *	 handles the execution of the CREATE POLICY command.
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 3436,3441 **** ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode)
--- 3436,3450 ----
  	{
  		AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
  
+ 		/*
+ 		 * ALTER table on sytem catalog tables is possible only when user specifies
+ 		 * CATALOG SECURITY on system catalog tables. To avoid the error in the 
+ 		 * AlterTableCreateToastTable function for system catalog tables, the system
+ 		 * catalog tables are ignored for the toast table creation.
+ 		 */
+ 		if (!IsUnderPostmaster && IsSharedRelation(tab->relid))
+ 			continue;
+ 
  		if (tab->relkind == RELKIND_RELATION ||
  			tab->relkind == RELKIND_MATVIEW)
  			AlterTableCreateToastTable(tab->relid, (Datum) 0, lockmode);
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
***************
*** 8881,8886 **** createdb_opt_name:
--- 8881,8887 ----
  			| OWNER							{ $$ = pstrdup($1); }
  			| TABLESPACE					{ $$ = pstrdup($1); }
  			| TEMPLATE						{ $$ = pstrdup($1); }
+ 			| CATALOG_P SECURITY				{ $$ = pstrdup("catalog_security"); }
  		;
  
  /*
*** a/src/backend/utils/adt/acl.c
--- b/src/backend/utils/adt/acl.c
***************
*** 17,27 ****
  #include <ctype.h>
  
  #include "access/htup_details.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_authid.h"
  #include "catalog/pg_auth_members.h"
! #include "catalog/pg_type.h"
  #include "catalog/pg_class.h"
  #include "commands/dbcommands.h"
  #include "commands/proclang.h"
  #include "commands/tablespace.h"
--- 17,35 ----
  #include <ctype.h>
  
  #include "access/htup_details.h"
+ #include "access/sysattr.h"
+ #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_authid.h"
  #include "catalog/pg_auth_members.h"
! #include "catalog/pg_attrdef.h"
! #include "catalog/pg_cast.h"
  #include "catalog/pg_class.h"
+ #include "catalog/pg_constraint.h"
+ #include "catalog/pg_policy.h"
+ #include "catalog/pg_trigger.h"
+ #include "catalog/pg_type.h"
+ #include "catalog/pg_user_mapping.h"
  #include "commands/dbcommands.h"
  #include "commands/proclang.h"
  #include "commands/tablespace.h"
***************
*** 31,36 ****
--- 39,45 ----
  #include "utils/acl.h"
  #include "utils/builtins.h"
  #include "utils/catcache.h"
+ #include "utils/fmgroids.h"
  #include "utils/inval.h"
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
***************
*** 2031,2036 **** convert_table_priv_string(text *priv_type_text)
--- 2040,2050 ----
  		{"REFERENCES WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_REFERENCES)},
  		{"TRIGGER", ACL_TRIGGER},
  		{"TRIGGER WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_TRIGGER)},
+ 		{"ANY", ACL_SELECT | ACL_GRANT_OPTION_FOR(ACL_SELECT) |
+ 				ACL_INSERT | ACL_GRANT_OPTION_FOR(ACL_INSERT) | ACL_UPDATE |
+ 				ACL_GRANT_OPTION_FOR(ACL_UPDATE) | ACL_DELETE | ACL_GRANT_OPTION_FOR(ACL_DELETE) |
+ 				ACL_TRUNCATE | ACL_GRANT_OPTION_FOR(ACL_TRUNCATE) | ACL_REFERENCES |
+ 				ACL_GRANT_OPTION_FOR(ACL_REFERENCES) | ACL_TRIGGER | ACL_GRANT_OPTION_FOR(ACL_TRIGGER)},
  		{"RULE", 0},			/* ignore old RULE privileges */
  		{"RULE WITH GRANT OPTION", 0},
  		{NULL, 0}
***************
*** 2243,2248 **** convert_sequence_priv_string(text *priv_type_text)
--- 2257,2263 ----
  		{"USAGE", ACL_USAGE},
  		{"SELECT", ACL_SELECT},
  		{"UPDATE", ACL_UPDATE},
+ 		{"ANY", ACL_USAGE | ACL_SELECT | ACL_UPDATE},
  		{NULL, 0}
  	};
  
***************
*** 2858,2863 **** convert_column_priv_string(text *priv_type_text)
--- 2873,2881 ----
  		{"UPDATE WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_UPDATE)},
  		{"REFERENCES", ACL_REFERENCES},
  		{"REFERENCES WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_REFERENCES)},
+ 		{"ANY", ACL_SELECT | ACL_GRANT_OPTION_FOR(ACL_SELECT) | ACL_INSERT |
+ 				ACL_GRANT_OPTION_FOR(ACL_INSERT) | ACL_GRANT_OPTION_FOR(ACL_INSERT) | ACL_UPDATE |
+ 				ACL_GRANT_OPTION_FOR(ACL_UPDATE) | ACL_REFERENCES | ACL_GRANT_OPTION_FOR(ACL_REFERENCES)},
  		{NULL, 0}
  	};
  
***************
*** 3055,3060 **** convert_database_priv_string(text *priv_type_text)
--- 3073,3081 ----
  		{"TEMP WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_CREATE_TEMP)},
  		{"CONNECT", ACL_CONNECT},
  		{"CONNECT WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_CONNECT)},
+ 		{"ANY", ACL_CREATE | ACL_GRANT_OPTION_FOR(ACL_CREATE) |
+ 									ACL_CREATE_TEMP | ACL_GRANT_OPTION_FOR(ACL_CREATE_TEMP) | ACL_CREATE_TEMP |
+ 									ACL_GRANT_OPTION_FOR(ACL_CREATE_TEMP) | ACL_CONNECT | ACL_GRANT_OPTION_FOR(ACL_CONNECT)},
  		{NULL, 0}
  	};
  
***************
*** 3238,3243 **** convert_foreign_data_wrapper_priv_string(text *priv_type_text)
--- 3259,3265 ----
  	static const priv_map foreign_data_wrapper_priv_map[] = {
  		{"USAGE", ACL_USAGE},
  		{"USAGE WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_USAGE)},
+ 		{"ANY", ACL_USAGE | ACL_GRANT_OPTION_FOR(ACL_USAGE)},
  		{NULL, 0}
  	};
  
***************
*** 3438,3443 **** convert_function_priv_string(text *priv_type_text)
--- 3460,3466 ----
  	static const priv_map function_priv_map[] = {
  		{"EXECUTE", ACL_EXECUTE},
  		{"EXECUTE WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_EXECUTE)},
+ 		{"ANY", ACL_EXECUTE | ACL_GRANT_OPTION_FOR(ACL_EXECUTE)},
  		{NULL, 0}
  	};
  
***************
*** 3629,3634 **** convert_language_priv_string(text *priv_type_text)
--- 3652,3658 ----
  	static const priv_map language_priv_map[] = {
  		{"USAGE", ACL_USAGE},
  		{"USAGE WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_USAGE)},
+ 		{"ANY", ACL_USAGE | ACL_GRANT_OPTION_FOR(ACL_USAGE)},
  		{NULL, 0}
  	};
  
***************
*** 3822,3827 **** convert_schema_priv_string(text *priv_type_text)
--- 3846,3852 ----
  		{"CREATE WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_CREATE)},
  		{"USAGE", ACL_USAGE},
  		{"USAGE WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_USAGE)},
+ 		{"ANY", ACL_CREATE | ACL_GRANT_OPTION_FOR(ACL_CREATE) | ACL_USAGE | ACL_GRANT_OPTION_FOR(ACL_USAGE)},
  		{NULL, 0}
  	};
  
***************
*** 4004,4009 **** convert_server_priv_string(text *priv_type_text)
--- 4029,4035 ----
  	static const priv_map server_priv_map[] = {
  		{"USAGE", ACL_USAGE},
  		{"USAGE WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_USAGE)},
+ 		{"ANY", ACL_USAGE | ACL_GRANT_OPTION_FOR(ACL_USAGE)},
  		{NULL, 0}
  	};
  
***************
*** 4186,4191 **** convert_tablespace_priv_string(text *priv_type_text)
--- 4212,4218 ----
  	static const priv_map tablespace_priv_map[] = {
  		{"CREATE", ACL_CREATE},
  		{"CREATE WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_CREATE)},
+ 		{"ANY", ACL_CREATE | ACL_GRANT_OPTION_FOR(ACL_CREATE)},
  		{NULL, 0}
  	};
  
***************
*** 4385,4390 **** convert_type_priv_string(text *priv_type_text)
--- 4412,4418 ----
  	static const priv_map type_priv_map[] = {
  		{"USAGE", ACL_USAGE},
  		{"USAGE WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_USAGE)},
+ 		{"ANY", ACL_USAGE | ACL_GRANT_OPTION_FOR(ACL_USAGE)},
  		{NULL, 0}
  	};
  
***************
*** 4566,4571 **** convert_role_priv_string(text *priv_type_text)
--- 4594,4600 ----
  		{"USAGE WITH ADMIN OPTION", ACL_GRANT_OPTION_FOR(ACL_CREATE)},
  		{"MEMBER WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_CREATE)},
  		{"MEMBER WITH ADMIN OPTION", ACL_GRANT_OPTION_FOR(ACL_CREATE)},
+ 		{"ANY", ACL_USAGE | ACL_CREATE | ACL_GRANT_OPTION_FOR(ACL_CREATE)},
  		{NULL, 0}
  	};
  
***************
*** 5247,5249 **** get_rolespec_name(const Node *node)
--- 5276,5568 ----
  
  	return rolename;
  }
+ 
+ /*
+  * has_cast_privilege_id
+  *		Check user privileges on a cast given
+  *		cast oid, and text priv name.
+  */
+ Datum
+ has_cast_privilege_id(PG_FUNCTION_ARGS)
+ {
+ 	Oid			castoid = PG_GETARG_OID(0);
+ 	text	   *priv_type_text = PG_GETARG_TEXT_P(1);
+ 	Oid			roleid;
+ 	AclMode		mode;
+ 	AclResult	aclresult1;
+ 	AclResult	aclresult2;
+ 	Relation	castDesc;
+ 	ScanKeyData skey[1];
+ 	SysScanDesc rcscan;
+ 	HeapTuple	tup;
+ 	Form_pg_cast castForm;
+ 
+ 	roleid = GetUserId();
+ 	mode = convert_server_priv_string(priv_type_text);
+ 
+ 	castDesc = heap_open(CastRelationId, AccessShareLock);
+ 
+ 	ScanKeyInit(&skey[0],
+ 		ObjectIdAttributeNumber,
+ 		BTEqualStrategyNumber, F_OIDEQ,
+ 		ObjectIdGetDatum(castoid));
+ 
+ 	rcscan = systable_beginscan(castDesc, CastOidIndexId, true,
+ 		NULL, 1, skey);
+ 
+ 	tup = systable_getnext(rcscan);
+ 
+ 	if (!HeapTupleIsValid(tup))
+ 	{
+ 		systable_endscan(rcscan);
+ 		heap_close(castDesc, AccessShareLock);
+ 		PG_RETURN_NULL();
+ 	}
+ 
+ 	castForm = (Form_pg_cast)GETSTRUCT(tup);
+ 
+ 	aclresult1 = pg_type_aclcheck(castForm->castsource, roleid, mode);
+ 	aclresult2 = pg_type_aclcheck(castForm->casttarget, roleid, mode);
+ 
+ 	systable_endscan(rcscan);
+ 	heap_close(castDesc, AccessShareLock);
+ 	PG_RETURN_BOOL((aclresult1 == ACLCHECK_OK) || (aclresult2 == ACLCHECK_OK));
+ }
+ 
+ /*
+  * has_constraint_privilege_id
+  *		Check user privileges on a constraint given
+  *		constraint oid, and text priv name.
+  */
+ Datum
+ has_constraint_privilege_id(PG_FUNCTION_ARGS)
+ {
+ 	Oid			constraintoid = PG_GETARG_OID(0);
+ 	text	   *priv_type_text = PG_GETARG_TEXT_P(1);
+ 	Oid			roleid;
+ 	AclMode		mode;
+ 	AclResult	aclresult;
+ 	Relation	constraintDesc;
+ 	ScanKeyData skey[1];
+ 	SysScanDesc rcscan;
+ 	HeapTuple	tup;
+ 	Form_pg_constraint constraintForm;
+ 
+ 	roleid = GetUserId();
+ 	mode = convert_server_priv_string(priv_type_text);
+ 
+ 	constraintDesc = heap_open(ConstraintRelationId, AccessShareLock);
+ 
+ 	ScanKeyInit(&skey[0],
+ 		ObjectIdAttributeNumber,
+ 		BTEqualStrategyNumber, F_OIDEQ,
+ 		ObjectIdGetDatum(constraintoid));
+ 
+ 	rcscan = systable_beginscan(constraintDesc, ConstraintOidIndexId, true,
+ 		NULL, 1, skey);
+ 
+ 	tup = systable_getnext(rcscan);
+ 
+ 	if (!HeapTupleIsValid(tup))
+ 	{
+ 		systable_endscan(rcscan);
+ 		heap_close(constraintDesc, AccessShareLock);
+ 		PG_RETURN_NULL();
+ 	}
+ 
+ 	constraintForm = (Form_pg_constraint)GETSTRUCT(tup);
+ 
+ 	if (constraintForm->contypid)
+ 		aclresult = pg_type_aclcheck(constraintForm->contypid, roleid, mode);
+ 	else
+ 		aclresult = pg_class_aclcheck(constraintForm->conrelid, roleid, mode);
+ 			
+ 	systable_endscan(rcscan);
+ 	heap_close(constraintDesc, AccessShareLock);
+ 	PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
+ }
+ 
+ /*
+  * has_column_default_privilege_id
+  *		Check user privileges on a column default given
+  *		attrdefault oid, and text priv name.
+  */
+ Datum
+ has_column_default_privilege_id(PG_FUNCTION_ARGS)
+ {
+ 	Oid			attrdefaulttoid = PG_GETARG_OID(0);
+ 	text	   *priv_type_text = PG_GETARG_TEXT_P(1);
+ 	Oid			roleid;
+ 	AclMode		mode;
+ 	int			privresult;
+ 	Relation	attrDefaultDesc;
+ 	ScanKeyData skey[1];
+ 	SysScanDesc rcscan;
+ 	HeapTuple	tup;
+ 	Form_pg_attrdef attrDefForm;
+ 
+ 	roleid = GetUserId();
+ 	mode = convert_server_priv_string(priv_type_text);
+ 
+ 	attrDefaultDesc = heap_open(AttrDefaultRelationId, AccessShareLock);
+ 
+ 	ScanKeyInit(&skey[0],
+ 		ObjectIdAttributeNumber,
+ 		BTEqualStrategyNumber, F_OIDEQ,
+ 		ObjectIdGetDatum(attrdefaulttoid));
+ 
+ 	rcscan = systable_beginscan(attrDefaultDesc, AttrDefaultOidIndexId, true,
+ 		NULL, 1, skey);
+ 
+ 	tup = systable_getnext(rcscan);
+ 
+ 	if (!HeapTupleIsValid(tup))
+ 	{
+ 		systable_endscan(rcscan);
+ 		heap_close(attrDefaultDesc, AccessShareLock);
+ 		PG_RETURN_NULL();
+ 	}
+ 
+ 	attrDefForm = (Form_pg_attrdef)GETSTRUCT(tup);
+ 
+ 	privresult = column_privilege_check(attrDefForm->adrelid, attrDefForm->adnum, roleid, mode);
+ 	
+ 	systable_endscan(rcscan);
+ 	heap_close(attrDefaultDesc, AccessShareLock);
+ 
+ 	if (privresult < 0)
+ 		PG_RETURN_NULL();
+ 	PG_RETURN_BOOL(privresult);
+ }
+ 
+ /*
+  * has_policy_privilege_id
+  *		Check user privileges on a policy given
+  *		policy oid, and text priv name.
+  */
+ Datum
+ has_policy_privilege_id(PG_FUNCTION_ARGS)
+ {
+ 	Oid			policyoid = PG_GETARG_OID(0);
+ 	text	   *priv_type_text = PG_GETARG_TEXT_P(1);
+ 	Oid			roleid;
+ 	AclMode		mode;
+ 	AclResult	aclresult;
+ 	Relation	policyDesc;
+ 	ScanKeyData skey[1];
+ 	SysScanDesc rcscan;
+ 	HeapTuple	tup;
+ 	Form_pg_policy policyForm;
+ 
+ 	roleid = GetUserId();
+ 	mode = convert_server_priv_string(priv_type_text);
+ 
+ 	policyDesc = heap_open(PolicyRelationId, AccessShareLock);
+ 
+ 	ScanKeyInit(&skey[0],
+ 		ObjectIdAttributeNumber,
+ 		BTEqualStrategyNumber, F_OIDEQ,
+ 		ObjectIdGetDatum(policyoid));
+ 
+ 	rcscan = systable_beginscan(policyDesc, PolicyOidIndexId, true,
+ 		NULL, 1, skey);
+ 
+ 	tup = systable_getnext(rcscan);
+ 
+ 	if (!HeapTupleIsValid(tup))
+ 	{
+ 		systable_endscan(rcscan);
+ 		heap_close(policyDesc, AccessShareLock);
+ 		PG_RETURN_NULL();
+ 	}
+ 
+ 	policyForm = (Form_pg_policy)GETSTRUCT(tup);
+ 
+ 	aclresult = pg_class_aclcheck(policyForm->polrelid, roleid, mode);
+ 
+ 	systable_endscan(rcscan);
+ 	heap_close(policyDesc, AccessShareLock);
+ 	PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
+ }
+ 
+ /*
+  * has_trigger_privilege_id
+  *		Check user privileges on a trigger given
+  *		trigger oid, and text priv name.
+  */
+ Datum
+ has_trigger_privilege_id(PG_FUNCTION_ARGS)
+ {
+ 	Oid			triggeroid = PG_GETARG_OID(0);
+ 	text	   *priv_type_text = PG_GETARG_TEXT_P(1);
+ 	Oid			roleid;
+ 	AclMode		mode;
+ 	AclResult	aclresult;
+ 	Relation	triggerDesc;
+ 	ScanKeyData skey[1];
+ 	SysScanDesc rcscan;
+ 	HeapTuple	tup;
+ 	Form_pg_trigger triggerForm;
+ 
+ 	roleid = GetUserId();
+ 	mode = convert_server_priv_string(priv_type_text);
+ 
+ 	triggerDesc = heap_open(PolicyRelationId, AccessShareLock);
+ 
+ 	ScanKeyInit(&skey[0],
+ 		ObjectIdAttributeNumber,
+ 		BTEqualStrategyNumber, F_OIDEQ,
+ 		ObjectIdGetDatum(triggeroid));
+ 
+ 	rcscan = systable_beginscan(triggerDesc, PolicyOidIndexId, true,
+ 		NULL, 1, skey);
+ 
+ 	tup = systable_getnext(rcscan);
+ 
+ 	if (!HeapTupleIsValid(tup))
+ 	{
+ 		systable_endscan(rcscan);
+ 		heap_close(triggerDesc, AccessShareLock);
+ 		PG_RETURN_NULL();
+ 	}
+ 
+ 	triggerForm = (Form_pg_trigger)GETSTRUCT(tup);
+ 
+ 	aclresult = pg_class_aclcheck(triggerForm->tgrelid, roleid, mode);
+ 
+ 	systable_endscan(rcscan);
+ 	heap_close(triggerDesc, AccessShareLock);
+ 	PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
+ }
+ 
+ /*
+ * has_user_mapping_privilege_id
+ *		Check user privileges on a user mapping given
+ *		user_mapping oid, and text priv name.
+ */
+ Datum
+ has_user_mapping_privilege_id(PG_FUNCTION_ARGS)
+ {
+ 	Oid			usermapoid = PG_GETARG_OID(0);
+ 	text	   *priv_type_text = PG_GETARG_TEXT_P(1);
+ 	Oid			roleid;
+ 	AclMode		mode;
+ 	AclResult	aclresult1;
+ 	AclResult	aclresult2;
+ 	HeapTuple	tup;
+ 	Form_pg_user_mapping usermapForm;
+ 
+ 	roleid = GetUserId();
+ 	mode = convert_server_priv_string(priv_type_text);
+ 
+ 	tup = SearchSysCache1(USERMAPPINGOID, usermapoid);
+ 	if (!HeapTupleIsValid(tup))
+ 		PG_RETURN_NULL();
+ 
+ 	usermapForm = (Form_pg_user_mapping)GETSTRUCT(tup);
+ 
+ 	aclresult1 = pg_role_aclcheck(usermapForm->umuser, roleid, mode);
+ 	aclresult2 = pg_foreign_server_aclcheck(usermapForm->umserver, roleid, mode);
+ 		
+ 	PG_RETURN_BOOL((aclresult1 == ACLCHECK_OK) || (aclresult2 == ACLCHECK_OK));
+ }
*** a/src/backend/utils/cache/relcache.c
--- b/src/backend/utils/cache/relcache.c
***************
*** 2076,2081 **** RelationClearRelation(Relation relation, bool rebuild)
--- 2076,2083 ----
  	 */
  	if (relation->rd_isnailed)
  	{
+ 		HeapTuple pg_class_tuple;
+ 
  		RelationInitPhysicalAddr(relation);
  
  		if (relation->rd_rel->relkind == RELKIND_INDEX)
***************
*** 2084,2089 **** RelationClearRelation(Relation relation, bool rebuild)
--- 2086,2112 ----
  			if (relation->rd_refcnt > 1 && IsTransactionState())
  				RelationReloadIndexInfo(relation);
  		}
+ 
+ 		/* 
+ 		 * A nailed-in system relation never ever blow away from rel cache, because
+ 		 * we'd be unable to recover. So for such relations, we will update the
+ 		 * row security descriptor if it is enabled. Usually this happens during
+ 		 * RelationBuildDesc function, but for nailed-in system relations, we will 
+ 		 * do it here.
+ 		 */
+ 		if (criticalRelcachesBuilt 
+ 			&& criticalSharedRelcachesBuilt
+ 			&& IsTransactionState())
+ 		{
+ 			/*
+ 			 * find the tuple in pg_class corresponding to the given relation id
+ 			 */
+ 			pg_class_tuple = ScanPgRelation(RelationGetRelid(relation), true, false);
+ 
+ 			if (((Form_pg_class)GETSTRUCT(pg_class_tuple))->relrowsecurity)
+ 				RelationBuildRowSecurity(relation);
+ 			heap_freetuple(pg_class_tuple);
+ 		}
  		return;
  	}
  
*** a/src/backend/utils/misc/rls.c
--- b/src/backend/utils/misc/rls.c
***************
*** 58,67 **** check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
  	bool		relforcerowsecurity;
  	Oid			user_id = checkAsUser ? checkAsUser : GetUserId();
  
- 	/* Nothing to do for built-in relations */
- 	if (relid < FirstNormalObjectId)
- 		return RLS_NONE;
- 
  	tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
  	if (!HeapTupleIsValid(tuple))
  		return RLS_NONE;
--- 58,63 ----
*** a/src/bin/initdb/initdb.c
--- b/src/bin/initdb/initdb.c
***************
*** 132,137 **** static bool do_sync = true;
--- 132,138 ----
  static bool sync_only = false;
  static bool show_setting = false;
  static bool data_checksums = false;
+ static bool shared_catalog_security = false;
  static char *xlog_dir = "";
  
  
***************
*** 186,191 **** static char *authwarning = NULL;
--- 187,193 ----
   */
  static const char *boot_options = "-F";
  static const char *backend_options = "--single -F -O -c search_path=pg_catalog -c exit_on_error=true";
+ static const char *catalog_security_options = "--single -F -O -c search_path=pg_catalog -c exit_on_error=true -c allow_system_table_mods=true";
  
  static const char *subdirs[] = {
  	"global",
***************
*** 255,260 **** static void setup_dictionary(void);
--- 257,263 ----
  static void setup_privileges(void);
  static void set_info_version(void);
  static void setup_schema(void);
+ static void setup_shared_catalog_security(void);
  static void load_plpgsql(void);
  static void vacuum_db(void);
  static void make_template0(void);
***************
*** 2252,2257 **** setup_schema(void)
--- 2255,2357 ----
  }
  
  /*
+  * setup shared catalog security by defining policies
+  */
+ static void
+ setup_shared_catalog_security(void)
+ {
+ 	PG_CMD_DECL;
+ 	char	  **line;
+ 	char	  **policy_lines;
+ 	static const char *pg_shared_catalog_security_setup[] = {
+ 		/* AuthMemRelationId */
+ 		/*
+ 		* Currently there is no policy needed for this table, so
+ 		* leave it as it is.
+ 		*/
+ 
+ 		/* AuthIdRelationId */
+ 		"create policy pg_authid_read_own_data on pg_authid for select using"
+ 		" ((oid < 16384) OR pg_has_role(oid, 'any'));\n",
+ 
+ 		"alter table pg_authid enable row level security;\n",
+ 
+ 		/* DatabaseRelationId */
+ 		"create policy pg_database_read_own_data on pg_database for select using"
+ 		" ((oid < 16384) OR has_database_privilege(oid,'any'));\n",
+ 
+ 		"alter table pg_database enable row level security;\n",
+ 
+ 		/* DbRoleSettingRelationId */
+ 		"create policy pg_db_role_setting_read_own_data on pg_db_role_setting for select using"
+ 		" (pg_get_userbyid(setrole) = current_user);\n",
+ 
+ 		"alter table pg_database enable row level security;\n",
+ 
+ 		/* PLTemplateRelationId */
+ 		/*
+ 		* Currently there is no policy needed for this table, so
+ 		* leave it as it is.
+ 		*/
+ 
+ 		/* ReplicationOriginRelationId */
+ 		"create policy pg_replication_origin_read_own_data on pg_replication_origin for select using"
+ 		" (pg_has_role(roident, 'any'));\n",
+ 
+ 		"alter table pg_replication_origin enable row level security;\n",
+ 
+ 		/* SharedDependRelationId */
+ 		"create policy pg_shdepend_read_own_data on pg_shdepend for select using"
+ 		" ((classid = 1262 AND has_database_privilege(objid, 'any'))"
+ 		" OR (classid = 1260 AND pg_has_role(objid, 'any'))"
+ 		" OR (classid = 1213 AND has_tablespace_privilege(objid, 'any')));\n",
+ 
+ 		"alter table pg_shdepend enable row level security;\n",
+ 
+ 		/* SharedDescriptionRelationId */
+ 		"create policy pg_shdescription_read_own_data on pg_shdescription for select using"
+ 		" ((classoid = 1262 AND has_database_privilege(objoid, 'any'))"
+ 		" OR (classoid = 1260 AND pg_has_role(objoid, 'any'))"
+ 		" OR (classoid = 1213 AND has_tablespace_privilege(objoid, 'any')));\n",
+ 
+ 		"alter table pg_shdescription enable row level security;\n",
+ 
+ 		/* SharedSecLabelRelationId */
+ 		"create policy pg_shseclabel_read_own_data on pg_shseclabel for select using"
+ 		" ((classoid = 1262 AND has_database_privilege(objoid, 'any'))"
+ 		" OR (classoid = 1260 AND pg_has_role(objoid, 'any'))"
+ 		" OR (classoid = 1213 AND has_tablespace_privilege(objoid, 'any')));\n",
+ 
+ 		"alter table pg_shseclabel enable row level security;\n",
+ 
+ 		/* TableSpaceRelationId */
+ 		"create policy pg_tablespace_read_own_data on pg_tablespace for select using"
+ 		" ((oid < 16384) OR has_tablespace_privilege(oid, 'any'));\n",
+ 
+ 		"alter table pg_tablespace enable row level security;\n",
+ 
+ 		NULL
+ 	};
+ 
+ 	fputs(_("creating shared catalog security policy ... "), stdout);
+ 	fflush(stdout);
+ 
+ 	snprintf(cmd, sizeof(cmd),
+ 		"\"%s\" %s template1 >%s",
+ 		backend_exec, catalog_security_options,
+ 		DEVNULL);
+ 
+ 	PG_CMD_OPEN;
+ 
+ 	for (line = pg_shared_catalog_security_setup; *line != NULL; line++)
+ 		PG_CMD_PUTS(*line);
+ 
+ 	PG_CMD_CLOSE;
+ 
+ 	check_ok();
+ }
+ 
+ /*
   * load PL/pgsql server-side language
   */
  static void
***************
*** 2768,2773 **** usage(const char *progname)
--- 2868,2875 ----
  	printf(_("\nLess commonly used options:\n"));
  	printf(_("  -d, --debug               generate lots of debugging output\n"));
  	printf(_("  -k, --data-checksums      use data page checksums\n"));
+ 	printf(_("  -C, --shared-catalog-security\n"
+ 			"						      use shared catalog security\n"));
  	printf(_("  -L DIRECTORY              where to find the input files\n"));
  	printf(_("  -n, --noclean             do not clean up after errors\n"));
  	printf(_("  -N, --nosync              do not wait for changes to be written safely to disk\n"));
***************
*** 3365,3377 **** initialize_data_directory(void)
  
  	setup_schema();
  
  	load_plpgsql();
  
  	vacuum_db();
  
  	make_template0();
  
! 	make_postgres();
  }
  
  
--- 3467,3482 ----
  
  	setup_schema();
  
+ 	if (shared_catalog_security)
+ 		setup_shared_catalog_security();
+ 	
  	load_plpgsql();
  
  	vacuum_db();
  
  	make_template0();
  
! 	make_postgres();		
  }
  
  
***************
*** 3405,3410 **** main(int argc, char *argv[])
--- 3510,3516 ----
  		{"sync-only", no_argument, NULL, 'S'},
  		{"xlogdir", required_argument, NULL, 'X'},
  		{"data-checksums", no_argument, NULL, 'k'},
+ 		{"shared-catalog-security", no_argument, NULL, 'C' },
  		{NULL, 0, NULL, 0}
  	};
  
***************
*** 3445,3451 **** main(int argc, char *argv[])
  
  	/* process command-line options */
  
! 	while ((c = getopt_long(argc, argv, "dD:E:kL:nNU:WA:sST:X:", long_options, &option_index)) != -1)
  	{
  		switch (c)
  		{
--- 3551,3557 ----
  
  	/* process command-line options */
  
! 	while ((c = getopt_long(argc, argv, "dD:E:kCL:nNU:WA:sST:X:", long_options, &option_index)) != -1)
  	{
  		switch (c)
  		{
***************
*** 3497,3502 **** main(int argc, char *argv[])
--- 3603,3611 ----
  			case 'k':
  				data_checksums = true;
  				break;
+ 			case 'C':
+ 				shared_catalog_security = true;
+ 				break;
  			case 'L':
  				share_path = pg_strdup(optarg);
  				break;
*** a/src/include/catalog/pg_database.h
--- b/src/include/catalog/pg_database.h
***************
*** 43,49 **** CATALOG(pg_database,1262) BKI_SHARED_RELATION BKI_ROWTYPE_OID(1248) BKI_SCHEMA_M
  	TransactionId datfrozenxid; /* all Xids < this are frozen in this DB */
  	TransactionId datminmxid;	/* all multixacts in the DB are >= this */
  	Oid			dattablespace;	/* default table space for this DB */
! 
  #ifdef CATALOG_VARLEN			/* variable-length fields start here */
  	aclitem		datacl[1];		/* access permissions */
  #endif
--- 43,49 ----
  	TransactionId datfrozenxid; /* all Xids < this are frozen in this DB */
  	TransactionId datminmxid;	/* all multixacts in the DB are >= this */
  	Oid			dattablespace;	/* default table space for this DB */
! 	bool		datcatalogsecurity; /* catalog security is enabled? */
  #ifdef CATALOG_VARLEN			/* variable-length fields start here */
  	aclitem		datacl[1];		/* access permissions */
  #endif
***************
*** 60,81 **** typedef FormData_pg_database *Form_pg_database;
   *		compiler constants for pg_database
   * ----------------
   */
! #define Natts_pg_database				13
! #define Anum_pg_database_datname		1
! #define Anum_pg_database_datdba			2
! #define Anum_pg_database_encoding		3
! #define Anum_pg_database_datcollate		4
! #define Anum_pg_database_datctype		5
! #define Anum_pg_database_datistemplate	6
! #define Anum_pg_database_datallowconn	7
! #define Anum_pg_database_datconnlimit	8
! #define Anum_pg_database_datlastsysoid	9
! #define Anum_pg_database_datfrozenxid	10
! #define Anum_pg_database_datminmxid		11
! #define Anum_pg_database_dattablespace	12
! #define Anum_pg_database_datacl			13
  
! DATA(insert OID = 1 (  template1 PGUID ENCODING "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1 1663 _null_));
  SHDESCR("default template for new databases");
  #define TemplateDbOid			1
  
--- 60,82 ----
   *		compiler constants for pg_database
   * ----------------
   */
! #define Natts_pg_database						14
! #define Anum_pg_database_datname				1
! #define Anum_pg_database_datdba					2
! #define Anum_pg_database_encoding				3
! #define Anum_pg_database_datcollate				4
! #define Anum_pg_database_datctype				5
! #define Anum_pg_database_datistemplate			6
! #define Anum_pg_database_datallowconn			7
! #define Anum_pg_database_datconnlimit			8
! #define Anum_pg_database_datlastsysoid			9
! #define Anum_pg_database_datfrozenxid			10
! #define Anum_pg_database_datminmxid				11
! #define Anum_pg_database_dattablespace			12
! #define Anum_pg_database_datcatalogsecurity	13
! #define Anum_pg_database_datacl					14
  
! DATA(insert OID = 1 (  template1 PGUID ENCODING "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1 1663 f _null_));
  SHDESCR("default template for new databases");
  #define TemplateDbOid			1
  
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 3642,3647 **** DESCR("current user privilege on role by role name");
--- 3642,3665 ----
  DATA(insert OID = 2710 (  pg_has_role		PGNSP PGUID 12 1 0 0 0 f f f f t f s s 2 0 16 "26 25" _null_ _null_ _null_ _null_ _null_ pg_has_role_id _null_ _null_ _null_ ));
  DESCR("current user privilege on role by role oid");
  
+ DATA(insert OID = 3315 (has_cast_privilege		PGNSP PGUID 12 1 0 0 0 f f f f t f s s 2 0 16 "26 25" _null_ _null_ _null_ _null_ _null_ has_cast_privilege_id _null_ _null_ _null_));
+ DESCR("current user privilege on cast by cast oid");
+ 
+ DATA(insert OID = 3316 (has_constraint_privilege		PGNSP PGUID 12 1 0 0 0 f f f f t f s s 2 0 16 "26 25" _null_ _null_ _null_ _null_ _null_ has_constraint_privilege_id _null_ _null_ _null_));
+ DESCR("current user privilege on contrainst by constraint oid");
+ 
+ DATA(insert OID = 3317 (has_column_default_privilege		PGNSP PGUID 12 1 0 0 0 f f f f t f s s 2 0 16 "26 25" _null_ _null_ _null_ _null_ _null_ has_column_default_privilege_id _null_ _null_ _null_));
+ DESCR("current user privilege on attrdefault by attrdefault oid");
+ 
+ DATA(insert OID = 3318 (has_policy_privilege		PGNSP PGUID 12 1 0 0 0 f f f f t f s s 2 0 16 "26 25" _null_ _null_ _null_ _null_ _null_ has_policy_privilege_id _null_ _null_ _null_));
+ DESCR("current user privilege on policy by policy oid");
+ 
+ DATA(insert OID = 3319 (has_trigger_privilege		PGNSP PGUID 12 1 0 0 0 f f f f t f s s 2 0 16 "26 25" _null_ _null_ _null_ _null_ _null_ has_trigger_privilege_id _null_ _null_ _null_));
+ DESCR("current user privilege on trigger by trigger oid");
+ 
+ DATA(insert OID = 3320 (has_user_mapping_privilege		PGNSP PGUID 12 1 0 0 0 f f f f t f s s 2 0 16 "26 25" _null_ _null_ _null_ _null_ _null_ has_user_mapping_privilege_id _null_ _null_ _null_));
+ DESCR("current user privilege on user mapping by user_mapping oid");
+ 
  DATA(insert OID = 1269 (  pg_column_size		PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 23 "2276" _null_ _null_ _null_ _null_ _null_	pg_column_size _null_ _null_ _null_ ));
  DESCR("bytes required to store the value, perhaps with compression");
  DATA(insert OID = 2322 ( pg_tablespace_size		PGNSP PGUID 12 1 0 0 0 f f f f t f v s 1 0 20 "26" _null_ _null_ _null_ _null_ _null_ pg_tablespace_size_oid _null_ _null_ _null_ ));
*** a/src/include/commands/policy.h
--- b/src/include/commands/policy.h
***************
*** 33,36 **** extern ObjectAddress rename_policy(RenameStmt *stmt);
--- 33,39 ----
  
  extern bool relation_has_policies(Relation rel);
  
+ extern void CreateCatalogPolicy(void);
+ extern void RemoveCatalogPolicy(void);
+ 
  #endif   /* POLICY_H */
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 106,111 **** extern Datum pg_has_role_id_name(PG_FUNCTION_ARGS);
--- 106,117 ----
  extern Datum pg_has_role_id_id(PG_FUNCTION_ARGS);
  extern Datum pg_has_role_name(PG_FUNCTION_ARGS);
  extern Datum pg_has_role_id(PG_FUNCTION_ARGS);
+ extern Datum has_cast_privilege_id(PG_FUNCTION_ARGS);
+ extern Datum has_constraint_privilege_id(PG_FUNCTION_ARGS);
+ extern Datum has_column_default_privilege_id(PG_FUNCTION_ARGS);
+ extern Datum has_policy_privilege_id(PG_FUNCTION_ARGS);
+ extern Datum has_trigger_privilege_id(PG_FUNCTION_ARGS);
+ extern Datum has_user_mapping_privilege_id(PG_FUNCTION_ARGS);
  
  /* bool.c */
  extern Datum boolin(PG_FUNCTION_ARGS);
*** /dev/null
--- b/src/test/regress/expected/multitenancy.out
***************
*** 0 ****
--- 1,322 ----
+ -- Create roles that are used by the following tests
+ create role tenancy_user1 login createdb;
+ create role tenancy_user2 login createdb;
+ create schema tenancy_user1;
+ grant all on schema tenancy_user1 to tenancy_user1;
+ create schema tenancy_user2;
+ grant all on schema tenancy_user2 to tenancy_user2;
+ alter database regression with catalog security = true;
+ -- create objects realted to tenacy_user1
+ SET SESSION ROLE tenancy_user1;
+ create table public.tenancy_user1_tbl1 (tenancy_user1_tbl1_column1 serial,
+ 								tenancy_user1_tbl1_column2 char(10) default 'FUJITSU',
+ 								tenancy_user1_tbl1_column3 int);
+ create index tenancy_user1_tbl1_idx on tenancy_user1_tbl1 (tenancy_user1_tbl1_column3);
+ insert into tenancy_user1_tbl1(tenancy_user1_tbl1_column3) values(1);
+ create table tenancy_user1.tenancy_user1_tbl2 (tenancy_user1_tbl2_column1 serial,
+ 								tenancy_user1_tbl2_column2 char(10) default 'FUJITSU',
+ 								tenancy_user1_tbl2_column3 int);
+ create index tenancy_user1_tbl2_idx on tenancy_user1.tenancy_user1_tbl2 (tenancy_user1_tbl2_column3);
+ create view public.tenancy_user1_view1 as select * from tenancy_user1_tbl1;
+ create materialized view public.tenancy_user1_matview1 as select * from tenancy_user1_tbl1;
+ select * from tenancy_user1_tbl1;
+  tenancy_user1_tbl1_column1 | tenancy_user1_tbl1_column2 | tenancy_user1_tbl1_column3 
+ ----------------------------+----------------------------+----------------------------
+                           1 | FUJITSU                    |                          1
+ (1 row)
+ 
+ select * from tenancy_user1_view1;
+  tenancy_user1_tbl1_column1 | tenancy_user1_tbl1_column2 | tenancy_user1_tbl1_column3 
+ ----------------------------+----------------------------+----------------------------
+                           1 | FUJITSU                    |                          1
+ (1 row)
+ 
+ select * from tenancy_user1_matview1;
+  tenancy_user1_tbl1_column1 | tenancy_user1_tbl1_column2 | tenancy_user1_tbl1_column3 
+ ----------------------------+----------------------------+----------------------------
+                           1 | FUJITSU                    |                          1
+ (1 row)
+ 
+ 								
+ -- verify all system catalogs related to the objects created by tenancy_user1
+ select relname from pg_class where relname = 'tenancy_user1_tbl1';
+       relname       
+ --------------------
+  tenancy_user1_tbl1
+ (1 row)
+ 
+ select relname from pg_class where relname = 'tenancy_user1_tbl1_idx';
+         relname         
+ ------------------------
+  tenancy_user1_tbl1_idx
+ (1 row)
+ 
+ select relname from pg_class where relname = 'tenancy_user1_view1';
+        relname       
+ ---------------------
+  tenancy_user1_view1
+ (1 row)
+ 
+ select relname from pg_class where relname = 'tenancy_user1_matview1';
+         relname         
+ ------------------------
+  tenancy_user1_matview1
+ (1 row)
+ 
+ select attname from pg_attribute where attname = 'tenancy_user1_tbl1_column1';
+           attname           
+ ----------------------------
+  tenancy_user1_tbl1_column1
+  tenancy_user1_tbl1_column1
+  tenancy_user1_tbl1_column1
+ (3 rows)
+ 
+ select adnum, adsrc from pg_attrdef where adrelid in (select oid from pg_class where relname = 'tenancy_user1_tbl1');
+  adnum |                                 adsrc                                  
+ -------+------------------------------------------------------------------------
+      1 | nextval('tenancy_user1_tbl1_tenancy_user1_tbl1_column1_seq'::regclass)
+      2 | 'FUJITSU'::bpchar
+ (2 rows)
+ 
+ select indnatts, indkey from pg_index where indrelid in (select oid from pg_class where relname = 'tenancy_user1_tbl1');
+  indnatts | indkey 
+ ----------+--------
+         1 | 3
+ (1 row)
+ 
+ select nspname, nspowner from pg_namespace where nspname = 'tenancy_user1';
+     nspname    | nspowner 
+ ---------------+----------
+  tenancy_user1 |       10
+ (1 row)
+ 
+ 		
+ -- verify all system views related to the objects created by tenancy_user1
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user1_tbl1';
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user1_tbl2' and schemaname = 'tenancy_user1';
+ 		
+ RESET ROLE;
+ -- create objects realted to tenacy_user2
+ SET SESSION ROLE tenancy_user2;
+ create table public.tenancy_user2_tbl1 (tenancy_user2_tbl1_column1 serial,
+ 								tenancy_user2_tbl1_column2 char(10) default 'FUJITSU',
+ 								tenancy_user2_tbl1_column3 int);
+ create index tenancy_user2_tbl1_idx on tenancy_user2_tbl1 (tenancy_user2_tbl1_column3);
+ insert into tenancy_user2_tbl1(tenancy_user2_tbl1_column3) values(1);
+ create table tenancy_user2.tenancy_user2_tbl2 (tenancy_user2_tbl2_column1 serial,
+ 								tenancy_user2_tbl2_column2 char(10) default 'FUJITSU',
+ 								tenancy_user2_tbl2_column3 int);
+ create index tenancy_user2_tbl2_idx on tenancy_user2.tenancy_user2_tbl2 (tenancy_user2_tbl2_column3);
+ create view public.tenancy_user2_view1 as select * from tenancy_user2_tbl1;
+ create materialized view public.tenancy_user2_matview1 as select * from tenancy_user2_tbl1;
+ select * from tenancy_user2_tbl1;
+  tenancy_user2_tbl1_column1 | tenancy_user2_tbl1_column2 | tenancy_user2_tbl1_column3 
+ ----------------------------+----------------------------+----------------------------
+                           1 | FUJITSU                    |                          1
+ (1 row)
+ 
+ select * from tenancy_user2_view1;
+  tenancy_user2_tbl1_column1 | tenancy_user2_tbl1_column2 | tenancy_user2_tbl1_column3 
+ ----------------------------+----------------------------+----------------------------
+                           1 | FUJITSU                    |                          1
+ (1 row)
+ 
+ select * from tenancy_user2_matview1;
+  tenancy_user2_tbl1_column1 | tenancy_user2_tbl1_column2 | tenancy_user2_tbl1_column3 
+ ----------------------------+----------------------------+----------------------------
+                           1 | FUJITSU                    |                          1
+ (1 row)
+ 
+ -- verify all system catalogs related to the objects created by tenancy_user2
+ select relname from pg_class where relname = 'tenancy_user2_tbl1';
+       relname       
+ --------------------
+  tenancy_user2_tbl1
+ (1 row)
+ 
+ select relname from pg_class where relname = 'tenancy_user2_tbl1_idx';
+         relname         
+ ------------------------
+  tenancy_user2_tbl1_idx
+ (1 row)
+ 
+ select relname from pg_class where relname = 'tenancy_user2_view1';
+        relname       
+ ---------------------
+  tenancy_user2_view1
+ (1 row)
+ 
+ select relname from pg_class where relname = 'tenancy_user2_matview1';
+         relname         
+ ------------------------
+  tenancy_user2_matview1
+ (1 row)
+ 
+ select attname from pg_attribute where attname = 'tenancy_user2_tbl1_column1';
+           attname           
+ ----------------------------
+  tenancy_user2_tbl1_column1
+  tenancy_user2_tbl1_column1
+  tenancy_user2_tbl1_column1
+ (3 rows)
+ 
+ select adnum, adsrc from pg_attrdef where adrelid in (select oid from pg_class where relname = 'tenancy_user2_tbl1');
+  adnum |                                 adsrc                                  
+ -------+------------------------------------------------------------------------
+      1 | nextval('tenancy_user2_tbl1_tenancy_user2_tbl1_column1_seq'::regclass)
+      2 | 'FUJITSU'::bpchar
+ (2 rows)
+ 
+ select indnatts, indkey from pg_index where indrelid in (select oid from pg_class where relname = 'tenancy_user2_tbl1');
+  indnatts | indkey 
+ ----------+--------
+         1 | 3
+ (1 row)
+ 
+ select nspname, nspowner from pg_namespace where nspname = 'tenancy_user2';
+     nspname    | nspowner 
+ ---------------+----------
+  tenancy_user2 |       10
+ (1 row)
+ 
+ 		
+ -- verify all system views related to the objects created by tenancy_user1
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user2_tbl1';
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user2_tbl2' and schemaname = 'tenancy_user2';
+ RESET ROLE;
+ -- Try to get the objects created by tenancy_user2 from tenancy_user1
+ SET SESSION ROLE tenancy_user1;
+ select * from tenancy_user2_tbl1;
+ ERROR:  permission denied for relation tenancy_user2_tbl1
+ select * from tenancy_user2_view1;
+ ERROR:  permission denied for relation tenancy_user2_view1
+ select * from tenancy_user2_matview1;
+ ERROR:  permission denied for relation tenancy_user2_matview1
+ select * from tenancy_user2.tenancy_user2.tbl2;
+ ERROR:  cross-database references are not implemented: "tenancy_user2.tenancy_user2.tbl2"
+ LINE 1: select * from tenancy_user2.tenancy_user2.tbl2;
+                       ^
+ -- verify all system catalogs related to the objects created by tenancy_user2
+ select relname from pg_class where relname = 'tenancy_user2_tbl1';
+  relname 
+ ---------
+ (0 rows)
+ 
+ select relname from pg_class where relname = 'tenancy_user2_tbl1_idx';
+  relname 
+ ---------
+ (0 rows)
+ 
+ select relname from pg_class where relname = 'tenancy_user2_view1';
+  relname 
+ ---------
+ (0 rows)
+ 
+ select relname from pg_class where relname = 'tenancy_user2_matview1';
+  relname 
+ ---------
+ (0 rows)
+ 
+ select attname from pg_attribute where attname = 'tenancy_user2_tbl1_column1';
+  attname 
+ ---------
+ (0 rows)
+ 
+ select adnum, adsrc from pg_attrdef where adrelid in (select oid from pg_class where relname = 'tenancy_user2_tbl1');
+  adnum | adsrc 
+ -------+-------
+ (0 rows)
+ 
+ select indnatts, indkey from pg_index where indrelid in (select oid from pg_class where relname = 'tenancy_user2_tbl1');
+  indnatts | indkey 
+ ----------+--------
+ (0 rows)
+ 
+ select nspname, nspowner from pg_namespace where nspname = 'tenancy_user2';
+  nspname | nspowner 
+ ---------+----------
+ (0 rows)
+ 
+ 		
+ -- verify all system views related to the objects created by tenancy_user1
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user2_tbl1';
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user2_tbl2' and schemaname = 'tenancy_user2';
+ RESET ROLE;
+ -- Try to get the objects created by tenancy_user1 from tenancy_user2
+ SET SESSION ROLE tenancy_user2;
+ select * from tenancy_user1_tbl1;
+ ERROR:  permission denied for relation tenancy_user1_tbl1
+ select * from tenancy_user1_view1;
+ ERROR:  permission denied for relation tenancy_user1_view1
+ select * from tenancy_user1_matview1;
+ ERROR:  permission denied for relation tenancy_user1_matview1
+ select * from tenancy_user1.tenancy_user1.tbl2;
+ ERROR:  cross-database references are not implemented: "tenancy_user1.tenancy_user1.tbl2"
+ LINE 1: select * from tenancy_user1.tenancy_user1.tbl2;
+                       ^
+ -- verify all system catalogs related to the objects created by tenancy_user1
+ select relname from pg_class where relname = 'tenancy_user1_tbl1';
+  relname 
+ ---------
+ (0 rows)
+ 
+ select relname from pg_class where relname = 'tenancy_user1_tbl1_idx';
+  relname 
+ ---------
+ (0 rows)
+ 
+ select relname from pg_class where relname = 'tenancy_user1_view1';
+  relname 
+ ---------
+ (0 rows)
+ 
+ select relname from pg_class where relname = 'tenancy_user1_matview1';
+  relname 
+ ---------
+ (0 rows)
+ 
+ select attname from pg_attribute where attname = 'tenancy_user1_tbl1_column1';
+  attname 
+ ---------
+ (0 rows)
+ 
+ select adnum, adsrc from pg_attrdef where adrelid in (select oid from pg_class where relname = 'tenancy_user1_tbl1');
+  adnum | adsrc 
+ -------+-------
+ (0 rows)
+ 
+ select indnatts, indkey from pg_index where indrelid in (select oid from pg_class where relname = 'tenancy_user1_tbl1');
+  indnatts | indkey 
+ ----------+--------
+ (0 rows)
+ 
+ select nspname, nspowner from pg_namespace where nspname = 'tenancy_user1';
+  nspname | nspowner 
+ ---------+----------
+ (0 rows)
+ 
+ 		
+ -- verify all system views related to the objects created by tenancy_user1
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user1_tbl1';
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user1_tbl2' and schemaname = 'tenancy_user1';
+ RESET ROLE;
+ -- Delete the roles and it's associated objects.
+ SET SESSION ROLE tenancy_user1;
+ DROP TABLE tenancy_user1_tbl1 cascade;
+ NOTICE:  drop cascades to 2 other objects
+ DETAIL:  drop cascades to view tenancy_user1_view1
+ drop cascades to materialized view tenancy_user1_matview1
+ DROP TABLE tenancy_user1_tbl2 cascade;
+ RESET ROLE;
+ SET SESSION ROLE tenancy_user2;
+ DROP TABLE tenancy_user2_tbl1 cascade;
+ NOTICE:  drop cascades to 2 other objects
+ DETAIL:  drop cascades to view tenancy_user2_view1
+ drop cascades to materialized view tenancy_user2_matview1
+ DROP TABLE tenancy_user2_tbl2 cascade;
+ RESET ROLE;
+ alter database regression with catalog security = false;
+ drop schema tenancy_user1;
+ drop schema tenancy_user2;
+ drop role tenancy_user1;
+ drop role tenancy_user2;
*** a/src/test/regress/parallel_schedule
--- b/src/test/regress/parallel_schedule
***************
*** 60,66 **** test: create_index create_view
  # ----------
  # Another group of parallel tests
  # ----------
! test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views rolenames roleattributes
  
  # ----------
  # sanity_check does a vacuum, affecting the sort order of SELECT *
--- 60,66 ----
  # ----------
  # Another group of parallel tests
  # ----------
! test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views rolenames roleattributes multitenancy
  
  # ----------
  # sanity_check does a vacuum, affecting the sort order of SELECT *
*** a/src/test/regress/serial_schedule
--- b/src/test/regress/serial_schedule
***************
*** 157,160 **** test: largeobject
--- 157,161 ----
  test: with
  test: xml
  test: event_trigger
+ test: multitenancy
  test: stats
*** /dev/null
--- b/src/test/regress/sql/multitenancy.sql
***************
*** 0 ****
--- 1,169 ----
+ -- Create roles that are used by the following tests
+ create role tenancy_user1 login createdb;
+ create role tenancy_user2 login createdb;
+ 
+ create schema tenancy_user1;
+ grant all on schema tenancy_user1 to tenancy_user1;
+ 
+ create schema tenancy_user2;
+ grant all on schema tenancy_user2 to tenancy_user2;
+ 
+ alter database regression with catalog security = true;
+ 
+ -- create objects realted to tenacy_user1
+ SET SESSION ROLE tenancy_user1;
+ 
+ create table public.tenancy_user1_tbl1 (tenancy_user1_tbl1_column1 serial,
+ 								tenancy_user1_tbl1_column2 char(10) default 'FUJITSU',
+ 								tenancy_user1_tbl1_column3 int);
+ create index tenancy_user1_tbl1_idx on tenancy_user1_tbl1 (tenancy_user1_tbl1_column3);
+ 
+ insert into tenancy_user1_tbl1(tenancy_user1_tbl1_column3) values(1);
+ 
+ create table tenancy_user1.tenancy_user1_tbl2 (tenancy_user1_tbl2_column1 serial,
+ 								tenancy_user1_tbl2_column2 char(10) default 'FUJITSU',
+ 								tenancy_user1_tbl2_column3 int);
+ create index tenancy_user1_tbl2_idx on tenancy_user1.tenancy_user1_tbl2 (tenancy_user1_tbl2_column3);
+ 
+ 
+ create view public.tenancy_user1_view1 as select * from tenancy_user1_tbl1;
+ create materialized view public.tenancy_user1_matview1 as select * from tenancy_user1_tbl1;
+ 
+ select * from tenancy_user1_tbl1;
+ select * from tenancy_user1_view1;
+ select * from tenancy_user1_matview1;
+ 								
+ 
+ -- verify all system catalogs related to the objects created by tenancy_user1
+ select relname from pg_class where relname = 'tenancy_user1_tbl1';
+ select relname from pg_class where relname = 'tenancy_user1_tbl1_idx';
+ select relname from pg_class where relname = 'tenancy_user1_view1';
+ select relname from pg_class where relname = 'tenancy_user1_matview1';
+ 
+ select attname from pg_attribute where attname = 'tenancy_user1_tbl1_column1';
+ select adnum, adsrc from pg_attrdef where adrelid in (select oid from pg_class where relname = 'tenancy_user1_tbl1');
+ select indnatts, indkey from pg_index where indrelid in (select oid from pg_class where relname = 'tenancy_user1_tbl1');
+ select nspname, nspowner from pg_namespace where nspname = 'tenancy_user1';
+ 		
+ -- verify all system views related to the objects created by tenancy_user1
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user1_tbl1';
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user1_tbl2' and schemaname = 'tenancy_user1';
+ 
+ 		
+ RESET ROLE;
+ 
+ 
+ -- create objects realted to tenacy_user2
+ SET SESSION ROLE tenancy_user2;
+ 
+ create table public.tenancy_user2_tbl1 (tenancy_user2_tbl1_column1 serial,
+ 								tenancy_user2_tbl1_column2 char(10) default 'FUJITSU',
+ 								tenancy_user2_tbl1_column3 int);
+ create index tenancy_user2_tbl1_idx on tenancy_user2_tbl1 (tenancy_user2_tbl1_column3);
+ 
+ insert into tenancy_user2_tbl1(tenancy_user2_tbl1_column3) values(1);
+ 
+ create table tenancy_user2.tenancy_user2_tbl2 (tenancy_user2_tbl2_column1 serial,
+ 								tenancy_user2_tbl2_column2 char(10) default 'FUJITSU',
+ 								tenancy_user2_tbl2_column3 int);
+ create index tenancy_user2_tbl2_idx on tenancy_user2.tenancy_user2_tbl2 (tenancy_user2_tbl2_column3);
+ 
+ create view public.tenancy_user2_view1 as select * from tenancy_user2_tbl1;
+ create materialized view public.tenancy_user2_matview1 as select * from tenancy_user2_tbl1;
+ 
+ select * from tenancy_user2_tbl1;
+ select * from tenancy_user2_view1;
+ select * from tenancy_user2_matview1;
+ 
+ -- verify all system catalogs related to the objects created by tenancy_user2
+ select relname from pg_class where relname = 'tenancy_user2_tbl1';
+ select relname from pg_class where relname = 'tenancy_user2_tbl1_idx';
+ select relname from pg_class where relname = 'tenancy_user2_view1';
+ select relname from pg_class where relname = 'tenancy_user2_matview1';
+ 
+ select attname from pg_attribute where attname = 'tenancy_user2_tbl1_column1';
+ select adnum, adsrc from pg_attrdef where adrelid in (select oid from pg_class where relname = 'tenancy_user2_tbl1');
+ select indnatts, indkey from pg_index where indrelid in (select oid from pg_class where relname = 'tenancy_user2_tbl1');
+ select nspname, nspowner from pg_namespace where nspname = 'tenancy_user2';
+ 		
+ -- verify all system views related to the objects created by tenancy_user1
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user2_tbl1';
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user2_tbl2' and schemaname = 'tenancy_user2';
+ 
+ RESET ROLE;
+ 
+ -- Try to get the objects created by tenancy_user2 from tenancy_user1
+ SET SESSION ROLE tenancy_user1;
+ 
+ select * from tenancy_user2_tbl1;
+ select * from tenancy_user2_view1;
+ select * from tenancy_user2_matview1;
+ 
+ select * from tenancy_user2.tenancy_user2.tbl2;
+ 
+ -- verify all system catalogs related to the objects created by tenancy_user2
+ select relname from pg_class where relname = 'tenancy_user2_tbl1';
+ select relname from pg_class where relname = 'tenancy_user2_tbl1_idx';
+ select relname from pg_class where relname = 'tenancy_user2_view1';
+ select relname from pg_class where relname = 'tenancy_user2_matview1';
+ 
+ select attname from pg_attribute where attname = 'tenancy_user2_tbl1_column1';
+ select adnum, adsrc from pg_attrdef where adrelid in (select oid from pg_class where relname = 'tenancy_user2_tbl1');
+ select indnatts, indkey from pg_index where indrelid in (select oid from pg_class where relname = 'tenancy_user2_tbl1');
+ select nspname, nspowner from pg_namespace where nspname = 'tenancy_user2';
+ 		
+ -- verify all system views related to the objects created by tenancy_user1
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user2_tbl1';
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user2_tbl2' and schemaname = 'tenancy_user2';
+ 
+ RESET ROLE;
+ 
+ 
+ -- Try to get the objects created by tenancy_user1 from tenancy_user2
+ SET SESSION ROLE tenancy_user2;
+ 
+ select * from tenancy_user1_tbl1;
+ select * from tenancy_user1_view1;
+ select * from tenancy_user1_matview1;
+ 
+ select * from tenancy_user1.tenancy_user1.tbl2;
+ 
+ -- verify all system catalogs related to the objects created by tenancy_user1
+ select relname from pg_class where relname = 'tenancy_user1_tbl1';
+ select relname from pg_class where relname = 'tenancy_user1_tbl1_idx';
+ select relname from pg_class where relname = 'tenancy_user1_view1';
+ select relname from pg_class where relname = 'tenancy_user1_matview1';
+ 
+ select attname from pg_attribute where attname = 'tenancy_user1_tbl1_column1';
+ select adnum, adsrc from pg_attrdef where adrelid in (select oid from pg_class where relname = 'tenancy_user1_tbl1');
+ select indnatts, indkey from pg_index where indrelid in (select oid from pg_class where relname = 'tenancy_user1_tbl1');
+ select nspname, nspowner from pg_namespace where nspname = 'tenancy_user1';
+ 		
+ -- verify all system views related to the objects created by tenancy_user1
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user1_tbl1';
+ --select schemaname, relname from pg_stat_all_tables where relname = 'tenancy_user1_tbl2' and schemaname = 'tenancy_user1';
+ 
+ RESET ROLE;
+ 
+ -- Delete the roles and it's associated objects.
+ SET SESSION ROLE tenancy_user1;
+ 
+ DROP TABLE tenancy_user1_tbl1 cascade;
+ DROP TABLE tenancy_user1_tbl2 cascade;
+ 
+ RESET ROLE;
+ 
+ SET SESSION ROLE tenancy_user2;
+ 
+ DROP TABLE tenancy_user2_tbl1 cascade;
+ DROP TABLE tenancy_user2_tbl2 cascade;
+ 
+ RESET ROLE;
+ 
+ alter database regression with catalog security = false;
+ 
+ drop schema tenancy_user1;
+ drop schema tenancy_user2;
+ 
+ drop role tenancy_user1;
+ drop role tenancy_user2;
