Adding COLLATION in postgres - postgresql

I am migrating data from SQL Server to Postgres. Since Postgres is case-sensitive, I am trying to add case-insensitive COLLATION but it is failing with the below error -
ERROR: could not create locale "en-u-ks-primary": No such file or
directory DETAIL: The operating system could not find any locale data
for the locale name "en-u-ks-primary". SQL state: 22023
CREATE COLLATION main.case_insensitive_collation (LC_COLLATE = 'en-u-ks-primary',
LC_CTYPE = 'en-u-ks-primary'
PROVIDER = icu,
DETERMINISTIC = False
);
Checked the version of postgres -
SELECT version();
"PostgreSQL 12.5 on x86_64-pc-linux-gnu, compiled by gcc (Debian
8.3.0-6) 8.3.0, 64-bit"
Any idea on how can I fix this or get this working ?
Thanks in advance,
Neha

Your collation definition is wrong. It should be something like
CREATE COLLATION english_ci (
PROVIDER = icu,
LOCALE = 'en-u-ks-level2',
DETERMINISTIC = FALSE
);
Here is an article that has some information about that.

Related

How to create DB with Latin9 locale

I have a new server running Postgres Linux Version 12.9 (2021-12-13), and I want to create a DB with these options:
CREATE DATABASE et_base WITH
ENCODING 'LATIN9' LC_COLLATE = 'fr_FR.iso885915#euro'
LC_CTYPE = 'fr_FR.iso885915#euro' TEMPLATE=template0.....
But I get this error message:
ERROR: invalid locale name: "fr_FR.iso885915#euro"

Get und-x-icu as collation and character type in Postgres 10 and win server 2008

I have successfully installed Postgres 10 in a Windows Server 2008 R2 standard, 64 bit.
I am trying to create a new database that has LC_COLLATE = 'und-x-icu' and LC_CTYPE = 'und-x-icu' with the following SQL
CREATE DATABASE hey
WITH
OWNER = postgres
ENCODING = 'UTF8'
LC_COLLATE = 'und-x-icu'
LC_CTYPE = 'und-x-icu'
TABLESPACE = pg_default
CONNECTION LIMIT = -1
TEMPLATE = template0
;
I get ERROR: invalid locale name: "und-x-icu" SQL state: 42809.
But the SELECT * FROM pg_collation; clearly shows und-x-icu.
The same SQL works on my laptop (windows 10).
I did select locale : C while installing on the server, I did not remember what I selected as a locale while installing on the laptop.
How can I make this work on win server 2008 and get und-x-icu?
The documentation does not seem to mention that restriction, but you cannot use ICU collations in CREATE DATABASE.
This may be improved in the future, but for now there is no way to have an ICU collation as the default collation.

Is there a way for pg_dump not to use search_path for schema

