Repair recently-introduced error in makeIndexable for LIKE:

a non-leading % would be put into the >=/<= patterns.  Also, repair
longstanding confusion about whether %% means a literal %%.  The SQL92
doesn't say any such thing, and textlike() knows that, but gram.y didn't.
This commit is contained in:
Tom Lane 1999-06-07 14:28:26 +00:00
parent 43c135e351
commit bad3b3068d
2 changed files with 29 additions and 14 deletions

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.83 1999/05/22 05:06:43 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.84 1999/06/07 14:28:25 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -5357,6 +5357,7 @@ static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
int pos, match_pos=0;
bool found_special = false;
/* Cannot optimize if unquoted | { } is present in pattern */
for (pos = 1; n->val.val.str[pos]; pos++)
{
if (n->val.val.str[pos] == '|' ||
@ -5367,12 +5368,16 @@ static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
break;
}
if (n->val.val.str[pos] == '\\')
{
pos++;
if (n->val.val.str[pos] == '\0')
break;
}
}
/* skip leading ^ */
if (!found_special)
{
/* note start at pos 1 to skip leading ^ */
for (pos = 1; n->val.val.str[pos]; pos++)
{
if (n->val.val.str[pos] == '.' ||
@ -5383,9 +5388,11 @@ static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
(strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
break;
if (n->val.val.str[pos] == '\\')
{
pos++;
if (n->val.val.str[pos] == '\0')
break;
if (n->val.val.str[pos] == '\0')
break;
}
match_least[match_pos] = n->val.val.str[pos];
match_most[match_pos++] = n->val.val.str[pos];
}
@ -5430,16 +5437,22 @@ static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
for (pos = 0; n->val.val.str[pos]; pos++)
{
if (n->val.val.str[pos] == '%' &&
n->val.val.str[pos+1] != '%')
/* % and _ are wildcard characters in LIKE */
if (n->val.val.str[pos] == '%' ||
n->val.val.str[pos] == '_')
break;
if(n->val.val.str[pos] == '_')
break;
if (n->val.val.str[pos] == '\\' ||
n->val.val.str[pos+1] == '%')
/* Backslash quotes the next character */
if (n->val.val.str[pos] == '\\')
{
pos++;
if (n->val.val.str[pos] == '\0')
break;
if (n->val.val.str[pos] == '\0')
break;
}
/*
* NOTE: this code used to think that %% meant a literal %,
* but textlike() itself does not think that, and the SQL92
* spec doesn't say any such thing either.
*/
match_least[match_pos] = n->val.val.str[pos];
match_most[match_pos++] = n->val.val.str[pos];
}

View File

@ -111,7 +111,7 @@ textnlike(struct varlena * s, struct varlena * p)
}
/* $Revision: 1.24 $
/* $Revision: 1.25 $
** "like.c" A first attempt at a LIKE operator for Postgres95.
**
** Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
@ -191,7 +191,9 @@ DoMatch(pg_wchar * text, pg_wchar * p)
else
{
/* End of input string. Do we have matching string remaining? */
if (p[0] == '\0' || (p[0] == '%' && p[1] == '\0'))
while (*p == '%') /* allow multiple %'s at end of pattern */
p++;
if (*p == '\0')
return LIKE_TRUE;
else
return LIKE_ABORT;