mirror of
https://github.com/postgres/postgres.git
synced 2025-12-19 17:02:53 +03:00
Previously, ltree_prefix_eq_ci() used lowercasing with the default collation; while ltree_crc32_sz() used tolower() directly. These were equivalent only if the default collation provider was libc and the encoding was single-byte. Change both to use casefolding with the default collation. Backpatch through 18, where the casefolding APIs were introduced. The bug exists in earlier versions, but would require some adaptation. A REINDEX is required for ltree indexes where the database default collation is not libc. Reviewed-by: Chao Li <li.evan.chao@gmail.com> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Backpatch-through: 18 Discussion: https://postgr.es/m/450ceb6260cad30d7afdf155d991a9caafee7c0d.camel@j-davis.com Discussion: https://postgr.es/m/01fc00fd66f641b9693d4f9f1af0ccf44cbdfbdf.camel@j-davis.com
72 lines
1.3 KiB
C
72 lines
1.3 KiB
C
/* contrib/ltree/crc32.c */
|
|
|
|
/*
|
|
* Implements CRC-32, as used in ltree.
|
|
*
|
|
* Note that the CRC is used in the on-disk format of GiST indexes, so we
|
|
* must stay backwards-compatible!
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
#include "ltree.h"
|
|
|
|
#include "crc32.h"
|
|
#include "utils/pg_crc.h"
|
|
#ifdef LOWER_NODE
|
|
#include "catalog/pg_collation.h"
|
|
#include "utils/pg_locale.h"
|
|
#endif
|
|
|
|
#ifdef LOWER_NODE
|
|
|
|
unsigned int
|
|
ltree_crc32_sz(const char *buf, int size)
|
|
{
|
|
pg_crc32 crc;
|
|
const char *p = buf;
|
|
static pg_locale_t locale = NULL;
|
|
|
|
if (!locale)
|
|
locale = pg_newlocale_from_collation(DEFAULT_COLLATION_OID);
|
|
|
|
INIT_TRADITIONAL_CRC32(crc);
|
|
while (size > 0)
|
|
{
|
|
char foldstr[UNICODE_CASEMAP_BUFSZ];
|
|
int srclen = pg_mblen(p);
|
|
size_t foldlen;
|
|
|
|
/* fold one codepoint at a time */
|
|
foldlen = pg_strfold(foldstr, UNICODE_CASEMAP_BUFSZ, p, srclen,
|
|
locale);
|
|
|
|
COMP_TRADITIONAL_CRC32(crc, foldstr, foldlen);
|
|
|
|
size -= srclen;
|
|
p += srclen;
|
|
}
|
|
FIN_TRADITIONAL_CRC32(crc);
|
|
return (unsigned int) crc;
|
|
}
|
|
|
|
#else
|
|
|
|
unsigned int
|
|
ltree_crc32_sz(const char *buf, int size)
|
|
{
|
|
pg_crc32 crc;
|
|
const char *p = buf;
|
|
|
|
INIT_TRADITIONAL_CRC32(crc);
|
|
while (size > 0)
|
|
{
|
|
COMP_TRADITIONAL_CRC32(crc, p, 1);
|
|
size--;
|
|
p++;
|
|
}
|
|
FIN_TRADITIONAL_CRC32(crc);
|
|
return (unsigned int) crc;
|
|
}
|
|
|
|
#endif /* !LOWER_NODE */
|