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;