pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Jim Finnerty <jfinnert@amazon.com>
To: pgsql-hackers@postgresql.org
Subject: Re: insensitive collations
Date: Thu, 25 Mar 2021 06:09:49 -0700 (MST)
Message-ID: <1616677789675-0.post@n3.nabble.com> (raw)
In-Reply-To: <54ef5bfe-043e-4328-9d70-5818789838f4@manitou-mail.org>
References: <cdd0ed2e-1d98-6fc4-07f1-23f19f53b201@2ndquadrant.com>
	<5c7f51b0-6788-4ffd-b9c4-23b710373140@manitou-mail.org>
	<fd54ad77-fb1a-c77d-1371-d7850562b080@2ndquadrant.com>
	<440ec733-d068-46d3-9756-f5f692aba7c8@manitou-mail.org>
	<99818c53-d10f-eb0b-bcb1-fd5d60f6dd96@2ndquadrant.com>
	<f2b3b8e8-12c4-ceb7-6803-b4af6eb2cb71@2ndquadrant.com>
	<693ad06d-db9a-4e59-8131-f823483c5893@manitou-mail.org>
	<1616528764665-0.post@n3.nabble.com>
	<1616618498263-0.post@n3.nabble.com>
	<54ef5bfe-043e-4328-9d70-5818789838f4@manitou-mail.org>

The two ideas can be combined to create a workaround for accent-sensitive
nondeterministic collations that enables an ordinary btree to be exploited
if available, and also provides the full LIKE logic in either case-sensitive
or case-insensitive collations:

SELECT * FROM locations WHERE location LIKE 'midi-Pyrén%ées';

becomes: 

SELECT * FROM locations 
WHERE 
    location COLLATE "C" ILIKE 'midi-Pyrén%ées'  AND                       
-- For CI collations only
    location BETWEEN 'midi-Pyrén' AND 'midi-Pyrén' || E'\uFFFF';         --
exploitable by ordinary btree

LIKE would also be valid for a case sensitive collation, but then the
collation would be CS_AS, so it would be deterministic and no transform
would be needed.

The expression above produces a good plan, but EXPLAIN complains if the
concatenated expression is not a valid character for the current
client_encoding, which I had set to WIN1252 to display the accented
characters properly on the client:

babel=# SELECT * FROM locations 
babel-# WHERE 
babel-#     location COLLATE "C" ILIKE 'midi-Pyrén%ées'  AND                       
-- For CI collations only
babel-#     location BETWEEN 'midi-Pyrén' AND 'midi-Pyrén' || E'\uFFFF';        
-- exploitable by ordinary btree
    location     
-----------------
 Midi-Pyrénées
 midi-Pyrénées
(2 rows)

babel=# EXPLAIN VERBOSE SELECT * FROM locations 
babel-# WHERE 
babel-#     location COLLATE "C" ILIKE 'midi-Pyrén%ées'  AND                       
-- For CI collations only
babel-#     location BETWEEN 'midi-Pyrén' AND 'midi-Pyrén' || E'\uFFFF';        
-- exploitable by ordinary btree
ERROR:  character with byte sequence 0xef 0xbf 0xbf in encoding "UTF8" has
no equivalent in encoding "WIN1252"

reset client_encoding;

babel=# EXPLAIN VERBOSE SELECT * FROM locations 
WHERE 
    location COLLATE "C" ILIKE 'midi-Pyrén%ées'  AND                       
-- For CI collations only
    location BETWEEN 'midi-Pyrén' AND 'midi-Pyrén' || E'\uFFFF';         --
exploitable by ordinary btree
                                                 QUERY PLAN                                                 
------------------------------------------------------------------------------------------------------------
 Index Only Scan using *location_index* on public.locations 
(cost=0.13..8.15 rows=1 width=18)
   Output: location
   Index Cond: ((locations.location >= 'midi-Pyrén'::text) AND
(locations.location <= 'midi-Pyrén￿'::text))
   Filter: ((locations.location)::text ~~* 'midi-Pyrén%ées'::text)
(4 rows)




-----
Jim Finnerty, AWS, Amazon Aurora PostgreSQL
--
Sent from: https://www.postgresql-archive.org/PostgreSQL-hackers-f1928748.html





view thread (44+ messages)  latest in thread

Message-ID: <1616677789675-0.post@n3.nabble.com>
Permalink:  ../1616677789675-0.post@n3.nabble.com/
Also on:    postgresql.org/message-id/1616677789675-0.post@n3.nabble.com

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: jfinnert@amazon.com
  Subject: Re: insensitive collations
  In-Reply-To: <1616677789675-0.post@n3.nabble.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox