Understanding the output of PSQL's \dp and \z - postgresql

I'm having trouble selecting from a database in PSQL. This is the output of the table I'm interested in. Can someone decipher the access priveleges for me? I know that arwdRxt means append,read,write,etc... The syntax is confusing to me, what exactly do the slashes and equals mean in the access privileges column? Please let me know if my question isn't clear.
Access privileges
schema | name | type | access privileges
--------+---------------+------+-------------------------
public | table_name | view | amazonuser=arwdRxt/amazonuser+
| | | readonly=r/amazonuser

It is described in detail in the docs. The thing before the = is who has those permissions, the thing after the / is who granted those permissions.

From the docs:
Privilege Abbreviation Applicable Object Types
SELECT r (“read”) LARGE OBJECT, SEQUENCE, TABLE (and table-like objects), table column
INSERT a (“append”) TABLE, table column
UPDATE w (“write”) LARGE OBJECT, SEQUENCE, TABLE, table column
DELETE d TABLE
TRUNCATE D TABLE
REFERENCES x TABLE, table column
TRIGGER t TABLE
CREATE C DATABASE, SCHEMA, TABLESPACE
CONNECT c DATABASE
TEMPORARY T DATABASE
EXECUTE X FUNCTION, PROCEDURE
USAGE U DOMAIN, FOREIGN DATA WRAPPER, FOREIGN SERVER, LANGUAGE, SCHEMA, SEQUENCE, TYPE

Related

How can I show the catalogs and schemas in postgresql?

From https://stackoverflow.com/a/17943883/156458
in both Postgres and the SQL Standard we have this containment
hierarchy:
A computer may have one cluster or multiple.
A database server is a cluster.
A cluster has [catalogs][8]. ( Catalog = Database )
Catalogs have [schemas][9]. (Schema = [namespace][10] of tables, and security boundary)
Schemas have [tables][11].
Tables have [rows][12].
Rows have values, defined by [columns][13].
In postgresql, I have a database called students and there is a table called student under it:
postgres=# \c students
You are now connected to database "students" as user "postgres".
students=# \dt;
public | student | table | postgres
I was wondering if database students is also a catalog?
Where is the schema between students and student?
In general, how can I list
all the catalogs and
all the schemas under a catalog, and
all the tables under a schema?
How can I show
the current catalog, and
the current schema?
Thanks.
In shortly, I usually explain to my junior teammate when they starting to research about PostgreSQL.
In PostgreSQL:
A Database Server is like an Industrial Zone, there will have many Databases-Cluster (Building)
Each Database-Cluster (Building) have many Databases. Those are like the floors in Building. The Databases is here as you call the Catalogs. Those Databases-Catalogs (floors) are quite independent with each other, you can not using others materials directly, you must use somethings just like stair, electric wire ... (in database is DBLINK).
Okay, next, each Database-Catalogs have many Schemas, which are like many Rooms on your floors. Those Schemas can use the material from each others.
Then, each Schemas have many cell elements such as Table, View, Function, Sequence .... All schemas have the same structure.
Now, back to you example:
students: is Database (which you call Catalogs)
public: is schema.
student: is table.
public | student | table | postgres is corresponding with schema | table | kind of table | owner of table
You can list:
catalogs (Database) by the command \l in psql or query select * from pg_database;
Schemas under a catalog by the command \dn in psql or query select * from information_schema.schemata;
Tables under a schemas by the query select * from pg_tables WHERE schemaname = 'Your schema';
You can show:
Current Database (Catalogs) by the query select current_database();
Current Schema by the query select current_schema;
Please pay attention that PostgreSQL have two system schema call information_schema and pg_catalog, this maybe make you confuse.
The pg_catalog is a system schema. More information.
The system catalogs are the place where a relational database management system stores schema metadata, such as information about tables and columns, and internal bookkeeping information. PostgreSQL's system catalogs are regular tables. You can drop and recreate the tables, add columns, insert and update values, and severely mess up your system that way. Normally, one should not change the system catalogs by hand, there are always SQL commands to do that. (For example, CREATE DATABASE inserts a row into the pg_database catalog — and actually creates the database on disk.) There are some exceptions for particularly esoteric operations, such as adding index access methods.
The information_schema is a system schema. More information.
The information schema consists of a set of views that contain information about the objects defined in the current database. The information schema is defined in the SQL standard and can therefore be expected to be portable and remain stable — unlike the system catalogs, which are specific to PostgreSQL and are modeled after implementation concerns. The information schema views do not, however, contain information about PostgreSQL-specific features; to inquire about those you need to query the system catalogs or other PostgreSQL-specific views.
I hope these information will help you clearly.

Create empty table in postgresql

i want to create a simple table inside a database in postgresql.
From the Documentation i have CREATE TABLE will create a new, initially empty table in the current database. The table will be owned by the user issuing the command.
With this command
CREATE TABLE *table_name*;
I thought i get a new empty table.But psql throws ERROR: syntax error at or near ";". When i user an empty argument list like:
CREATE TABLE *table_name*();
psql tells me that the table was created through
postgres=# create table *table_name*();
CREATE TABLE
But \l shows is not showing the newly created table. And its also not possible to login with psql -d table_name -U user_name. Can anyone help?
You can have a table with no columns, and even with some rows in it:
CREATE TABLE nocolumn (dummy INTEGER NOT NULL PRIMARY KEY)
;
INSERT INTO nocolumn(dummy) VALUES (1);
ALTER TABLE nocolumn
DROP COLUMN dummy;
\d nocolumn
SELECT COUNT(*) FROM nocolumn;
Output:
CREATE TABLE
INSERT 0 1
ALTER TABLE
Table "tmp.nocolumn"
Column | Type | Modifiers
--------+------+-----------
count
-------
1
(1 row)
You seem to be confusing the terms database and table
But \l is not showing the newly created table.
Of course \l will not show you that table, because \l will list databases not relations. To see all tables you need to use \d or \dt.
And its also not possible to login with psql -d table_name -U user_name
Of course this is not possible, because the -d parameter is used to specify a database, not a table
I'm not sure why other answers suggest to create a table with a column and then ignore that column. It is certainly possible, but it seems different from what you tried to do.
It seems you have to use parenthesis:
postgres=# CREATE TABLE t ();
CREATE TABLE
To insert a row:
postgres=# INSERT INTO t DEFAULT VALUES;
INSERT 0 1
To count the rows you inserted:
postgres=# SELECT FROM t;
--
(2 rows)
You can't delete a single rows, because all rows are equal. But to completely empty the table, you can use DELETE without WHERE, or TRUNCATE TABLE.
You can find more info here: PostgreSQL: Tables without columns.
That said, I have to say that I understand "empty table" as "table without rows", not necessarily without columns.
An hour ago i suggested to add at least one column like this:
create table tab1 (columnname varchar(42) not null)
But this seems to be not necessary as a commentator just told. (I consider to keep the wrong answer here instead of deleting it, to prevent that others suggest the same)

How to drop a Redshift index?

I've got a superuser account and am trying to drop an index on a Redshift table with:
DROP INDEX my_table_pkey;
But I receive a ERROR: Insufficient privileges. I'm confused because I can drop the table just fine, and I'm logged in as a Superuser.
# \du admin
List of roles
Role name | Attributes | Member of
-----------+----------------------+-----------
admin | Superuser, Create DB |
I've even tried
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO admin;
But I still get the insufficient privileges error when I try to drop the index.
Any ideas?
Please note that as documented here, Redshift doesn't support indexes so likely as not, there's not an actual index to drop. Primary and foreign keys are for informational purposes only but are still recommend (see Defining Constraints) for the optimizer. It is up to the application though, to actually enforce the keys.
you can't drop index in Redshift.
but you can.
create your table without the index.
insert the data from the old table
change the table name

At what level do Postgres index names need to be unique?

In Microsoft SQL Server and MySQL, index names need to unique within the table, but not within the database. This doesn't seem to be the case for PostgreSQL.
Here's what I'm doing: I made a copy of a table using CREATE TABLE new_table AS SELECT * FROM old_table etc and need to re-create the indexes.
Running a query like CREATE INDEX idx_column_name ON new_table USING GIST(column_name) causes ERROR: relation "idx_column_name" already exists
What's going on here?
Indexes and tables (and views, and sequences, and...) are stored in the pg_class catalog, and they're unique per schema due to a unique key on it:
# \d pg_class
Table "pg_catalog.pg_class"
Column | Type | Modifiers
----------------+-----------+-----------
relname | name | not null
relnamespace | oid | not null
...
Indexes:
"pg_class_oid_index" UNIQUE, btree (oid)
"pg_class_relname_nsp_index" UNIQUE, btree (relname, relnamespace)
Per #wildplasser's comment, you can omit the name when creating the index, and PG will assign a unique name automatically.
Names are unique within the schema. A schema is basically a namespace for {tables,constraints}, (and indexes, functions,etc).
cross-schema-constraints are allowed
Indexes share their namespace ( :=schema) with tables. (for Postgres: an index is a table).
(IIRC) the SQL standard does not define indexes; use constraints whenever you can (The GIST index in the question is probably an exception)
Ergo You'll need to invent another name.
or omit it: the system can invent a name if you dont supply one.
The downside of this: you can create multipe indices with the same definition (their names will be suffixed with _1, _2, IIRC)

How to find all object in a database using a script?

Can someone help me with this? I need to find out all the objects in a database using a script. The reason why I need this is, I am asked to change the owner of all database objects so for that I need to first list down all objects.
I think you probably want REASSIGN OWNED instead. No need to identify all the objects, just the users.
If you're changing every object from role A to role B, you might like REASSIGN OWNED:
REASSIGN OWNED BY A TO B
In PostgreSQL (or almost any other RDBMS for that matter), I would recommend to take a look at metadata tables (system catalog).
Example. You want all tables:
db => \d pg_tables
View "pg_catalog.pg_tables"
Column | Type | Modifiers
-------------+---------+-----------
schemaname | name |
tablename | name |
tableowner | name |
tablespace | name |
hasindexes | boolean |
hasrules | boolean |
hastriggers | boolean |
db => select tablename from pg_tables;
Will get you a list of all tables. You can use a query to build a script to change ownership of the tables you want.
Similarly, you can query other views/tables in the catalog to get other object types (sequences, indexes, you name it).
If you can do a pg_dump and pg_restore to create a new database the adding the --no-owner flag on the pg_restore and running the pg_restore as the user you wish to set ownership to should work for this.