Commit 9b66aa00 authored by Dean Rasheed's avatar Dean Rasheed

Fix psql's \ev and \sv commands so that they handle view reloptions.

Commit 8eb6407a added support for
editing and showing view definitions, but neglected to account for
view options such as security_barrier and WITH CHECK OPTION which are
not returned by pg_get_viewdef() and so need special handling.

Author: Dean Rasheed
Reviewed-by: Peter Eisentraut
Discussion: http://www.postgresql.org/message-id/CAEZATCWZjCgKRyM-agE0p8ax15j9uyQoF=qew7D2xB6cF76T8A@mail.gmail.com
parent 93a8c6fd
......@@ -3274,12 +3274,51 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid,
* CREATE for ourselves. We must fully qualify the view name to
* ensure the right view gets replaced. Also, check relation kind
* to be sure it's a view.
*
* Starting with 9.2, views may have reloptions (security_barrier)
* and from 9.4 onwards they may also have WITH [LOCAL|CASCADED]
* CHECK OPTION. These are not part of the view definition
* returned by pg_get_viewdef() and so need to be retrieved
* separately. Materialized views (introduced in 9.3) may have
* arbitrary storage parameter reloptions.
*/
printfPQExpBuffer(query,
"SELECT nspname, relname, relkind, pg_catalog.pg_get_viewdef(c.oid, true) FROM "
"pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n "
"ON c.relnamespace = n.oid WHERE c.oid = %u",
oid);
if (pset.sversion >= 90400)
{
printfPQExpBuffer(query,
"SELECT nspname, relname, relkind, "
"pg_catalog.pg_get_viewdef(c.oid, true), "
"array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption "
"FROM pg_catalog.pg_class c "
"LEFT JOIN pg_catalog.pg_namespace n "
"ON c.relnamespace = n.oid WHERE c.oid = %u",
oid);
}
else if (pset.sversion >= 90200)
{
printfPQExpBuffer(query,
"SELECT nspname, relname, relkind, "
"pg_catalog.pg_get_viewdef(c.oid, true), "
"c.reloptions AS reloptions, "
"NULL AS checkoption "
"FROM pg_catalog.pg_class c "
"LEFT JOIN pg_catalog.pg_namespace n "
"ON c.relnamespace = n.oid WHERE c.oid = %u",
oid);
}
else
{
printfPQExpBuffer(query,
"SELECT nspname, relname, relkind, "
"pg_catalog.pg_get_viewdef(c.oid, true), "
"NULL AS reloptions, "
"NULL AS checkoption "
"FROM pg_catalog.pg_class c "
"LEFT JOIN pg_catalog.pg_namespace n "
"ON c.relnamespace = n.oid WHERE c.oid = %u",
oid);
}
break;
}
......@@ -3304,6 +3343,8 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid,
char *relname = PQgetvalue(res, 0, 1);
char *relkind = PQgetvalue(res, 0, 2);
char *viewdef = PQgetvalue(res, 0, 3);
char *reloptions = PQgetvalue(res, 0, 4);
char *checkoption = PQgetvalue(res, 0, 5);
/*
* If the backend ever supports CREATE OR REPLACE
......@@ -3328,11 +3369,33 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid,
break;
}
appendPQExpBuffer(buf, "%s.", fmtId(nspname));
appendPQExpBuffer(buf, "%s AS\n", fmtId(relname));
appendPQExpBufferStr(buf, viewdef);
appendPQExpBufferStr(buf, fmtId(relname));
/* reloptions, if not an empty array "{}" */
if (reloptions != NULL && strlen(reloptions) > 2)
{
appendPQExpBufferStr(buf, "\n WITH (");
if (!appendReloptionsArray(buf, reloptions, "",
pset.encoding,
standard_strings()))
{
psql_error("Could not parse reloptions array\n");
result = false;
}
appendPQExpBufferStr(buf, ")");
}
/* View definition from pg_get_viewdef (a SELECT query) */
appendPQExpBuffer(buf, " AS\n%s", viewdef);
/* Get rid of the semicolon that pg_get_viewdef appends */
if (buf->len > 0 && buf->data[buf->len - 1] == ';')
buf->data[--(buf->len)] = '\0';
/* WITH [LOCAL|CASCADED] CHECK OPTION */
if (checkoption && checkoption[0] != '\0')
appendPQExpBuffer(buf, "\n WITH %s CHECK OPTION",
checkoption);
}
break;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment