Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions contrib/btree_gist/btree_utils_var.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,36 +116,47 @@ gbt_var_leaf2node(GBT_VARKEY *leaf, const gbtree_vinfo *tinfo, FmgrInfo *flinfo)

/*
* returns the common prefix length of a node key
*
* If the underlying type is character data, the prefix length may point in
* the middle of a multibyte character.
*/
static int32
gbt_var_node_cp_len(const GBT_VARKEY *node, const gbtree_vinfo *tinfo)
{
GBT_VARKEY_R r = gbt_var_key_readable(node);
int32 i = 0;
int32 l = 0;
int32 l_left_to_match = 0;
int32 l_total = 0;
int32 t1len = VARSIZE(r.lower) - VARHDRSZ;
int32 t2len = VARSIZE(r.upper) - VARHDRSZ;
int32 ml = Min(t1len, t2len);
char *p1 = VARDATA(r.lower);
char *p2 = VARDATA(r.upper);
const char *end1 = p1 + t1len;
const char *end2 = p2 + t2len;

if (ml == 0)
return 0;

while (i < ml)
{
if (tinfo->eml > 1 && l == 0)
if (tinfo->eml > 1 && l_left_to_match == 0)
{
if ((l = pg_mblen(p1)) != pg_mblen(p2))
l_total = pg_mblen_range(p1, end1);
if (l_total != pg_mblen_range(p2, end2))
{
return i;
}
l_left_to_match = l_total;
}
if (*p1 != *p2)
{
if (tinfo->eml > 1)
{
return (i - l + 1);
int32 l_matched_subset = l_total - l_left_to_match;

/* end common prefix at final byte of last matching char */
return i - l_matched_subset;
}
else
{
Expand All @@ -155,7 +166,7 @@ gbt_var_node_cp_len(const GBT_VARKEY *node, const gbtree_vinfo *tinfo)

p1++;
p2++;
l--;
l_left_to_match--;
i++;
}
return ml; /* lower == upper */
Expand Down
8 changes: 4 additions & 4 deletions contrib/dict_xsyn/dict_xsyn.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ find_word(char *in, char **end)
char *start;

*end = NULL;
while (*in && t_isspace(in))
in += pg_mblen(in);
while (*in && t_isspace_cstr(in))
in += pg_mblen_cstr(in);

if (!*in || *in == '#')
return NULL;
start = in;

while (*in && !t_isspace(in))
in += pg_mblen(in);
while (*in && !t_isspace_cstr(in))
in += pg_mblen_cstr(in);

*end = in;

Expand Down
2 changes: 1 addition & 1 deletion contrib/hstore/hstore_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ prssyntaxerror(HSParser *state)
errsave(state->escontext,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error in hstore, near \"%.*s\" at position %d",
pg_mblen(state->ptr), state->ptr,
pg_mblen_cstr(state->ptr), state->ptr,
(int) (state->ptr - state->begin))));
/* In soft error situation, return false as convenience for caller */
return false;
Expand Down
14 changes: 13 additions & 1 deletion contrib/intarray/_int_selfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "catalog/pg_operator.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "commands/extension.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
Expand Down Expand Up @@ -171,7 +172,18 @@ _int_matchsel(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(0.0);
}

/* The caller made sure the const is a query, so get it now */
/*
* Verify that the Const is a query_int, else return a default estimate.
* (This could only fail if someone attached this estimator to the wrong
* operator.)
*/
if (((Const *) other)->consttype !=
get_function_sibling_type(fcinfo->flinfo->fn_oid, "query_int"))
{
ReleaseVariableStats(vardata);
PG_RETURN_FLOAT8(DEFAULT_EQ_SEL);
}

query = DatumGetQueryTypeP(((Const *) other)->constvalue);

/* Empty query matches nothing */
Expand Down
4 changes: 2 additions & 2 deletions contrib/ltree/lquery_op.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ getlexeme(char *start, char *end, int *len)
char *ptr;

while (start < end && t_iseq(start, '_'))
start += pg_mblen(start);
start += pg_mblen_range(start, end);

ptr = start;
if (ptr >= end)
return NULL;

while (ptr < end && !t_iseq(ptr, '_'))
ptr += pg_mblen(ptr);
ptr += pg_mblen_range(ptr, end);

*len = ptr - start;
return start;
Expand Down
2 changes: 1 addition & 1 deletion contrib/ltree/ltree.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ typedef struct
#define LQUERY_HASNOT 0x01

/* valid label chars are alphanumerics, underscores and hyphens */
#define ISLABEL(x) ( t_isalnum(x) || t_iseq(x, '_') || t_iseq(x, '-') )
#define ISLABEL(x) ( t_isalnum_cstr(x) || t_iseq(x, '_') || t_iseq(x, '-') )

/* full text query */

Expand Down
16 changes: 8 additions & 8 deletions contrib/ltree/ltree_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ parse_ltree(const char *buf, struct Node *escontext)
ptr = buf;
while (*ptr)
{
charlen = pg_mblen(ptr);
charlen = pg_mblen_cstr(ptr);
if (t_iseq(ptr, '.'))
num++;
ptr += charlen;
Expand All @@ -71,7 +71,7 @@ parse_ltree(const char *buf, struct Node *escontext)
ptr = buf;
while (*ptr)
{
charlen = pg_mblen(ptr);
charlen = pg_mblen_cstr(ptr);

switch (state)
{
Expand Down Expand Up @@ -293,7 +293,7 @@ parse_lquery(const char *buf, struct Node *escontext)
ptr = buf;
while (*ptr)
{
charlen = pg_mblen(ptr);
charlen = pg_mblen_cstr(ptr);

if (t_iseq(ptr, '.'))
num++;
Expand All @@ -313,7 +313,7 @@ parse_lquery(const char *buf, struct Node *escontext)
ptr = buf;
while (*ptr)
{
charlen = pg_mblen(ptr);
charlen = pg_mblen_cstr(ptr);

switch (state)
{
Expand Down Expand Up @@ -418,7 +418,7 @@ parse_lquery(const char *buf, struct Node *escontext)
case LQPRS_WAITFNUM:
if (t_iseq(ptr, ','))
state = LQPRS_WAITSNUM;
else if (t_isdigit(ptr))
else if (t_isdigit_cstr(ptr))
{
int low = atoi(ptr);

Expand All @@ -436,7 +436,7 @@ parse_lquery(const char *buf, struct Node *escontext)
UNCHAR;
break;
case LQPRS_WAITSNUM:
if (t_isdigit(ptr))
if (t_isdigit_cstr(ptr))
{
int high = atoi(ptr);

Expand Down Expand Up @@ -467,7 +467,7 @@ parse_lquery(const char *buf, struct Node *escontext)
case LQPRS_WAITCLOSE:
if (t_iseq(ptr, '}'))
state = LQPRS_WAITEND;
else if (!t_isdigit(ptr))
else if (!t_isdigit_cstr(ptr))
UNCHAR;
break;
case LQPRS_WAITND:
Expand All @@ -478,7 +478,7 @@ parse_lquery(const char *buf, struct Node *escontext)
}
else if (t_iseq(ptr, ','))
state = LQPRS_WAITSNUM;
else if (!t_isdigit(ptr))
else if (!t_isdigit_cstr(ptr))
UNCHAR;
break;
case LQPRS_WAITEND:
Expand Down
4 changes: 2 additions & 2 deletions contrib/ltree/ltxtquery_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ gettoken_query(QPRS_STATE *state, int32 *val, int32 *lenval, char **strval, uint

for (;;)
{
charlen = pg_mblen(state->buf);
charlen = pg_mblen_cstr(state->buf);

switch (state->state)
{
Expand All @@ -88,7 +88,7 @@ gettoken_query(QPRS_STATE *state, int32 *val, int32 *lenval, char **strval, uint
*lenval = charlen;
*flag = 0;
}
else if (!t_isspace(state->buf))
else if (!t_isspace_cstr(state->buf))
ereturn(state->escontext, ERR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("operand syntax error")));
Expand Down
2 changes: 1 addition & 1 deletion contrib/pageinspect/heapfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ text_to_bits(char *str, int len)
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
errmsg("invalid character \"%.*s\" in t_bits string",
pg_mblen(str + off), str + off)));
pg_mblen_cstr(str + off), str + off)));

if (off % 8 == 7)
bits[off / 8] = byte;
Expand Down
2 changes: 1 addition & 1 deletion contrib/pg_trgm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ DATA = pg_trgm--1.5--1.6.sql pg_trgm--1.4--1.5.sql pg_trgm--1.3--1.4.sql \
pg_trgm--1.0--1.1.sql
PGFILEDESC = "pg_trgm - trigram matching"

REGRESS = pg_trgm pg_word_trgm pg_strict_word_trgm
REGRESS = pg_trgm pg_utf8_trgm pg_word_trgm pg_strict_word_trgm
REGRESS_OPTS += --init-file=$(top_srcdir)/src/test/regress/init_file

ifdef USE_PGXS
Expand Down
50 changes: 50 additions & 0 deletions contrib/pg_trgm/data/trgm_utf8.data
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
Mathematics
数学
गणित
Matemáticas
رياضيات
Mathématiques
গণিত
Matemática
Математика
ریاضی
Matematika
Mathematik
数学
Mathematics
गणित
గణితం
Matematik
கணிதம்
數學
Toán học
Matematika
数学
수학
ریاضی
Lissafi
Hisabati
Matematika
Matematica
ریاضی
ಗಣಿತ
ગણિત
คณิตศาสตร์
ሂሳብ
गणित
ਗਣਿਤ
數學
数学
Iṣiro
數學
သင်္ချာ
Herrega
رياضي
गणित
Математика
Matematyka
ഗണിതം
Matematika
رياضي
Matematika
Matematică
8 changes: 8 additions & 0 deletions contrib/pg_trgm/expected/pg_utf8_trgm.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
\if :skip_test
\quit
\endif
-- Index 50 translations of the word "Mathematics"
CREATE TEMP TABLE mb (s text);
\copy mb from 'data/trgm_utf8.data'
CREATE INDEX ON mb USING gist(s gist_trgm_ops);
3 changes: 3 additions & 0 deletions contrib/pg_trgm/expected/pg_utf8_trgm_1.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
\if :skip_test
\quit
1 change: 1 addition & 0 deletions contrib/pg_trgm/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ tests += {
'regress': {
'sql': [
'pg_trgm',
'pg_utf8_trgm',
'pg_word_trgm',
'pg_strict_word_trgm',
],
Expand Down
9 changes: 9 additions & 0 deletions contrib/pg_trgm/sql/pg_utf8_trgm.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
\if :skip_test
\quit
\endif

-- Index 50 translations of the word "Mathematics"
CREATE TEMP TABLE mb (s text);
\copy mb from 'data/trgm_utf8.data'
CREATE INDEX ON mb USING gist(s gist_trgm_ops);
4 changes: 2 additions & 2 deletions contrib/pg_trgm/trgm.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ typedef char trgm[3];
} while(0)

#ifdef KEEPONLYALNUM
#define ISWORDCHR(c) (t_isalnum(c))
#define ISWORDCHR(c, len) (t_isalnum_with_len(c, len))
#define ISPRINTABLECHAR(a) ( isascii( *(unsigned char*)(a) ) && (isalnum( *(unsigned char*)(a) ) || *(unsigned char*)(a)==' ') )
#else
#define ISWORDCHR(c) (!t_isspace(c))
#define ISWORDCHR(c, len) (!t_isspace_with_len(c, len))
#define ISPRINTABLECHAR(a) ( isascii( *(unsigned char*)(a) ) && isprint( *(unsigned char*)(a) ) )
#endif
#define ISPRINTABLETRGM(t) ( ISPRINTABLECHAR( ((char*)(t)) ) && ISPRINTABLECHAR( ((char*)(t))+1 ) && ISPRINTABLECHAR( ((char*)(t))+2 ) )
Expand Down
Loading
Loading