Question:
Is there a way for pg_dump commands not to use search_path to set a schema, and instead define the schema with the table name
My general context is that I'm trying to dump and restore a postgis database which contains many schemas (this is to migrate my database into an Amazon RDS). In each schema I have tables that have a geography column. The generated SQL from the dump is something like:
CREATE SCHEMA aaaa;
SET search_path = aaaa, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- TOC entry 346 (class 1259 OID 1135099)
-- Name: main; Type: TABLE; Schema: aaaa; Owner: -
--
CREATE TABLE main (
pk bigint NOT NULL,
geometry public.geography(Geometry,4283),
batch bigint NOT NULL,
json jsonb NOT NULL,
cache jsonb NOT NULL,
active bigint DEFAULT date_part('epoch'::text, now()) NOT NULL,
inactive bigint DEFAULT '8640000000000000'::bigint NOT NULL );
However, when restoring, I get the following error:
pg_restore: [archiver (db)] Error from TOC entry 346; 1259 1135099
TABLE main mapworks pg_restore: [archiver (db)] could not execute
query: ERROR: relation "spatial_ref_sys" does not exist LINE 3:
geometry public.geography(Geometry,4283),
^ QUERY: SELECT proj4text FROM spatial_ref_sys WHERE srid = 4283 LIMIT 1
Command was: CREATE TABLE main (
pk bigint NOT NULL,
geometry public.geography(Geometry,4283),
batch bigint NOT NULL,
jso...
Then things just go pear shaped from there.
What I've deduced so far is that because the 'public' schema is not included in the search path, the operation cant find the 'spatial_ref_sys' table.
Oddly enough, this works fine if the EPSG code is 4326.
So ... what can I do about this? Is there a way to tell pg_dump not to use search_path?
The server I'm dumping from:
PostgreSQL 9.6.1 on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit
POSTGIS="2.3.1 r15264" GEOS="3.4.2-CAPI-1.8.2 r3921" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.10.1, released 2013/08/26" LIBXML="2.9.1" LIBJSON="0.11.99" (core procs from "2.3.0 r15146" need upgrade) TOPOLOGY (topology procs from "2.3.0 r15146" need upgrade) RASTER (raster procs from "2.3.0 r15146" need upgrade)
The server I'm restoring to:
PostgreSQL 9.6.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.2 20140120 (Red Hat 4.8.2-16), 64-bit
POSTGIS="2.3.0 r15146" GEOS="3.5.0-CAPI-1.9.0 r4084" PROJ="Rel. 4.9.2, 08 September 2015" GDAL="GDAL 2.1.1, released 2016/07/07" LIBXML="2.9.1" LIBJSON="0.12" TOPOLOGY RASTER

Why UPPER function doesnt change lower case accent char [duplicate]

I have a PostgreSQL database on a shared host and the result of using the upper function is different in my local database because of the locale setting.
Here is what I want, and have in my local environment:
SELECT version();
-- "PostgreSQL 8.4.16 on i386-apple-darwin10.8.0, compiled by GCC i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3), 64-bit"
SHOW LC_COLLATE;
-- "fr_FR.UTF-8"
SELECT upper('étienne');
-- "ÉTIENNE"
Here is what I have in the production environment:
SELECT version();
-- "PostgreSQL 9.0.13 on x86_64-pc-linux-gnu, compiled by GCC gcc-4.3.real (Debian 4.3.2-1.1) 4.3.2, 64-bit"
SHOW LC_COLLATE;
-- "C"
SELECT upper('étienne');
-- éTIENNE
Now, because the production environment is in a shared host, I cannot change the locale due to the host policies. So, is there another way to have the expected result when using upper function?
For 9.1 and up, you can just choose collation locally for the query.
Sadly, considering your version numbers, that would require an upgrade, so may or may not be helpful.
SELECT UPPER('étienne' COLLATE "C") C_Collation,
UPPER('étienne' COLLATE "fr_FR") FR_Collation;
C_Collation FR_Collation
--------------------------------------
éTIENNE ÉTIENNE
An SQLfiddle to test with.
Note that you cannot override the collation (like demonstrated by other answers) in your versions 8.4 or 9.0. This feature was introduced with Postgres 9.1.
In earlier versions, you cannot change the collation chosen when the database was created. The COLLATE key word does not exist and you get an error if you try SET LC_COLLATE = ...:
ERROR: parameter "lc_collate" cannot be changed
You need a more current version to do that.
-> SQLfiddle
Sorry, but you are out of luck.
select upper('étienne') collate "fr_FR";

How to use PostgreSQL upper() function with a different locale?

I have a PostgreSQL database on a shared host and the result of using the upper function is different in my local database because of the locale setting.
Here is what I want, and have in my local environment:
SELECT version();
-- "PostgreSQL 8.4.16 on i386-apple-darwin10.8.0, compiled by GCC i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3), 64-bit"
SHOW LC_COLLATE;
-- "fr_FR.UTF-8"
SELECT upper('étienne');
-- "ÉTIENNE"
Here is what I have in the production environment:
SELECT version();
-- "PostgreSQL 9.0.13 on x86_64-pc-linux-gnu, compiled by GCC gcc-4.3.real (Debian 4.3.2-1.1) 4.3.2, 64-bit"
SHOW LC_COLLATE;
-- "C"
SELECT upper('étienne');
-- éTIENNE
Now, because the production environment is in a shared host, I cannot change the locale due to the host policies. So, is there another way to have the expected result when using upper function?
For 9.1 and up, you can just choose collation locally for the query.
Sadly, considering your version numbers, that would require an upgrade, so may or may not be helpful.
SELECT UPPER('étienne' COLLATE "C") C_Collation,
UPPER('étienne' COLLATE "fr_FR") FR_Collation;
C_Collation FR_Collation
--------------------------------------
éTIENNE ÉTIENNE
An SQLfiddle to test with.
Note that you cannot override the collation (like demonstrated by other answers) in your versions 8.4 or 9.0. This feature was introduced with Postgres 9.1.
In earlier versions, you cannot change the collation chosen when the database was created. The COLLATE key word does not exist and you get an error if you try SET LC_COLLATE = ...:
ERROR: parameter "lc_collate" cannot be changed
You need a more current version to do that.
-> SQLfiddle
Sorry, but you are out of luck.
select upper('étienne') collate "fr_FR";