diff -cpr HEAD/src/backend/utils/adt/like.c patched/src/backend/utils/adt/like.c
*** HEAD/src/backend/utils/adt/like.c	Thu Mar  1 09:40:18 2007
--- patched/src/backend/utils/adt/like.c	Fri Mar 30 17:30:06 2007
*************** wchareq(char *p1, char *p2)
*** 78,86 ****
--- 78,90 ----
   * different again in the future.
   */
  
+ #define NextByte(p, plen)	((p)++, (plen)--)
+ #define BYTEEQ(p1, p2)		(*(p1) == *(p2))
+ 
  /* Set up to compile like_match.c for multibyte characters */
  #define CHAREQ(p1, p2) wchareq(p1, p2)
  #define ICHAREQ(p1, p2) wchareq(p1, p2)
+ #define IBYTEEQ(p1, p2)	BYTEEQ(p1, p2)
  #define NextChar(p, plen) \
  	do { int __l = pg_mblen(p); (p) +=__l; (plen) -=__l; } while (0)
  #define CopyAdvChar(dst, src, srclen) \
*************** wchareq(char *p1, char *p2)
*** 98,103 ****
--- 102,108 ----
  
  #undef CHAREQ
  #undef ICHAREQ
+ #undef IBYTEEQ
  #undef NextChar
  #undef CopyAdvChar
  #undef MatchText
*************** wchareq(char *p1, char *p2)
*** 105,113 ****
  #undef do_like_escape
  
  /* Set up to compile like_match.c for single-byte characters */
! #define CHAREQ(p1, p2) (*(p1) == *(p2))
  #define ICHAREQ(p1, p2) (tolower((unsigned char) *(p1)) == tolower((unsigned char) *(p2)))
! #define NextChar(p, plen) ((p)++, (plen)--)
  #define CopyAdvChar(dst, src, srclen) (*(dst)++ = *(src)++, (srclen)--)
  
  #include "like_match.c"
--- 110,119 ----
  #undef do_like_escape
  
  /* Set up to compile like_match.c for single-byte characters */
! #define CHAREQ(p1, p2) BYTEEQ(p1, p2)
  #define ICHAREQ(p1, p2) (tolower((unsigned char) *(p1)) == tolower((unsigned char) *(p2)))
! #define IBYTEEQ(p1, p2)	ICHAREQ(p1, p2)
! #define NextChar(p, plen) NextByte(p, plen)
  #define CopyAdvChar(dst, src, srclen) (*(dst)++ = *(src)++, (srclen)--)
  
  #include "like_match.c"
diff -cpr HEAD/src/backend/utils/adt/like_match.c patched/src/backend/utils/adt/like_match.c
*** HEAD/src/backend/utils/adt/like_match.c	Thu Mar  1 09:40:18 2007
--- patched/src/backend/utils/adt/like_match.c	Fri Mar 30 17:30:06 2007
*************** MatchText(char *t, int tlen, char *p, in
*** 82,88 ****
  		if (*p == '\\')
  		{
  			/* Next pattern char must match literally, whatever it is */
! 			NextChar(p, plen);
  			if ((plen <= 0) || !CHAREQ(t, p))
  				return LIKE_FALSE;
  		}
--- 82,88 ----
  		if (*p == '\\')
  		{
  			/* Next pattern char must match literally, whatever it is */
! 			NextByte(p, plen);
  			if ((plen <= 0) || !CHAREQ(t, p))
  				return LIKE_FALSE;
  		}
*************** MatchText(char *t, int tlen, char *p, in
*** 91,97 ****
  			/* %% is the same as % according to the SQL standard */
  			/* Advance past all %'s */
  			while ((plen > 0) && (*p == '%'))
! 				NextChar(p, plen);
  			/* Trailing percent matches everything. */
  			if (plen <= 0)
  				return LIKE_TRUE;
--- 91,97 ----
  			/* %% is the same as % according to the SQL standard */
  			/* Advance past all %'s */
  			while ((plen > 0) && (*p == '%'))
! 				NextByte(p, plen);
  			/* Trailing percent matches everything. */
  			if (plen <= 0)
  				return LIKE_TRUE;
*************** MatchText(char *t, int tlen, char *p, in
*** 123,129 ****
  			 */
  			return LIKE_ABORT;
  		}
! 		else if ((*p != '_') && !CHAREQ(t, p))
  		{
  			/*
  			 * Not the single-character wildcard and no explicit match? Then
--- 123,135 ----
  			 */
  			return LIKE_ABORT;
  		}
! 		else if (*p == '_')
! 		{
! 			NextChar(t, tlen);
! 			NextByte(p, plen);
! 			continue;
! 		}
! 		else if (!BYTEEQ(t, p))
  		{
  			/*
  			 * Not the single-character wildcard and no explicit match? Then
*************** MatchText(char *t, int tlen, char *p, in
*** 132,139 ****
  			return LIKE_FALSE;
  		}
  
! 		NextChar(t, tlen);
! 		NextChar(p, plen);
  	}
  
  	if (tlen > 0)
--- 138,145 ----
  			return LIKE_FALSE;
  		}
  
! 		NextByte(t, tlen);
! 		NextByte(p, plen);
  	}
  
  	if (tlen > 0)
*************** MatchText(char *t, int tlen, char *p, in
*** 142,148 ****
  	/* End of input string.  Do we have matching pattern remaining? */
  	while ((plen > 0) && (*p == '%'))	/* allow multiple %'s at end of
  										 * pattern */
! 		NextChar(p, plen);
  	if (plen <= 0)
  		return LIKE_TRUE;
  
--- 148,154 ----
  	/* End of input string.  Do we have matching pattern remaining? */
  	while ((plen > 0) && (*p == '%'))	/* allow multiple %'s at end of
  										 * pattern */
! 		NextByte(p, plen);
  	if (plen <= 0)
  		return LIKE_TRUE;
  
*************** MatchTextIC(char *t, int tlen, char *p, 
*** 168,174 ****
  		if (*p == '\\')
  		{
  			/* Next pattern char must match literally, whatever it is */
! 			NextChar(p, plen);
  			if ((plen <= 0) || !ICHAREQ(t, p))
  				return LIKE_FALSE;
  		}
--- 174,180 ----
  		if (*p == '\\')
  		{
  			/* Next pattern char must match literally, whatever it is */
! 			NextByte(p, plen);
  			if ((plen <= 0) || !ICHAREQ(t, p))
  				return LIKE_FALSE;
  		}
*************** MatchTextIC(char *t, int tlen, char *p, 
*** 177,183 ****
  			/* %% is the same as % according to the SQL standard */
  			/* Advance past all %'s */
  			while ((plen > 0) && (*p == '%'))
! 				NextChar(p, plen);
  			/* Trailing percent matches everything. */
  			if (plen <= 0)
  				return LIKE_TRUE;
--- 183,189 ----
  			/* %% is the same as % according to the SQL standard */
  			/* Advance past all %'s */
  			while ((plen > 0) && (*p == '%'))
! 				NextByte(p, plen);
  			/* Trailing percent matches everything. */
  			if (plen <= 0)
  				return LIKE_TRUE;
*************** MatchTextIC(char *t, int tlen, char *p, 
*** 209,215 ****
  			 */
  			return LIKE_ABORT;
  		}
! 		else if ((*p != '_') && !ICHAREQ(t, p))
  		{
  			/*
  			 * Not the single-character wildcard and no explicit match? Then
--- 215,227 ----
  			 */
  			return LIKE_ABORT;
  		}
! 		else if (*p == '_')
! 		{
! 			NextChar(t, tlen);
! 			NextByte(p, plen);
! 			continue;
! 		}
! 		else if (!IBYTEEQ(t, p))
  		{
  			/*
  			 * Not the single-character wildcard and no explicit match? Then
*************** MatchTextIC(char *t, int tlen, char *p, 
*** 218,225 ****
  			return LIKE_FALSE;
  		}
  
! 		NextChar(t, tlen);
! 		NextChar(p, plen);
  	}
  
  	if (tlen > 0)
--- 230,237 ----
  			return LIKE_FALSE;
  		}
  
! 		NextByte(t, tlen);
! 		NextByte(p, plen);
  	}
  
  	if (tlen > 0)
*************** MatchTextIC(char *t, int tlen, char *p, 
*** 228,234 ****
  	/* End of input string.  Do we have matching pattern remaining? */
  	while ((plen > 0) && (*p == '%'))	/* allow multiple %'s at end of
  										 * pattern */
! 		NextChar(p, plen);
  	if (plen <= 0)
  		return LIKE_TRUE;
  
--- 240,246 ----
  	/* End of input string.  Do we have matching pattern remaining? */
  	while ((plen > 0) && (*p == '%'))	/* allow multiple %'s at end of
  										 * pattern */
! 		NextByte(p, plen);
  	if (plen <= 0)
  		return LIKE_TRUE;
  
