19
19
* Copyright (c) 1996-2009, PostgreSQL Global Development Group
22
* $PostgreSQL: pgsql/src/backend/utils/adt/like_match.c,v 1.24 2009/01/01 17:23:49 momjian Exp $
22
* $PostgreSQL: pgsql/src/backend/utils/adt/like_match.c,v 1.26 2009/06/11 14:49:03 momjian Exp $
24
24
*-------------------------------------------------------------------------
28
** Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
29
** Rich $alz is now <rsalz@bbn.com>.
30
** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the LABORT code.
32
** This code was shamelessly stolen from the "pql" code by myself and
33
** slightly modified :)
35
** All references to the word "star" were replaced by "percent"
36
** All references to the word "wild" were replaced by "like"
38
** All the nice shell RE matching stuff was replaced by just "_" and "%"
40
** As I don't have a copy of the SQL standard handy I wasn't sure whether
41
** to leave in the '\' escape character handling.
43
** Keith Parks. <keith@mtcc.demon.co.uk>
45
** SQL92 lets you specify the escape character by saying
46
** LIKE <pattern> ESCAPE <escape character>. We are a small operation
47
** so we force you to use '\'. - ay 7/95
49
** Now we have the like_escape() function that converts patterns with
50
** any specified escape character (or none at all) to the internal
51
** default escape character, which is still '\'. - tgl 9/2000
53
** The code is rewritten to avoid requiring null-terminated strings,
54
** which in turn allows us to leave out some memcpy() operations.
55
** This code should be faster and take less memory, but no promises...
56
** - thomas 2000-08-06
28
* Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
29
* Rich $alz is now <rsalz@bbn.com>.
30
* Special thanks to Lars Mathiesen <thorinn@diku.dk> for the LABORT code.
32
* This code was shamelessly stolen from the "pql" code by myself and
33
* slightly modified :)
35
* All references to the word "star" were replaced by "percent"
36
* All references to the word "wild" were replaced by "like"
38
* All the nice shell RE matching stuff was replaced by just "_" and "%"
40
* As I don't have a copy of the SQL standard handy I wasn't sure whether
41
* to leave in the '\' escape character handling.
43
* Keith Parks. <keith@mtcc.demon.co.uk>
45
* SQL92 lets you specify the escape character by saying
46
* LIKE <pattern> ESCAPE <escape character>. We are a small operation
47
* so we force you to use '\'. - ay 7/95
49
* Now we have the like_escape() function that converts patterns with
50
* any specified escape character (or none at all) to the internal
51
* default escape character, which is still '\'. - tgl 9/2000
53
* The code is rewritten to avoid requiring null-terminated strings,
54
* which in turn allows us to leave out some memcpy() operations.
55
* This code should be faster and take less memory, but no promises...
61
60
/*--------------------
62
* Match text and p, return LIKE_TRUE, LIKE_FALSE, or LIKE_ABORT.
61
* Match text and pattern, return LIKE_TRUE, LIKE_FALSE, or LIKE_ABORT.
64
63
* LIKE_TRUE: they match
65
64
* LIKE_FALSE: they don't match
80
79
MatchText(char *t, int tlen, char *p, int plen)
82
81
/* Fast path for match-everything pattern */
83
if ((plen == 1) && (*p == '%'))
82
if (plen == 1 && *p == '%')
87
86
* In this loop, we advance by char when matching wildcards (and thus on
88
87
* recursive entry to this function we are properly char-synced). On other
89
88
* occasions it is safe to advance by byte, as the text and pattern will
90
* be in lockstep. This allows us to perform all comparisons between the
89
* be in lockstep. This allows us to perform all comparisons between the
91
90
* text and pattern on a byte by byte basis, even for multi-byte
95
while ((tlen > 0) && (plen > 0))
93
while (tlen > 0 && plen > 0)
127
125
* rest of the pattern.
132
129
/* %_ is the same as _% - avoid matching _ repeatedly */
139
return (plen <= 0) ? LIKE_TRUE : LIKE_ABORT;
135
} while (tlen > 0 && plen > 0 && *p == '_');
138
* If we are at the end of the pattern, succeed: % followed by
139
* n _'s matches any string of at least n characters, and we
140
* have now found there are at least n characters.
145
/* Look for a place that matches the rest of the pattern */
148
148
int matched = MatchText(t, tlen, p, plen);
193
191
else if (*p == '_')
193
/* _ matches any single character, and we know there is one */
195
194
NextChar(t, tlen);
196
195
NextByte(p, plen);
199
else if (TCHAR(*t) != TCHAR(*p))
198
else if (TCHAR (*p) != TCHAR (*t))
202
* Not the single-character wildcard and no explicit match? Then
200
/* non-wildcard pattern char fails to match text char */
205
201
return LIKE_FALSE;
205
* Pattern and text match, so advance.
209
207
* It is safe to use NextByte instead of NextChar here, even for
210
208
* multi-byte character sets, because we are not following immediately
211
209
* after a wildcard character. If we are in the middle of a multibyte