mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 13:51:23 +02:00
Fix CreatePolicy, pg_dump -v; psql and doc updates
Peter G pointed out that valgrind was, rightfully, complaining about CreatePolicy() ending up copying beyond the end of the parsed policy name. Name is a fixed-size type and we need to use namein (through DirectFunctionCall1()) to flush out the entire array before we pass it down to heap_form_tuple. Michael Paquier pointed out that pg_dump --verbose was missing a newline and Fabrízio de Royes Mello further pointed out that the schema was also missing from the messages, so fix those also. Also, based on an off-list comment from Kevin, rework the psql \d output to facilitate copy/pasting into a new CREATE or ALTER POLICY command. Lastly, improve the pg_policies view and update the documentation for it, along with a few other minor doc corrections based on an off-list discussion with Adam Brightwell.
This commit is contained in:
parent
5968570430
commit
78d72563ef
@ -5396,6 +5396,13 @@
|
|||||||
<entry>The command type to which the row-security policy is applied.</entry>
|
<entry>The command type to which the row-security policy is applied.</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><structfield>rsecroles</structfield></entry>
|
||||||
|
<entry><type>char</type></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>The roles to which the row-security policy is applied.</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><structfield>rsecqual</structfield></entry>
|
<entry><structfield>rsecqual</structfield></entry>
|
||||||
<entry><type>pg_node_tree</type></entry>
|
<entry><type>pg_node_tree</type></entry>
|
||||||
@ -5417,8 +5424,8 @@
|
|||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
<literal>pg_class.relrowsecurity</literal>
|
<literal>pg_class.relrowsecurity</literal>
|
||||||
True if the table has row-security enabled.
|
True if the table has row-security enabled. Policies will not be applied
|
||||||
Must be true if the table has a row-security policy in this catalog.
|
unless row-security is enabled on the table.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
@ -7299,6 +7306,11 @@
|
|||||||
<entry>materialized views</entry>
|
<entry>materialized views</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry><link linkend="view-pg-policies"><structname>pg_policies</structname></link></entry>
|
||||||
|
<entry>policies</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><link linkend="view-pg-prepared-statements"><structname>pg_prepared_statements</structname></link></entry>
|
<entry><link linkend="view-pg-prepared-statements"><structname>pg_prepared_statements</structname></link></entry>
|
||||||
<entry>prepared statements</entry>
|
<entry>prepared statements</entry>
|
||||||
@ -8146,6 +8158,81 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
|
|||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
<sect1 id="view-pg-policies">
|
||||||
|
<title><structname>pg_policies</structname></title>
|
||||||
|
|
||||||
|
<indexterm zone="view-pg-policies">
|
||||||
|
<primary>pg_policies</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The view <structname>pg_policies</structname> provides access to
|
||||||
|
useful information about each policy in the database.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<title><structname>pg_policies</> Columns</title>
|
||||||
|
|
||||||
|
<tgroup cols="4">
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>Name</entry>
|
||||||
|
<entry>Type</entry>
|
||||||
|
<entry>References</entry>
|
||||||
|
<entry>Description</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>schemaname</structfield></entry>
|
||||||
|
<entry><type>name</type></entry>
|
||||||
|
<entry><literal><link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.nspname</literal></entry>
|
||||||
|
<entry>Name of schema containing table policy is on</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>tablename</structfield></entry>
|
||||||
|
<entry><type>name</type></entry>
|
||||||
|
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.relname</literal></entry>
|
||||||
|
<entry>Name of table policy is on</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>policyname</structfield></entry>
|
||||||
|
<entry><type>name</type></entry>
|
||||||
|
<entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.relname</literal></entry>
|
||||||
|
<entry>Name of policy</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>cmd</structfield></entry>
|
||||||
|
<entry><type>text</type></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>The command type to which the policy is applied.</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>roles</structfield></entry>
|
||||||
|
<entry><type>name[]</type></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>The roles to which this policy applies.</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>qual</structfield></entry>
|
||||||
|
<entry><type>text</type></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>The expression added to the security barrier qualifications for
|
||||||
|
queries which this policy applies to.</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><structfield>with_check</structfield></entry>
|
||||||
|
<entry><type>text</type></entry>
|
||||||
|
<entry></entry>
|
||||||
|
<entry>The expression added to the with check qualifications for
|
||||||
|
queries which attempt to add rows to this table.</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="view-pg-prepared-statements">
|
<sect1 id="view-pg-prepared-statements">
|
||||||
<title><structname>pg_prepared_statements</structname></title>
|
<title><structname>pg_prepared_statements</structname></title>
|
||||||
|
|
||||||
|
@ -65,8 +65,9 @@ CREATE VIEW pg_user AS
|
|||||||
|
|
||||||
CREATE VIEW pg_policies AS
|
CREATE VIEW pg_policies AS
|
||||||
SELECT
|
SELECT
|
||||||
|
N.nspname AS schemaname,
|
||||||
|
C.relname AS tablename,
|
||||||
rs.rsecpolname AS policyname,
|
rs.rsecpolname AS policyname,
|
||||||
(SELECT relname FROM pg_catalog.pg_class WHERE oid = rs.rsecrelid) AS tablename,
|
|
||||||
CASE
|
CASE
|
||||||
WHEN rs.rsecroles = '{0}' THEN
|
WHEN rs.rsecroles = '{0}' THEN
|
||||||
string_to_array('public', '')
|
string_to_array('public', '')
|
||||||
@ -89,7 +90,8 @@ CREATE VIEW pg_policies AS
|
|||||||
pg_catalog.pg_get_expr(rs.rsecqual, rs.rsecrelid) AS qual,
|
pg_catalog.pg_get_expr(rs.rsecqual, rs.rsecrelid) AS qual,
|
||||||
pg_catalog.pg_get_expr(rs.rsecwithcheck, rs.rsecrelid) AS with_check
|
pg_catalog.pg_get_expr(rs.rsecwithcheck, rs.rsecrelid) AS with_check
|
||||||
FROM pg_catalog.pg_rowsecurity rs
|
FROM pg_catalog.pg_rowsecurity rs
|
||||||
ORDER BY 1;
|
JOIN pg_catalog.pg_class C ON (C.oid = rs.rsecrelid)
|
||||||
|
LEFT JOIN pg_catalog.pg_namespace N ON (N.oid = C.relnamespace);
|
||||||
|
|
||||||
CREATE VIEW pg_rules AS
|
CREATE VIEW pg_rules AS
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -556,7 +556,7 @@ CreatePolicy(CreatePolicyStmt *stmt)
|
|||||||
|
|
||||||
values[Anum_pg_rowsecurity_rsecrelid - 1] = ObjectIdGetDatum(table_id);
|
values[Anum_pg_rowsecurity_rsecrelid - 1] = ObjectIdGetDatum(table_id);
|
||||||
values[Anum_pg_rowsecurity_rsecpolname - 1]
|
values[Anum_pg_rowsecurity_rsecpolname - 1]
|
||||||
= CStringGetDatum(stmt->policy_name);
|
= DirectFunctionCall1(namein, CStringGetDatum(stmt->policy_name));
|
||||||
|
|
||||||
if (rseccmd)
|
if (rseccmd)
|
||||||
values[Anum_pg_rowsecurity_rseccmd - 1] = CharGetDatum(rseccmd);
|
values[Anum_pg_rowsecurity_rseccmd - 1] = CharGetDatum(rseccmd);
|
||||||
|
@ -2803,7 +2803,8 @@ getRowSecurity(Archive *fout, TableInfo tblinfo[], int numTables)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (g_verbose)
|
if (g_verbose)
|
||||||
write_msg(NULL, "reading row-security enabled for table \"%s\"",
|
write_msg(NULL, "reading row-security enabled for table \"%s\".\"%s\"\n",
|
||||||
|
tbinfo->dobj.namespace->dobj.name,
|
||||||
tbinfo->dobj.name);
|
tbinfo->dobj.name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2833,7 +2834,8 @@ getRowSecurity(Archive *fout, TableInfo tblinfo[], int numTables)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (g_verbose)
|
if (g_verbose)
|
||||||
write_msg(NULL, "reading row-security policies for table \"%s\"\n",
|
write_msg(NULL, "reading row-security policies for table \"%s\".\"%s\"\n",
|
||||||
|
tbinfo->dobj.namespace->dobj.name,
|
||||||
tbinfo->dobj.name);
|
tbinfo->dobj.name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2011,10 +2011,15 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
|
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT rs.rsecpolname,\n"
|
"SELECT rs.rsecpolname,\n"
|
||||||
"CASE WHEN rs.rsecroles = '{0}' THEN NULL ELSE array(select rolname from pg_roles where oid = any (rs.rsecroles) order by 1) END,\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.rsecqual, rs.rsecrelid),\n"
|
||||||
"pg_catalog.pg_get_expr(rs.rsecwithcheck, rs.rsecrelid),\n"
|
"pg_catalog.pg_get_expr(rs.rsecwithcheck, rs.rsecrelid),\n"
|
||||||
"rs.rseccmd AS cmd\n"
|
"CASE rs.rseccmd \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"
|
"FROM pg_catalog.pg_rowsecurity rs\n"
|
||||||
"WHERE rs.rsecrelid = '%s' ORDER BY 1;",
|
"WHERE rs.rsecrelid = '%s' ORDER BY 1;",
|
||||||
oid);
|
oid);
|
||||||
@ -2046,26 +2051,25 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
PQgetvalue(result, i, 0));
|
PQgetvalue(result, i, 0));
|
||||||
|
|
||||||
if (!PQgetisnull(result, i, 4))
|
if (!PQgetisnull(result, i, 4))
|
||||||
appendPQExpBuffer(&buf, " (%s)",
|
appendPQExpBuffer(&buf, " FOR %s",
|
||||||
PQgetvalue(result, i, 4));
|
PQgetvalue(result, i, 4));
|
||||||
|
|
||||||
|
if (!PQgetisnull(result, i, 1))
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(&buf, "\n TO %s",
|
||||||
|
PQgetvalue(result, i, 1));
|
||||||
|
}
|
||||||
|
|
||||||
if (!PQgetisnull(result, i, 2))
|
if (!PQgetisnull(result, i, 2))
|
||||||
appendPQExpBuffer(&buf, " EXPRESSION %s",
|
appendPQExpBuffer(&buf, "\n USING %s",
|
||||||
PQgetvalue(result, i, 2));
|
PQgetvalue(result, i, 2));
|
||||||
|
|
||||||
if (!PQgetisnull(result, i, 3))
|
if (!PQgetisnull(result, i, 3))
|
||||||
appendPQExpBuffer(&buf, " WITH CHECK %s",
|
appendPQExpBuffer(&buf, "\n WITH CHECK %s",
|
||||||
PQgetvalue(result, i, 3));
|
PQgetvalue(result, i, 3));
|
||||||
|
|
||||||
printTableAddFooter(&cont, buf.data);
|
printTableAddFooter(&cont, buf.data);
|
||||||
|
|
||||||
if (!PQgetisnull(result, i, 1))
|
|
||||||
{
|
|
||||||
printfPQExpBuffer(&buf, " APPLIED TO %s",
|
|
||||||
PQgetvalue(result, i, 1));
|
|
||||||
|
|
||||||
printTableAddFooter(&cont, buf.data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PQclear(result);
|
PQclear(result);
|
||||||
}
|
}
|
||||||
|
@ -1353,10 +1353,9 @@ pg_matviews| SELECT n.nspname AS schemaname,
|
|||||||
LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
|
LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
|
||||||
LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace)))
|
LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace)))
|
||||||
WHERE (c.relkind = 'm'::"char");
|
WHERE (c.relkind = 'm'::"char");
|
||||||
pg_policies| SELECT rs.rsecpolname AS policyname,
|
pg_policies| SELECT n.nspname AS schemaname,
|
||||||
( SELECT pg_class.relname
|
c.relname AS tablename,
|
||||||
FROM pg_class
|
rs.rsecpolname AS policyname,
|
||||||
WHERE (pg_class.oid = rs.rsecrelid)) AS tablename,
|
|
||||||
CASE
|
CASE
|
||||||
WHEN (rs.rsecroles = '{0}'::oid[]) THEN (string_to_array('public'::text, ''::text))::name[]
|
WHEN (rs.rsecroles = '{0}'::oid[]) THEN (string_to_array('public'::text, ''::text))::name[]
|
||||||
ELSE ARRAY( SELECT pg_authid.rolname
|
ELSE ARRAY( SELECT pg_authid.rolname
|
||||||
@ -1377,8 +1376,9 @@ pg_policies| SELECT rs.rsecpolname AS policyname,
|
|||||||
END AS cmd,
|
END AS cmd,
|
||||||
pg_get_expr(rs.rsecqual, rs.rsecrelid) AS qual,
|
pg_get_expr(rs.rsecqual, rs.rsecrelid) AS qual,
|
||||||
pg_get_expr(rs.rsecwithcheck, rs.rsecrelid) AS with_check
|
pg_get_expr(rs.rsecwithcheck, rs.rsecrelid) AS with_check
|
||||||
FROM pg_rowsecurity rs
|
FROM ((pg_rowsecurity rs
|
||||||
ORDER BY rs.rsecpolname;
|
JOIN pg_class c ON ((c.oid = rs.rsecrelid)))
|
||||||
|
LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)));
|
||||||
pg_prepared_statements| SELECT p.name,
|
pg_prepared_statements| SELECT p.name,
|
||||||
p.statement,
|
p.statement,
|
||||||
p.prepare_time,
|
p.prepare_time,
|
||||||
|
Loading…
Reference in New Issue
Block a user