Equivalent of PRAGMA table_info(table) for Postgres SQL? - postgresql

I am working with a script made for SQLite but I need to adapt it to a PostgreSQL database and this line is always returning an error:
PRAGMA table_info(table)
How can I get an equivalent result on postgres >

Found it !
SELECT *
FROM information_schema.columns
WHERE table_name = 'table_name'

Related

fixing orphaend Sequences in postgres-12

I'm trying to run pg_dump and it's failing due to a orphaned sequence.
pg_dump -U db --format=custom --compress=0 db
pg_dump: error: query to get data of sequence "non_existing_table_id_seq" returned 0 rows (expected 1)
https://wiki.postgresql.org/wiki/Fixing_Sequences
The above wiki page has some snippets which can be used to fix this issue, the last snippit does work to display the orphaned snippets.
select ns.nspname as schema_name, seq.relname as seq_name
from pg_class as seq
join pg_namespace ns on (seq.relnamespace=ns.oid)
where seq.relkind = 'S'
and not exists (select * from pg_depend where objid=seq.oid and deptype='a')
order by seq.relname;
schema_name | seq_name
-------------+--------------------------------
public | non_existing_table_id_seq
public | another_non_existing_table_id_seq
(2 rows)
The command which should fix this issue doesn't run because column d.adsrc does not exist
It seems to have been removed from postgres-12.
https://stackoverflow.com/a/58798028/1891184 says I can replace d.adsrc with pg_get_expr(d.adbin, d.adrelid). and that runs, however the issue still remains.
Other than this, the database is working fine.
How can I either fix or remove the offending sequences in order to let pg_dump work?

why can I not parse variable parsed from outside?

I am trying to make a drop database script, which I would have to trigger using psql.
psql ... -f reset-database.sql -v dbname=$database
The problem is that I am not able to access the variable :dbname in my script.
DO
$$
BEGIN
IF EXISTS (SELECT EXISTS( SELECT datname FROM pg_catalog.pg_database WHERE datname = :dbname)) THEN
UPDATE pg_database SET datallowconn = 'false' WHERE datname = :dbname;
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = :dbname;
DROP DATABASE IF EXISTS :dbname;
END IF;
END
$$
This is executed as is, and :dbname is not replaced with the database name parsed in as as variable? Why? And how do I parse it?
The variable substitution will not work in a DO statement, because the statement body is a (dollar quoted) string literal. Otherwise, it should work fine, but you have to use single quotes in your metadata query. Besides, you cannot run DROP DATABASE inside a DO statement, since you cannot run it inside a transaction.
Also, don't update catalog tables.
You can use psql's \if for conditional processing:
SELECT EXISTS (
SELECT 1 FROM pg_catalog.pg_database
WHERE datname = :'dbname'
) AS have_db \gset
\if :have_db
ALTER DATABASE :dbname ALLOW_CONNECTIONS FALSE;
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = :'dbname';
DROP DATABASE :dbname;
\endif
From PostgreSQL v13 on, this is much simpler:
DROP DATABASE IF EXISTS :dbname WITH (FORCE);

How to fix “ERROR: column relhasoids does not exist” in phpPgAdmin?

I'm updating a Linux server with a new version of PostgreSql and I have an Error Message in phpPgAdmin when I browse a table.
The Ubuntu 18.04.3 LTS server running Apache 2.4.41, PHP 7.3.11 and when I update to PostgreSQL 12.0 and phpPgAdmin 7.12.0 the error occurs. With PostgreSQL 11.5 and phpPgAdmin 5.6 I didn't have this problem.
I expect to visualize the data stored in the table using phpPgAdmin, but the actual output is:
SQL error:
ERROR: column «relhasoids» does not exist
LINE 1: SELECT relhasoids FROM pg_catalog.pg_class WHERE relname='pr...
In statement:
SELECT relhasoids FROM pg_catalog.pg_class WHERE relname='product'
AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname='public')
Editing the file /usr/share/phppgadmin/classes/database/Postgres.php and comment line 1045 to line 1054 the error disappears:
function hasObjectID($table) {
$c_schema = $this->_schema;
$this->clean($c_schema);
$this->clean($table);
/*
$sql = "SELECT relhasoids FROM pg_catalog.pg_class WHERE relname='{$table}'
AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname='{$c_schema}')";
$rs = $this->selectSet($sql);
if ($rs->recordCount() != 1) return null;
else {
$rs->fields['relhasoids'] = $this->phpBool($rs->fields['relhasoids']);
return $rs->fields['relhasoids'];
} */
}
This column does not exist anymore, since you cannot create tables with OID any longer.
From the documentation:
WITH ( storage_parameter [= value] [, ... ] )
This clause specifies optional storage parameters for a table or index; see Storage Parameters for more information. For backward-compatibility the WITH clause for a table can also include OIDS=FALSE to specify that rows of the new table should not contain OIDs (object identifiers), OIDS=TRUE is not supported anymore.
WITHOUT OIDS
This is backward-compatible syntax for declaring a table WITHOUT OIDS, creating a table WITH OIDS is not supported anymore.
This is because phpPgAdmin is not compatible with PostgreSQL v. 12. PostgreSQL v. 12 has removed the relhasoids column because of the new way that OIDs are handled. As of the time of this post, pgPgAdmin does not support PostgreSQL v. 12 (it is not listed on the website). You may need to look into alternate clients.
See also How to fix “ERROR: column c.relhasoids does not exist” in Postgres?

