Tom Lane wrote:
> Bruce Momjian <br...@momjian.us> writes:
> > Tom Lane wrote:
> >> I have a feeling that this represents still another bug in the
> >> special-case path for % followed by _ (cf bug #4821).  If so,
> >> maybe we ought to just toss out that optimization?
> 
> > Yea, looks like it is this code in like_match.c:
> 
> No, actually it's the bit right after that:
> 
>                 /* Look for a place that matches the rest of the pattern */
>                 while (tlen > 0)
>                 {
>                     int            matched = MatchText(t, tlen, p, plen);
> 
>                     if (matched != LIKE_FALSE)
>                         return matched; /* TRUE or ABORT */
> 
>                     NextChar(t, tlen);
>                 }
> 
> If tlen == 0 when we reach this loop, we'll fall through and fail.
> But that is wrong since we need to consider the possibility that
> the remaining pattern can match a zero-length substring.  So the
> loop needs to be changed to attempt a recursive MatchText for
> tlen equal to zero as well as greater than zero.

I took a different approach.  I think the problem is that we check for
end of pattern without consuming '%' patterns.  I copied that consume
loop from code above that where we also test for end of pattern.

With the attached patch (which includes a regression test addition), it
works fine:

        test=> select 'ba' like '%__%';
         ?column?
        ----------
         t
        (1 row)

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com
Index: src/backend/utils/adt/like_match.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/like_match.c,v
retrieving revision 1.27
diff -c -c -r1.27 like_match.c
*** src/backend/utils/adt/like_match.c  2 Jan 2010 16:57:54 -0000       1.27
--- src/backend/utils/adt/like_match.c  28 May 2010 15:36:09 -0000
***************
*** 139,144 ****
--- 139,146 ----
                                 * n _'s matches any string of at least n 
characters, and we
                                 * have now found there are at least n 
characters.
                                 */
+                               while (plen > 0 && *p == '%')
+                                       NextByte(p, plen);
                                if (plen <= 0)
                                        return LIKE_TRUE;
  
Index: src/test/regress/expected/strings.out
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/expected/strings.out,v
retrieving revision 1.40
diff -c -c -r1.40 strings.out
*** src/test/regress/expected/strings.out       25 Jan 2010 20:55:32 -0000      
1.40
--- src/test/regress/expected/strings.out       28 May 2010 15:36:12 -0000
***************
*** 943,948 ****
--- 943,954 ----
   t
  (1 row)
  
+ SELECT 'jack' LIKE '%____%' AS "true";
+  true 
+ ------
+  t
+ (1 row)
+ 
  --
  -- test ILIKE (case-insensitive LIKE)
  -- Be sure to form every test as an ILIKE/NOT ILIKE pair.
Index: src/test/regress/sql/strings.sql
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/sql/strings.sql,v
retrieving revision 1.28
diff -c -c -r1.28 strings.sql
*** src/test/regress/sql/strings.sql    25 Jan 2010 20:55:32 -0000      1.28
--- src/test/regress/sql/strings.sql    28 May 2010 15:36:12 -0000
***************
*** 282,287 ****
--- 282,288 ----
  SELECT 'be_r' LIKE '__e__r' ESCAPE '_' AS "false";
  SELECT 'be_r' NOT LIKE '__e__r' ESCAPE '_' AS "true";
  
+ SELECT 'jack' LIKE '%____%' AS "true";
  
  --
  -- test ILIKE (case-insensitive LIKE)
***************
*** 310,316 ****
  SELECT 'foo' LIKE '__%' as t, 'foo' LIKE '___%' as t, 'foo' LIKE '____%' as f;
  SELECT 'foo' LIKE '%__' as t, 'foo' LIKE '%___' as t, 'foo' LIKE '%____' as f;
  
- 
  --
  -- test implicit type conversion
  --
--- 311,316 ----
-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Reply via email to