Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbad3b30

Browse files
committed
Repair recently-introduced error in makeIndexable for LIKE:
a non-leading % would be put into the >=/<= patterns. Also, repairlongstanding confusion about whether %% means a literal %%. The SQL92doesn't say any such thing, and textlike() knows that, but gram.y didn't.
1 parent43c135e commitbad3b30

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed

‎src/backend/parser/gram.y

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.83 1999/05/22 05:06:43 momjian Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.84 1999/06/07 14:28:25 tgl Exp $
1414
*
1515
* HISTORY
1616
* AUTHORDATEMAJOR EVENT
@@ -5357,6 +5357,7 @@ static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
53575357
int pos, match_pos=0;
53585358
bool found_special = false;
53595359

5360+
/* Cannot optimize if unquoted | { } is present in pattern */
53605361
for (pos = 1; n->val.val.str[pos]; pos++)
53615362
{
53625363
if (n->val.val.str[pos] == '|' ||
@@ -5367,12 +5368,16 @@ static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
53675368
break;
53685369
}
53695370
if (n->val.val.str[pos] == '\\')
5371+
{
53705372
pos++;
5373+
if (n->val.val.str[pos] == '\0')
5374+
break;
5375+
}
53715376
}
53725377

5373-
/* skip leading ^ */
53745378
if (!found_special)
53755379
{
5380+
/* note start at pos 1 to skip leading ^ */
53765381
for (pos = 1; n->val.val.str[pos]; pos++)
53775382
{
53785383
if (n->val.val.str[pos] == '.' ||
@@ -5383,9 +5388,11 @@ static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
53835388
(strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
53845389
break;
53855390
if (n->val.val.str[pos] == '\\')
5391+
{
53865392
pos++;
5387-
if (n->val.val.str[pos] == '\0')
5388-
break;
5393+
if (n->val.val.str[pos] == '\0')
5394+
break;
5395+
}
53895396
match_least[match_pos] = n->val.val.str[pos];
53905397
match_most[match_pos++] = n->val.val.str[pos];
53915398
}
@@ -5430,16 +5437,22 @@ static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
54305437

54315438
for (pos = 0; n->val.val.str[pos]; pos++)
54325439
{
5433-
if (n->val.val.str[pos] == '%' &&
5434-
n->val.val.str[pos+1] != '%')
5435-
break;
5436-
if(n->val.val.str[pos] == '_')
5440+
/* % and _ are wildcard characters in LIKE */
5441+
if (n->val.val.str[pos] == '%' ||
5442+
n->val.val.str[pos] == '_')
54375443
break;
5438-
if (n->val.val.str[pos] == '\\' ||
5439-
n->val.val.str[pos+1] == '%')
5444+
/* Backslash quotes the next character */
5445+
if (n->val.val.str[pos] == '\\')
5446+
{
54405447
pos++;
5441-
if (n->val.val.str[pos] == '\0')
5442-
break;
5448+
if (n->val.val.str[pos] == '\0')
5449+
break;
5450+
}
5451+
/*
5452+
* NOTE: this code used to think that %% meant a literal %,
5453+
* but textlike() itself does not think that, and the SQL92
5454+
* spec doesn't say any such thing either.
5455+
*/
54435456
match_least[match_pos] = n->val.val.str[pos];
54445457
match_most[match_pos++] = n->val.val.str[pos];
54455458
}

‎src/backend/utils/adt/like.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ textnlike(struct varlena * s, struct varlena * p)
111111
}
112112

113113

114-
/*$Revision: 1.24 $
114+
/*$Revision: 1.25 $
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.
@@ -191,7 +191,9 @@ DoMatch(pg_wchar * text, pg_wchar * p)
191191
else
192192
{
193193
/* End of input string. Do we have matching string remaining? */
194-
if (p[0]=='\0'|| (p[0]=='%'&&p[1]=='\0'))
194+
while (*p=='%')/* allow multiple %'s at end of pattern */
195+
p++;
196+
if (*p=='\0')
195197
returnLIKE_TRUE;
196198
else
197199
returnLIKE_ABORT;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp