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

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";

Related

Adding COLLATION in postgres

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.

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.

Attempted to delete invisible tuple + Postgres

I have system where we perform large number of inserts and updates query(something upsert as well)
I see occasionally error on my logs that states ..
PG::ObjectNotInPrerequisiteState: ERROR: attempted to delete invisible tuple
INSERT INTO call_records(plain_crn,efd,acd,slt,slr,ror,raw_processing_data,parsed_json,timestamp,active,created_at,updated_at) VALUES (9873,2016030233,'R',0,0,'PKC01','\x02000086000181f9000101007 ... ')
What I fail to understand even when no (delete) query is performed (the above error appear on insert clause) yet the error was thrown.
I have been googling around this issue but no conclusive evidence of why this happen.
Version of Postgres.
database=# select version();
version
--------------------------------------------------------------------------------------------------------------
PostgreSQL 9.5.2 on x86_64-apple-darwin14.5.0, compiled by Apple LLVM version 7.0.0 (clang-700.1.76), 64-bit
(1 row)
Any Clue ??

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";

Postgresql update trigger not accepting When / OF condition

I am trying to write a trigger but getting syntax error:
CREATE TRIGGER archive_domain_trig
AFTER UPDATE OF is_rejected ON pending_domains
FOR EACH ROW
WHEN (new.is_rejected is True)
EXECUTE PROCEDURE archive_domain_fun();
ERROR: syntax error at or near "OF"
not only this but it is giving error on "when" condition also e.g.
CREATE TRIGGER archive_domain_trig
AFTER UPDATE ON pending_domains
FOR EACH ROW
WHEN (new.is_rejected is True)
EXECUTE PROCEDURE archive_domain_fun();
gives:
ERROR: syntax error at or near "WHEN".
select version();
"EnterpriseDB 8.3.0.116 on x86_64-unknown-linux-gnu, compiled by GCC gcc (GCC) 4.1.0"
This is almost similar to postgres example, can anyone tell me what am I doing wrong here?
I'd guess that EnterpriseDB 8.3 is the EnterpriseDB version of PostgreSQL 8.3. Conditional triggers (i.e. the WHEN option) are a new feature in PostgreSQL 9.0. Compare the CREATE TRIGGER documentation for 8.3 and 9.0.