diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index f98e282741f71ce2968c537dccc773970695cfd4..9ceb96b54c74bc090373050e069a25897432e458 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -239,8 +239,8 @@
      </row>
 
      <row>
-      <entry><link linkend="catalog-pg-rowsecurity"><structname>pg_rowsecurity</structname></link></entry>
-      <entry>table row-level security policies</entry>
+      <entry><link linkend="catalog-pg-policy"><structname>pg_policy</structname></link></entry>
+      <entry>table policies</entry>
      </row>
 
      <row>
@@ -1944,8 +1944,8 @@
       <entry><type>bool</type></entry>
       <entry></entry>
       <entry>
-       True if table has row-security enabled; see
-       <link linkend="catalog-pg-rowsecurity"><structname>pg_rowsecurity</structname></link> catalog
+       True if table has row level security enabled; see
+       <link linkend="catalog-pg-policy"><structname>pg_policy</structname></link> catalog
       </entry>
      </row>
 
@@ -5342,15 +5342,15 @@
   </table>
  </sect1>
 
- <sect1 id="catalog-pg-rowsecurity">
-  <title><structname>pg_rowsecurity</structname></title>
+ <sect1 id="catalog-pg-policy">
+  <title><structname>pg_policy</structname></title>
 
-  <indexterm zone="catalog-pg-rowsecurity">
-   <primary>pg_rowsecurity</primary>
+  <indexterm zone="catalog-pg-policy">
+   <primary>pg_policy</primary>
   </indexterm>
 
   <para>
-   The catalog <structname>pg_rowsecurity</structname> stores row-level
+   The catalog <structname>pg_policy</structname> stores row-level
    security policies for each table.  A policy includes the kind of
    command which it applies to (or all commands), the roles which it
    applies to, the expression to be added as a security-barrier
@@ -5361,7 +5361,7 @@
 
   <table>
 
-   <title><structname>pg_rowsecurity</structname> Columns</title>
+   <title><structname>pg_policy</structname> Columns</title>
 
    <tgroup cols="4">
     <thead>
@@ -5375,42 +5375,42 @@
 
     <tbody>
      <row>
-      <entry><structfield>rsecpolname</structfield></entry>
+      <entry><structfield>polname</structfield></entry>
       <entry><type>name</type></entry>
       <entry></entry>
-      <entry>The name of the row-security policy</entry>
+      <entry>The name of the policy</entry>
      </row>
 
      <row>
-      <entry><structfield>rsecrelid</structfield></entry>
+      <entry><structfield>polrelid</structfield></entry>
       <entry><type>oid</type></entry>
       <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
-      <entry>The table to which the row-security policy belongs</entry>
+      <entry>The table to which the policy belongs</entry>
      </row>
 
      <row>
-      <entry><structfield>rseccmd</structfield></entry>
+      <entry><structfield>polcmd</structfield></entry>
       <entry><type>char</type></entry>
       <entry></entry>
-      <entry>The command type to which the row-security policy is applied.</entry>
+      <entry>The command type to which the policy is applied.</entry>
      </row>
 
      <row>
-      <entry><structfield>rsecroles</structfield></entry>
+      <entry><structfield>polroles</structfield></entry>
       <entry><type>char</type></entry>
       <entry></entry>
-      <entry>The roles to which the row-security policy is applied.</entry>
+      <entry>The roles to which the policy is applied.</entry>
      </row>
 
      <row>
-      <entry><structfield>rsecqual</structfield></entry>
+      <entry><structfield>polqual</structfield></entry>
       <entry><type>pg_node_tree</type></entry>
       <entry></entry>
       <entry>The expression tree to be added to the security barrier qualifications for queries which use the table.</entry>
      </row>
 
      <row>
-      <entry><structfield>rsecwithcheck</structfield></entry>
+      <entry><structfield>polwithcheck</structfield></entry>
       <entry><type>pg_node_tree</type></entry>
       <entry></entry>
       <entry>The expression tree to be added to the with check qualifications for queries which attempt to add rows to the table.</entry>
@@ -5423,8 +5423,8 @@
   <note>
    <para>
     <literal>pg_class.relrowsecurity</literal>
-    True if the table has row-security enabled.  Policies will not be applied
-    unless row-security is enabled on the table.
+    True if the table has row security enabled.  Policies will not be applied
+    unless row security is enabled on the table.
    </para>
   </note>
 
diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml
index f9dc151a0cc711df40a2cae5dedfc7e7ead2614c..570a003e4a9d37daa470dbe007342f8a824bad6c 100644
--- a/doc/src/sgml/ddl.sgml
+++ b/doc/src/sgml/ddl.sgml
@@ -1558,8 +1558,8 @@ REVOKE ALL ON accounts FROM PUBLIC;
 
   <para>
    To specify which rows are visible and what rows can be added to the
-   table with row security, an expression is required which returns a
-   boolean result.  This expression will be evaluated for each row prior
+   table with row level security, an expression is required which returns
+   a boolean result.  This expression will be evaluated for each row prior
    to other conditionals or functions which are part of the query.  The
    one exception to this rule are <literal>leakproof</literal> functions,
    which are guaranteed to not leak information.  Two expressions may be
diff --git a/doc/src/sgml/ref/alter_policy.sgml b/doc/src/sgml/ref/alter_policy.sgml
index ab717f31c51b92b82f2b59078df3ad01ff39c3d2..796035e9da92cf4bbbf1dfe07b3e5ffba7f81d35 100644
--- a/doc/src/sgml/ref/alter_policy.sgml
+++ b/doc/src/sgml/ref/alter_policy.sgml
@@ -16,7 +16,7 @@ PostgreSQL documentation
 
  <refnamediv>
   <refname>ALTER POLICY</refname>
-  <refpurpose>change the definition of a row-security policy</refpurpose>
+  <refpurpose>change the definition of a policy</refpurpose>
  </refnamediv>
 
  <refsynopsisdiv>
@@ -34,7 +34,7 @@ ALTER POLICY <replaceable class="parameter">name</replaceable> ON <replaceable c
 
   <para>
    <command>ALTER POLICY</command> changes the <replaceable class="parameter">
-   definition</replaceable> of an existing row-security policy.
+   definition</replaceable> of an existing policy.
   </para>
 
   <para>
diff --git a/doc/src/sgml/ref/create_policy.sgml b/doc/src/sgml/ref/create_policy.sgml
index eff062c114f0c59d8b78587cae3915f92a3919ce..4c8c00193139600a8741b3e9a45cbebbe9873766 100644
--- a/doc/src/sgml/ref/create_policy.sgml
+++ b/doc/src/sgml/ref/create_policy.sgml
@@ -16,7 +16,7 @@ PostgreSQL documentation
 
  <refnamediv>
   <refname>CREATE POLICY</refname>
-  <refpurpose>define a new row-security policy for a table</refpurpose>
+  <refpurpose>define a new policy for a table</refpurpose>
  </refnamediv>
 
  <refsynopsisdiv>
@@ -33,14 +33,13 @@ CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable
   <title>Description</title>
 
   <para>
-   The <command>CREATE POLICY</command> command defines a new row-security
-   policy for a table.  Note that row-security must also be enabled on the
-   table using <command>ALTER TABLE</command> in order for created policies
-   to be applied.
+   The <command>CREATE POLICY</command> command defines a new policy for a
+   table.  Note that row level security must also be enabled on the table using
+   <command>ALTER TABLE</command> in order for created policies to be applied.
   </para>
 
   <para>
-   A row-security policy is an expression which is added to the security-barrier
+   A policy is an expression which is added to the security-barrier
    qualifications of queries which are run against the table the policy is on,
    or an expression which is added to the with-check options for a table and
    which is applied to rows which would be added to the table.
@@ -49,7 +48,7 @@ CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable
    expression will be evaluated against the rows which are going to be added to
    the table.  By adding policies to a table, a user can limit the rows which a
    given user can select, insert, update, or delete.  This capability is also
-   known as Row-Level Security or RLS.
+   known as Row Level Security or RLS.
   </para>
 
   <para>
@@ -66,22 +65,22 @@ CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable
   </para>
 
   <para>
-   Note that while row-security policies will be applied for explicit queries
-   against tables in the system, they are not applied when the system is
-   performing internal referential integrity checks or validating constraints.
-   This means there are indirect ways to determine that a given value exists.
-   An example of this is attempting to insert a duplicate value
-   into a column which is the primary key or has a unique constraint.  If the
-   insert fails then the user can infer that the value already exists (this
-   example assumes that the user is permitted by policy to insert
-   records which they are not allowed to see).  Another example is where a user
-   is allowed to insert into a table which references another, otherwise hidden
-   table.  Existence can be determined by the user inserting values into the
-   referencing table, where success would indicate that the value exists in the
-   referenced table.  These issues can be addressed by carefully crafting
-   policies which prevent users from being able to insert, delete, or update
-   records at all which might possibly indicate a value they are not otherwise
-   able to see, or by using generated values (e.g.: surrogate keys) instead.
+   Note that while policies will be applied for explicit queries against tables
+   in the system, they are not applied when the system is performing internal
+   referential integrity checks or validating constraints.  This means there are
+   indirect ways to determine that a given value exists.  An example of this is
+   attempting to insert a duplicate value into a column which is the primary key
+   or has a unique constraint.  If the insert fails then the user can infer that
+   the value already exists (this example assumes that the user is permitted by
+   policy to insert records which they are not allowed to see).  Another example
+   is where a user is allowed to insert into a table which references another,
+   otherwise hidden table.  Existence can be determined by the user inserting
+   values into the referencing table, where success would indicate that the
+   value exists in the referenced table.  These issues can be addressed by
+   carefully crafting policies which prevent users from being able to insert,
+   delete, or update records at all which might possibly indicate a value they
+   are not otherwise able to see, or by using generated values (e.g.: surrogate
+   keys) instead.
   </para>
 
   <para>
@@ -291,8 +290,8 @@ CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable
 
   <para>
    In order to maintain <firstterm>referential integrity</firstterm> between
-   two related tables, row-security policies are not applied when the system
-   performs checks on foreign key constraints.
+   two related tables, policies are not applied when the system performs
+   checks on foreign key constraints.
   </para>
 
  </refsect1>
diff --git a/doc/src/sgml/ref/drop_policy.sgml b/doc/src/sgml/ref/drop_policy.sgml
index 31ca9db220eca6148a1fe5d7e0ebae94dd64e6c6..bd4ef5cf7ce03f80d5283b4dcf60fdae4b40d436 100644
--- a/doc/src/sgml/ref/drop_policy.sgml
+++ b/doc/src/sgml/ref/drop_policy.sgml
@@ -16,7 +16,7 @@ PostgreSQL documentation
 
  <refnamediv>
   <refname>DROP POLICY</refname>
-  <refpurpose>remove a row-security policy from a table</refpurpose>
+  <refpurpose>remove a policy from a table</refpurpose>
  </refnamediv>
 
  <refsynopsisdiv>
@@ -29,11 +29,11 @@ DROP POLICY [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ON <
   <title>Description</title>
 
   <para>
-   <command>DROP POLICY</command> removes the specified row-security policy
-   from the table.  Note that if the last policy is removed for a table and
-   the table still has ROW POLICY enabled via <command>ALTER TABLE</command>,
-   then the default-deny policy will be used.  <command>ALTER TABLE</command>
-   can be used to disable row security for a table using
+   <command>DROP POLICY</command> removes the specified policy from the table.
+   Note that if the last policy is removed for a table and the table still has
+   row level security enabled via <command>ALTER TABLE</command>, then the
+   default-deny policy will be used.  <command>ALTER TABLE</command> can be used
+   to disable row level security for a table using
    <literal>DISABLE ROW SECURITY</literal>, whether policies for the table
    exist or not.
   </para>
@@ -80,8 +80,8 @@ DROP POLICY [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ON <
   <title>Examples</title>
 
   <para>
-   To drop the row-security policy called <literal>p1</literal> on the
-   table named <literal>my_table</literal>:
+   To drop the policy called <literal>p1</literal> on the table named
+   <literal>my_table</literal>:
 
    <programlisting>
     DROP POLICY p1 ON my_table;
diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml
index 66b3cc9bf2f48d3140040f1f2650f70ac967a90b..973db7435bc58d395a60a18b11a1f6e483cc9bd2 100644
--- a/doc/src/sgml/rules.sgml
+++ b/doc/src/sgml/rules.sgml
@@ -2133,7 +2133,7 @@ SELECT * FROM phone_number WHERE tricky(person, phone);
 </para>
 
 <para>
-    When it is necessary for a view to provide row-level security, the
+    When it is necessary for a view to provide row level security, the
     <literal>security_barrier</literal> attribute should be applied to
     the view.  This prevents maliciously-chosen functions and operators from
     being invoked on rows until after the view has done its work.  For
diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index b257b02ff5c198d56d00dff9376ac6adf02fec7d..a403c643600b82201ff6e8f0f7e310db6054839a 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -39,7 +39,7 @@ POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
 	pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
 	pg_ts_parser.h pg_ts_template.h pg_extension.h \
 	pg_foreign_data_wrapper.h pg_foreign_server.h pg_user_mapping.h \
-	pg_foreign_table.h pg_rowsecurity.h \
+	pg_foreign_table.h pg_policy.h \
 	pg_default_acl.h pg_seclabel.h pg_shseclabel.h pg_collation.h pg_range.h \
 	toasting.h indexing.h \
     )
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index f338acf827d6c7976829f6dfaac215250fcbd96d..8ba5123c101a51e0dde74a49971477c2640932de 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -43,9 +43,9 @@
 #include "catalog/pg_opclass.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_opfamily.h"
+#include "catalog/pg_policy.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_rewrite.h"
-#include "catalog/pg_rowsecurity.h"
 #include "catalog/pg_tablespace.h"
 #include "catalog/pg_trigger.h"
 #include "catalog/pg_ts_config.h"
@@ -156,7 +156,8 @@ static const Oid object_classes[MAX_OCLASS] = {
 	UserMappingRelationId,		/* OCLASS_USER_MAPPING */
 	DefaultAclRelationId,		/* OCLASS_DEFACL */
 	ExtensionRelationId,		/* OCLASS_EXTENSION */
-	EventTriggerRelationId		/* OCLASS_EVENT_TRIGGER */
+	EventTriggerRelationId,		/* OCLASS_EVENT_TRIGGER */
+	PolicyRelationId			/* OCLASS_POLICY */
 };
 
 
@@ -1251,7 +1252,7 @@ doDeletion(const ObjectAddress *object, int flags)
 			RemoveEventTriggerById(object->objectId);
 			break;
 
-		case OCLASS_ROWSECURITY:
+		case OCLASS_POLICY:
 			RemovePolicyById(object->objectId);
 			break;
 
@@ -2361,8 +2362,8 @@ getObjectClass(const ObjectAddress *object)
 		case EventTriggerRelationId:
 			return OCLASS_EVENT_TRIGGER;
 
-		case RowSecurityRelationId:
-			return OCLASS_ROWSECURITY;
+		case PolicyRelationId:
+			return OCLASS_POLICY;
 	}
 
 	/* shouldn't get here */
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index b69b75bcc2e1e53b0f6f7bff51dd970fe075b88c..e261307e9d5fbce0943c2572505a5d45a09cc55a 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -42,7 +42,7 @@
 #include "catalog/pg_opfamily.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
-#include "catalog/pg_rowsecurity.h"
+#include "catalog/pg_policy.h"
 #include "catalog/pg_rewrite.h"
 #include "catalog/pg_tablespace.h"
 #include "catalog/pg_trigger.h"
