mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Adjust string comparison so that only bitwise-equal strings are considered
equal: if strcoll claims two strings are equal, check it with strcmp, and sort according to strcmp if not identical. This fixes inconsistent behavior under glibc's hu_HU locale, and probably under some other locales as well. Also, take advantage of the now-well-defined behavior to speed up texteq, textne, bpchareq, bpcharne: they may as well just do a bitwise comparison and not bother with strcoll at all. NOTE: affected databases may need to REINDEX indexes on text columns to be sure they are self-consistent.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.113 2005/10/15 02:49:30 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.114 2005/12/22 22:50:00 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -614,11 +614,14 @@ bpchareq(PG_FUNCTION_ARGS)
|
||||
len1 = bcTruelen(arg1);
|
||||
len2 = bcTruelen(arg2);
|
||||
|
||||
/* fast path for different-length inputs */
|
||||
/*
|
||||
* Since we only care about equality or not-equality, we can avoid all
|
||||
* the expense of strcoll() here, and just do bitwise comparison.
|
||||
*/
|
||||
if (len1 != len2)
|
||||
result = false;
|
||||
else
|
||||
result = (varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2) == 0);
|
||||
result = (strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0);
|
||||
|
||||
PG_FREE_IF_COPY(arg1, 0);
|
||||
PG_FREE_IF_COPY(arg2, 1);
|
||||
@ -638,11 +641,14 @@ bpcharne(PG_FUNCTION_ARGS)
|
||||
len1 = bcTruelen(arg1);
|
||||
len2 = bcTruelen(arg2);
|
||||
|
||||
/* fast path for different-length inputs */
|
||||
/*
|
||||
* Since we only care about equality or not-equality, we can avoid all
|
||||
* the expense of strcoll() here, and just do bitwise comparison.
|
||||
*/
|
||||
if (len1 != len2)
|
||||
result = true;
|
||||
else
|
||||
result = (varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2) != 0);
|
||||
result = (strncmp(VARDATA(arg1), VARDATA(arg2), len1) != 0);
|
||||
|
||||
PG_FREE_IF_COPY(arg1, 0);
|
||||
PG_FREE_IF_COPY(arg2, 1);
|
||||
@ -789,7 +795,9 @@ bpchar_smaller(PG_FUNCTION_ARGS)
|
||||
* bpchar needs a specialized hash function because we want to ignore
|
||||
* trailing blanks in comparisons.
|
||||
*
|
||||
* XXX is there any need for locale-specific behavior here?
|
||||
* Note: currently there is no need for locale-specific behavior here,
|
||||
* but if we ever change the semantics of bpchar comparison to trust
|
||||
* strcoll() completely, we'd need to do something different in non-C locales.
|
||||
*/
|
||||
Datum
|
||||
hashbpchar(PG_FUNCTION_ARGS)
|
||||
|
Reference in New Issue
Block a user