Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbee7cd2

Browse files
committed
Repair logic error in LIKE: should not return LIKE_ABORT
when reach end of pattern before end of text. Improve code comments.
1 parentea582ad commitbee7cd2

File tree

1 file changed

+50
-41
lines changed

1 file changed

+50
-41
lines changed

‎src/backend/utils/adt/like.c

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,14 @@
33
* like.c
44
* like expression handling code.
55
*
6-
* Copyright (c) 1994, Regents of the University of California
7-
*
8-
*
9-
* IDENTIFICATION
10-
* /usr/local/devel/pglite/cvs/src/backend/utils/adt/like.c,v 1.1 1995/07/30 23:55:36 emkxp01 Exp
11-
*
12-
*
136
* NOTES
147
*A big hack of the regexp.c code!! Contributed by
158
*Keith Parks <emkxp01@mtcc.demon.co.uk> (7/95).
169
*
10+
* Copyright (c) 1994, Regents of the University of California
11+
*
12+
* IDENTIFICATION
13+
*$Header: /cvsroot/pgsql/src/backend/utils/adt/like.c,v 1.31 1999/09/07 19:09:46 tgl Exp $
1714
*
1815
*-------------------------------------------------------------------------
1916
*/
@@ -109,9 +106,7 @@ textnlike(struct varlena * s, struct varlena * p)
109106
}
110107

111108

112-
/*$Revision: 1.30 $
113-
**"like.c" A first attempt at a LIKE operator for Postgres95.
114-
**
109+
/*
115110
**Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
116111
**Rich $alz is now <rsalz@bbn.com>.
117112
**Special thanks to Lars Mathiesen <thorinn@diku.dk> for the LABORT code.
@@ -125,8 +120,7 @@ textnlike(struct varlena * s, struct varlena * p)
125120
**All the nice shell RE matching stuff was replaced by just "_" and "%"
126121
**
127122
**As I don't have a copy of the SQL standard handy I wasn't sure whether
128-
**to leave in the '\' escape character handling. (I suspect the standard
129-
**handles "%%" as a single literal percent)
123+
**to leave in the '\' escape character handling.
130124
**
131125
**Keith Parks. <keith@mtcc.demon.co.uk>
132126
**
@@ -140,15 +134,21 @@ textnlike(struct varlena * s, struct varlena * p)
140134
#defineLIKE_FALSE0
141135
#defineLIKE_ABORT-1
142136

143-
/*
144-
**Match text and p, return LIKE_TRUE, LIKE_FALSE, or LIKE_ABORT.
145-
*/
137+
/*--------------------
138+
*Match text and p, return LIKE_TRUE, LIKE_FALSE, or LIKE_ABORT.
139+
*
140+
*LIKE_TRUE: they match
141+
*LIKE_FALSE: they don't match
142+
*LIKE_ABORT: not only don't they match, but the text is too short.
143+
*
144+
* If LIKE_ABORT is returned, then no suffix of the text can match the
145+
* pattern either, so an upper-level % scan can stop scanning now.
146+
*--------------------
147+
*/
146148
staticint
147149
DoMatch(pg_wchar*text,pg_wchar*p)
148150
{
149-
intmatched;
150-
151-
for (;*p&&*text;text++,p++)
151+
for (;*p&&*text;text++,p++)
152152
{
153153
switch (*p)
154154
{
@@ -157,54 +157,63 @@ DoMatch(pg_wchar * text, pg_wchar * p)
157157
p++;
158158
/* FALLTHROUGH */
159159
default:
160-
if (*text!=*p)
160+
if (*text!=*p)
161161
returnLIKE_FALSE;
162162
break;
163163
case'_':
164-
/* Matchanything. */
164+
/* Matchany single character. */
165165
break;
166166
case'%':
167167
/* %% is the same as % according to the SQL standard */
168168
/* Advance past all %'s */
169169
while (*p=='%')
170170
p++;
171+
/* Trailing percent matches everything. */
171172
if (*p=='\0')
172-
/* Trailing percent matches everything. */
173173
returnLIKE_TRUE;
174-
while (*text)
174+
/* Otherwise, scan for a text position at which we
175+
* can match the rest of the pattern.
176+
*/
177+
for (;*text;text++)
175178
{
176-
/* Optimization to prevent most recursion */
177-
if ((*text==*p||
178-
*p=='\\'||*p=='%'||*p=='_')&&
179-
(matched=DoMatch(text,p))!=LIKE_FALSE)
180-
returnmatched;
181-
text++;
179+
/* Optimization to prevent most recursion: don't recurse
180+
* unless first pattern char might match this text char.
181+
*/
182+
if (*text==*p||*p=='\\'||*p=='_')
183+
{
184+
intmatched=DoMatch(text,p);
185+
if (matched!=LIKE_FALSE)
186+
returnmatched;/* TRUE or ABORT */
187+
}
182188
}
189+
/* End of text with no match, so no point in trying later
190+
* places to start matching this pattern.
191+
*/
183192
returnLIKE_ABORT;
184193
}
185194
}
186195

187-
if (*text!='\0')
188-
returnLIKE_ABORT;
189-
else
190-
{
191-
/* End of input string. Do we have matching string remaining? */
192-
while (*p=='%')/* allow multiple %'s at end of pattern */
193-
p++;
194-
if (*p=='\0')
195-
returnLIKE_TRUE;
196-
else
197-
returnLIKE_ABORT;
198-
}
199-
}
196+
if (*text!='\0')
197+
returnLIKE_FALSE;/* end of pattern, but not of text */
200198

199+
/* End of input string. Do we have matching pattern remaining? */
200+
while (*p=='%')/* allow multiple %'s at end of pattern */
201+
p++;
202+
if (*p=='\0')
203+
returnLIKE_TRUE;
204+
/* End of text with no match, so no point in trying later
205+
* places to start matching this pattern.
206+
*/
207+
returnLIKE_ABORT;
208+
}
201209

202210
/*
203211
**User-level routine. Returns TRUE or FALSE.
204212
*/
205213
staticint
206214
like(pg_wchar*text,pg_wchar*p)
207215
{
216+
/* Fast path for match-everything pattern */
208217
if (p[0]=='%'&&p[1]=='\0')
209218
return TRUE;
210219
returnDoMatch(text,p)==LIKE_TRUE;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp