How to configure pg_trgm similarity threshold parameters in a Google Cloud SQL PostgreSQL instance - postgresql

I have a Postgres database in Cloud SQL and would like to utilize the pg_trgm extension to do similarity searches. However, the default threshold parameters are not sensitive enough in my use case so they should be altered.
The problem is that Cloud SQL does not provide database flags for either pg_trgm.similarity_threshold or pg_trgm.word_similarity_threshold and the database users do not have the privileges to alter the user or database:
postgres=> ALTER ROLE postgres SET pg_trgm.similarity_threshold = 0.1;
ERROR: permission denied to set parameter "pg_trgm.similarity_threshold"
postgres=> ALTER DATABASE postgres SET pg_trgm.similarity_threshold = 0.1;
ERROR: permission denied to set parameter "pg_trgm.similarity_threshold"
Is there any other way to alter these parameters?

Can you do the straightforward SET pg_trgm.similarity_threshold = 0.1;? You would have to repeat it in every session, so maybe incorporate it into your connection sub.
For similarity_threshold, you can use the function set_limit unless Google has also disabled that. You would also have to set it this way in each session, though. There is no alternative way to set word_similarity_threshold, though, unless Google has invented one.

Related

Grant privileges to set session_replication_role

A script has to import SQL data into an PostgreSQL database. The SQL includes these two lines of code:
SET session_replication_role = 'replica';
...
SET session_replication_role = 'origin';
The user xyz who starts the import doesn't have the power to do this yet. The error PG::InsufficientPrivilege gets displayed.
How (with which SQL query) can the user postgres grant the user xyz the right to set session_replication_role? I can't find any documentation about that.
As of PostgreSQL 15+ there is a way to do this:
GRANT SET ON PARAMETER session_replication_role TO xyz;
https://www.postgresql.org/docs/15/sql-grant.html
I haven't tried this yet but I bet it works good - in version 14, I used SECURITY DEFINER at the end of a plpgsql procedure with "SET session_replication_role" statements inside of it, and made sure a superuser account was the definer/owner of the procedure - then, any user with EXECUTE privilege can still run it and the parameter setting works as you would hope.
It is impossible :-(. See:
It seems this is currently only possible with superuser privilege:
Setting this variable requires superuser privilege, cf.
postgresql.org/docs/current/runtime-config-client.html

Readonly admin user in postgresql

we have a postgres database we want to run a number of checks against. Part of the tool involves looping over database all the database tables and views, checking grants and other things - so it would be entirely pointless if we had to grant access to this user to individual tables.
We want to be able to create a user that has full read privileges to anything, regardless of what permissions are set in the database - like a db owner - but has no write access at all.
Is this possible in any way?
The only way to do this is granting the SELECT privilege on every individual object that needs to be examined. You can make the work easier with
GRANT SELECT ON ALL TABLES/SEQUENCES/... IN SCHEMA ... TO ...;
You can also use ALTER DEFAULT PRIVILEGES to set the permissions on future objects.
I recommend that you create a readonly role and do all that once. Then you can create a read-only user by making the user a member of that role.
With postgresql 14 you can just do:
GRANT pg_read_all_data TO my_role;
https://www.postgresql.org/docs/14/predefined-roles.html

PostgreSQL: insufficient privilege

I'm using postgreSQL as a database for an application that I build. When I run the application, I open dbeaver and typed the SQL query:
select * from pg_stat_activity
in order to see a list of SQL queries that has been processed during the application running.
In "query" column I got "insufficient privilege" for some queries. Do you know what I can do to see the actual SQL query?
You would have to run the query as a root-user to see all the queries. This is usually the postgres user.
On certain managed postgresql services (AWS), access to the root-user is restricted, and it is not possible to see queries executed by that user by design.
In general, the more privileges your user has, the more queries you can see in pg_stat_activity
If you are using Postgresql 10 and above, you can grant pg_read_all_stats role to your user from superuser account (postgres)
GRANT pg_read_all_stats TO username;
You do not necessarily have to run the query as a root-user. Giving someone root user access could have very bad security implications, as they could literally do anything. There is a workaround where you can create a function as root that has access to pg_stat_statements, and then grant the read-only user access to the function. For example:
CREATE OR REPLACE FUNCTION your_schema.get_stat_statements(showtext boolean = true) RETURNS SETOF pg_stat_statements AS
$$
/* pganalyze-collector */ SELECT * FROM public.pg_stat_statements(showtext) LIMIT 100;
$$ LANGUAGE sql VOLATILE SECURITY DEFINER;
GRANT USAGE on SCHEMA your_schema TO your_readonly_user;
GRANT EXECUTE on FUNCTION your_schema.get_stat_statements(boolean) TO your_readonly_user;
Thanks to https://pganalyze.com/docs/install/amazon_rds/02_create_monitoring_user
You can find an example of a similar approach here.
One possible workaround to this is defining a MATERIALIZED VIEW using a user that has enough privileges to view the data, and granting access to the view to the use that does not have the privileges.
One downside to this is that the view will have to be refreshed periodically using REFRESH MATERIALIZED VIEW, also by the owner of the view (or some other user with privileges).

SET/RESET command in ALTER DATABASE is not supported

Encountered this issue when trying to modify the search_path to my new Redshift db.
Presently, I've migrated the contents of my MySQL db into a redshift cluster via AWS' Data Migration Service. The data was imported into a schema lets call my_schema. When I try to execute queries against the cluster it requires me to prefix table names with the schema name
i.e.
select * from my_schema.my_table
I wanted to change the setup so that I can reference the table directly without needing the prefix. After a bit of looking around I found out that this was possible by modifying the search_path attribute.
First I tried doing this by running
set search_path = "$user", my_schema;
This appeared to work but then I realized that this was simply setting my_schema as the default schema in the context of the current session, I wanted it set on a database level. I found several sources saying that the way to do this was to use the alter command like so...
alter database my_db set search_path = "$user", public, my_schema
However, running this command results in the following error which somehow shows up in 0 google results:
SET/RESET commmand in ALTER DATABASE is not supported
I'm pretty baffled by how the above error hasn't ever had a post made about it but I'm also pretty interested in figuring out how to resolve my initial issue of setting a global default schema for my redshift cluster.
ALTER DATABASE SET is not supported in Redshift. However you can SET/RESET configuration parameters at USER level using the ALTER USER SET SEARCH_PATH TO <SCHEMA1>,<SCHMEA2>;
Please check: http://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_USER.html
http://docs.aws.amazon.com/redshift/latest/dg/r_search_path.html
When you set the search_path to <SCHEMA1>,<SCHMEA2> in db1 for a user it is not for just current session, it will be set for all future sessions.

Database Schema Right Issue

I am using postgresql. I have created a user and grant access on db. I want user can only see granted schema objects and rest database/schema objects can't watchable. Please guide me.
You need to alter the user and set the search path.
ALTER USER foo SET search_path TO '$newschema,pg_catalog';
Note that in order to get a proper backup of globals such as this you have to use pg_dumpall -g, not pg_dump. Obviously a base backup will have them as well.