Skip to content

Commit 2743d9a

Browse files
committed
Cosmetic improvements in ltree code.
Add more comments in ltree.h, and correct a misstatement or two. Use a symbol, rather than hardwired constants, for the maximum length of an ltree label. The max length is still hardwired in the associated error messages, but I want to clean that up as part of a separate patch to improve the error messages.
1 parent 122b0cc commit 2743d9a

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

contrib/ltree/ltree.h

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,19 @@
77
#include "tsearch/ts_locale.h"
88
#include "utils/memutils.h"
99

10+
11+
/* ltree */
12+
13+
/*
14+
* We want the maximum length of a label to be encoding-independent, so
15+
* set it somewhat arbitrarily at 255 characters (not bytes), while using
16+
* uint16 fields to hold the byte length.
17+
*/
18+
#define LTREE_LABEL_MAX_CHARS 255
19+
1020
typedef struct
1121
{
12-
uint16 len;
22+
uint16 len; /* label string length in bytes */
1323
char name[FLEXIBLE_ARRAY_MEMBER];
1424
} ltree_level;
1525

@@ -19,7 +29,8 @@ typedef struct
1929
typedef struct
2030
{
2131
int32 vl_len_; /* varlena header (do not touch directly!) */
22-
uint16 numlevel;
32+
uint16 numlevel; /* number of labels */
33+
/* Array of maxalign'd ltree_level structs follows: */
2334
char data[FLEXIBLE_ARRAY_MEMBER];
2435
} ltree;
2536

@@ -30,25 +41,35 @@ typedef struct
3041

3142
/* lquery */
3243

44+
/* lquery_variant: one branch of some OR'ed alternatives */
3345
typedef struct
3446
{
35-
int32 val;
36-
uint16 len;
47+
int32 val; /* CRC of label string */
48+
uint16 len; /* label string length in bytes */
3749
uint8 flag; /* see LVAR_xxx flags below */
3850
char name[FLEXIBLE_ARRAY_MEMBER];
3951
} lquery_variant;
4052

53+
/*
54+
* Note: these macros contain too many MAXALIGN calls and so will sometimes
55+
* overestimate the space needed for an lquery_variant. However, we can't
56+
* change it without breaking on-disk compatibility for lquery.
57+
*/
4158
#define LVAR_HDRSIZE MAXALIGN(offsetof(lquery_variant, name))
4259
#define LVAR_NEXT(x) ( (lquery_variant*)( ((char*)(x)) + MAXALIGN(((lquery_variant*)(x))->len) + LVAR_HDRSIZE ) )
4360

44-
#define LVAR_ANYEND 0x01
45-
#define LVAR_INCASE 0x02
46-
#define LVAR_SUBLEXEME 0x04
61+
#define LVAR_ANYEND 0x01 /* '*' flag: prefix match */
62+
#define LVAR_INCASE 0x02 /* '@' flag: case-insensitive match */
63+
#define LVAR_SUBLEXEME 0x04 /* '%' flag: word-wise match */
4764

65+
/*
66+
* In an lquery_level, "flag" contains the union of the variants' flags
67+
* along with possible LQL_xxx flags; so those bit sets can't overlap.
68+
*/
4869
typedef struct
4970
{
5071
uint16 totallen; /* total length of this level, in bytes */
51-
uint16 flag; /* see LQL_xxx flags below */
72+
uint16 flag; /* see LQL_xxx and LVAR_xxx flags */
5273
uint16 numvar; /* number of variants; 0 means '*' */
5374
uint16 low; /* minimum repeat count for '*' */
5475
uint16 high; /* maximum repeat count for '*' */
@@ -60,7 +81,7 @@ typedef struct
6081
#define LQL_NEXT(x) ( (lquery_level*)( ((char*)(x)) + MAXALIGN(((lquery_level*)(x))->totallen) ) )
6182
#define LQL_FIRST(x) ( (lquery_variant*)( ((char*)(x))+LQL_HDRSIZE ) )
6283

63-
#define LQL_NOT 0x10
84+
#define LQL_NOT 0x10 /* level has '!' (NOT) prefix */
6485

6586
#ifdef LOWER_NODE
6687
#define FLG_CANLOOKSIGN(x) ( ( (x) & ( LQL_NOT | LVAR_ANYEND | LVAR_SUBLEXEME ) ) == 0 )
@@ -73,7 +94,7 @@ typedef struct
7394
{
7495
int32 vl_len_; /* varlena header (do not touch directly!) */
7596
uint16 numlevel; /* number of lquery_levels */
76-
uint16 firstgood;
97+
uint16 firstgood; /* number of leading simple-match levels */
7798
uint16 flag; /* see LQUERY_xxx flags below */
7899
/* Array of maxalign'd lquery_level structs follows: */
79100
char data[FLEXIBLE_ARRAY_MEMBER];

contrib/ltree/ltree_io.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ ltree_in(PG_FUNCTION_ARGS)
8585
if (charlen == 1 && t_iseq(ptr, '.'))
8686
{
8787
lptr->len = ptr - lptr->start;
88-
if (lptr->wlen > 255)
88+
if (lptr->wlen > LTREE_LABEL_MAX_CHARS)
8989
ereport(ERROR,
9090
(errcode(ERRCODE_NAME_TOO_LONG),
9191
errmsg("name of level is too long"),
@@ -112,7 +112,7 @@ ltree_in(PG_FUNCTION_ARGS)
112112
if (state == LTPRS_WAITDELIM)
113113
{
114114
lptr->len = ptr - lptr->start;
115-
if (lptr->wlen > 255)
115+
if (lptr->wlen > LTREE_LABEL_MAX_CHARS)
116116
ereport(ERROR,
117117
(errcode(ERRCODE_NAME_TOO_LONG),
118118
errmsg("name of level is too long"),
@@ -302,7 +302,7 @@ lquery_in(PG_FUNCTION_ARGS)
302302
((lptr->flag & LVAR_SUBLEXEME) ? 1 : 0) -
303303
((lptr->flag & LVAR_INCASE) ? 1 : 0) -
304304
((lptr->flag & LVAR_ANYEND) ? 1 : 0);
305-
if (lptr->wlen > 255)
305+
if (lptr->wlen > LTREE_LABEL_MAX_CHARS)
306306
ereport(ERROR,
307307
(errcode(ERRCODE_NAME_TOO_LONG),
308308
errmsg("name of level is too long"),
@@ -318,7 +318,7 @@ lquery_in(PG_FUNCTION_ARGS)
318318
((lptr->flag & LVAR_SUBLEXEME) ? 1 : 0) -
319319
((lptr->flag & LVAR_INCASE) ? 1 : 0) -
320320
((lptr->flag & LVAR_ANYEND) ? 1 : 0);
321-
if (lptr->wlen > 255)
321+
if (lptr->wlen > LTREE_LABEL_MAX_CHARS)
322322
ereport(ERROR,
323323
(errcode(ERRCODE_NAME_TOO_LONG),
324324
errmsg("name of level is too long"),
@@ -453,7 +453,7 @@ lquery_in(PG_FUNCTION_ARGS)
453453
errmsg("lquery syntax error"),
454454
errdetail("Unexpected end of line.")));
455455

456-
if (lptr->wlen > 255)
456+
if (lptr->wlen > LTREE_LABEL_MAX_CHARS)
457457
ereport(ERROR,
458458
(errcode(ERRCODE_NAME_TOO_LONG),
459459
errmsg("name of level is too long"),
@@ -522,12 +522,21 @@ lquery_in(PG_FUNCTION_ARGS)
522522
}
523523
pfree(GETVAR(curqlevel));
524524
if (cur->numvar > 1 || cur->flag != 0)
525+
{
526+
/* Not a simple match */
525527
wasbad = true;
528+
}
526529
else if (wasbad == false)
530+
{
531+
/* count leading simple matches */
527532
(result->firstgood)++;
533+
}
528534
}
529535
else
536+
{
537+
/* '*', so this isn't a simple match */
530538
wasbad = true;
539+
}
531540
curqlevel = NEXTLEV(curqlevel);
532541
cur = LQL_NEXT(cur);
533542
}

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