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
Message: Re: Support LIKE with nondeterministic collations
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