Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9b66aa0

Browse files
committed
Fix psql's \ev and \sv commands so that they handle view reloptions.
Commit 8eb6407 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
1 parent 93a8c6f commit 9b66aa0

File tree

1 file changed

+70
-7
lines changed

1 file changed

+70
-7
lines changed

src/bin/psql/command.c

+70-7
Original file line numberDiff line numberDiff line change
@@ -3274,12 +3274,51 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid,
32743274
* CREATE for ourselves. We must fully qualify the view name to
32753275
* ensure the right view gets replaced. Also, check relation kind
32763276
* to be sure it's a view.
3277+
*
3278+
* Starting with 9.2, views may have reloptions (security_barrier)
3279+
* and from 9.4 onwards they may also have WITH [LOCAL|CASCADED]
3280+
* CHECK OPTION. These are not part of the view definition
3281+
* returned by pg_get_viewdef() and so need to be retrieved
3282+
* separately. Materialized views (introduced in 9.3) may have
3283+
* arbitrary storage parameter reloptions.
32773284
*/
3278-
printfPQExpBuffer(query,
3279-
"SELECT nspname, relname, relkind, pg_catalog.pg_get_viewdef(c.oid, true) FROM "
3280-
"pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n "
3281-
"ON c.relnamespace = n.oid WHERE c.oid = %u",
3282-
oid);
3285+
if (pset.sversion >= 90400)
3286+
{
3287+
printfPQExpBuffer(query,
3288+
"SELECT nspname, relname, relkind, "
3289+
"pg_catalog.pg_get_viewdef(c.oid, true), "
3290+
"array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
3291+
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
3292+
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption "
3293+
"FROM pg_catalog.pg_class c "
3294+
"LEFT JOIN pg_catalog.pg_namespace n "
3295+
"ON c.relnamespace = n.oid WHERE c.oid = %u",
3296+
oid);
3297+
}
3298+
else if (pset.sversion >= 90200)
3299+
{
3300+
printfPQExpBuffer(query,
3301+
"SELECT nspname, relname, relkind, "
3302+
"pg_catalog.pg_get_viewdef(c.oid, true), "
3303+
"c.reloptions AS reloptions, "
3304+
"NULL AS checkoption "
3305+
"FROM pg_catalog.pg_class c "
3306+
"LEFT JOIN pg_catalog.pg_namespace n "
3307+
"ON c.relnamespace = n.oid WHERE c.oid = %u",
3308+
oid);
3309+
}
3310+
else
3311+
{
3312+
printfPQExpBuffer(query,
3313+
"SELECT nspname, relname, relkind, "
3314+
"pg_catalog.pg_get_viewdef(c.oid, true), "
3315+
"NULL AS reloptions, "
3316+
"NULL AS checkoption "
3317+
"FROM pg_catalog.pg_class c "
3318+
"LEFT JOIN pg_catalog.pg_namespace n "
3319+
"ON c.relnamespace = n.oid WHERE c.oid = %u",
3320+
oid);
3321+
}
32833322
break;
32843323
}
32853324

@@ -3304,6 +3343,8 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid,
33043343
char *relname = PQgetvalue(res, 0, 1);
33053344
char *relkind = PQgetvalue(res, 0, 2);
33063345
char *viewdef = PQgetvalue(res, 0, 3);
3346+
char *reloptions = PQgetvalue(res, 0, 4);
3347+
char *checkoption = PQgetvalue(res, 0, 5);
33073348

33083349
/*
33093350
* If the backend ever supports CREATE OR REPLACE
@@ -3328,11 +3369,33 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid,
33283369
break;
33293370
}
33303371
appendPQExpBuffer(buf, "%s.", fmtId(nspname));
3331-
appendPQExpBuffer(buf, "%s AS\n", fmtId(relname));
3332-
appendPQExpBufferStr(buf, viewdef);
3372+
appendPQExpBufferStr(buf, fmtId(relname));
3373+
3374+
/* reloptions, if not an empty array "{}" */
3375+
if (reloptions != NULL && strlen(reloptions) > 2)
3376+
{
3377+
appendPQExpBufferStr(buf, "\n WITH (");
3378+
if (!appendReloptionsArray(buf, reloptions, "",
3379+
pset.encoding,
3380+
standard_strings()))
3381+
{
3382+
psql_error("Could not parse reloptions array\n");
3383+
result = false;
3384+
}
3385+
appendPQExpBufferStr(buf, ")");
3386+
}
3387+
3388+
/* View definition from pg_get_viewdef (a SELECT query) */
3389+
appendPQExpBuffer(buf, " AS\n%s", viewdef);
3390+
33333391
/* Get rid of the semicolon that pg_get_viewdef appends */
33343392
if (buf->len > 0 && buf->data[buf->len - 1] == ';')
33353393
buf->data[--(buf->len)] = '\0';
3394+
3395+
/* WITH [LOCAL|CASCADED] CHECK OPTION */
3396+
if (checkoption && checkoption[0] != '\0')
3397+
appendPQExpBuffer(buf, "\n WITH %s CHECK OPTION",
3398+
checkoption);
33363399
}
33373400
break;
33383401
}

0 commit comments

Comments
 (0)