Quotes taken from the documentation.
If you have the SUPER privilege, you can specify any syntactically legal account name. If the account does not actually exist, a warning is generated.
Being able to specify security accounts other than the view's creator is a key piece of using DEFINER, which you seem to have missed.
When a view has been referenced, privileges for objects accessed by the view are checked against the privileges held by the view DEFINER account...
This means that you can set the DEFINER to use a security account which has access to the underlying objects, but deny access to those objects to users at large, thus maintaining tighter security.
For example, say you have some table PrivateData, which users should not be able to generally access, but you want to create an internal report which tracks metadata on this table. You deny permissions on PrivateData to users, but create an account PrivateDataReader which has read-only access to the table. You can then create a view which presents the metadata information, specifying PrivateDataReader as the DEFINER.
If you always want to use the security of the user accessing the view, then you should specify INVOKER.
At the scope at which you're working. I think JSONB is ideal. It handles deeply nested structures and structures with array-keys. It's also standardized and in the spec for sql2016.
In addition, as I answered here, there is an extension that should help you with space consumption called ZSON,
ZSON is a PostgreSQL extension for transparent JSONB compression. Compression is based on a shared dictionary of strings most frequently used in specific JSONB documents (not only keys, but also values, array elements, etc).
In some cases ZSON can save half of your disk space and give you about 10% more TPS. Memory is saved as well. See docs/benchmark.md. Everything depends on your data and workload, though. Don't believe any benchmarks, re-check everything on your data, configuration, hardware, workload and PostgreSQL version.
You may want to look into ZSON.
Best Answer
pg_temp is always in the search path. If you don't add it to search_path parameter explicitly, it will behave as if it were there at the beginning of the setting. That means the user could create tables which masked the ones the function was supposed to operate on.