@@ -346,11 +346,11 @@ static const ObjectPropertyType ObjectProperty[] =
 		false
 	},
 	{
-		RowSecurityRelationId,
-		RowSecurityOidIndexId,
+		PolicyRelationId,
+		PolicyOidIndexId,
 		-1,
 		-1,
-		Anum_pg_rowsecurity_rsecpolname,
+		Anum_pg_policy_polname,
 		InvalidAttrNumber,
 		InvalidAttrNumber,
 		InvalidAttrNumber,
@@ -998,7 +998,7 @@ get_object_address_relobject(ObjectType objtype, List *objname,
 				address.objectSubId = 0;
 				break;
 			case OBJECT_POLICY:
-				address.classId = RowSecurityRelationId;
+				address.classId = PolicyRelationId;
 				address.objectId = relation ?
 					get_relation_policy_oid(reloid, depname, missing_ok) :
 					InvalidOid;
@@ -2189,38 +2189,38 @@ getObjectDescription(const ObjectAddress *object)
 				break;
 			}
 
-		case OCLASS_ROWSECURITY:
+		case OCLASS_POLICY:
 			{
-				Relation	rsec_rel;
+				Relation	policy_rel;
 				ScanKeyData	skey[1];
 				SysScanDesc	sscan;
 				HeapTuple	tuple;
-				Form_pg_rowsecurity form_rsec;
+				Form_pg_policy form_policy;
 
-				rsec_rel = heap_open(RowSecurityRelationId, AccessShareLock);
+				policy_rel = heap_open(PolicyRelationId, AccessShareLock);
 
 				ScanKeyInit(&skey[0],
 							ObjectIdAttributeNumber,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
-				sscan = systable_beginscan(rsec_rel, RowSecurityOidIndexId,
+				sscan = systable_beginscan(policy_rel, PolicyOidIndexId,
 										   true, NULL, 1, skey);
 
 				tuple = systable_getnext(sscan);
 
 				if (!HeapTupleIsValid(tuple))
-					elog(ERROR, "cache lookup failed for row-security relation %u",
+					elog(ERROR, "cache lookup failed for policy %u",
 						 object->objectId);
 
-				form_rsec = (Form_pg_rowsecurity) GETSTRUCT(tuple);
+				form_policy = (Form_pg_policy) GETSTRUCT(tuple);
 
 				appendStringInfo(&buffer, _("policy %s on "),
-								 NameStr(form_rsec->rsecpolname));
-				getRelationDescription(&buffer, form_rsec->rsecrelid);
+								 NameStr(form_policy->polname));
+				getRelationDescription(&buffer, form_policy->polrelid);
 
 				systable_endscan(sscan);
-				heap_close(rsec_rel, AccessShareLock);
+				heap_close(policy_rel, AccessShareLock);
 				break;
 			}
 
@@ -2635,6 +2635,10 @@ getObjectTypeDescription(const ObjectAddress *object)
 			appendStringInfoString(&buffer, "event trigger");
 			break;
 
+		case OCLASS_POLICY:
+			appendStringInfoString(&buffer, "policy");
+			break;
+
 		default:
 			appendStringInfo(&buffer, "unrecognized %u", object->classId);
 			break;
@@ -3119,6 +3123,30 @@ getObjectIdentity(const ObjectAddress *object)
 				break;
 			}
 
+		case OCLASS_POLICY:
+			{
+				Relation	polDesc;
+				HeapTuple	tup;
+				Form_pg_policy policy;
+
+				polDesc = heap_open(PolicyRelationId, AccessShareLock);
+
+				tup = get_catalog_object_by_oid(polDesc, object->objectId);
+
+				if (!HeapTupleIsValid(tup))
+					elog(ERROR, "could not find tuple for policy %u",
+						 object->objectId);
+
+				policy = (Form_pg_policy) GETSTRUCT(tup);
+
+				appendStringInfo(&buffer, "%s on ",
+								 quote_identifier(NameStr(policy->polname)));
+				getRelationIdentity(&buffer, policy->polrelid);
+
+				heap_close(polDesc, AccessShareLock);
+				break;
+			}
+
 		case OCLASS_SCHEMA:
 			{
 				char	   *nspname;
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index a819952c75dec233d01a823925d0ce243e50e3e2..22b8ceef622603cd4eae9a334cc8305b9e3dad6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -67,30 +67,30 @@ CREATE VIEW pg_policies AS
     SELECT
         N.nspname AS schemaname,
         C.relname AS tablename,
-        rs.rsecpolname AS policyname,
+        pol.polname AS policyname,
         CASE
-            WHEN rs.rsecroles = '{0}' THEN
+            WHEN pol.polroles = '{0}' THEN
                 string_to_array('public', '')
             ELSE
                 ARRAY
                 (
                     SELECT rolname
                     FROM pg_catalog.pg_authid
-                    WHERE oid = ANY (rs.rsecroles) ORDER BY 1
+                    WHERE oid = ANY (pol.polroles) ORDER BY 1
                 )
         END AS roles,
-        CASE WHEN rs.rseccmd IS NULL THEN 'ALL' ELSE
-            CASE rs.rseccmd
+        CASE WHEN pol.polcmd IS NULL THEN 'ALL' ELSE
+            CASE pol.polcmd
                 WHEN 'r' THEN 'SELECT'
                 WHEN 'a' THEN 'INSERT'
                 WHEN 'u' THEN 'UPDATE'
                 WHEN 'd' THEN 'DELETE'
             END
         END AS cmd,
-        pg_catalog.pg_get_expr(rs.rsecqual, rs.rsecrelid) AS qual,
-        pg_catalog.pg_get_expr(rs.rsecwithcheck, rs.rsecrelid) AS with_check
-    FROM pg_catalog.pg_rowsecurity rs
-    JOIN pg_catalog.pg_class C ON (C.oid = rs.rsecrelid)
+        pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS qual,
+        pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS with_check
+    FROM pg_catalog.pg_policy pol
+    JOIN pg_catalog.pg_class C ON (C.oid = pol.polrelid)
     LEFT JOIN pg_catalog.pg_namespace N ON (N.oid = C.relnamespace);
 
 CREATE VIEW pg_rules AS
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 83e8f891222a3137934557e4a5f67ce8d059f8ee..08abe141f4169f98d671fe22fc3be1151b48daa0 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -282,12 +282,13 @@ static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0";
 
 /* non-export function prototypes */
 static CopyState BeginCopy(bool is_from, Relation rel, Node *raw_query,
-		  const char *queryString, List *attnamelist, List *options);
+		  const char *queryString, const Oid queryRelId, List *attnamelist,
+		  List *options);
 static void EndCopy(CopyState cstate);
 static void ClosePipeToProgram(CopyState cstate);
 static CopyState BeginCopyTo(Relation rel, Node *query, const char *queryString,
-			const char *filename, bool is_program, List *attnamelist,
-			List *options);
+			const Oid queryRelId, const char *filename, bool is_program,
+			List *attnamelist, List *options);
 static void EndCopyTo(CopyState cstate);
 static uint64 DoCopyTo(CopyState cstate);
 static uint64 CopyTo(CopyState cstate);
@@ -843,7 +844,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed)
 		ExecCheckRTPerms(list_make1(rte), true);
 
 		/*
-		 * Permission check for row security.
+		 * Permission check for row security policies.
 		 *
 		 * check_enable_rls will ereport(ERROR) if the user has requested
 		 * something invalid and will otherwise indicate if we should enable
@@ -866,7 +867,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed)
 			if (is_from)
 				ereport(ERROR,
 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-						 errmsg("COPY FROM not supported with row security."),
+						 errmsg("COPY FROM not supported with row level security."),
 						 errhint("Use direct INSERT statements instead.")));
 
 			/* Build target list */
@@ -886,7 +887,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed)
 			target->location = 1;
 
 			/* Build FROM clause */
-			from = makeRangeVar(NULL, RelationGetRelationName(rel), 1);
+			from = stmt->relation;
 
 			/* Build query */
 			select = makeNode(SelectStmt);
@@ -895,8 +896,6 @@ DoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed)
 
 			query = (Node*) select;
 
-			relid = InvalidOid;
-
 			/* Close the handle to the relation as it is no longer needed. */
 			heap_close(rel, (is_from ? RowExclusiveLock : AccessShareLock));
 			rel = NULL;
@@ -926,7 +925,7 @@ DoCopy(const CopyStmt *stmt, const char *queryString, uint64 *processed)
 	}
 	else
 	{
-		cstate = BeginCopyTo(rel, query, queryString,
+		cstate = BeginCopyTo(rel, query, queryString, relid,
 							 stmt->filename, stmt->is_program,
 							 stmt->attlist, stmt->options);
 		*processed = DoCopyTo(cstate);	/* copy from database to file */
@@ -1304,6 +1303,7 @@ BeginCopy(bool is_from,
 		  Relation rel,
 		  Node *raw_query,
 		  const char *queryString,
+		  const Oid queryRelId,
 		  List *attnamelist,
 		  List *options)
 {
@@ -1394,6 +1394,30 @@ BeginCopy(bool is_from,
 		/* plan the query */
 		plan = planner(query, 0, NULL);
 
+		/*
+		 * If we were passed in a relid, make sure we got the same one back
+		 * after planning out the query.  It's possible that it changed between
+		 * when we checked the policies on the table and decided to use a query
+		 * and now.
+		 */
+		if (queryRelId != InvalidOid)
+		{
+			Oid relid = linitial_oid(plan->relationOids);
+
+			/*
+			 * There should only be one relationOid in this case, since we will
+			 * only get here when we have changed the command for the user from
+			 * a "COPY relation TO" to "COPY (SELECT * FROM relation) TO", to
+			 * allow row level security policies to be applied.
+			 */
+			Assert(list_length(plan->relationOids) == 1);
+
+			if (relid != queryRelId)
+				ereport(ERROR,
+						(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+						 errmsg("relation referenced by COPY statement has changed")));
+		}
+
 		/*
 		 * Use a snapshot with an updated command ID to ensure this query sees
 		 * results of any previously executed queries.
@@ -1595,6 +1619,7 @@ static CopyState
 BeginCopyTo(Relation rel,
 			Node *query,
 			const char *queryString,
+			const Oid queryRelId,
 			const char *filename,
 			bool is_program,
 			List *attnamelist,
@@ -1636,7 +1661,8 @@ BeginCopyTo(Relation rel,
 							RelationGetRelationName(rel))));
 	}
 
-	cstate = BeginCopy(false, rel, query, queryString, attnamelist, options);
+	cstate = BeginCopy(false, rel, query, queryString, queryRelId, attnamelist,
+					   options);
 	oldcontext = MemoryContextSwitchTo(cstate->copycontext);
 
 	if (pipe)
@@ -2565,7 +2591,7 @@ BeginCopyFrom(Relation rel,
 	MemoryContext oldcontext;
 	bool		volatile_defexprs;
 
-	cstate = BeginCopy(true, rel, NULL, NULL, attnamelist, options);
+	cstate = BeginCopy(true, rel, NULL, NULL, InvalidOid, attnamelist, options);
 	oldcontext = MemoryContextSwitchTo(cstate->copycontext);
 
 	/* Initialize state variables */
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index 1b8c94bcfdf91668a42eb317ac33c1ba8fd8c48e..6a3002f5268e33cf349fca2a4934b0916bad1aec 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -997,7 +997,7 @@ EventTriggerSupportsObjectClass(ObjectClass objclass)
 		case OCLASS_USER_MAPPING:
 		case OCLASS_DEFACL:
 		case OCLASS_EXTENSION:
-		case OCLASS_ROWSECURITY:
+		case OCLASS_POLICY:
 			return true;
 
 		case MAX_OCLASS:
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 470db5705cc57fa7838fee543d2e3aafbb80444f..d3a59aa3567c3c42e588247caedb0829d209f3d1 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -904,9 +904,9 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
 	ReleaseSysCache(languageTuple);
 
 	/*
-	 * Only superuser is allowed to create leakproof functions because it
-	 * possibly allows unprivileged users to reference invisible tuples to be
-	 * filtered out using views for row-level security.
+	 * Only superuser is allowed to create leakproof functions because leakproof
+	 * functions can see tuples which have not yet been filtered out by security
+	 * barrier views or row level security policies.
 	 */
 	if (isLeakProof && !superuser())
 		ereport(ERROR,
diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c
index 10d230ef431c5deb96161938c3be763899203b3a..290c826a68040d10b2db7b3a1da2543df7f7a789 100644
--- a/src/backend/commands/policy.c
+++ b/src/backend/commands/policy.c
@@ -22,7 +22,7 @@
 #include "catalog/indexing.h"
 #include "catalog/namespace.h"
 #include "catalog/objectaccess.h"
-#include "catalog/pg_rowsecurity.h"
+#include "catalog/pg_policy.h"
 #include "catalog/pg_type.h"
 #include "commands/policy.h"
 #include "miscadmin.h"
@@ -46,8 +46,8 @@
 
 static void RangeVarCallbackForPolicy(const RangeVar *rv,
 				Oid relid, Oid oldrelid, void *arg);
-static char parse_row_security_command(const char *cmd_name);
-static ArrayType* rls_role_list_to_array(List *roles);
+static char parse_policy_command(const char *cmd_name);
+static ArrayType* policy_role_list_to_array(List *roles);
 
 /*
  * Callback to RangeVarGetRelidExtended().
@@ -95,7 +95,7 @@ RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid,
 }
 
 /*
- * parse_row_security_command -
+ * parse_policy_command -
  *   helper function to convert full command strings to their char
  *   representation.
  *
@@ -104,7 +104,7 @@ RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid,
  *
  */
 static char
-parse_row_security_command(const char *cmd_name)
+parse_policy_command(const char *cmd_name)
 {
 	char cmd;
 
@@ -128,7 +128,7 @@ parse_row_security_command(const char *cmd_name)
 }
 
 /*
- * rls_role_list_to_array
+ * policy_role_list_to_array
  *   helper function to convert a list of role names in to an array of
  *   role ids.
  *
@@ -138,7 +138,7 @@ parse_row_security_command(const char *cmd_name)
  * roles - the list of role names to convert.
  */
 static ArrayType *
-rls_role_list_to_array(List *roles)
+policy_role_list_to_array(List *roles)
 {
 	ArrayType  *role_ids;
 	Datum	   *temp_array;
@@ -190,7 +190,7 @@ rls_role_list_to_array(List *roles)
 }
 
 /*
- * Load row-security policy from the catalog, and keep it in
+ * Load row security policy from the catalog, and keep it in
  * the relation cache.
  */
 void
@@ -204,14 +204,14 @@ RelationBuildRowSecurity(Relation relation)
 	MemoryContext		rscxt = NULL;
 	RowSecurityDesc	   *rsdesc = NULL;
 
-	catalog = heap_open(RowSecurityRelationId, AccessShareLock);
+	catalog = heap_open(PolicyRelationId, AccessShareLock);
 
 	ScanKeyInit(&skey,
-				Anum_pg_rowsecurity_rsecrelid,
+				Anum_pg_policy_polrelid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(RelationGetRelid(relation)));
 
-	sscan = systable_beginscan(catalog, RowSecurityRelidPolnameIndexId, true,
+	sscan = systable_beginscan(catalog, PolicyPolrelidPolnameIndexId, true,
 							   NULL, 1, &skey);
 	PG_TRY();
 	{
@@ -221,7 +221,7 @@ RelationBuildRowSecurity(Relation relation)
 		 * default-deny policy is created.
 		 */
 		rscxt = AllocSetContextCreate(CacheMemoryContext,
-									  "Row-security descriptor",
+									  "row security descriptor",
 									  ALLOCSET_SMALL_MINSIZE,
 									  ALLOCSET_SMALL_INITSIZE,
 									  ALLOCSET_SMALL_MAXSIZE);
@@ -229,7 +229,7 @@ RelationBuildRowSecurity(Relation relation)
 		rsdesc->rscxt = rscxt;
 
 		/*
-		 * Loop through the row-level security entries for this relation, if
+		 * Loop through the row level security policies for this relation, if
 		 * any.
 		 */
 		while (HeapTupleIsValid(tuple = systable_getnext(sscan)))
@@ -249,7 +249,7 @@ RelationBuildRowSecurity(Relation relation)
 			oldcxt = MemoryContextSwitchTo(rscxt);
 
 			/* Get policy command */
-			value_datum = heap_getattr(tuple, Anum_pg_rowsecurity_rseccmd,
+			value_datum = heap_getattr(tuple, Anum_pg_policy_polcmd,
 								 RelationGetDescr(catalog), &isnull);
 			if (isnull)
 				cmd_value = 0;
@@ -257,19 +257,19 @@ RelationBuildRowSecurity(Relation relation)
 				cmd_value = DatumGetChar(value_datum);
 
 			/* Get policy name */
-			value_datum = heap_getattr(tuple, Anum_pg_rowsecurity_rsecpolname,
+			value_datum = heap_getattr(tuple, Anum_pg_policy_polname,
 										RelationGetDescr(catalog), &isnull);
 			Assert(!isnull);
 			policy_name_value = DatumGetCString(value_datum);
 
 			/* Get policy roles */
-			value_datum = heap_getattr(tuple, Anum_pg_rowsecurity_rsecroles,
+			value_datum = heap_getattr(tuple, Anum_pg_policy_polroles,
 										RelationGetDescr(catalog), &isnull);
 			Assert(!isnull);
 			roles = DatumGetArrayTypeP(value_datum);
 
 			/* Get policy qual */
-			value_datum = heap_getattr(tuple, Anum_pg_rowsecurity_rsecqual,
+			value_datum = heap_getattr(tuple, Anum_pg_policy_polqual,
 								 RelationGetDescr(catalog), &isnull);
 			if (!isnull)
 			{
@@ -280,7 +280,7 @@ RelationBuildRowSecurity(Relation relation)
 				qual_expr = NULL;
 
 			/* Get WITH CHECK qual */
-			value_datum = heap_getattr(tuple, Anum_pg_rowsecurity_rsecwithcheck,
+			value_datum = heap_getattr(tuple, Anum_pg_policy_polwithcheck,
 										RelationGetDescr(catalog), &isnull);
 
 			if (!isnull)
@@ -295,7 +295,7 @@ RelationBuildRowSecurity(Relation relation)
 
 			policy = palloc0(sizeof(RowSecurityPolicy));
 			policy->policy_name = policy_name_value;
-			policy->rsecid = policy_id;
+			policy->policy_id = policy_id;
 			policy->cmd = cmd_value;
 			policy->roles = roles;
 			policy->qual = copyObject(qual_expr);
@@ -317,7 +317,7 @@ RelationBuildRowSecurity(Relation relation)
 		/*
 		 * Check if no policies were added
 		 *
-		 * If no policies exist in pg_rowsecurity for this relation, then we
+		 * If no policies exist in pg_policy for this relation, then we
 		 * need to create a single default-deny policy.  We use InvalidOid for
 		 * the Oid to indicate that this is the default-deny policy (we may
 		 * decide to ignore the default policy if an extension adds policies).
@@ -333,7 +333,7 @@ RelationBuildRowSecurity(Relation relation)
 
 			policy = palloc0(sizeof(RowSecurityPolicy));
 			policy->policy_name = pstrdup("default-deny policy");
-			policy->rsecid = InvalidOid;
+			policy->policy_id = InvalidOid;
 			policy->cmd = '\0';
 			policy->roles = construct_array(&role, 1, OIDOID, sizeof(Oid), true,
 											'i');
@@ -364,22 +364,22 @@ RelationBuildRowSecurity(Relation relation)
 
 /*
  * RemovePolicyById -
- *   remove a row-security policy by its OID.  If a policy does not exist with
- *   the provided oid, then an error is raised.
+ *   remove a policy by its OID.  If a policy does not exist with the provided
+ *   oid, then an error is raised.
  *
- * policy_id - the oid of the row-security policy.
+ * policy_id - the oid of the policy.
  */
 void
 RemovePolicyById(Oid policy_id)
 {
-	Relation 	pg_rowsecurity_rel;
+	Relation 	pg_policy_rel;
 	SysScanDesc sscan;
 	ScanKeyData skey[1];
 	HeapTuple	tuple;
 	Oid			relid;
 	Relation	rel;
 
-	pg_rowsecurity_rel = heap_open(RowSecurityRelationId, RowExclusiveLock);
+	pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock);
 
 	/*
 	 * Find the policy to delete.
@@ -389,19 +389,19 @@ RemovePolicyById(Oid policy_id)
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(policy_id));
 
-	sscan = systable_beginscan(pg_rowsecurity_rel, RowSecurityOidIndexId, true,
+	sscan = systable_beginscan(pg_policy_rel, PolicyOidIndexId, true,
 							   NULL, 1, skey);
 
 	tuple = systable_getnext(sscan);
 
 	/* If the policy exists, then remove it, otherwise raise an error. */
 	if (!HeapTupleIsValid(tuple))
-		elog(ERROR, "could not find tuple for row-security %u", policy_id);
+		elog(ERROR, "could not find tuple for policy %u", policy_id);
 
 	/*
 	 * Open and exclusive-lock the relation the policy belong to.
 	 */
-	relid = ((Form_pg_rowsecurity) GETSTRUCT(tuple))->rsecrelid;
+	relid = ((Form_pg_policy) GETSTRUCT(tuple))->polrelid;
 
 	rel = heap_open(relid, AccessExclusiveLock);
 	if (rel->rd_rel->relkind != RELKIND_RELATION)
@@ -416,7 +416,7 @@ RemovePolicyById(Oid policy_id)
 				 errmsg("permission denied: \"%s\" is a system catalog",
 						RelationGetRelationName(rel))));
 
-	simple_heap_delete(pg_rowsecurity_rel, &tuple->t_self);
+	simple_heap_delete(pg_policy_rel, &tuple->t_self);
 
 	systable_endscan(sscan);
 	heap_close(rel, AccessExclusiveLock);
@@ -424,9 +424,8 @@ RemovePolicyById(Oid policy_id)
 	/*
 	 * Note that, unlike some of the other flags in pg_class, relrowsecurity
 	 * is not just an indication of if policies exist.  When relrowsecurity
-	 * is set (which can be done directly by the user or indirectly by creating
-	 * a policy on the table), then all access to the relation must be through
-	 * a policy.  If no policy is defined for the relation then a default-deny
+	 * is set by a user, then all access to the relation must be through a
+	 * policy.  If no policy is defined for the relation then a default-deny
 	 * policy is created and all records are filtered (except for queries from
 	 * the owner).
 	 */
@@ -434,7 +433,7 @@ RemovePolicyById(Oid policy_id)
 	CacheInvalidateRelcache(rel);
 
 	/* Clean up */
-	heap_close(pg_rowsecurity_rel, RowExclusiveLock);
+	heap_close(pg_policy_rel, RowExclusiveLock);
 }
 
 /*
@@ -446,11 +445,11 @@ RemovePolicyById(Oid policy_id)
 Oid
 CreatePolicy(CreatePolicyStmt *stmt)
 {
-	Relation		pg_rowsecurity_rel;
-	Oid				rowsec_id;
+	Relation		pg_policy_rel;
+	Oid				policy_id;
 	Relation		target_table;
 	Oid				table_id;
-	char			rseccmd;
+	char			polcmd;
 	ArrayType	   *role_ids;
 	ParseState	   *qual_pstate;
 	ParseState	   *with_check_pstate;
@@ -459,19 +458,19 @@ CreatePolicy(CreatePolicyStmt *stmt)
 	Node		   *with_check_qual;
 	ScanKeyData		skey[2];
 	SysScanDesc		sscan;
-	HeapTuple		rsec_tuple;
-	Datum			values[Natts_pg_rowsecurity];
-	bool			isnull[Natts_pg_rowsecurity];
+	HeapTuple		policy_tuple;
+	Datum			values[Natts_pg_policy];
+	bool			isnull[Natts_pg_policy];
 	ObjectAddress	target;
 	ObjectAddress	myself;
 
 	/* Parse command */
-	rseccmd = parse_row_security_command(stmt->cmd);
+	polcmd = parse_policy_command(stmt->cmd);
 
 	/*
 	 * If the command is SELECT or DELETE then WITH CHECK should be NULL.
 	 */
-	if ((rseccmd == ACL_SELECT_CHR || rseccmd == ACL_DELETE_CHR)
+	if ((polcmd == ACL_SELECT_CHR || polcmd == ACL_DELETE_CHR)
 		&& stmt->with_check != NULL)
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
@@ -481,14 +480,14 @@ CreatePolicy(CreatePolicyStmt *stmt)
 	 * If the command is INSERT then WITH CHECK should be the only expression
 	 * provided.
 	 */
-	if (rseccmd == ACL_INSERT_CHR && stmt->qual != NULL)
+	if (polcmd == ACL_INSERT_CHR && stmt->qual != NULL)
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("only WITH CHECK expression allowed for INSERT")));
 
 
 	/* Collect role ids */
-	role_ids = rls_role_list_to_array(stmt->roles);
+	role_ids = policy_role_list_to_array(stmt->roles);
 
 	/* Parse the supplied clause */
 	qual_pstate = make_parsestate(NULL);
@@ -527,74 +526,74 @@ CreatePolicy(CreatePolicyStmt *stmt)
 								EXPR_KIND_WHERE,
 								"POLICY");
 
-	/* Open pg_rowsecurity catalog */
-	pg_rowsecurity_rel = heap_open(RowSecurityRelationId, RowExclusiveLock);
+	/* Open pg_policy catalog */
+	pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock);
 
-	/* Set key - row security relation id. */
+	/* Set key - policy's relation id. */
 	ScanKeyInit(&skey[0],
-				Anum_pg_rowsecurity_rsecrelid,
+				Anum_pg_policy_polrelid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(table_id));
 
-	/* Set key - row security policy name. */
+	/* Set key - policy's name. */
 	ScanKeyInit(&skey[1],
-				Anum_pg_rowsecurity_rsecpolname,
+				Anum_pg_policy_polname,
 				BTEqualStrategyNumber, F_NAMEEQ,
 				CStringGetDatum(stmt->policy_name));
 
-	sscan = systable_beginscan(pg_rowsecurity_rel,
-							   RowSecurityRelidPolnameIndexId, true, NULL, 2,
+	sscan = systable_beginscan(pg_policy_rel,
+							   PolicyPolrelidPolnameIndexId, true, NULL, 2,
 							   skey);
 
-	rsec_tuple = systable_getnext(sscan);
+	policy_tuple = systable_getnext(sscan);
 
 	/* Complain if the policy name already exists for the table */
-	if (HeapTupleIsValid(rsec_tuple))
+	if (HeapTupleIsValid(policy_tuple))
 		ereport(ERROR,
 				(errcode(ERRCODE_DUPLICATE_OBJECT),
 				 errmsg("policy \"%s\" for relation \"%s\" already exists",
 				 stmt->policy_name, RelationGetRelationName(target_table))));
 
-	values[Anum_pg_rowsecurity_rsecrelid - 1] = ObjectIdGetDatum(table_id);
-	values[Anum_pg_rowsecurity_rsecpolname - 1]
+	values[Anum_pg_policy_polrelid - 1] = ObjectIdGetDatum(table_id);
+	values[Anum_pg_policy_polname - 1]
 		= DirectFunctionCall1(namein, CStringGetDatum(stmt->policy_name));
 
-	if (rseccmd)
-		values[Anum_pg_rowsecurity_rseccmd - 1] = CharGetDatum(rseccmd);
+	if (polcmd)
+		values[Anum_pg_policy_polcmd - 1] = CharGetDatum(polcmd);
 	else
-		isnull[Anum_pg_rowsecurity_rseccmd - 1] = true;
+		isnull[Anum_pg_policy_polcmd - 1] = true;
 
-	values[Anum_pg_rowsecurity_rsecroles - 1] = PointerGetDatum(role_ids);
+	values[Anum_pg_policy_polroles - 1] = PointerGetDatum(role_ids);
 
 	/* Add qual if present. */
 	if (qual)
-		values[Anum_pg_rowsecurity_rsecqual - 1]
+		values[Anum_pg_policy_polqual - 1]
 			= CStringGetTextDatum(nodeToString(qual));
 	else
-		isnull[Anum_pg_rowsecurity_rsecqual - 1] = true;
+		isnull[Anum_pg_policy_polqual - 1] = true;
 
 	/* Add WITH CHECK qual if present */
 	if (with_check_qual)
-		values[Anum_pg_rowsecurity_rsecwithcheck - 1]
+		values[Anum_pg_policy_polwithcheck - 1]
 			= CStringGetTextDatum(nodeToString(with_check_qual));
 	else
-		isnull[Anum_pg_rowsecurity_rsecwithcheck - 1] = true;
+		isnull[Anum_pg_policy_polwithcheck - 1] = true;
 
-	rsec_tuple = heap_form_tuple(RelationGetDescr(pg_rowsecurity_rel), values,
-								 isnull);
+	policy_tuple = heap_form_tuple(RelationGetDescr(pg_policy_rel), values,
+								   isnull);
 
-	rowsec_id = simple_heap_insert(pg_rowsecurity_rel, rsec_tuple);
+	policy_id = simple_heap_insert(pg_policy_rel, policy_tuple);
 
 	/* Update Indexes */
-	CatalogUpdateIndexes(pg_rowsecurity_rel, rsec_tuple);
+	CatalogUpdateIndexes(pg_policy_rel, policy_tuple);
 
 	/* Record Dependencies */
 	target.classId = RelationRelationId;
 	target.objectId = table_id;
 	target.objectSubId = 0;
 
-	myself.classId = RowSecurityRelationId;
-	myself.objectId = rowsec_id;
+	myself.classId = PolicyRelationId;
+	myself.objectId = policy_id;
 	myself.objectSubId = 0;
 
 	recordDependencyOn(&myself, &target, DEPENDENCY_AUTO);
@@ -609,14 +608,14 @@ CreatePolicy(CreatePolicyStmt *stmt)
 	CacheInvalidateRelcache(target_table);
 
 	/* Clean up. */
-	heap_freetuple(rsec_tuple);
+	heap_freetuple(policy_tuple);
 	free_parsestate(qual_pstate);
 	free_parsestate(with_check_pstate);
 	systable_endscan(sscan);
 	relation_close(target_table, NoLock);
-	heap_close(pg_rowsecurity_rel, RowExclusiveLock);
+	heap_close(pg_policy_rel, RowExclusiveLock);
 
-	return rowsec_id;
+	return policy_id;
 }
 
 /*
@@ -628,8 +627,8 @@ CreatePolicy(CreatePolicyStmt *stmt)
 Oid
 AlterPolicy(AlterPolicyStmt *stmt)
 {
-	Relation		pg_rowsecurity_rel;
-	Oid				rowsec_id;
+	Relation		pg_policy_rel;
+	Oid				policy_id;
 	Relation		target_table;
 	Oid				table_id;
 	ArrayType	   *role_ids = NULL;
@@ -639,20 +638,20 @@ AlterPolicy(AlterPolicyStmt *stmt)
 	Node		   *with_check_qual = NULL;
 	ScanKeyData		skey[2];
 	SysScanDesc		sscan;
-	HeapTuple		rsec_tuple;
+	HeapTuple		policy_tuple;
 	HeapTuple		new_tuple;
-	Datum			values[Natts_pg_rowsecurity];
-	bool			isnull[Natts_pg_rowsecurity];
-	bool			replaces[Natts_pg_rowsecurity];
+	Datum			values[Natts_pg_policy];
+	bool			isnull[Natts_pg_policy];
+	bool			replaces[Natts_pg_policy];
 	ObjectAddress	target;
 	ObjectAddress	myself;
 	Datum			cmd_datum;
-	char			rseccmd;
-	bool			rseccmd_isnull;
+	char			polcmd;
+	bool			polcmd_isnull;
 
 	/* Parse role_ids */
 	if (stmt->roles != NULL)
-		role_ids = rls_role_list_to_array(stmt->roles);
+		role_ids = policy_role_list_to_array(stmt->roles);
 
 	/* Get id of table.  Also handles permissions checks. */
 	table_id = RangeVarGetRelidExtended(stmt->table, AccessExclusiveLock,
@@ -662,7 +661,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
 
 	target_table = relation_open(table_id, NoLock);
 
-	/* Parse the row-security clause */
+	/* Parse the using policy clause */
 	if (stmt->qual)
 	{
 		RangeTblEntry  *rte;
@@ -675,13 +674,13 @@ AlterPolicy(AlterPolicyStmt *stmt)
 
 		qual = transformWhereClause(qual_pstate, copyObject(stmt->qual),
 									EXPR_KIND_WHERE,
-									"ROW SECURITY");
+									"POLICY");
 
 		qual_parse_rtable = qual_pstate->p_rtable;
 		free_parsestate(qual_pstate);
 	}
 
-	/* Parse the with-check row-security clause */
+	/* Parse the with-check policy clause */
 	if (stmt->with_check)
 	{
 		RangeTblEntry  *rte;
@@ -695,7 +694,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
 		with_check_qual = transformWhereClause(with_check_pstate,
 											   copyObject(stmt->with_check),
 											   EXPR_KIND_WHERE,
-											   "ROW SECURITY");
+											   "POLICY");
 
 		with_check_parse_rtable = with_check_pstate->p_rtable;
 		free_parsestate(with_check_pstate);
@@ -707,28 +706,28 @@ AlterPolicy(AlterPolicyStmt *stmt)
 	memset(isnull,   0, sizeof(isnull));
 
 	/* Find policy to update. */
-	pg_rowsecurity_rel = heap_open(RowSecurityRelationId, RowExclusiveLock);
+	pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock);
 
-	/* Set key - row security relation id. */
+	/* Set key - policy's relation id. */
 	ScanKeyInit(&skey[0],
-				Anum_pg_rowsecurity_rsecrelid,
+				Anum_pg_policy_polrelid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(table_id));
 
-	/* Set key - row security policy name. */
+	/* Set key - policy's name. */
 	ScanKeyInit(&skey[1],
-				Anum_pg_rowsecurity_rsecpolname,
+				Anum_pg_policy_polname,
 				BTEqualStrategyNumber, F_NAMEEQ,
 				CStringGetDatum(stmt->policy_name));
 
-	sscan = systable_beginscan(pg_rowsecurity_rel,
-							   RowSecurityRelidPolnameIndexId, true, NULL, 2,
+	sscan = systable_beginscan(pg_policy_rel,
+							   PolicyPolrelidPolnameIndexId, true, NULL, 2,
 							   skey);
 
-	rsec_tuple = systable_getnext(sscan);
+	policy_tuple = systable_getnext(sscan);
 
 	/* Check that the policy is found, raise an error if not. */
-	if (!HeapTupleIsValid(rsec_tuple))
+	if (!HeapTupleIsValid(policy_tuple))
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("policy \"%s\" on table \"%s\" does not exist",
@@ -736,18 +735,18 @@ AlterPolicy(AlterPolicyStmt *stmt)
 						RelationGetRelationName(target_table))));
 
 	/* Get policy command */
-	cmd_datum = heap_getattr(rsec_tuple, Anum_pg_rowsecurity_rseccmd,
-							 RelationGetDescr(pg_rowsecurity_rel),
-							 &rseccmd_isnull);
-	if (rseccmd_isnull)
-		rseccmd = 0;
+	cmd_datum = heap_getattr(policy_tuple, Anum_pg_policy_polcmd,
+							 RelationGetDescr(pg_policy_rel),
+							 &polcmd_isnull);
+	if (polcmd_isnull)
+		polcmd = 0;
 	else
-		rseccmd = DatumGetChar(cmd_datum);
+		polcmd = DatumGetChar(cmd_datum);
 
 	/*
 	 * If the command is SELECT or DELETE then WITH CHECK should be NULL.
 	 */
-	if ((rseccmd == ACL_SELECT_CHR || rseccmd == ACL_DELETE_CHR)
+	if ((polcmd == ACL_SELECT_CHR || polcmd == ACL_DELETE_CHR)
 		&& stmt->with_check != NULL)
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
@@ -757,52 +756,52 @@ AlterPolicy(AlterPolicyStmt *stmt)
 	 * If the command is INSERT then WITH CHECK should be the only
 	 * expression provided.
 	 */
-	if ((rseccmd == ACL_INSERT_CHR)
+	if ((polcmd == ACL_INSERT_CHR)
 		&& stmt->qual != NULL)
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("only WITH CHECK expression allowed for INSERT")));
 
-	rowsec_id = HeapTupleGetOid(rsec_tuple);
+	policy_id = HeapTupleGetOid(policy_tuple);
 
 	if (role_ids != NULL)
 	{
-		replaces[Anum_pg_rowsecurity_rsecroles - 1] = true;
-		values[Anum_pg_rowsecurity_rsecroles - 1] = PointerGetDatum(role_ids);
+		replaces[Anum_pg_policy_polroles - 1] = true;
+		values[Anum_pg_policy_polroles - 1] = PointerGetDatum(role_ids);
 	}
 
 	if (qual != NULL)
 	{
-		replaces[Anum_pg_rowsecurity_rsecqual - 1] = true;
-		values[Anum_pg_rowsecurity_rsecqual - 1]
+		replaces[Anum_pg_policy_polqual - 1] = true;
+		values[Anum_pg_policy_polqual - 1]
 			= CStringGetTextDatum(nodeToString(qual));
 	}
 
 	if (with_check_qual != NULL)
 	{
-		replaces[Anum_pg_rowsecurity_rsecwithcheck - 1] = true;
-		values[Anum_pg_rowsecurity_rsecwithcheck - 1]
+		replaces[Anum_pg_policy_polwithcheck - 1] = true;
+		values[Anum_pg_policy_polwithcheck - 1]
 			= CStringGetTextDatum(nodeToString(with_check_qual));
 	}
 
-	new_tuple = heap_modify_tuple(rsec_tuple,
-								  RelationGetDescr(pg_rowsecurity_rel),
+	new_tuple = heap_modify_tuple(policy_tuple,
+								  RelationGetDescr(pg_policy_rel),
 								  values, isnull, replaces);
-	simple_heap_update(pg_rowsecurity_rel, &new_tuple->t_self, new_tuple);
+	simple_heap_update(pg_policy_rel, &new_tuple->t_self, new_tuple);
 
 	/* Update Catalog Indexes */
-	CatalogUpdateIndexes(pg_rowsecurity_rel, new_tuple);
+	CatalogUpdateIndexes(pg_policy_rel, new_tuple);
 
 	/* Update Dependencies. */
-	deleteDependencyRecordsFor(RowSecurityRelationId, rowsec_id, false);
+	deleteDependencyRecordsFor(PolicyRelationId, policy_id, false);
 
 	/* Record Dependencies */
 	target.classId = RelationRelationId;
 	target.objectId = table_id;
 	target.objectSubId = 0;
 
-	myself.classId = RowSecurityRelationId;
-	myself.objectId = rowsec_id;
+	myself.classId = PolicyRelationId;
+	myself.objectId = policy_id;
 	myself.objectSubId = 0;
 
 	recordDependencyOn(&myself, &target, DEPENDENCY_AUTO);
@@ -820,9 +819,9 @@ AlterPolicy(AlterPolicyStmt *stmt)
 	/* Clean up. */
 	systable_endscan(sscan);
 	relation_close(target_table, NoLock);
-	heap_close(pg_rowsecurity_rel, RowExclusiveLock);
+	heap_close(pg_policy_rel, RowExclusiveLock);
 
-	return rowsec_id;
+	return policy_id;
 }
 
 /*
@@ -832,13 +831,13 @@ AlterPolicy(AlterPolicyStmt *stmt)
 Oid
 rename_policy(RenameStmt *stmt)
 {
-	Relation		pg_rowsecurity_rel;
+	Relation		pg_policy_rel;
 	Relation		target_table;
 	Oid				table_id;
 	Oid				opoloid;
 	ScanKeyData		skey[2];
 	SysScanDesc		sscan;
-	HeapTuple		rsec_tuple;
+	HeapTuple		policy_tuple;
 
 	/* Get id of table.  Also handles permissions checks. */
 	table_id = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
@@ -848,74 +847,74 @@ rename_policy(RenameStmt *stmt)
 
 	target_table = relation_open(table_id, NoLock);
 
-	pg_rowsecurity_rel = heap_open(RowSecurityRelationId, RowExclusiveLock);
+	pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock);
 
 	/* First pass -- check for conflict */
 
-	/* Add key - row security relation id. */
+	/* Add key - policy's relation id. */
 	ScanKeyInit(&skey[0],
-				Anum_pg_rowsecurity_rsecrelid,
+				Anum_pg_policy_polrelid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(table_id));
 
-	/* Add key - row security policy name. */
+	/* Add key - policy's name. */
 	ScanKeyInit(&skey[1],
-				Anum_pg_rowsecurity_rsecpolname,
+				Anum_pg_policy_polname,
 				BTEqualStrategyNumber, F_NAMEEQ,
 				CStringGetDatum(stmt->newname));
 
-	sscan = systable_beginscan(pg_rowsecurity_rel,
-							   RowSecurityRelidPolnameIndexId, true, NULL, 2,
+	sscan = systable_beginscan(pg_policy_rel,
+							   PolicyPolrelidPolnameIndexId, true, NULL, 2,
 							   skey);
 
 	if (HeapTupleIsValid(systable_getnext(sscan)))
 		ereport(ERROR,
 				(errcode(ERRCODE_DUPLICATE_OBJECT),
-				 errmsg("row-policy \"%s\" for table \"%s\" already exists",
+				 errmsg("policy \"%s\" for table \"%s\" already exists",
 						stmt->newname, RelationGetRelationName(target_table))));
 
 	systable_endscan(sscan);
 
 	/* Second pass -- find existing policy and update */
-	/* Add key - row security relation id. */
+	/* Add key - policy's relation id. */
 	ScanKeyInit(&skey[0],
-				Anum_pg_rowsecurity_rsecrelid,
+				Anum_pg_policy_polrelid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(table_id));
 
-	/* Add key - row security policy name. */
+	/* Add key - policy's name. */
 	ScanKeyInit(&skey[1],
-				Anum_pg_rowsecurity_rsecpolname,
+				Anum_pg_policy_polname,
 				BTEqualStrategyNumber, F_NAMEEQ,
 				CStringGetDatum(stmt->subname));
 
-	sscan = systable_beginscan(pg_rowsecurity_rel,
-							   RowSecurityRelidPolnameIndexId, true, NULL, 2,
+	sscan = systable_beginscan(pg_policy_rel,
+							   PolicyPolrelidPolnameIndexId, true, NULL, 2,
 							   skey);
 
-	rsec_tuple = systable_getnext(sscan);
+	policy_tuple = systable_getnext(sscan);
 
 	/* Complain if we did not find the policy */
-	if (!HeapTupleIsValid(rsec_tuple))
+	if (!HeapTupleIsValid(policy_tuple))
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("row-policy \"%s\" for table \"%s\" does not exist",
+				 errmsg("policy \"%s\" for table \"%s\" does not exist",
 						stmt->subname, RelationGetRelationName(target_table))));
 
-	opoloid = HeapTupleGetOid(rsec_tuple);
+	opoloid = HeapTupleGetOid(policy_tuple);
 
-	rsec_tuple = heap_copytuple(rsec_tuple);
+	policy_tuple = heap_copytuple(policy_tuple);
 
-	namestrcpy(&((Form_pg_rowsecurity) GETSTRUCT(rsec_tuple))->rsecpolname,
+	namestrcpy(&((Form_pg_policy) GETSTRUCT(policy_tuple))->polname,
 			   stmt->newname);
 
-	simple_heap_update(pg_rowsecurity_rel, &rsec_tuple->t_self, rsec_tuple);
+	simple_heap_update(pg_policy_rel, &policy_tuple->t_self, policy_tuple);
 
 	/* keep system catalog indexes current */
-	CatalogUpdateIndexes(pg_rowsecurity_rel, rsec_tuple);
+	CatalogUpdateIndexes(pg_policy_rel, policy_tuple);
 
-	InvokeObjectPostAlterHook(RowSecurityRelationId,
-							  HeapTupleGetOid(rsec_tuple), 0);
+	InvokeObjectPostAlterHook(PolicyRelationId,
+							  HeapTupleGetOid(policy_tuple), 0);
 
 	/*
 	 * Invalidate relation's relcache entry so that other backends (and
@@ -926,7 +925,7 @@ rename_policy(RenameStmt *stmt)
 
 	/* Clean up. */
 	systable_endscan(sscan);
-	heap_close(pg_rowsecurity_rel, RowExclusiveLock);
+	heap_close(pg_policy_rel, RowExclusiveLock);
 	relation_close(target_table, NoLock);
 
 	return opoloid;
@@ -941,33 +940,33 @@ rename_policy(RenameStmt *stmt)
 Oid
 get_relation_policy_oid(Oid relid, const char *policy_name, bool missing_ok)
 {
-	Relation		pg_rowsecurity_rel;
+	Relation		pg_policy_rel;
 	ScanKeyData		skey[2];
 	SysScanDesc		sscan;
-	HeapTuple		rsec_tuple;
+	HeapTuple		policy_tuple;
 	Oid				policy_oid;
 
-	pg_rowsecurity_rel = heap_open(RowSecurityRelationId, AccessShareLock);
+	pg_policy_rel = heap_open(PolicyRelationId, AccessShareLock);
 
-	/* Add key - row security relation id. */
+	/* Add key - policy's relation id. */
 	ScanKeyInit(&skey[0],
-				Anum_pg_rowsecurity_rsecrelid,
+				Anum_pg_policy_polrelid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(relid));
 
-	/* Add key - row security policy name. */
+	/* Add key - policy's name. */
 	ScanKeyInit(&skey[1],
-				Anum_pg_rowsecurity_rsecpolname,
+				Anum_pg_policy_polname,
 				BTEqualStrategyNumber, F_NAMEEQ,
 				CStringGetDatum(policy_name));
 
-	sscan = systable_beginscan(pg_rowsecurity_rel,
-							   RowSecurityRelidPolnameIndexId, true, NULL, 2,
+	sscan = systable_beginscan(pg_policy_rel,
+							   PolicyPolrelidPolnameIndexId, true, NULL, 2,
 							   skey);
 
-	rsec_tuple = systable_getnext(sscan);
+	policy_tuple = systable_getnext(sscan);
 
-	if (!HeapTupleIsValid(rsec_tuple))
+	if (!HeapTupleIsValid(policy_tuple))
 	{
 		if (!missing_ok)
 			ereport(ERROR,
@@ -978,11 +977,11 @@ get_relation_policy_oid(Oid relid, const char *policy_name, bool missing_ok)
 		policy_oid = InvalidOid;
 	}
 	else
-		policy_oid = HeapTupleGetOid(rsec_tuple);
+		policy_oid = HeapTupleGetOid(policy_tuple);
 
 	/* Clean up. */
 	systable_endscan(sscan);
-	heap_close(pg_rowsecurity_rel, AccessShareLock);
+	heap_close(pg_policy_rel, AccessShareLock);
 
 	return policy_oid;
 }
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 56294552e715c8bb1516b7055e2c9c0b19355dba..2333e1bed926bba45664496a2e91ae4444507719 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -37,7 +37,6 @@
 #include "catalog/pg_inherits_fn.h"
 #include "catalog/pg_namespace.h"
 #include "catalog/pg_opclass.h"
-#include "catalog/pg_rowsecurity.h"
 #include "catalog/pg_tablespace.h"
 #include "catalog/pg_trigger.h"
 #include "catalog/pg_type.h"
@@ -7986,6 +7985,24 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
 								   colName)));
 				break;
 
+			case OCLASS_POLICY:
+
+				/*
+				 * A policy can depend on a column because the column is
+				 * specified in the policy's USING or WITH CHECK qual
+				 * expressions.  It might be possible to rewrite and recheck
+				 * the policy expression, but punt for now.  It's certainly
+				 * easy enough to remove and recreate the policy; still,
+				 * FIXME someday.
+				 */
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("cannot alter type of a column used in a policy definition"),
+						 errdetail("%s depends on column \"%s\"",
+								   getObjectDescription(&foundObject),
+								   colName)));
+				break;
+
 			case OCLASS_DEFAULT:
 
 				/*
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index a753b2070088fcff5aaf1d8e61b150f56a2ddd34..c499486f01652bf25fff0b47a2bb4611fd8ff5c0 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -502,7 +502,7 @@ ExecutorRewind(QueryDesc *queryDesc)
  * Returns true if permissions are adequate.  Otherwise, throws an appropriate
  * error if ereport_on_violation is true, or simply returns false otherwise.
  *
- * Note that this does NOT address row-level security policies (aka: RLS).  If
+ * Note that this does NOT address row level security policies (aka: RLS).  If
  * rows will be returned to the user as a result of this permission check
  * passing, then RLS also needs to be consulted (and check_enable_rls()).
  *
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index c97355e8fda8bacf5245f3e958b04d82e7f5621e..25f30676f0258e32bfa34378a73dbfab624754e2 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -1171,7 +1171,7 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
 
 	/*
 	 * If the subquery has the "security_barrier" flag, it means the subquery
-	 * originated from a view that must enforce row-level security.  Then we
+	 * originated from a view that must enforce row level security.  Then we
 	 * must not push down quals that contain leaky functions.  (Ideally this
 	 * would be checked inside subquery_is_pushdown_safe, but since we don't
 	 * currently pass the RTE to that function, we must do it here.)
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index fb74d6bf1f41df08ce52b25622320e2710dc3aed..f752ecc16a58dc2a289198715e6965f98815ea89 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -177,7 +177,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
 	glob->lastPHId = 0;
 	glob->lastRowMarkId = 0;
 	glob->transientPlan = false;
-	glob->has_rls = false;
+	glob->hasRowSecurity = false;
 
 	/* Determine what fraction of the plan is likely to be scanned */
 	if (cursorOptions & CURSOR_OPT_FAST_PLAN)
@@ -255,7 +255,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
 	result->relationOids = glob->relationOids;
 	result->invalItems = glob->invalItems;
 	result->nParamExec = glob->nParamExec;
-	result->has_rls = glob->has_rls;
+	result->hasRowSecurity = glob->hasRowSecurity;
 
 	return result;
 }
@@ -1208,7 +1208,7 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
 		 * This may add new security barrier subquery RTEs to the rangetable.
 		 */
 		expand_security_quals(root, tlist);
-		root->glob->has_rls = parse->hasRowSecurity;
+		root->glob->hasRowSecurity = parse->hasRowSecurity;
 
 		/*
 		 * Locate any window functions in the tlist.  (We don't need to look
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index e630d0b6d81fc0219f5ebf764155560006e9b2e7..4d3fbca5969d8e4e956b27e53d6e640234883acd 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -2109,7 +2109,7 @@ extract_query_dependencies(Node *query,
 	glob.type = T_PlannerGlobal;
 	glob.relationOids = NIL;
 	glob.invalItems = NIL;
-	glob.has_rls = false;
+	glob.hasRowSecurity = false;
 
 	MemSet(&root, 0, sizeof(root));
 	root.type = T_PlannerInfo;
@@ -2119,7 +2119,7 @@ extract_query_dependencies(Node *query,
 
 	*relationOids = glob.relationOids;
 	*invalItems = glob.invalItems;
-	*hasRowSecurity = glob.has_rls;
+	*hasRowSecurity = glob.hasRowSecurity;
 }
 
 static bool
@@ -2135,8 +2135,8 @@ extract_query_dependencies_walker(Node *node, PlannerInfo *context)
 		Query	   *query = (Query *) node;
 		ListCell   *lc;
 
-		/* Collect row-security information */
-		context->glob->has_rls = query->hasRowSecurity;
+		/* Collect row security information */
+		context->glob->hasRowSecurity = query->hasRowSecurity;
 
 		if (query->commandType == CMD_UTILITY)
 		{
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index bd180e7e87ba941b30a02ddbbc5017533c7584b5..7e48958ae85cdd3d8dd0aacbe1b8ea523f2d1031 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -5535,7 +5535,7 @@ opt_restart_seqs:
  *	COMMENT ON [ [ CONVERSION | COLLATION | DATABASE | DOMAIN |
  *                 EXTENSION | EVENT TRIGGER | FOREIGN DATA WRAPPER |
  *                 FOREIGN TABLE | INDEX | [PROCEDURAL] LANGUAGE |
- *                 MATERIALIZED VIEW | ROLE | SCHEMA | SEQUENCE |
+ *                 MATERIALIZED VIEW | POLICY | ROLE | SCHEMA | SEQUENCE |
  *                 SERVER | TABLE | TABLESPACE |
  *                 TEXT SEARCH CONFIGURATION | TEXT SEARCH DICTIONARY |
  *                 TEXT SEARCH PARSER | TEXT SEARCH TEMPLATE | TYPE |
@@ -5601,6 +5601,15 @@ CommentStmt:
 					n->comment = $8;
 					$$ = (Node *) n;
 				}
+			| COMMENT ON POLICY name ON any_name IS comment_text
+				{
+					CommentStmt *n = makeNode(CommentStmt);
+					n->objtype = OBJECT_POLICY;
+					n->objname = lappend($6, makeString($4));
+					n->objargs = NIL;
+					n->comment = $8;
+					$$ = (Node *) n;
+				}
 			| COMMENT ON RULE name ON any_name IS comment_text
 				{
 					CommentStmt *n = makeNode(CommentStmt);
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index e7021509017dfd13ca6fb02d72da1a88dcd49157..ad983c7158b3ca7071be222fd661d777b0b90f99 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -1715,7 +1715,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown)
 			}
 		}
 		/*
-		 * If the RTE has row-security quals, apply them and recurse into the
+		 * If the RTE has row security quals, apply them and recurse into the
 		 * securityQuals.
 		 */
 		if (prepend_row_security_policies(parsetree, rte, rt_index))
@@ -1727,7 +1727,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown)
 			if (list_member_oid(activeRIRs, RelationGetRelid(rel)))
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-							 errmsg("infinite recursion detected in row-security policy for relation \"%s\"",
+							 errmsg("infinite recursion detected in policy for relation \"%s\"",
 									RelationGetRelationName(rel))));
 
 			/*
diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c
index 66c358cdec9b841fb53d9b99885d628acf7ef384..6c232dcf9ae3cf3d58dd290c2dc6771661ef48bd 100644
--- a/src/backend/rewrite/rowsecurity.c
+++ b/src/backend/rewrite/rowsecurity.c
@@ -1,6 +1,6 @@
 /*
  * rewrite/rowsecurity.c
- *    Routines to support policies for row-level security.
+ *    Routines to support policies for row level security (aka RLS).
  *
  * Policies in PostgreSQL provide a mechanism to limit what records are
  * returned to a user and what records a user is permitted to add to a table.
@@ -38,7 +38,7 @@
 #include "access/sysattr.h"
 #include "catalog/pg_class.h"
 #include "catalog/pg_inherits_fn.h"
-#include "catalog/pg_rowsecurity.h"
+#include "catalog/pg_policy.h"
 #include "catalog/pg_type.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
@@ -72,8 +72,8 @@ static bool check_role_for_policy(ArrayType *policy_roles, Oid user_id);
 row_security_policy_hook_type	row_security_policy_hook = NULL;
 
 /*
- * Check the given RTE to see whether it's already had row-security quals
- * expanded and, if not, prepend any row-security rules from built-in or
+ * Check the given RTE to see whether it's already had row security quals
+ * expanded and, if not, prepend any row security rules from built-in or
  * plug-in sources to the securityQuals. The security quals are rewritten (for
  * view expansion, etc) before being added to the RTE.
  *
@@ -154,14 +154,14 @@ prepend_row_security_policies(Query* root, RangeTblEntry* rte, int rt_index)
 	/*
 	 * Check if this is only the default-deny policy.
 	 *
-	 * Normally, if the table has row-security enabled but there are
+	 * Normally, if the table has row security enabled but there are
 	 * no policies, we use a default-deny policy and not allow anything.
 	 * However, when an extension uses the hook to add their own
 	 * policies, we don't want to include the default deny policy or
 	 * there won't be any way for a user to use an extension exclusively
 	 * for the policies to be used.
 	 */
-	if (((RowSecurityPolicy *) linitial(rowsec_policies))->rsecid
+	if (((RowSecurityPolicy *) linitial(rowsec_policies))->policy_id
 			== InvalidOid)
 		defaultDeny = true;
 
@@ -353,7 +353,7 @@ pull_row_security_policies(CmdType cmd, Relation relation, Oid user_id)
 
 		policy = palloc0(sizeof(RowSecurityPolicy));
 		policy->policy_name = pstrdup("default-deny policy");
-		policy->rsecid = InvalidOid;
+		policy->policy_id = InvalidOid;
 		policy->cmd = '\0';
 		policy->roles = construct_array(&role, 1, OIDOID, sizeof(Oid), true,
 										'i');
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c
index d85ea1bbd3ae8fa693807e289a547bfb1e7efeef..c537fe3236ced2a0256ca3cfae28ffed9470ce13 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -207,7 +207,7 @@ CreateCachedPlan(Node *raw_parse_tree,
 	plansource->generic_cost = -1;
 	plansource->total_custom_cost = 0;
 	plansource->num_custom_plans = 0;
-	plansource->has_rls = false;
+	plansource->hasRowSecurity = false;
 	plansource->rowSecurityDisabled
 		= (security_context & SECURITY_ROW_LEVEL_DISABLED) != 0;
 	plansource->row_security_env = row_security;
@@ -383,7 +383,7 @@ CompleteCachedPlan(CachedPlanSource *plansource,
 		extract_query_dependencies((Node *) querytree_list,
 								   &plansource->relationOids,
 								   &plansource->invalItems,
-								   &plansource->has_rls);
+								   &plansource->hasRowSecurity);
 
 		/*
 		 * Also save the current search_path in the query_context.  (This
@@ -617,7 +617,7 @@ RevalidateCachedQuery(CachedPlanSource *plansource)
 	 */
 	if (plansource->is_valid
 		&& !plansource->rowSecurityDisabled
-		&& plansource->has_rls
+		&& plansource->hasRowSecurity
 		&& (plansource->planUserId != GetUserId()
 			|| plansource->row_security_env != row_security))
 		plansource->is_valid = false;
@@ -766,7 +766,7 @@ RevalidateCachedQuery(CachedPlanSource *plansource)
 	extract_query_dependencies((Node *) qlist,
 							   &plansource->relationOids,
 							   &plansource->invalItems,
-							   &plansource->has_rls);
+							   &plansource->hasRowSecurity);
 
 	/*
 	 * Also save the current search_path in the query_context.  (This should
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index c80ef3c6f899ac01a04f3c97ea592fcdf381b91e..79244e5686512a0de81d8609e5cd5d7b5015503c 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -866,7 +866,7 @@ equalPolicy(RowSecurityPolicy *policy1, RowSecurityPolicy *policy2)
 		if (policy2 == NULL)
 			return false;
 
-		if (policy1->rsecid != policy2->rsecid)
+		if (policy1->policy_id != policy2->policy_id)
 			return false;
 		if (policy1->cmd != policy2->cmd)
 			return false;
@@ -3439,7 +3439,7 @@ RelationCacheInitializePhase3(void)
 		 * they are not preserved in the cache.  Note that we can never NOT
 		 * have a policy while relrowsecurity is true,
 		 * RelationBuildRowSecurity will create a single default-deny policy
-		 * if there is no policy defined in pg_rowsecurity.
+		 * if there is no policy defined in pg_policy.
 		 */
 		if (relation->rd_rel->relrowsecurity && relation->rd_rsdesc == NULL)
 		{
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 8bfc604eabbecb86edee5f0befebdbeb8325a081..1269ec3b28d9b371fec5d4a8d61215e393375785 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -248,8 +248,8 @@ getSchemaData(Archive *fout, DumpOptions *dopt, int *numTablesPtr)
 	getRules(fout, &numRules);
 
 	if (g_verbose)
-		write_msg(NULL, "reading row-security policies\n");
-	getRowSecurity(fout, tblinfo, numTables);
+		write_msg(NULL, "reading policies\n");
+	getPolicies(fout, tblinfo, numTables);
 
 	*numTablesPtr = numTables;
 	return tblinfo;
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 1a2ebcb1f48fb55e2c9899109e55aa64fb940cad..43065e84b2f267ff97f08d68a8a3ade3633e177b 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -3328,6 +3328,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
 				 strcmp(te->desc, "RULE") == 0 ||
 				 strcmp(te->desc, "TRIGGER") == 0 ||
 				 strcmp(te->desc, "ROW SECURITY") == 0 ||
+				 strcmp(te->desc, "POLICY") == 0 ||
 				 strcmp(te->desc, "USER MAPPING") == 0)
 		{
 			/* these object types don't have separate owners */
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 69d359458bc878d3de546037bf5583a8c650d660..4175ddc823eb88bb93d2d3bf74f8b46f21ab63ff 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -233,7 +233,7 @@ static char *myFormatType(const char *typname, int32 typmod);
 static void getBlobs(Archive *fout);
 static void dumpBlob(Archive *fout, DumpOptions *dopt, BlobInfo *binfo);
 static int	dumpBlobs(Archive *fout, DumpOptions *dopt, void *arg);
-static void dumpRowSecurity(Archive *fout, DumpOptions *dopt, RowSecurityInfo *rsinfo);
+static void dumpPolicy(Archive *fout, DumpOptions *dopt, PolicyInfo *polinfo);
 static void dumpDatabase(Archive *AH, DumpOptions *dopt);
 static void dumpEncoding(Archive *AH);
 static void dumpStdStrings(Archive *AH);
@@ -2765,22 +2765,22 @@ dumpBlobs(Archive *fout, DumpOptions *dopt, void *arg)
 }
 
 /*
- * getRowSecurity
- *	  get information about every row-security policy on a dumpable table.
+ * getPolicies
+ *	  get information about policies on a dumpable table.
  */
 void
-getRowSecurity(Archive *fout, TableInfo tblinfo[], int numTables)
+getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
 {
 	PQExpBuffer query;
 	PGresult   *res;
-	RowSecurityInfo *rsinfo;
+	PolicyInfo *polinfo;
 	int			i_oid;
 	int			i_tableoid;
-	int			i_rsecpolname;
-	int			i_rseccmd;
-	int			i_rsecroles;
-	int			i_rsecqual;
-	int			i_rsecwithcheck;
+	int			i_polname;
+	int			i_polcmd;
+	int			i_polroles;
+	int			i_polqual;
+	int			i_polwithcheck;
 	int			i,
 				j,
 				ntups;
@@ -2794,18 +2794,18 @@ getRowSecurity(Archive *fout, TableInfo tblinfo[], int numTables)
 	{
 		TableInfo  *tbinfo = &tblinfo[i];
 
-		/* Ignore row-security on tables not to be dumped */
+		/* Ignore row security on tables not to be dumped */
 		if (!tbinfo->dobj.dump)
 			continue;
 
 		if (g_verbose)
-			write_msg(NULL, "reading row-security enabled for table \"%s\".\"%s\"\n",
+			write_msg(NULL, "reading row security enabled for table \"%s\".\"%s\"\n",
 					  tbinfo->dobj.namespace->dobj.name,
 					  tbinfo->dobj.name);
 
 		/*
-		 * Get row-security enabled information for the table. We represent
-		 * RLS enabled on a table by creating RowSecurityInfo object with an
+		 * Get row security enabled information for the table. We represent
+		 * RLS enabled on a table by creating PolicyInfo object with an
 		 * empty policy.
 		 */
 		if (tbinfo->rowsec)
@@ -2814,23 +2814,23 @@ getRowSecurity(Archive *fout, TableInfo tblinfo[], int numTables)
 			 * Note: use tableoid 0 so that this object won't be mistaken for
 			 * something that pg_depend entries apply to.
 			 */
-			rsinfo = pg_malloc(sizeof(RowSecurityInfo));
-			rsinfo->dobj.objType = DO_ROW_SECURITY;
-			rsinfo->dobj.catId.tableoid = 0;
-			rsinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
-			AssignDumpId(&rsinfo->dobj);
-			rsinfo->dobj.namespace = tbinfo->dobj.namespace;
-			rsinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
-			rsinfo->rstable = tbinfo;
-			rsinfo->rsecpolname = NULL;
-			rsinfo->rseccmd = NULL;
-			rsinfo->rsecroles = NULL;
-			rsinfo->rsecqual = NULL;
-			rsinfo->rsecwithcheck = NULL;
+			polinfo = pg_malloc(sizeof(PolicyInfo));
+			polinfo->dobj.objType = DO_POLICY;
+			polinfo->dobj.catId.tableoid = 0;
+			polinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
+			AssignDumpId(&polinfo->dobj);
+			polinfo->dobj.namespace = tbinfo->dobj.namespace;
+			polinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
+			polinfo->poltable = tbinfo;
+			polinfo->polname = NULL;
+			polinfo->polcmd = NULL;
+			polinfo->polroles = NULL;
+			polinfo->polqual = NULL;
+			polinfo->polwithcheck = NULL;
 		}
 
 		if (g_verbose)
-			write_msg(NULL, "reading row-security policies for table \"%s\".\"%s\"\n",
+			write_msg(NULL, "reading policies for table \"%s\".\"%s\"\n",
 					  tbinfo->dobj.namespace->dobj.name,
 					  tbinfo->dobj.name);
 
@@ -2843,13 +2843,13 @@ getRowSecurity(Archive *fout, TableInfo tblinfo[], int numTables)
 
 		/* Get the policies for the table. */
 		appendPQExpBuffer(query,
-						  "SELECT oid, tableoid, s.rsecpolname, s.rseccmd, "
-						  "CASE WHEN s.rsecroles = '{0}' THEN 'PUBLIC' ELSE "
-						  "   array_to_string(ARRAY(SELECT rolname from pg_roles WHERE oid = ANY(s.rsecroles)), ', ') END AS rsecroles, "
-						  "pg_get_expr(s.rsecqual, s.rsecrelid) AS rsecqual, "
-				"pg_get_expr(s.rsecwithcheck, s.rsecrelid) AS rsecwithcheck "
-						  "FROM pg_catalog.pg_rowsecurity s "
-						  "WHERE rsecrelid = '%u'",
+						  "SELECT oid, tableoid, pol.polname, pol.polcmd, "
+						  "CASE WHEN pol.polroles = '{0}' THEN 'PUBLIC' ELSE "
+						  "   array_to_string(ARRAY(SELECT rolname from pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, "
+						  "pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
+				"pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
+						  "FROM pg_catalog.pg_policy pol "
+						  "WHERE polrelid = '%u'",
 						  tbinfo->dobj.catId.oid);
 		res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -2868,45 +2868,44 @@ getRowSecurity(Archive *fout, TableInfo tblinfo[], int numTables)
 
 		i_oid = PQfnumber(res, "oid");
 		i_tableoid = PQfnumber(res, "tableoid");
-		i_rsecpolname = PQfnumber(res, "rsecpolname");
-		i_rseccmd = PQfnumber(res, "rseccmd");
-		i_rsecroles = PQfnumber(res, "rsecroles");
-		i_rsecqual = PQfnumber(res, "rsecqual");
-		i_rsecwithcheck = PQfnumber(res, "rsecwithcheck");
+		i_polname = PQfnumber(res, "polname");
+		i_polcmd = PQfnumber(res, "polcmd");
+		i_polroles = PQfnumber(res, "polroles");
+		i_polqual = PQfnumber(res, "polqual");
+		i_polwithcheck = PQfnumber(res, "polwithcheck");
 
-		rsinfo = pg_malloc(ntups * sizeof(RowSecurityInfo));
+		polinfo = pg_malloc(ntups * sizeof(PolicyInfo));
 
 		for (j = 0; j < ntups; j++)
 		{
-			rsinfo[j].dobj.objType = DO_ROW_SECURITY;
-			rsinfo[j].dobj.catId.tableoid =
+			polinfo[j].dobj.objType = DO_POLICY;
+			polinfo[j].dobj.catId.tableoid =
 				atooid(PQgetvalue(res, j, i_tableoid));
-			rsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
-			AssignDumpId(&rsinfo[j].dobj);
-			rsinfo[j].dobj.namespace = tbinfo->dobj.namespace;
-			rsinfo[j].rstable = tbinfo;
-			rsinfo[j].rsecpolname = pg_strdup(PQgetvalue(res, j,
-														 i_rsecpolname));
+			polinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
+			AssignDumpId(&polinfo[j].dobj);
+			polinfo[j].dobj.namespace = tbinfo->dobj.namespace;
+			polinfo[j].poltable = tbinfo;
+			polinfo[j].polname = pg_strdup(PQgetvalue(res, j, i_polname));
 
-			rsinfo[j].dobj.name = pg_strdup(rsinfo[j].rsecpolname);
+			polinfo[j].dobj.name = pg_strdup(polinfo[j].polname);
 
-			if (PQgetisnull(res, j, i_rseccmd))
-				rsinfo[j].rseccmd = NULL;
+			if (PQgetisnull(res, j, i_polcmd))
+				polinfo[j].polcmd = NULL;
 			else
-				rsinfo[j].rseccmd = pg_strdup(PQgetvalue(res, j, i_rseccmd));
+				polinfo[j].polcmd = pg_strdup(PQgetvalue(res, j, i_polcmd));
 
-			rsinfo[j].rsecroles = pg_strdup(PQgetvalue(res, j, i_rsecroles));
+			polinfo[j].polroles = pg_strdup(PQgetvalue(res, j, i_polroles));
 
-			if (PQgetisnull(res, j, i_rsecqual))
-				rsinfo[j].rsecqual = NULL;
+			if (PQgetisnull(res, j, i_polqual))
+				polinfo[j].polqual = NULL;
 			else
-				rsinfo[j].rsecqual = pg_strdup(PQgetvalue(res, j, i_rsecqual));
+				polinfo[j].polqual = pg_strdup(PQgetvalue(res, j, i_polqual));
 
-			if (PQgetisnull(res, j, i_rsecwithcheck))
-				rsinfo[j].rsecwithcheck = NULL;
+			if (PQgetisnull(res, j, i_polwithcheck))
+				polinfo[j].polwithcheck = NULL;
 			else
-				rsinfo[j].rsecwithcheck
-					= pg_strdup(PQgetvalue(res, j, i_rsecwithcheck));
+				polinfo[j].polwithcheck
+					= pg_strdup(PQgetvalue(res, j, i_polwithcheck));
 		}
 		PQclear(res);
 	}
@@ -2914,13 +2913,13 @@ getRowSecurity(Archive *fout, TableInfo tblinfo[], int numTables)
 }
 
 /*
- * dumpRowSecurity
- *	  dump the definition of the given row-security policy
+ * dumpPolicy
+ *	  dump the definition of the given policy
  */
 static void
-dumpRowSecurity(Archive *fout, DumpOptions *dopt, RowSecurityInfo *rsinfo)
+dumpPolicy(Archive *fout, DumpOptions *dopt, PolicyInfo *polinfo)
 {
-	TableInfo  *tbinfo = rsinfo->rstable;
+	TableInfo  *tbinfo = polinfo->poltable;
 	PQExpBuffer query;
 	PQExpBuffer delqry;
 	const char *cmd;
@@ -2929,23 +2928,23 @@ dumpRowSecurity(Archive *fout, DumpOptions *dopt, RowSecurityInfo *rsinfo)
 		return;
 
 	/*
-	 * If rsecpolname is NULL, then this record is just indicating that ROW
+	 * If polname is NULL, then this record is just indicating that ROW
 	 * LEVEL SECURITY is enabled for the table. Dump as ALTER TABLE <table>
 	 * ENABLE ROW LEVEL SECURITY.
 	 */
-	if (rsinfo->rsecpolname == NULL)
+	if (polinfo->polname == NULL)
 	{
 		query = createPQExpBuffer();
 
 		appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;",
-						  fmtId(rsinfo->dobj.name));
+						  fmtId(polinfo->dobj.name));
 
-		ArchiveEntry(fout, rsinfo->dobj.catId, rsinfo->dobj.dumpId,
-					 rsinfo->dobj.name,
-					 rsinfo->dobj.namespace->dobj.name,
+		ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
+					 polinfo->dobj.name,
+					 polinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 tbinfo->rolname, false,
-					 "ROW SECURITY", SECTION_NONE,
+					 "ROW SECURITY", SECTION_POST_DATA,
 					 query->data, "", NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -2954,19 +2953,19 @@ dumpRowSecurity(Archive *fout, DumpOptions *dopt, RowSecurityInfo *rsinfo)
 		return;
 	}
 
-	if (!rsinfo->rseccmd)
+	if (!polinfo->polcmd)
 		cmd = "ALL";
-	else if (strcmp(rsinfo->rseccmd, "r") == 0)
+	else if (strcmp(polinfo->polcmd, "r") == 0)
 		cmd = "SELECT";
-	else if (strcmp(rsinfo->rseccmd, "a") == 0)
+	else if (strcmp(polinfo->polcmd, "a") == 0)
 		cmd = "INSERT";
-	else if (strcmp(rsinfo->rseccmd, "w") == 0)
+	else if (strcmp(polinfo->polcmd, "w") == 0)
 		cmd = "UPDATE";
-	else if (strcmp(rsinfo->rseccmd, "d") == 0)
+	else if (strcmp(polinfo->polcmd, "d") == 0)
 		cmd = "DELETE";
 	else
 	{
-		write_msg(NULL, "unexpected command type: '%s'\n", rsinfo->rseccmd);
+		write_msg(NULL, "unexpected command type: '%s'\n", polinfo->polcmd);
 		exit_nicely(1);
 	}
 
@@ -2974,28 +2973,28 @@ dumpRowSecurity(Archive *fout, DumpOptions *dopt, RowSecurityInfo *rsinfo)
 	delqry = createPQExpBuffer();
 
 	appendPQExpBuffer(query, "CREATE POLICY %s ON %s FOR %s",
-					  rsinfo->rsecpolname, fmtId(tbinfo->dobj.name), cmd);
+					  polinfo->polname, fmtId(tbinfo->dobj.name), cmd);
 
-	if (rsinfo->rsecroles != NULL)
-		appendPQExpBuffer(query, " TO %s", rsinfo->rsecroles);
+	if (polinfo->polroles != NULL)
+		appendPQExpBuffer(query, " TO %s", polinfo->polroles);
 
-	if (rsinfo->rsecqual != NULL)
-		appendPQExpBuffer(query, " USING %s", rsinfo->rsecqual);
+	if (polinfo->polqual != NULL)
+		appendPQExpBuffer(query, " USING %s", polinfo->polqual);
 
-	if (rsinfo->rsecwithcheck != NULL)
-		appendPQExpBuffer(query, " WITH CHECK %s", rsinfo->rsecwithcheck);
+	if (polinfo->polwithcheck != NULL)
+		appendPQExpBuffer(query, " WITH CHECK %s", polinfo->polwithcheck);
 
 	appendPQExpBuffer(query, ";\n");
 
 	appendPQExpBuffer(delqry, "DROP POLICY %s ON %s;\n",
-					  rsinfo->rsecpolname, fmtId(tbinfo->dobj.name));
+					  polinfo->polname, fmtId(tbinfo->dobj.name));
 
-	ArchiveEntry(fout, rsinfo->dobj.catId, rsinfo->dobj.dumpId,
-				 rsinfo->dobj.name,
-				 rsinfo->dobj.namespace->dobj.name,
+	ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
+				 polinfo->dobj.name,
+				 polinfo->dobj.namespace->dobj.name,
 				 NULL,
 				 tbinfo->rolname, false,
-				 "ROW SECURITY", SECTION_POST_DATA,
+				 "POLICY", SECTION_POST_DATA,
 				 query->data, delqry->data, NULL,
 				 NULL, 0,
 				 NULL, NULL);
@@ -8232,8 +8231,8 @@ dumpDumpableObject(Archive *fout, DumpOptions *dopt, DumpableObject *dobj)
 						 NULL, 0,
 						 dumpBlobs, NULL);
 			break;
-		case DO_ROW_SECURITY:
-			dumpRowSecurity(fout, dopt, (RowSecurityInfo *) dobj);
+		case DO_POLICY:
+			dumpPolicy(fout, dopt, (PolicyInfo *) dobj);
 			break;
 		case DO_PRE_DATA_BOUNDARY:
 		case DO_POST_DATA_BOUNDARY:
@@ -15631,7 +15630,7 @@ addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
 			case DO_TRIGGER:
 			case DO_EVENT_TRIGGER:
 			case DO_DEFAULT_ACL:
-			case DO_ROW_SECURITY:
+			case DO_POLICY:
 				/* Post-data objects: must come after the post-data boundary */
 				addObjectDependency(dobj, postDataBound->dumpId);
 				break;
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index a7eb2fd9364b427ced713f531f88203fd279e906..d1d9ecbaa2d69fc773b4347e1b911188faa5df65 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -76,7 +76,7 @@ typedef enum
 	DO_POST_DATA_BOUNDARY,
 	DO_EVENT_TRIGGER,
 	DO_REFRESH_MATVIEW,
-	DO_ROW_SECURITY
+	DO_POLICY
 } DumpableObjectType;
 
 typedef struct _dumpableObject
@@ -210,7 +210,7 @@ typedef struct _tableInfo
 	bool		hasindex;		/* does it have any indexes? */
 	bool		hasrules;		/* does it have any rules? */
 	bool		hastriggers;	/* does it have any triggers? */
