Permission denied for schema pg_toast while querying sequences - sql

The goal is to get the table and column which are "using" a sequence, and the query I've come up with is this:
select attrelid::regclass::text, attname
from pg_attribute
where pg_get_serial_sequence(attrelid::regclass::text, attname) = 'public.websession_idcntr_seq';
It's inefficient so any other suggestions are also welcome, but the problem at hand is that this breaks with the following error:
ERROR: permission denied for schema pg_toast
So the next thing I did was try to avoid pg_toast:
select attrelid::regclass::text, attname
from pg_attribute
join pg_class tbl on tbl.oid = pg_attribute.attrelid
join pg_namespace nsp on tbl.relnamespace = nsp.oid
where
nsp.nspname != 'pg_toast'
and pg_get_serial_sequence(attrelid::regclass::text, attname) = 'public.websession_idcntr_seq';
That also fails with exactly the same message.
I have no intention of doing anything with the pg_toast schema, and I can't run this under a superuser account. (EDIT: And I can't modify permissions to get around that).
Why doesn't the workaround with nspname != 'pg_toast' work?
Is there a better way to do this whole operation?

SQL does not guarantee you a certain order in which the conditions in the WHERE clause are evaluated, and EXPLAIN will show you that pg_get_serial_sequence (which causes the error) is executed first.
Try the following that excludes the offending tables earlier on:
SELECT t.oid::regclass, a.attname
FROM pg_class AS t
JOIN pg_attribute AS a ON t.oid = a.attrelid
WHERE t.relkind IN ('r', 'p') /* only normal and partitioned tables */
AND pg_get_serial_sequence(t.oid::regclass::text, attname)
= 'public.websession_idcntr_seq';

Related

How to list the columns of a view in Postgres?

For a physical table, I have been using the following SQL:
select column_name, data_type, character_maximum_length
from INFORMATION_SCHEMA.COLUMNS
where table_name = 'a_table_name'
I found that this doesn't work for a view. Is there a way to get the schema of a view by running a SQL command (not via psql).
Postgres has dedicated System Catalog Information Functions to help with that.
To get the full view definition:
SELECT pg_get_viewdef('public.view_name');
Schema-qualification is optional. If no schema is prefixed, the current search_path setting decides visibility.
A quick hack would be to just:
SELECT * FROM public.view_name LIMIT 0;
Depending on your client, column names and types should still be displayed. Or LIMIT n to get some sample values, too. The underlying query is actually executed then (unlike with LIMIT 0).
To list columns and their data type, in order, you might base the query on pg_attribute:
SELECT attname AS column_name, format_type(atttypid, atttypmod) AS data_type
FROM pg_attribute
WHERE attrelid = 'public.view_name'::regclass
-- AND NOT attisdropped
-- AND attnum > 0
ORDER BY attnum;
Type modifiers like maximum length are included in data_type this way.
Internally, a VIEW is implemented as special table with a rewrite rule. Details in the manual here. The table is saved in the system catalogs much like any regular table.
About the cast to regclass:
How to check if a table exists in a given schema
The same query works for tables or materialized views as well. Uncomment the additional filters above to only get visible user columns for tables.
SELECT
a.attname,
t.typname,
a.atttypmod
FROM pg_class c
INNER JOIN pg_attribute a ON a.attrelid = c.oid
INNER JOIN pg_type t ON t.oid = a.atttypid
WHERE c.relkind = 'v'
AND c.relname = 'put_viewname_here';
ATTENTION: Since the viewname is unique only in the schema, you might also want to add an INNER JOIN to pg_namespace and add a condition to the where-clause.
For the first version of your question:
SELECT n.nspname
FROM pg_class c
INNER JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'v'
AND c.relname = 'put_viewname_here';
ATTENTION: This might give you multiple schemas, since a viewname is only unique inside a schema and thus a viewname does not always identify one view.

Where is pg_shadow table located?

