SET/RESET command in ALTER DATABASE is not supported - amazon-redshift

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.

Related

does set search_path of postgres affect connection or the database

Typeorm's migration is quite unexpected, even though I specify the schema, migrations run though the queryRunner, don't respect the schema specified in the connection:
const dbconfig: DataSourceOptions = {
...baseConnection,
schema: my_schema,
migrations: ['./**/*.migration.js'],
};
let data = new DataSource(dbconfig);
data = await data.initialize();
data.runMigrations()
it only seems to work if you've used something like a repository, orm specific.
One way I got around this is by using a static variable that persists throughout the migration process the name of the schema, and sets search_path of the database before each query, like this:
set search_path to ${static_variable.my_schema};
run_query_1;
set search_path to ${static_variable.my_schema};
run_query_2;
...
set search_path to ${static_variable.my_schema};
run_query_n;
Consider this case,(1) an admin starts a migration, the schema is set to 'X', the database search_path is set to 'X', in the midst of this process, if a request comes in from tenant 'Y', then would he be writing to the tenant 'X' or 'Y'
(2) If the app is horizontally scaled, then if two admins are performing migrations for two tenants, (there are two different static vars now), how would this affect the authenticity and integrity of the data.
If the set search_path is connection specifically maintained, then I suppose it could matter less , but if the database globally manages it, this could be an issue.
Are these concurrent operations going to be a problem? Should I opt to modify the search_path at all?
EDIT: What about for the case like this:
START TRANSACTION;
set search_path to ${static_variable.my_schema};
run_query_1;
set search_path to ${static_variable.my_schema};
run_query_2;
...
set search_path to ${static_variable.my_schema};
run_query_n;
COMMIT;
As documented in the manual SET changes the setting for the session (or just the transaction if the local keyword is included).
So if you always use set search_patt to ... it's always specific to the connection (session) that executed the statement. You will not have a concurrency issue.
There is one way this could have an effect globally: if you change the search path in the database using alter database set search_path ... or for the user using alter user set search_path ...

PostgreSQL Create Table command not working, checked access privileges and all default privileges are there

I'm extremely new to PostgreSQL and I just installed it using Homebrew.
I ran through creating and connecting to a database and now I'm trying to create a table with the standard command CREATE TABLE users(name string, age smallint, birthday date) and the command completes. However as soon as I run the command to list all tables I get the following Did not find any relations.
I checked all users and privileges and it looks like my profiles roles include Superuser, Create Role, Create DB, Replication, Bypass RLS and I'm a member of {}.
I'm not sure if there's something more I need to do in order to create tables under a certain database or not, but I've looked all over and can't seem to find an answer to this.
I'm not really sure what you're intending to do, be more explicit.
But it seems to me you've juste created tables and did not create any relations.
Try using a key and defining mother tables ?

Default schema for native SQL queries (spring-boot + hibernate + postgresql + postgis)

I am introducing spring to the existing application (hibernate has already been there) and encountered a problem with native SQL queries.
A sample query:
SELECT ST_MAKEPOINT(cast(longitude as float), cast(latitude as float)) FROM
OUR_TABLE;
OUR_TABLE is in OUR_SCHEMA.
When we connect to the db to OUR_SCHEMA:
spring.datasource.url: jdbc:postgresql://host:port/db_name?currentSchema=OUR_SCHEMA
the query fails because function ST_MAKEPOINT is not found - the function is located in schema: PUBLIC.
When we connect to the db without specifying the schema, ST_MAKEPOINT is found and runs correctly, though schema name needs to be added to the table name in the query.
As we are talking about thousands of such queries and all the tables are located in OUR_SCHEMA, is there a chance to anyhow specify the default schema, so still functions from PUBLIC schema were visible?
So far, I have tried the following springboot properties - with no success:
spring.jpa.properties.hibernate.default_schema: OUR_SCHEMA
spring.datasource.tomcat.initSQL: ALTER SESSION SET CURRENT_SCHEMA=OUR_SCHEMA
spring.datasource.initSQL: ALTER SESSION SET CURRENT_SCHEMA=OUR_SCHEMA
Also, it worked before switching to springboot config - specifying hibernate.default-schema = OUR_SCHEMA in persistence.xml was enough.
Stack:
spring-boot: 2.0.6
hibernate: 5.3.1.Final
postgresql: 42.2.5
postgis: 2.2.1
You're probably looking for the PostgreSQL search_path variable, which controls which schemas are checked when trying to resolve database object names. The path accepts several schema names, which are checked in order. So you can use the following
SET search_path=our_schema,public;
This will make PostgreSQL look for your tables (and functions!) first in our_schema, and then in public. Your JDBC driver may or may not support multiple schemas in its current_schema parameter.
Another option is to install the PostGIS extension (which provides the make_point() function) in the our_schema schema:
CREATE EXTENSION postgis SCHEMA our_schema;
This way you only have to have one schema in your search path.
JDBC param currentSchema explicitly allows specifying several schemas separating them by commas:
jdbc:postgresql://postgres-cert:5432/db?currentSchema=my,public&connectTimeout=4&ApplicationName=my-app
From https://jdbc.postgresql.org/documentation/head/connect.html
currentSchema = String
Specify the schema (or several schema separated by commas) to be set in the search-path. This schema will be used to resolve unqualified object names used in statements over this connection.
Note you probably need Postgres 9.6 or better for currentSchema support.
PS Probably better solution is to set search_path per user:
ALTER USER myuser SET search_path TO mydb,pg_catalog;
if you use hibernate.default_schema, then for native queries, you need to provide the {h-schema} placeholder, something like that
SELECT ST_MAKEPOINT(cast(longitude as float), cast(latitude as float)) FROM {h-schema}OUR_TABLE;

PSQL was inferring schema, but how?

We're in the process of upgrading our software from PostgreSQL 9.2 to 9.6 and we've run into an odd issue.
Our installation runs an SQL script to create the database. This is done using psql -f. This worked fine under 9.2 but seems to have issues with not creating objects in 9.6. I've been looking into this and found something odd in the SQL script. Most of the tables are created using statements that look like this:
--
-- Name: crawler_run; Type: TABLE; Schema: analytics; Owner: postgres; Tablespace:
--
CREATE TABLE IF NOT EXISTS crawler_run (
... columns, etc.
);
--
ALTER TABLE analytics.crawler_run OWNER TO postgres;
Note that there is no schema in the create table statement. But the tables were being created in the correct schema and the subsequent alter table statement was not failing.
My best guess is that the preceding comment has something to do with it, but I've not been able to find any documentation to support that.
So how was this working?
Tables are created in the first schema of the user/role search_path, which is either set permanently or just for the current session.
Look for a statement like:
SET search_path = analytics
In your case it was analytics and now it is probably back to the default public.

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.