@@ -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