From 42d0442d8ed6171bc912de52e53c98ce67192a3c Mon Sep 17 00:00:00 2001 From: Michele Cereda Date: Tue, 1 Oct 2024 23:43:22 +0200 Subject: [PATCH] chore(postgres): functions and query improvements --- knowledge base/postgresql.md | 52 ++++++++++++++++++++++++++++++++++++ snippets/postgresql.sh | 3 +++ snippets/postgresql.sql | 48 ++++++++++++++++++++++++++++----- 3 files changed, 97 insertions(+), 6 deletions(-) diff --git a/knowledge base/postgresql.md b/knowledge base/postgresql.md index 5f18a18..c281639 100644 --- a/knowledge base/postgresql.md +++ b/knowledge base/postgresql.md @@ -1,6 +1,7 @@ # PostgreSQL 1. [TL;DR](#tldr) +1. [Functions](#functions) 1. [Extensions of interest](#extensions-of-interest) 1. [PostGIS](#postgis) 1. [`postgresql_anonymizer`](#postgresql_anonymizer) @@ -119,6 +120,44 @@ ALTER DATABASE postgres SET session_preload_libraries = 'anon'; +## Functions + +Refer [CREATE FUNCTION]. + +```sql +CREATE OR REPLACE FUNCTION just_return_1() RETURNS integer +LANGUAGE SQL +RETURN 1; + +SELECT just_return_1(); +``` + +```sql +CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer +AS $$ + BEGIN + RETURN i + 1; + END +$$ +LANGUAGE plpgsql; +``` + +```sql +CREATE OR REPLACE FUNCTION entries_in_column( + table_name TEXT, + column_name TEXT +) RETURNS INTEGER +LANGUAGE plpgsql +AS $func$ + DECLARE result INTEGER; + BEGIN + EXECUTE format('SELECT count(%s) FROM %s LIMIT 2', column_name, table_name) INTO result; + RETURN result; + END +$func$; +SELECT * FROM entries_in_column('vendors','vendor_id'); +``` + ## Extensions of interest ### PostGIS @@ -177,6 +216,8 @@ psql -h 'localhost' -p '6543' -U 'postgres' -d 'postgres' -W - [What is the pg_dump command for backing up a PostgreSQL database?] - [How to SCRAM in Postgres with pgBouncer] - [`postgresql_anonymizer`][postgresql_anonymizer] +- [pgxn-manager] +- [dverite/postgresql-functions] ### Sources @@ -187,6 +228,10 @@ psql -h 'localhost' -p '6543' -U 'postgres' -d 'postgres' -W - [How to Generate SCRAM-SHA-256 to Create Postgres 13 User] - [PostgreSQL: Get member roles and permissions] - [An In-Depth Guide to Postgres Data Masking with Anonymizer] +- [Get count of records affected by INSERT or UPDATE in PostgreSQL] +- [How to write update function (stored procedure) in Postgresql?] +- [How to search a specific value in all tables (PostgreSQL)?] +- [PostgreSQL: Show all the privileges for a concrete user] [an in-depth guide to postgres data masking with anonymizer]: https://thelinuxcode.com/postgresql-anonymizer-data-masking/ [bidirectional replication in postgresql using pglogical]: https://www.jamesarmes.com/2023/03/bidirectional-replication-postgresql-pglogical.html [connect to a postgresql database]: https://www.postgresqltutorial.com/connect-to-postgresql-database/ +[dverite/postgresql-functions]: https://github.com/dverite/postgresql-functions +[get count of records affected by insert or update in postgresql]: https://stackoverflow.com/questions/4038616/get-count-of-records-affected-by-insert-or-update-in-postgresql#78459743 [how to generate scram-sha-256 to create postgres 13 user]: https://stackoverflow.com/questions/68400120/how-to-generate-scram-sha-256-to-create-postgres-13-user [how to scram in postgres with pgbouncer]: https://www.crunchydata.com/blog/pgbouncer-scram-authentication-postgresql +[how to search a specific value in all tables (postgresql)?]: https://stackoverflow.com/questions/5350088/how-to-search-a-specific-value-in-all-tables-postgresql/23036421#23036421 +[how to write update function (stored procedure) in postgresql?]: https://stackoverflow.com/questions/21087710/how-to-write-update-function-stored-procedure-in-postgresql +[pgxn-manager]: https://github.com/pgxn/pgxn-manager [postgresql_anonymizer]: https://postgresql-anonymizer.readthedocs.io/en/stable/ [postgresql: get member roles and permissions]: https://www.cybertec-postgresql.com/en/postgresql-get-member-roles-and-permissions/ +[postgresql: show all the privileges for a concrete user]: https://stackoverflow.com/questions/40759177/postgresql-show-all-the-privileges-for-a-concrete-user [what is the pg_dump command for backing up a postgresql database?]: https://www.linkedin.com/advice/3/what-pgdump-command-backing-up-postgresql-ke2ef diff --git a/snippets/postgresql.sh b/snippets/postgresql.sh index c35cd23..dae628c 100644 --- a/snippets/postgresql.sh +++ b/snippets/postgresql.sh @@ -1,5 +1,8 @@ #!/usr/bin/env sh +# Start DBs +docker run --rm --name 'postgres' -d -p '5432:5432' -e POSTGRES_PASSWORD='password' 'postgres:14.12' + # Connect to DBs psql 'postgres' psql 'postgres' 'admin' diff --git a/snippets/postgresql.sql b/snippets/postgresql.sql index 73578f1..e5a9785 100644 --- a/snippets/postgresql.sql +++ b/snippets/postgresql.sql @@ -73,19 +73,23 @@ DROP SCHEMA IF EXISTS mundane CASCADE; -- Create tables CREATE TABLE people ( - id char(2) PRIMARY KEY, - firstname varchar(40) NOT NULL, - lastname varchar(40) NOT NULL, - phone varchar(20) NOT NULL + id char(2) PRIMARY KEY, + first_name varchar(40) NOT NULL, + last_name text(40) NOT NULL, + phone varchar(20) ); -- Show table structure \d sales \d+ clients +SELECT column_name, data_type, character_maximum_length FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'vendors'; -- Insert data -INSERT INTO people(id,firstname,lastname,phone) VALUES ('T1','Sarah','Conor','0609110911'); +INSERT INTO people(id, first_name, last_name, phone) +VALUES + ('T1', 'Sarah', 'Conor', '0609110911'), + ('wa', 'Wally', 'Polly', null); -- Revoke *default* privileges @@ -140,6 +144,31 @@ GRANT rds_superuser TO mike; -- Remove role memberships from users REVOKE engineers FROM mike; +-- List permissions +-- on tables +SELECT * +FROM information_schema.role_table_grants +WHERE grantee = 'darwin'; +-- about ownership +SELECT * +FROM pg_tables +WHERE tableowner = 'darwin'; +-- on schemas +SELECT + r.usename AS grantor, + e.usename AS grantee, + nspname, + privilege_type, + is_grantable +FROM pg_namespace +JOIN LATERAL ( + SELECT * + FROM aclexplode(nspacl) AS x +) a ON true +JOIN pg_user e ON a.grantee = e.usesysid +JOIN pg_user r ON a.grantor = r.usesysid +WHERE e.usename = 'darwin'; + -- Close the connection to the current DB \q @@ -244,9 +273,16 @@ UPDATE vendors -- Deterministic random values -select setseed(0.25), round(random()::decimal, 15) as random_number; -- seed must be in [-1:1] +SELECT setseed(0.25), round(random()::DECIMAL, 15) AS random_number; -- seed must be in [-1:1] -- Search values in all tables -- source: https://stackoverflow.com/questions/5350088/how-to-search-a-specific-value-in-all-tables-postgresql/23036421#23036421 -- └── https://github.com/dverite/postgresql-functions/tree/master/global_search + + +-- Functions +-- Refer +CREATE OR REPLACE FUNCTION return_1() RETURNS integer +LANGUAGE SQL +RETURN 1;