mirror of
https://github.com/postgres/postgres.git
synced 2026-07-08 09:10:57 -04:00
Avoid collation lookup failure when considering a "char" column.
If a "char" column has a statistics histogram, scalarineqsel()
would fail with "cache lookup failed for collation 0". Avoid
the failing lookup by acting as though the collation is "C".
Prior to commit 06421b084, this code didn't fail because
lc_collate_is_c() intentionally didn't spit up on InvalidOid.
It did act differently though: it would take the non-C-collation
code path and hence apply strxfrm using libc's prevailing locale.
But that seems like the wrong thing for a non-collatable comparison,
so let's not resurrect that aspect.
Author: Feng Wu <wufengwufengwufeng@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CACK3muq6s-O1Wc3w4dRL1Fe8YQ-Fz1zJbezeQwhuLgNxGNEFiA@mail.gmail.com
Backpatch-through: 18
This commit is contained in:
parent
d6ed87d198
commit
b574fec00f
3 changed files with 25 additions and 0 deletions
|
|
@ -5295,6 +5295,14 @@ convert_string_datum(Datum value, Oid typid, Oid collid, bool *failure)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we don't have a collation, act as though it's "C". This would
|
||||
* normally happen only for the "char" type, but perhaps there are other
|
||||
* cases.
|
||||
*/
|
||||
if (!OidIsValid(collid))
|
||||
return val;
|
||||
|
||||
mylocale = pg_newlocale_from_collation(collid);
|
||||
|
||||
if (!mylocale->collate_is_c)
|
||||
|
|
|
|||
|
|
@ -210,4 +210,15 @@ false, true, false, true);
|
|||
-> Result (cost=N..N rows=1 width=N)
|
||||
(4 rows)
|
||||
|
||||
-- Verify that scalarineqsel() works on "char" columns
|
||||
CREATE TEMP TABLE char_table_1 AS
|
||||
SELECT i::"char" AS c FROM generate_series(64,96) i;
|
||||
ANALYZE char_table_1;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM char_table_1 WHERE c < 'Q';
|
||||
QUERY PLAN
|
||||
-----------------------------
|
||||
Seq Scan on char_table_1
|
||||
Filter: (c < 'Q'::"char")
|
||||
(2 rows)
|
||||
|
||||
DROP FUNCTION explain_mask_costs(text, bool, bool, bool, bool);
|
||||
|
|
|
|||
|
|
@ -147,4 +147,10 @@ SELECT explain_mask_costs($$
|
|||
SELECT * FROM tenk1 WHERE unique1 <> ALL (ARRAY[1, 2, 98, (SELECT 99), NULL]);$$,
|
||||
false, true, false, true);
|
||||
|
||||
-- Verify that scalarineqsel() works on "char" columns
|
||||
CREATE TEMP TABLE char_table_1 AS
|
||||
SELECT i::"char" AS c FROM generate_series(64,96) i;
|
||||
ANALYZE char_table_1;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM char_table_1 WHERE c < 'Q';
|
||||
|
||||
DROP FUNCTION explain_mask_costs(text, bool, bool, bool, bool);
|
||||
|
|
|
|||
Loading…
Reference in a new issue