Create this in your plpgsql function to make sure that the view and table share the same column names in the same sequence:
IF EXISTS ( SELECT 1 FROM ( SELECT * FROM pg_attribute WHERE attrelid = matview::regclass AND attisdropped = FALSE AND attnum > 0 ) t FULL OUTER JOIN ( SELECT * FROM pg_attribute WHERE attrelid = entry.v_name::regclass AND attisdropped = FALSE AND attnum > 0 ) v USING (attnum, attname)
FULL OUTER JOIN adds a NULL for any mismatch between the list of column names. So, if EXISTS finds a string, something is not working.
And casting to ::regclass will immediately throw an exception if any table or view does not exist (or outside the scope - not in search_path , and not as a schema).
If you also want to check the column data types, just add atttypid to the USING .
Aside: querying pg_catalog tables is regularly faster by an order of magnitude than querying for bloated views int information_schema - information_schema is only good for keeping SQL standard and code portable. Since you are writing 100% Postgres specific code, not here.
source share