-	bool		rowsec;			/* is row-security enabled? */
+	bool		rowsec;			/* is row security enabled? */
 	bool		hasoids;		/* does it have OIDs? */
 	uint32		frozenxid;		/* for restore frozen xid */
 	uint32		minmxid;		/* for restore min multi xid */
@@ -453,21 +453,21 @@ typedef struct _blobInfo
 } BlobInfo;
 
 /*
- * The RowSecurityInfo struct is used to represent row policies on a table and
+ * The PolicyInfo struct is used to represent policies on a table and
  * to indicate if a table has RLS enabled (ENABLE ROW SECURITY).  If
- * rsecpolname is NULL, then the record indicates ENABLE ROW SECURITY, while if
+ * polname is NULL, then the record indicates ENABLE ROW SECURITY, while if
  * it's non-NULL then this is a regular policy definition.
  */
-typedef struct _rowSecurityInfo
+typedef struct _policyInfo
 {
 	DumpableObject dobj;
-	TableInfo  *rstable;
-	char	   *rsecpolname;	/* null indicates RLS is enabled on rel */
-	char	   *rseccmd;
-	char	   *rsecroles;
-	char	   *rsecqual;
-	char	   *rsecwithcheck;
-} RowSecurityInfo;
+	TableInfo  *poltable;
+	char	   *polname;	/* null indicates RLS is enabled on rel */
+	char	   *polcmd;
+	char	   *polroles;
+	char	   *polqual;
+	char	   *polwithcheck;
+} PolicyInfo;
 
 /* global decls */
 extern bool force_quotes;		/* double-quotes for identifiers flag */