Access SAP Tables in DB2

I have a DB2 database, where few of the tablenames are starting with '/'.
eg: /dev/r32
How can I query on the above table
I have tried with the following approaches
select * from schemaname./dev/r32
select * from schemaname.'/dev/r32'
select * from schemaname."/dev/r32"
But I am getting the following error:
An error occurred when executing the SQL command:
select * from schemaname."/dev/r32"
[SQL0204] /dev/r32 in schemaname type *FILE not found. [SQL State=42704, DB Errorcode=-204]
describe schemaname."/dev/r32" works.
Any help would be appreciated
The table names are changed and issue is resolved.

PostgreSQL pgp_sym_encrypt() broken in version 9.1

The following works in PostgreSQL 8.4:
insert into credentials values('demo', pgp_sym_encrypt('password', 'longpassword'));
When I try it in version 9.1 I get this:
ERROR: function pgp_sym_encrypt(unknown, unknown) does not exist LINE
1: insert into credentials values('demo', pgp_sym_encrypt('pass...
^ HINT: No function matches the given name and argument types. You might need to add
explicit type casts.
*** Error ***
ERROR: function pgp_sym_encrypt(unknown, unknown) does not exist SQL
state: 42883 Hint: No function matches the given name and argument
types. You might need to add explicit type casts. Character: 40
If I try some explicit casts like this
insert into credentials values('demo', pgp_sym_encrypt(cast('password' as text), cast('longpassword' as text)))
I get a slightly different error message:
ERROR: function pgp_sym_encrypt(text, text) does not exist
I have pgcrypto installed. Does anyone have pgp_sym_encrypt() working in PostgreSQL 9.1?
On explanation could be that the module was installed into a schema that is not in your search path - or to the wrong database.
Diagnose your problem with this query and report back the output:
SELECT n.nspname, p.proname, pg_catalog.pg_get_function_arguments(p.oid) as params
FROM pg_catalog.pg_proc p
JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE p.proname ~~* '%pgp_sym_encrypt%'
AND pg_catalog.pg_function_is_visible(p.oid);
Finds functions in all schemas in your database. Similar to the psql meta-command
\df *pgp_sym_encrypt*
Make sure you install the extension on the desired schema.
sudo -i -u postgres
psql $database
CREATE EXTENSION pgcrypto;
OK, problem solved.
I was creating the pgcrypto extension as the first operation in the script. Then I dropped and added the VGDB database. That's why pgcrypto was there immediately after creating it, but didn't exist when running the sql later in the script or when I opened pgadmin.
This script is meant for setting up new databases and if I had tried it on a new database the create extension would have failed right away.
My bad. Thanks for the help, Erwin.
Just mention de schema where is installed pgcrypto like this:
#ColumnTransformer(forColumn = "TEST",
read = "public.pgp_sym_decrypt(TEST, 'password')",
write = "public.pgp_sym_encrypt(?, 'password')")
#Column(name = "TEST", columnDefinition = "bytea", nullable = false)
private String test;
I ran my (python) script again and the CREATE EXTENSION ran without error. The script also executes this command
psql -d VGDB -U postgres -c "select * from pg_available_extensions order by name"
which includes the following in the result set:
pgcrypto | 1.0 | 1.0 | cryptographic functions
So psql believes that it has installed pgcrypto.
Later in the same script when I execute
psql -d VGDB -U postgres -f sql/Create.Credentials.table.sql
where sql/Create.Credentials.table.sql includes this
insert into credentials values('demo', pgp_sym_encrypt('password', 'longpassword'));
I get this
psql:sql/Create.Credentials.table.sql:31: ERROR: function pgp_sym_encrypt(unknown, unknown) does not exist
LINE 1: insert into credentials values('demo', pgp_sym_encrypt('pass...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
When I open pgadmin it does not show pgcrypto in either the VGDB or postgres databases even though the query above called by psql shows that pgcrypto is installed.
Could there be an issue with needing to commit after using psql to execute the "create extension ..." command? None of my other DDL or SQL statements require a commit when they get executed with psql.
It's starting to look like psql is just flakey. Is there another way to call "create extension pgcrypto" - e.g. with Python's database support classes - or does that have to be run through psql?