diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/psql/command.c | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 4fa7760a2a9..87adfce9c11 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -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; } |