@@ -549,6 +549,6 @@ extern DefaultACLInfo *getDefaultACLs(Archive *fout, DumpOptions *dopt, int *num
 extern void getExtensionMembership(Archive *fout, DumpOptions *dopt, ExtensionInfo extinfo[],
 					   int numExtensions);
 extern EventTriggerInfo *getEventTriggers(Archive *fout, int *numEventTriggers);
-extern void getRowSecurity(Archive *fout, TableInfo tblinfo[], int numTables);
+extern void getPolicies(Archive *fout, TableInfo tblinfo[], int numTables);
 
 #endif   /* PG_DUMP_H */
diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index 030bccc7e65a875ce7e0289707c77cdd2f513751..0e62af27765de642f1cfd4566e7ec16458f17c4c 100644
--- a/src/bin/pg_dump/pg_dump_sort.c
+++ b/src/bin/pg_dump/pg_dump_sort.c
@@ -28,8 +28,8 @@ static const char *modulename = gettext_noop("sorter");
  * by OID.  (This is a relatively crude hack to provide semi-reasonable
  * behavior for old databases without full dependency info.)  Note: collations,
  * extensions, text search, foreign-data, materialized view, event trigger,
- * and default ACL objects can't really happen here, so the rather bogus
- * priorities for them don't matter.
+ * policies, and default ACL objects can't really happen here, so the rather
+ * bogus priorities for them don't matter.
  *
  * NOTE: object-type priorities must match the section assignments made in
  * pg_dump.c; that is, PRE_DATA objects must sort before DO_PRE_DATA_BOUNDARY,
@@ -73,7 +73,7 @@ static const int oldObjectTypePriority[] =
 	13,							/* DO_POST_DATA_BOUNDARY */
 	20,							/* DO_EVENT_TRIGGER */
 	15,							/* DO_REFRESH_MATVIEW */
-	21							/* DO_ROW_SECURITY */
+	21							/* DO_POLICY */
 };
 
 /*
@@ -122,7 +122,7 @@ static const int newObjectTypePriority[] =
 	25,							/* DO_POST_DATA_BOUNDARY */
 	32,							/* DO_EVENT_TRIGGER */
 	33,							/* DO_REFRESH_MATVIEW */
-	34							/* DO_ROW_SECURITY */
+	34							/* DO_POLICY */
 };
 
 static DumpId preDataBoundId;
@@ -1438,9 +1438,9 @@ describeDumpableObject(DumpableObject *obj, char *buf, int bufsize)
 					 "BLOB DATA  (ID %d)",
 					 obj->dumpId);
 			return;
-		case DO_ROW_SECURITY:
+		case DO_POLICY:
 			snprintf(buf, bufsize,
-					 "ROW-SECURITY POLICY (ID %d OID %u)",
+					 "POLICY (ID %d OID %u)",
 					 obj->dumpId, obj->catId.oid);
 			return;
 		case DO_PRE_DATA_BOUNDARY:
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index a062fa871fafa42cb2d893ac6d159023fc2f9267..5a9ceca0df5e6ba1da3597d9a73b5f98582289d0 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -783,31 +783,31 @@ permissionsList(const char *pattern)
 	if (pset.sversion >= 90500)
 		appendPQExpBuffer(&buf,
 						  ",\n  pg_catalog.array_to_string(ARRAY(\n"
-						  "    SELECT rsecpolname\n"
-						  "    || CASE WHEN rseccmd IS NOT NULL THEN\n"
-						  "           E' (' || rseccmd || E')'\n"
+						  "    SELECT polname\n"
+						  "    || CASE WHEN polcmd IS NOT NULL THEN\n"
+						  "           E' (' || polcmd || E')'\n"
 						  "       ELSE E':' \n"
 						  "       END\n"
-						  "    || CASE WHEN rs.rsecqual IS NOT NULL THEN\n"
-						  "           E'\\n  (u): ' || pg_catalog.pg_get_expr(rsecqual, rsecrelid)\n"
+						  "    || CASE WHEN polqual IS NOT NULL THEN\n"
+						  "           E'\\n  (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n"
 						  "       ELSE E''\n"
 						  "       END\n"
-						  "    || CASE WHEN rsecwithcheck IS NOT NULL THEN\n"
-						  "           E'\\n  (c): ' || pg_catalog.pg_get_expr(rsecwithcheck, rsecrelid)\n"
+						  "    || CASE WHEN polwithcheck IS NOT NULL THEN\n"
+						  "           E'\\n  (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n"
 						  "       ELSE E''\n"
 						  "       END"
-						  "    || CASE WHEN rs.rsecroles <> '{0}' THEN\n"
+						  "    || CASE WHEN polroles <> '{0}' THEN\n"
 						  "           E'\\n  to: ' || pg_catalog.array_to_string(\n"
 						  "               ARRAY(\n"
 						  "                   SELECT rolname\n"
 						  "                   FROM pg_catalog.pg_roles\n"
-						  "                   WHERE oid = ANY (rs.rsecroles)\n"
+						  "                   WHERE oid = ANY (polroles)\n"
 						  "                   ORDER BY 1\n"
 						  "               ), E', ')\n"
 						  "       ELSE E''\n"
 						  "       END\n"
-						  "    FROM pg_catalog.pg_rowsecurity rs\n"
-						  "    WHERE rsecrelid = c.oid), E'\\n')\n"
+						  "    FROM pg_catalog.pg_policy pol\n"
+						  "    WHERE polrelid = c.oid), E'\\n')\n"
 						  "    AS \"%s\"",
 						  gettext_noop("Policies"));
 
@@ -2001,27 +2001,19 @@ describeOneTableDetails(const char *schemaname,
 		/* print any row-level policies */
 		if (pset.sversion >= 90500)
 		{
-			appendPQExpBuffer(&buf,
-				",\n pg_catalog.pg_get_expr(rs.rsecqual, c.oid) as \"%s\"",
-				gettext_noop("Row-security"));
-
-			if (verbose)
-				appendPQExpBuffer(&buf,
-					"\n     LEFT JOIN pg_rowsecurity rs ON rs.rsecrelid = c.oid");
-
 			printfPQExpBuffer(&buf,
-						   "SELECT rs.rsecpolname,\n"
-						   "CASE WHEN rs.rsecroles = '{0}' THEN NULL ELSE array_to_string(array(select rolname from pg_roles where oid = any (rs.rsecroles) order by 1),',') END,\n"
-						   "pg_catalog.pg_get_expr(rs.rsecqual, rs.rsecrelid),\n"
-						   "pg_catalog.pg_get_expr(rs.rsecwithcheck, rs.rsecrelid),\n"
-						   "CASE rs.rseccmd \n"
+						   "SELECT pol.polname,\n"
+						   "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE array_to_string(array(select rolname from pg_roles where oid = any (pol.polroles) order by 1),',') END,\n"
+						   "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n"
+						   "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),\n"
+						   "CASE pol.polcmd \n"
 						   "WHEN 'r' THEN 'SELECT'\n"
 						   "WHEN 'u' THEN 'UPDATE'\n"
 						   "WHEN 'a' THEN 'INSERT'\n"
 						   "WHEN 'd' THEN 'DELETE'\n"
 						   "END AS cmd\n"
-							  "FROM pg_catalog.pg_rowsecurity rs\n"
-				  "WHERE rs.rsecrelid = '%s' ORDER BY 1;",
+							  "FROM pg_catalog.pg_policy pol\n"
+				  "WHERE pol.polrelid = '%s' ORDER BY 1;",
 							  oid);
 
 			result = PSQLexec(buf.data);
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 278d3952d4d0ad6e2c2d6707d96a715f9505fb44..1bb5a8373f3d1f18438f91f116ba73f99e7b1b6f 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2069,7 +2069,7 @@ psql_completion(const char *text, int start, int end)
 		static const char *const list_COMMENT[] =
 		{"CAST", "COLLATION", "CONVERSION", "DATABASE", "EVENT TRIGGER", "EXTENSION",
 			"FOREIGN DATA WRAPPER", "FOREIGN TABLE",
-			"SERVER", "INDEX", "LANGUAGE", "RULE", "SCHEMA", "SEQUENCE",
+			"SERVER", "INDEX", "LANGUAGE", "POLICY", "RULE", "SCHEMA", "SEQUENCE",
 			"TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", "COLUMN", "AGGREGATE", "FUNCTION",
 			"OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT",
 		"TABLESPACE", "TEXT SEARCH", "ROLE", NULL};
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index b670902b7d22eb24b97973b5bca43dcdbafe3030..a9290886252ad1b66ab83f025d544a39436ed3b8 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	201411251
+#define CATALOG_VERSION_NO	201411271
 
 #endif
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 6a4913a66e57f3d6f6d0705c6798370b50e168e3..87ac9240ae9e3a990691333db4ab8ffee51d0c74 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -147,7 +147,7 @@ typedef enum ObjectClass
 	OCLASS_DEFACL,				/* pg_default_acl */
 	OCLASS_EXTENSION,			/* pg_extension */
 	OCLASS_EVENT_TRIGGER,		/* pg_event_trigger */
-	OCLASS_ROWSECURITY,			/* pg_rowsecurity */
+	OCLASS_POLICY,				/* pg_policy */
 	MAX_OCLASS					/* MUST BE LAST */
 } ObjectClass;
 
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index 870692cf54f9e5151ed116583dbf7fa6d713227f..bde1a848fee2b28502ca3b331aa8fe37eb229b68 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -299,11 +299,11 @@ DECLARE_UNIQUE_INDEX(pg_extension_name_index, 3081, on pg_extension using btree(
 DECLARE_UNIQUE_INDEX(pg_range_rngtypid_index, 3542, on pg_range using btree(rngtypid oid_ops));
 #define RangeTypidIndexId					3542
 
-DECLARE_UNIQUE_INDEX(pg_rowsecurity_oid_index, 3257, on pg_rowsecurity using btree(oid oid_ops));
-#define RowSecurityOidIndexId				3257
+DECLARE_UNIQUE_INDEX(pg_policy_oid_index, 3257, on pg_policy using btree(oid oid_ops));
+#define PolicyOidIndexId				3257
 
-DECLARE_UNIQUE_INDEX(pg_rowsecurity_polname_relid_index, 3258, on pg_rowsecurity using btree(rsecrelid oid_ops, rsecpolname name_ops));
-#define RowSecurityRelidPolnameIndexId				3258
+DECLARE_UNIQUE_INDEX(pg_policy_polrelid_polname_index, 3258, on pg_policy using btree(polrelid oid_ops, polname name_ops));
+#define PolicyPolrelidPolnameIndexId				3258
 
 /* last step of initialization script: build the indexes declared above */
 BUILD_INDICES
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 22c55a94903b63cfb30d11e56d2141de9889faa3..1054cd0500be3ce8c646ea3a463964850c538968 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -65,7 +65,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO
 	bool		relhasrules;	/* has (or has had) any rules */
 	bool		relhastriggers; /* has (or has had) any TRIGGERs */
 	bool		relhassubclass; /* has (or has had) derived classes */
-	bool		relrowsecurity;	/* row-security is enabled or not */
+	bool		relrowsecurity;	/* row security is enabled or not */
 	bool		relispopulated; /* matview currently holds query results */
 	char		relreplident;	/* see REPLICA_IDENTITY_xxx constants  */
 	TransactionId relfrozenxid; /* all Xids < this are frozen in this rel */
diff --git a/src/include/catalog/pg_policy.h b/src/include/catalog/pg_policy.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d377a483899bc9ef1efffa69ad420becfc0eaf6
--- /dev/null
+++ b/src/include/catalog/pg_policy.h
@@ -0,0 +1,53 @@
+/*
+ * pg_policy.h
+ *   definition of the system "policy" relation (pg_policy)
+ *
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ */
+#ifndef PG_POLICY_H
+#define PG_POLICY_H
+
+#include "catalog/genbki.h"
+
+/* ----------------
+ *		pg_policy definition. cpp turns this into
+ *		typedef struct FormData_pg_policy
+ * ----------------
+ */
+#define PolicyRelationId	3256
+
+CATALOG(pg_policy,3256)
+{
+	NameData		polname;		/* Policy name. */
+	Oid				polrelid;		/* Oid of the relation with policy. */
+	char			polcmd;			/* One of ACL_*_CHR, or \0 for all */
+
+#ifdef CATALOG_VARLEN
+	Oid				polroles[1]		/* Roles associated with policy, not-NULL */
+	pg_node_tree	polqual;		/* Policy quals. */
+	pg_node_tree	polwithcheck;	/* WITH CHECK quals. */
+#endif
+} FormData_pg_policy;
+
+/* ----------------
+ *		Form_pg_policy corresponds to a pointer to a row with
+ *		the format of pg_policy relation.
+ * ----------------
+ */
+typedef FormData_pg_policy *Form_pg_policy;
+
+/* ----------------
+ * 		compiler constants for pg_policy
+ * ----------------
+ */
+#define Natts_pg_policy				6
+#define Anum_pg_policy_polname		1
+#define Anum_pg_policy_polrelid		2
+#define Anum_pg_policy_polcmd		3
+#define Anum_pg_policy_polroles		4
+#define Anum_pg_policy_polqual		5
+#define Anum_pg_policy_polwithcheck	6
+
+#endif  /* PG_POLICY_H */
diff --git a/src/include/catalog/pg_rowsecurity.h b/src/include/catalog/pg_rowsecurity.h
deleted file mode 100644
index 2638d5e684894dbce672c21c38a99502076d0f1f..0000000000000000000000000000000000000000
--- a/src/include/catalog/pg_rowsecurity.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * pg_rowsecurity.h
- *   definition of the system catalog for row-security policy (pg_rowsecurity)
- *
- * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- */
-#ifndef PG_ROWSECURITY_H
-#define PG_ROWSECURITY_H
-
-#include "catalog/genbki.h"
-
-/* ----------------
- *		pg_rowsecurity definition. cpp turns this into
- *		typedef struct FormData_pg_rowsecurity
- * ----------------
- */
-#define RowSecurityRelationId	3256
-
-CATALOG(pg_rowsecurity,3256)
-{
-	NameData		rsecpolname;	/* Policy name. */
-	Oid				rsecrelid;		/* Oid of the relation with policy. */
-	char			rseccmd;		/* One of ACL_*_CHR, or \0 for all */
-
-#ifdef CATALOG_VARLEN
-	Oid				rsecroles[1]	/* Roles associated with policy, not-NULL */
-	pg_node_tree	rsecqual;		/* Policy quals. */
-	pg_node_tree	rsecwithcheck;	/* WITH CHECK quals. */
-#endif
-} FormData_pg_rowsecurity;
-
-/* ----------------
- *		Form_pg_rowsecurity corresponds to a pointer to a row with
- *		the format of pg_rowsecurity relation.
- * ----------------
- */
-typedef FormData_pg_rowsecurity *Form_pg_rowsecurity;
-
-/* ----------------
- * 		compiler constants for pg_rowsecurity
- * ----------------
- */
-#define Natts_pg_rowsecurity				6
-#define Anum_pg_rowsecurity_rsecpolname		1
-#define Anum_pg_rowsecurity_rsecrelid		2
-#define Anum_pg_rowsecurity_rseccmd			3
-#define Anum_pg_rowsecurity_rsecroles		4
-#define Anum_pg_rowsecurity_rsecqual		5
-#define Anum_pg_rowsecurity_rsecwithcheck	6
-
-#endif  /* PG_ROWSECURITY_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 3e4f815852d5659a6d0e2bae77e4a8b4a98c6213..255415d93a3f50773a5aa24071c255d7d5a51406 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -121,7 +121,7 @@ typedef struct Query
 	bool		hasRecursive;	/* WITH RECURSIVE was specified */
 	bool		hasModifyingCTE;	/* has INSERT/UPDATE/DELETE in WITH */
 	bool		hasForUpdate;	/* FOR [KEY] UPDATE/SHARE was specified */
-	bool		hasRowSecurity;	/* Row-security policy is applied */
+	bool		hasRowSecurity;	/* row security applied? */
 
 	List	   *cteList;		/* WITH list (of CommonTableExpr's) */
 
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 7f9eaf0df267d4cb1dad3cb86e06d78987bdb70e..48203a0d21faade68529a3cc217ce39f46a3b260 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -70,7 +70,7 @@ typedef struct PlannedStmt
 
 	int			nParamExec;		/* number of PARAM_EXEC Params used */
 
-	bool		has_rls;		/* row-security applied? */
+	bool		hasRowSecurity;	/* row security applied? */
 
 } PlannedStmt;
 
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 810b9c8893b077b5cc2d3689c4612d5b86b071b0..711649687ae8f4cd404d0a85b9cb6d311da8c82c 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -101,7 +101,7 @@ typedef struct PlannerGlobal
 
 	bool		transientPlan;	/* redo plan when TransactionXmin changes? */
 
-	bool		has_rls;		/* row-security is applied? */
+	bool		hasRowSecurity;	/* row security applied? */
 
 } PlannerGlobal;
 
diff --git a/src/include/rewrite/rowsecurity.h b/src/include/rewrite/rowsecurity.h
index 8b4d5c0918faacb236a1cc6b1f3d70edebf14f60..4144b25fec75cf4dc440a3ba077d4195f8d5a649 100644
--- a/src/include/rewrite/rowsecurity.h
+++ b/src/include/rewrite/rowsecurity.h
@@ -19,7 +19,7 @@
 
 typedef struct RowSecurityPolicy
 {
-	Oid					rsecid;			/* OID of the policy */
+	Oid					policy_id;		/* OID of the policy */
 	char			   *policy_name;	/* Name of the policy */
 	char				cmd;			/* Type of command policy is for */
 	ArrayType		   *roles;			/* Array of roles policy is for */
@@ -30,8 +30,8 @@ typedef struct RowSecurityPolicy
 
 typedef struct RowSecurityDesc
 {
-	MemoryContext		rscxt;		/* row-security memory context */
-	List			   *policies;	/* list of row-security policies */
+	MemoryContext		rscxt;		/* row security memory context */
+	List			   *policies;	/* list of row security policies */
 } RowSecurityDesc;
 
 /* GUC variable */
diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h
index 2622ceb54bc1908c4146d4332c631a530a048c54..9e1c0000aab06bd87c25b0475c704094b9460d1e 100644
--- a/src/include/utils/plancache.h
+++ b/src/include/utils/plancache.h
@@ -109,9 +109,9 @@ typedef struct CachedPlanSource
 	double		generic_cost;	/* cost of generic plan, or -1 if not known */
 	double		total_custom_cost;		/* total cost of custom plans so far */
 	int			num_custom_plans;		/* number of plans included in total */
-	bool		has_rls;				/* planned with row-security? */
+	bool		hasRowSecurity;			/* planned with row security? */
 	int			row_security_env;		/* row security setting when planned */
-	bool		rowSecurityDisabled;	/* is row-security disabled? */
+	bool		rowSecurityDisabled;	/* is row security disabled? */
 } CachedPlanSource;
 
 /*
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 01a9ef32ebf9158815a67fae3b4f599654c9137b..48ebf5949430cc77690e1d73de6fb84de2b74613 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -106,7 +106,7 @@ typedef struct RelationData
 	MemoryContext rd_rulescxt;	/* private memory cxt for rd_rules, if any */
 	TriggerDesc *trigdesc;		/* Trigger info, or NULL if rel has none */
 	/* use "struct" here to avoid needing to include rowsecurity.h: */
-	struct RowSecurityDesc *rd_rsdesc;	/* Row-security policies, or NULL */
+	struct RowSecurityDesc *rd_rsdesc;	/* row security policies, or NULL */
 
 	/* data managed by RelationGetIndexList: */
 	List	   *rd_indexlist;	/* list of OIDs of indexes on relation */
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index 376292ac2effc0990f2effc58b8ed75405d76ad0..5eb61c46aa2afedd8521372c041890cdb20ffc12 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -173,7 +173,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dt
                              Index Cond: (pguser = "current_user"())
 (11 rows)
 
--- only owner can change row-level security
+-- only owner can change policies
 ALTER POLICY p1 ON document USING (true);    --fail
 ERROR:  must be owner of relation document
 DROP POLICY p1 ON document;                  --fail
@@ -724,7 +724,7 @@ CREATE TABLE dependent (x integer, y integer);
 CREATE POLICY d1 ON dependent FOR ALL
     TO PUBLIC
     USING (x = (SELECT d.x FROM dependee d WHERE d.y = y));
-DROP TABLE dependee; -- Should fail without CASCADE due to dependency on row-security qual?
+DROP TABLE dependee; -- Should fail without CASCADE due to dependency on row security qual?
 ERROR:  cannot drop table dependee because other objects depend on it
 DETAIL:  policy d1 on table dependent depends on table dependee
 HINT:  Use DROP ... CASCADE to drop the dependent objects too.
@@ -746,7 +746,7 @@ CREATE POLICY r1 ON rec1 USING (x = (SELECT r.x FROM rec1 r WHERE y = r.y));
 ALTER TABLE rec1 ENABLE ROW LEVEL SECURITY;
 SET SESSION AUTHORIZATION rls_regress_user1;
 SELECT * FROM rec1; -- fail, direct recursion
-ERROR:  infinite recursion detected in row-security policy for relation "rec1"
+ERROR:  infinite recursion detected in policy for relation "rec1"
 --
 -- Mutual recursion
 --
@@ -757,7 +757,7 @@ CREATE POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1 WHERE y = b));
 ALTER TABLE rec2 ENABLE ROW LEVEL SECURITY;
 SET SESSION AUTHORIZATION rls_regress_user1;
 SELECT * FROM rec1;    -- fail, mutual recursion
-ERROR:  infinite recursion detected in row-security policy for relation "rec1"
+ERROR:  infinite recursion detected in policy for relation "rec1"
 --
 -- Mutual recursion via views
 --
@@ -769,7 +769,7 @@ ALTER POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y));
 ALTER POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b));
 SET SESSION AUTHORIZATION rls_regress_user1;
 SELECT * FROM rec1;    -- fail, mutual recursion via views
-ERROR:  infinite recursion detected in row-security policy for relation "rec1"
+ERROR:  infinite recursion detected in policy for relation "rec1"
 --
 -- Mutual recursion via .s.b views
 --
@@ -785,7 +785,7 @@ CREATE POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y));
 CREATE POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b));
 SET SESSION AUTHORIZATION rls_regress_user1;
 SELECT * FROM rec1;    -- fail, mutual recursion via s.b. views
-ERROR:  infinite recursion detected in row-security policy for relation "rec1"
+ERROR:  infinite recursion detected in policy for relation "rec1"
 --
 -- recursive RLS and VIEWs in policy
 --
@@ -803,9 +803,9 @@ ALTER TABLE s2 ENABLE ROW LEVEL SECURITY;
 SET SESSION AUTHORIZATION rls_regress_user1;
 CREATE VIEW v2 AS SELECT * FROM s2 WHERE y like '%af%';
 SELECT * FROM s1 WHERE f_leak(b); -- fail (infinite recursion)
-ERROR:  infinite recursion detected in row-security policy for relation "s1"
+ERROR:  infinite recursion detected in policy for relation "s1"
 INSERT INTO s1 VALUES (1, 'foo'); -- fail (infinite recursion)
-ERROR:  infinite recursion detected in row-security policy for relation "s1"
+ERROR:  infinite recursion detected in policy for relation "s1"
 SET SESSION AUTHORIZATION rls_regress_user0;
 DROP POLICY p3 on s1;
 ALTER POLICY p2 ON s2 USING (x % 2 = 0);
@@ -897,7 +897,7 @@ SET SESSION AUTHORIZATION rls_regress_user0;
 ALTER POLICY p2 ON s2 USING (x in (select a from s1 where b like '%d2%'));
 SET SESSION AUTHORIZATION rls_regress_user1;
 SELECT * FROM s1 WHERE f_leak(b);	-- fail (infinite recursion via view)
-ERROR:  infinite recursion detected in row-security policy for relation "s1"
+ERROR:  infinite recursion detected in policy for relation "s1"
 -- prepared statement with rls_regress_user0 privilege
 PREPARE p1(int) AS SELECT * FROM t1 WHERE a <= $1;
 EXECUTE p1(2);
@@ -1714,24 +1714,24 @@ WITH cte1 AS (INSERT INTO t1 VALUES (20, 'Success') RETURNING *) SELECT * FROM c
 --
 RESET SESSION AUTHORIZATION;
 ALTER POLICY p1 ON t1 RENAME TO p1; --fail
-ERROR:  row-policy "p1" for table "t1" already exists
-SELECT rsecpolname, relname
-    FROM pg_rowsecurity rs
-    JOIN pg_class pc ON (pc.oid = rs.rsecrelid)
+ERROR:  policy "p1" for table "t1" already exists
+SELECT polname, relname
+    FROM pg_policy pol
+    JOIN pg_class pc ON (pc.oid = pol.polrelid)
     WHERE relname = 't1';
- rsecpolname | relname 
--------------+---------
- p1          | t1
+ polname | relname 
+---------+---------
+ p1      | t1
 (1 row)
 
 ALTER POLICY p1 ON t1 RENAME TO p2; --ok
-SELECT rsecpolname, relname
-    FROM pg_rowsecurity rs
-    JOIN pg_class pc ON (pc.oid = rs.rsecrelid)
+SELECT polname, relname
+    FROM pg_policy pol
+    JOIN pg_class pc ON (pc.oid = pol.polrelid)
     WHERE relname = 't1';
- rsecpolname | relname 
--------------+---------
- p2          | t1
+ polname | relname 
+---------+---------
+ p2      | t1
 (1 row)
 
 --
@@ -2161,7 +2161,7 @@ SET row_security TO ON;
 COPY copy_t FROM STDIN; --ok
 SET row_security TO FORCE;
 COPY copy_t FROM STDIN; --fail - COPY FROM not supported by RLS.
-ERROR:  COPY FROM not supported with row security.
+ERROR:  COPY FROM not supported with row level security.
 HINT:  Use direct INSERT statements instead.
 -- Check COPY FROM as user with permissions.
 SET SESSION AUTHORIZATION rls_regress_user1;
@@ -2170,11 +2170,11 @@ COPY copy_t FROM STDIN; --fail - insufficient privilege to bypass rls.
 ERROR:  insufficient privilege to bypass row security.
 SET row_security TO ON;
 COPY copy_t FROM STDIN; --fail - COPY FROM not supported by RLS.
-ERROR:  COPY FROM not supported with row security.
+ERROR:  COPY FROM not supported with row level security.
 HINT:  Use direct INSERT statements instead.
 SET row_security TO FORCE;
 COPY copy_t FROM STDIN; --fail - COPY FROM not supported by RLS.
-ERROR:  COPY FROM not supported with row security.
+ERROR:  COPY FROM not supported with row level security.
 HINT:  Use direct INSERT statements instead.
 -- Check COPY TO as user with permissions and BYPASSRLS
 SET SESSION AUTHORIZATION rls_regress_exempt_user;
@@ -2182,11 +2182,11 @@ SET row_security TO OFF;
 COPY copy_t FROM STDIN; --ok
 SET row_security TO ON;
 COPY copy_t FROM STDIN; --fail - COPY FROM not supported by RLS.
-ERROR:  COPY FROM not supported with row security.
+ERROR:  COPY FROM not supported with row level security.
 HINT:  Use direct INSERT statements instead.
 SET row_security TO FORCE;
 COPY copy_t FROM STDIN; --fail - COPY FROM not supported by RLS.
-ERROR:  COPY FROM not supported with row security.
+ERROR:  COPY FROM not supported with row level security.
 HINT:  Use direct INSERT statements instead.
 -- Check COPY FROM as user without permissions.
 SET SESSION AUTHORIZATION rls_regress_user2;
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index c79b45c53a0fd2f233a6b389056532b4308445cd..80c3351291638cc8f37194f34e0eb773564616ca 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1355,18 +1355,18 @@ pg_matviews| SELECT n.nspname AS schemaname,
   WHERE (c.relkind = 'm'::"char");
 pg_policies| SELECT n.nspname AS schemaname,
     c.relname AS tablename,
-    rs.rsecpolname AS policyname,
+    pol.polname AS policyname,
         CASE
-            WHEN (rs.rsecroles = '{0}'::oid[]) THEN (string_to_array('public'::text, ''::text))::name[]
+            WHEN (pol.polroles = '{0}'::oid[]) THEN (string_to_array('public'::text, ''::text))::name[]
             ELSE ARRAY( SELECT pg_authid.rolname
                FROM pg_authid
-              WHERE (pg_authid.oid = ANY (rs.rsecroles))
+              WHERE (pg_authid.oid = ANY (pol.polroles))
               ORDER BY pg_authid.rolname)
         END AS roles,
         CASE
-            WHEN (rs.rseccmd IS NULL) THEN 'ALL'::text
+            WHEN (pol.polcmd IS NULL) THEN 'ALL'::text
             ELSE
-            CASE rs.rseccmd
+            CASE pol.polcmd
                 WHEN 'r'::"char" THEN 'SELECT'::text
                 WHEN 'a'::"char" THEN 'INSERT'::text
                 WHEN 'u'::"char" THEN 'UPDATE'::text
@@ -1374,10 +1374,10 @@ pg_policies| SELECT n.nspname AS schemaname,
                 ELSE NULL::text
             END
         END AS cmd,
-    pg_get_expr(rs.rsecqual, rs.rsecrelid) AS qual,
-    pg_get_expr(rs.rsecwithcheck, rs.rsecrelid) AS with_check
-   FROM ((pg_rowsecurity rs
-     JOIN pg_class c ON ((c.oid = rs.rsecrelid)))
+    pg_get_expr(pol.polqual, pol.polrelid) AS qual,
+    pg_get_expr(pol.polwithcheck, pol.polrelid) AS with_check
+   FROM ((pg_policy pol
+     JOIN pg_class c ON ((c.oid = pol.polrelid)))
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)));
 pg_prepared_statements| SELECT p.name,
     p.statement,
diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out
index 2c8ec118a754ccc296720f446b7069daf5daa638..c7be273ae166146fbd44a8f1afc5ba7f89e42f3e 100644
--- a/src/test/regress/expected/sanity_check.out
+++ b/src/test/regress/expected/sanity_check.out
@@ -118,10 +118,10 @@ pg_opclass|t
 pg_operator|t
 pg_opfamily|t
 pg_pltemplate|t
+pg_policy|t
 pg_proc|t
 pg_range|t
 pg_rewrite|t
-pg_rowsecurity|t
 pg_seclabel|t
 pg_shdepend|t
 pg_shdescription|t
diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql
index 2d5ddb4b8328b891b24018b003f267dc35e6da6b..181043f416489dccea0ec51930f0c89928691638 100644
--- a/src/test/regress/sql/rowsecurity.sql
+++ b/src/test/regress/sql/rowsecurity.sql
@@ -102,7 +102,7 @@ SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did;
 EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle);
 EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle);
 
--- only owner can change row-level security
+-- only owner can change policies
 ALTER POLICY p1 ON document USING (true);    --fail
 DROP POLICY p1 ON document;                  --fail
 
@@ -274,7 +274,7 @@ CREATE POLICY d1 ON dependent FOR ALL
     TO PUBLIC
     USING (x = (SELECT d.x FROM dependee d WHERE d.y = y));
 
-DROP TABLE dependee; -- Should fail without CASCADE due to dependency on row-security qual?
+DROP TABLE dependee; -- Should fail without CASCADE due to dependency on row security qual?
 
 DROP TABLE dependee CASCADE;
 
@@ -659,16 +659,16 @@ WITH cte1 AS (INSERT INTO t1 VALUES (20, 'Success') RETURNING *) SELECT * FROM c
 RESET SESSION AUTHORIZATION;
 ALTER POLICY p1 ON t1 RENAME TO p1; --fail
 
-SELECT rsecpolname, relname
-    FROM pg_rowsecurity rs
-    JOIN pg_class pc ON (pc.oid = rs.rsecrelid)
+SELECT polname, relname
+    FROM pg_policy pol
+    JOIN pg_class pc ON (pc.oid = pol.polrelid)
     WHERE relname = 't1';
 
 ALTER POLICY p1 ON t1 RENAME TO p2; --ok
 
-SELECT rsecpolname, relname
-    FROM pg_rowsecurity rs
-    JOIN pg_class pc ON (pc.oid = rs.rsecrelid)
+SELECT polname, relname
+    FROM pg_policy pol
+    JOIN pg_class pc ON (pc.oid = pol.polrelid)
     WHERE relname = 't1';
 
 --