Hello I am checking pg_catalog database and I cannot see pg_shadow table is it normal? Basically I want to retrieve users and passwords pg_user is showing ****** always also it doesn't show pg_user here but when I run select * from pg_user it's working is it normal?
I see only these tables below at pg_catalog. How can I get stored hashes except that table?
pg_aggregate
pg_am
pg_amop
pg_amproc
pg_attrdef
pg_attribute
pg_auth_members
pg_cast
pg_class
pg_constraint
pg_conversion
pg_database
pg_depend
pg_description
pg_enum
pg_foreign_data_wrapper
pg_foreign_server
pg_index
pg_inherits
pg_language
pg_largeobject
pg_listener
pg_namespace
pg_opclass
pg_operator
pg_opfamily
pg_pltemplate
pg_proc
pg_rewrite
pg_shdepend
pg_shdescription
pg_statistic
pg_suthid
pg_tablespace
pg_trigger
pg_ts_config
pg_ts_config_map
pg_ts_dict
pg_ts_parser
pg_ts_template
pg_type
pg_user_mapping
It's a view, not a table. It's in pg_catalog.
The base table is pg_authid.
All tables with passwords in them are superuser only.

PostgreSQL: getting all functions related to table

I have this function:
SELECT n.nspname AS schema_name
,p.proname AS function_name
,pg_get_function_arguments(p.oid) AS args
,pg_get_functiondef(p.oid) AS func_def
FROM (SELECT oid, * FROM pg_proc p WHERE NOT p.proisagg) p
JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname !~~ 'pg_%'
AND n.nspname <> 'information_schema'
AND pg_get_functiondef(p.oid) ~ '\mTableName\M';
it gives me a list of functions that uses TableName. However it doesn't ignore notes. For example if in function A there will be a line like:
-- select * from TableName
it will show A in the result even though its a note and A doesn't really uses TableName.
How can I make a query that does the same thing but ignore all notes?
You may find everything you need directly on this wiki page : https://wiki.postgresql.org/wiki/Pg_depend_display
There is all sorts of dependency views depending on you PostgreSQL version.

What select query will list domains within Postgres?

I'm aware of the psql command that will list these, but I'm attempting to write an extension for Oracle's SQL Developer that will list them on the left-hand navigator panel. The XML format requires a select statement.
For example purposes, I'll include the code I cooked up for sequences:
<sql constrained="true">
<![CDATA[SELECT relname FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace WHERE relkind = 'S' AND nspname = :SCHEMA]]>
</sql>
I've attempted to figure it out for myself, but I don't see anything with my test domain names in pg_class or any other of those internal tables (though it must be in one, somewhere).
Does anyone have a hint?
Asked too soon... here's a select query that will return domains from a specific schema:
SELECT typname FROM pg_catalog.pg_type JOIN pg_catalog.pg_namespace ON pg_namespace.oid = pg_type.typnamespace WHERE typtype = 'd' AND nspname = 'someschema'
Minor tweaking can also return enums, ranges, and composites/rows. More information in the docs.

cant delete data from postgresql

I'm quite new to PostgreSQL, so maybe I'm getting some noob error I cannot recognize, so please, tell me why I cannot get this data deleted.
This is what is happening:
DELETE FROM userprofile WHERE user LIKE (SELECT User FROM User WHERE username LIKE 'testuser');
ERROR: column "username" does not exist
LINE 1: ...file WHERE user LIKE (SELECT User FROM User WHERE username L...
As I'm using django user, I know that username does exists, so, how can I get it deleted?
Chances are (stab in the dark for lack of information) you didn't think of lower-case names.
Start by reading the manual about identifiers.
What do you get for:
SELECT n.nspname, c.relname, a.attnum, a.attname
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname ilike 'user'
AND NOT a.attisdropped -- no dropped (dead) columns
AND a.attnum > 0 -- no system cols
ORDER BY 1,2,3
Pay attention to capitalization of identifiers. Why? Follow the link to the manual above.
You also seem to be confusing the name of a column with a value stored in this column. The error message complains about the name, because it does not exist.
And you should never use reserved words like user as identifiers to avoid problems like the one at hand. Those need to be enclosed in double-quotes at all times.