@@ -111,7 +111,7 @@ textnlike(struct varlena *s, struct varlena *p)
111111}
112112
113113
114- /*$Revision: 1.22 $
114+ /*$Revision: 1.23 $
115115**"like.c" A first attempt at a LIKE operator for Postgres95.
116116**
117117**Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
@@ -150,38 +150,52 @@ DoMatch(pg_wchar *text, pg_wchar *p)
150150{
151151int matched ;
152152
153- for (;* p ; text ++ ,p ++ )
153+ for (;* p && * text ; text ++ ,p ++ )
154154{
155- if (* text == '\0' && * p != '%' )
156- return LIKE_ABORT ;
157155switch (* p )
158156{
159157case '\\' :
160158/* Literal match with following character. */
161159p ++ ;
162160/* FALLTHROUGH */
163161default :
164- if (* text != * p )
162+ if (* text != * p )
165163return LIKE_FALSE ;
166- continue ;
164+ break ;
167165case '_' :
168166/* Match anything. */
169- continue ;
167+ break ;
170168case '%' :
171- while (* ++ p == '%' )
172- /* Consecutive percents act just like one. */
173- continue ;
169+ /* %% is the same as % according to the SQL standard */
170+ /* Advance past all %'s */
171+ while (* p == '%' )
172+ p ++ ;
174173if (* p == '\0' )
175174/* Trailing percent matches everything. */
176175return LIKE_TRUE ;
177176while (* text )
178- if ((matched = DoMatch (text ++ ,p ))!= LIKE_FALSE )
177+ {
178+ /* Optimization to prevent most recursion */
179+ if ((* text == * p ||
180+ * p == '\\' || * p == '%' || * p == '_' )&&
181+ (matched = DoMatch (text ,p ))!= LIKE_FALSE )
179182return matched ;
183+ text ++ ;
184+ }
180185return LIKE_ABORT ;
181186}
182187}
183188
184- return * text == '\0' ;
189+ if (* text != '\0' )
190+ return LIKE_ABORT ;
191+ else
192+ {
193+ /* End of input string. Do we have matching string remaining? */
194+ if (p [0 ]== '\0' || (p [0 ]== '%' && p [1 ]== '\0' ))
195+ return LIKE_TRUE ;
196+ else
197+ return LIKE_ABORT ;
198+ }
185199}
186200
187201