Skip to content

Commit 8eee65c

Browse files
committed
ltree support for multibyte encodings. Patch was made by
laser <laserlist@pgsqldb.com> with some editorization by me.
1 parent 995fb74 commit 8eee65c

File tree

5 files changed

+136
-87
lines changed

5 files changed

+136
-87
lines changed

contrib/ltree/lquery_op.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
/*
22
* op function for ltree and lquery
33
* Teodor Sigaev <teodor@stack.net>
4-
* $PostgreSQL: pgsql/contrib/ltree/lquery_op.c,v 1.12 2008/05/12 00:00:42 alvherre Exp $
4+
* $PostgreSQL: pgsql/contrib/ltree/lquery_op.c,v 1.13 2008/06/30 18:30:48 teodor Exp $
55
*/
66
#include "postgres.h"
77

88
#include <ctype.h>
99

1010
#include "utils/array.h"
11+
#include "utils/formatting.h"
1112
#include "ltree.h"
1213

1314
PG_FUNCTION_INFO_V1(ltq_regex);
@@ -32,23 +33,24 @@ static char *
3233
getlexeme(char *start, char *end, int *len)
3334
{
3435
char *ptr;
35-
36-
while (start < end && *start == '_')
37-
start++;
36+
int charlen;
37+
38+
while (start < end && (charlen = pg_mblen(start)) == 1 && t_iseq(start,'_') )
39+
start += charlen;
3840

3941
ptr = start;
40-
if (ptr == end)
42+
if (ptr >= end)
4143
return NULL;
4244

43-
while (ptr < end && *ptr != '_')
44-
ptr++;
45+
while (ptr < end && !( (charlen = pg_mblen(ptr)) == 1 && t_iseq(ptr, '_') ) )
46+
ptr += charlen;
4547

4648
*len = ptr - start;
4749
return start;
4850
}
4951

5052
bool
51-
compare_subnode(ltree_level * t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
53+
compare_subnode(ltree_level * t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
5254
{
5355
char *endt = t->name + t->len;
5456
char *endq = qn + len;
@@ -85,6 +87,21 @@ bool
8587
return true;
8688
}
8789

90+
int
91+
ltree_strncasecmp(const char *a, const char *b, size_t s)
92+
{
93+
char *al = str_tolower(a, s);
94+
char *bl = str_tolower(b, s);
95+
int res;
96+
97+
res = strncmp(al, bl,s);
98+
99+
pfree(al);
100+
pfree(bl);
101+
102+
return res;
103+
}
104+
88105
static bool
89106
checkLevel(lquery_level * curq, ltree_level * curt)
90107
{
@@ -94,7 +111,7 @@ checkLevel(lquery_level * curq, ltree_level * curt)
94111

95112
for (i = 0; i < curq->numvar; i++)
96113
{
97-
cmpptr = (curvar->flag & LVAR_INCASE) ? pg_strncasecmp : strncmp;
114+
cmpptr = (curvar->flag & LVAR_INCASE) ? ltree_strncasecmp : strncmp;
98115

99116
if (curvar->flag & LVAR_SUBLEXEME)
100117
{

contrib/ltree/ltree.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
/* $PostgreSQL: pgsql/contrib/ltree/ltree.h,v 1.20 2008/05/12 00:00:42 alvherre Exp $ */
1+
/* $PostgreSQL: pgsql/contrib/ltree/ltree.h,v 1.21 2008/06/30 18:30:48 teodor Exp $ */
22

33
#ifndef __LTREE_H__
44
#define __LTREE_H__
55

6+
#include "postgres.h"
67
#include "fmgr.h"
8+
#include "tsearch/ts_locale.h"
79

810
typedef struct
911
{
10-
uint8 len;
12+
uint16 len;
1113
char name[1];
1214
} ltree_level;
1315

14-
#define LEVEL_HDRSIZE (sizeof(uint8))
16+
#define LEVEL_HDRSIZE (offsetof(ltree_level,name))
1517
#define LEVEL_NEXT(x) ( (ltree_level*)( ((char*)(x)) + MAXALIGN(((ltree_level*)(x))->len + LEVEL_HDRSIZE) ) )
1618

1719
typedef struct
@@ -21,7 +23,7 @@ typedef struct
2123
char data[1];
2224
} ltree;
2325

24-
#define LTREE_HDRSIZE MAXALIGN(VARHDRSZ + sizeof(uint16))
26+
#define LTREE_HDRSIZE MAXALIGN( offsetof(ltree, data) )
2527
#define LTREE_FIRST(x) ( (ltree_level*)( ((char*)(x))+LTREE_HDRSIZE ) )
2628

2729

@@ -30,12 +32,12 @@ typedef struct
3032
typedef struct
3133
{
3234
int4 val;
33-
uint8 len;
35+
uint16 len;
3436
uint8 flag;
3537
char name[1];
3638
} lquery_variant;
3739

38-
#define LVAR_HDRSIZE MAXALIGN(sizeof(uint8)*2 + sizeof(int4))
40+
#define LVAR_HDRSIZE MAXALIGN(offsetof(lquery_variant, name))
3941
#define LVAR_NEXT(x) ( (lquery_variant*)( ((char*)(x)) + MAXALIGN(((lquery_variant*)(x))->len) + LVAR_HDRSIZE ) )
4042

4143
#define LVAR_ANYEND 0x01
@@ -52,7 +54,7 @@ typedef struct
5254
char variants[1];
5355
} lquery_level;
5456

55-
#define LQL_HDRSIZE MAXALIGN( sizeof(uint16)*5 )
57+
#define LQL_HDRSIZE MAXALIGN( offsetof(lquery_level,variants) )
5658
#define LQL_NEXT(x) ( (lquery_level*)( ((char*)(x)) + MAXALIGN(((lquery_level*)(x))->totallen) ) )
5759
#define LQL_FIRST(x) ( (lquery_variant*)( ((char*)(x))+LQL_HDRSIZE ) )
5860

@@ -73,12 +75,12 @@ typedef struct
7375
char data[1];
7476
} lquery;
7577

76-
#define LQUERY_HDRSIZE MAXALIGN(VARHDRSZ + 3*sizeof(uint16))
78+
#define LQUERY_HDRSIZE MAXALIGN( offsetof(lquery, data) )
7779
#define LQUERY_FIRST(x) ( (lquery_level*)( ((char*)(x))+LQUERY_HDRSIZE ) )
7880

7981
#define LQUERY_HASNOT 0x01
8082

81-
#define ISALNUM(x) ( isalnum((unsigned char)(x)) || (x) == '_' )
83+
#define ISALNUM(x) ( t_isalpha(x) || t_isdigit(x) || ( pg_mblen(x) == 1 && t_iseq((x), '_') ) )
8284

8385
/* full text query */
8486

@@ -156,9 +158,10 @@ bool ltree_execute(ITEM * curitem, void *checkval,
156158

157159
int ltree_compare(const ltree * a, const ltree * b);
158160
bool inner_isparent(const ltree * c, const ltree * p);
159-
bool compare_subnode(ltree_level * t, char *q, int len,
160-
int (*cmpptr) (const char *, const char *, size_t), bool anyend);
161+
bool compare_subnode(ltree_level * t, char *q, int len,
162+
int (*cmpptr) (const char *, const char *, size_t), bool anyend);
161163
ltree *lca_inner(ltree ** a, int len);
164+
int ltree_strncasecmp(const char *a, const char *b, size_t s);
162165

163166
#define PG_GETARG_LTREE(x) ((ltree*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(x))))
164167
#define PG_GETARG_LTREE_COPY(x) ((ltree*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(x))))

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy