|
|
|
@ -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. |
|
|
|
|
*/ |
|
|
|
|
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) FROM " |
|
|
|
|
"pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n " |
|
|
|
|
"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; |
|
|
|
|
} |
|
|
|
|