Where is pg_shadow table located? - sql

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.

Related

Permission denied for schema pg_toast while querying sequences

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';

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.

How to filter Postgres enums by database?

I can get enums, but I don't know how to filter it by database.
SELECT * FROM pg_catalog.pg_type t WHERE t.typtype = 'e';
That is the question — how to filter enums by database?
pg_catalog.pg_type is not a shared catalog. It's per-database. So by definition, if a row appears in pg_type it's in the database you are currently connected to.
The schema ("namespace") it's in is defined by the typnamespace column, which you can join to pg_catalog.pg_namespace.oid e.g.
select typname, nspname
from pg_type
inner join pg_namespace on pg_type.typnamespace = pg_namespace.oid
where nspname = 'public';

Can I select a field from data type?

Can I select a field/column from data type?
Postgres 7.4 (yep we are upgrading)
SELECT *
FROM tbl_name
WHERE tbl_name.column = 'timestamp with time zone'
That requires metadata.
select column_name
from information_schema.columns
where table_schema='your_schema'
and table_name='tbl_name'
and data_type='timestamp without time zone'
order by ordinal_position;
ETA: If you want the actual data from the table with column names matching the list above, you could probably set up a user-defined function that would grab those column names, put them in a comma-delimited list, and parse the query from tbl_name appropriately (of course, this is a lot easier if you're working in a scripting language slightly outside of the database).
I had to do that recently. To ease things I defined two views :
CREATE VIEW view_table_columns AS
SELECT n.nspname AS schema, cl.relname AS table_name,
a.attname AS column_name, ty.typname AS data_type,
a.attnotnull AS nnull,
a.atthasdef AS hasdef,
descr.description AS descr, cl.oid AS tableoid, a.attnum AS colnum
FROM pg_attribute a
JOIN pg_class cl ON a.attrelid = cl.oid AND cl.relkind = 'r'::"char"
JOIN pg_namespace n ON n.oid = cl.relnamespace
JOIN pg_type ty ON ty.oid = a.atttypid
LEFT JOIN pg_description descr
ON descr.objoid = cl.oid AND descr.objsubid = a.attnum
WHERE a.attnum > 0 AND NOT a.attisdropped
AND n.nspname !~~ 'pg_%'::text
AND n.nspname <> 'information_schema'::name;
COMMENT ON VIEW view_table_columns IS 'Lista all fields of all tables';
CREATE VIEW view_table_columns2 AS
SELECT view_table_columns.*,
( SELECT count(*) AS count
FROM pg_index
WHERE pg_index.indrelid = pg_index.tableoid AND
(view_table_columns.colnum = ANY (pg_index.indkey::smallint[]))) AS indexes
FROM view_table_columns;
COMMENT ON VIEW view_table_columns2 IS 'Adds to view_table_columns info about indexed fields';
That includes, for every field in your tables the following info:
schema name
table name
column name
data_type name
is nullable?
has default value?
description (comment)
tableoid (handy if you need to get more data from catalog)
column number (idem)
indexes (in second view - number of indexes that refer to this column)

List all NON-GENERATED sequences for a schema in PostgreSQL

In PostgreSQL there are 2 types of sequences:
Sequences created by the user using CREATE SEQUENCE
Sequences generated by the DB to back a column of type SERIAL
INFORMATION_SCHEMA.SEQUENCES returns both types of sequences.
What SQL statement can get a list of the sequences created by the user (WITHOUT the ones generated by the DB) for a specific schema?
P.S.: I'm using PostgreSQL 9
For a generated sequence the "owning" column will be defined automatically so that could be a distinguishing factor.
But that can be done manually as well, so there is no way to tell the difference between:
create table foo (
id_col serial not null
);
and
create table foo (
id_col integer not null
);
create sequence foo_id_col_seq owned by foo.id_col;
But if that is OK for you, the following statement can get you that information:
SELECT s.relname as sequence_name,
t.relname as related_table,
a.attname as related_column,
d.deptype
FROM pg_class s
JOIN pg_depend d ON d.objid = s.oid
LEFT JOIN pg_class t ON d.refobjid = t.oid
LEFT JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)
WHERE s.relkind = 'S';
You'll get at least one row for each sequence by that query: the dependency on the schema it was created in.
For a sequence owned by a column you'll get another row with the table and column it belongs to.
The only difference may (at the least) be where it is defined. Entering \d yourtable will list serials in the modifiers column as nextval(...), but sequences defined afterward will not. pg_catalog.attr_def holds data to the actual strings that were used for definition.
I agree with horse that functionally there is no difference. Its akin to declaring something on one line or two but the same exact things happens. The DB is generating all these sequences and there is no user sequences. The only difference is in how they are declared and the only way this information is persisted is the actual strings that defined the column are held in the system catalogs.
From the system tables:
create view check_seq as
SELECT a.attname,
relname,
(
SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
FROM pg_catalog.pg_attrdef d
WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef
) as "column def"
FROM pg_catalog.pg_attribute a
join pg_catalog.pg_class c on a.attrelid = c.oid
WHERE a.attnum > 0 AND NOT a.attisdropped
and c.relname in ('foo')
ORDER BY a.attnum
;
Examples:
create table foo (
id_col serial not null
);
select * from check_seq;
attname | relname | column def
---------+---------+-------------------------------------
id_col | foo | nextval('foo_id_col_seq'::regclass)
drop table foo;
create table foo (
id_col integer not null
);
create sequence foo_id_col_seq owned by foo.id_col;
select * from check_seq;
attname | relname | column def
---------+---------+------------
id_col | foo |