v8-0001-LIKE-with-nondeterministic-collations-no-trail.no-cfbot
application/octet-stream
Filename: v8-0001-LIKE-with-nondeterministic-collations-no-trail.no-cfbot
Type: application/octet-stream
Part: 0
From 3f82ad436deaf81218dc4b4898f6d6edb3005c78 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Mon, 18 Nov 2024 11:06:17 +0800
Subject: [PATCH v8 1/1] LIKE with nondeterministic collations no trailing wild
cards
optimize where there is no trailing wildcards.
---
src/backend/utils/adt/like_match.c | 38 ++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/src/backend/utils/adt/like_match.c b/src/backend/utils/adt/like_match.c
index f3ca4d3082..dd1b136255 100644
--- a/src/backend/utils/adt/like_match.c
+++ b/src/backend/utils/adt/like_match.c
@@ -212,6 +212,7 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
const char *t1;
size_t t1len;
bool found_escape;
+ bool trailing_wildcards = false;
const char *subpat;
size_t subpatlen;
char *buf = NULL;
@@ -279,7 +280,33 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
CHECK_FOR_INTERRUPTS();
- cmp = pg_strncoll(subpat, subpatlen, t, (t1 - t), locale);
+ if (!trailing_wildcards)
+ {
+ /* we check subpatlen and next character is wild-card or
+ * not. if subpatlen == 1, then we don't have to check the
+ * next char. if we didn't found trailing_wildcards then we can
+ * safely compare whole subpat with t. if cmp != 0 we return
+ * LIKE_FALSE.
+ */
+ if (subpatlen == 1 && (subpat[0] == '%' || subpat[0] == '_'))
+ {
+ trailing_wildcards = true;
+ break;
+ }
+ for (int i = 0; i <=subpatlen; i++)
+ {
+ if (subpat[i] == '%' || subpat[i] == '_')
+ {
+ trailing_wildcards = true;
+ break;
+ }
+ }
+ }
+
+ if (!trailing_wildcards)
+ cmp = pg_strncoll(subpat, subpatlen, t, tlen, locale);
+ else
+ cmp = pg_strncoll(subpat, subpatlen, t, (t1 - t), locale);
/*
* If we found a match, we have to test if the rest of pattern
@@ -299,7 +326,12 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
*/
if (cmp == 0)
{
- int matched = MatchText(t1, t1len, p1, p1len, locale);
+ int matched;
+
+ if (!trailing_wildcards)
+ return LIKE_TRUE;
+
+ matched = MatchText(t1, t1len, p1, p1len, locale);
if (matched == LIKE_TRUE)
{
@@ -308,6 +340,8 @@ MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale)
return matched;
}
}
+ else if (!trailing_wildcards)
+ return LIKE_FALSE;
/*
* Didn't match. If we used up the whole text, then the match
--
2.34.1