summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2022-10-06 15:08:56 +0000
committerTom Lane2022-10-06 15:08:56 +0000
commitca71131eebba63809ceb86be033a264a5f0a1d79 (patch)
treebff861724e38a284e336b166f60ce6c341c69973
parent5757141caeaff4af0c206ab672d542cbd608542c (diff)
Introduce t_isalnum() to replace t_isalpha() || t_isdigit() tests.
ts_locale.c omitted support for "isalnum" tests, perhaps on the grounds that there were initially no use-cases for that. However, both ltree and pg_trgm need such tests, and we do also have one use-case now in the core backend. The workaround of testing isalpha and isdigit separately seems quite inefficient, especially when dealing with multibyte characters; so let's fill in the missing support. Discussion: https://postgr.es/m/[email protected]
-rw-r--r--contrib/ltree/ltree.h2
-rw-r--r--contrib/pg_trgm/trgm.h2
-rw-r--r--src/backend/tsearch/ts_locale.c16
-rw-r--r--src/backend/utils/adt/tsquery.c2
-rw-r--r--src/include/tsearch/ts_locale.h1
5 files changed, 20 insertions, 3 deletions
diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h
index 40aed0ca0c8..6939d7349a1 100644
--- a/contrib/ltree/ltree.h
+++ b/contrib/ltree/ltree.h
@@ -126,7 +126,7 @@ typedef struct
#define LQUERY_HASNOT 0x01
-#define ISALNUM(x) ( t_isalpha(x) || t_isdigit(x) || ( pg_mblen(x) == 1 && t_iseq((x), '_') ) )
+#define ISALNUM(x) ( t_isalnum(x) || ( pg_mblen(x) == 1 && t_iseq((x), '_') ) )
/* full text query */
diff --git a/contrib/pg_trgm/trgm.h b/contrib/pg_trgm/trgm.h
index 405a1d95528..afb0adb222b 100644
--- a/contrib/pg_trgm/trgm.h
+++ b/contrib/pg_trgm/trgm.h
@@ -52,7 +52,7 @@ typedef char trgm[3];
} while(0)
#ifdef KEEPONLYALNUM
-#define ISWORDCHR(c) (t_isalpha(c) || t_isdigit(c))
+#define ISWORDCHR(c) (t_isalnum(c))
#define ISPRINTABLECHAR(a) ( isascii( *(unsigned char*)(a) ) && (isalnum( *(unsigned char*)(a) ) || *(unsigned char*)(a)==' ') )
#else
#define ISWORDCHR(c) (!t_isspace(c))
diff --git a/src/backend/tsearch/ts_locale.c b/src/backend/tsearch/ts_locale.c
index e0aa570bf5e..fc21bf9ee8e 100644
--- a/src/backend/tsearch/ts_locale.c
+++ b/src/backend/tsearch/ts_locale.c
@@ -82,6 +82,22 @@ t_isalpha(const char *ptr)
}
int
+t_isalnum(const char *ptr)
+{
+ int clen = pg_mblen(ptr);
+ wchar_t character[WC_BUF_LEN];
+ Oid collation = DEFAULT_COLLATION_OID; /* TODO */
+ pg_locale_t mylocale = 0; /* TODO */
+
+ if (clen == 1 || lc_ctype_is_c(collation))
+ return isalnum(TOUCHAR(ptr));
+
+ char2wchar(character, WC_BUF_LEN, ptr, clen, mylocale);
+
+ return iswalnum((wint_t) character[0]);
+}
+
+int
t_isprint(const char *ptr)
{
int clen = pg_mblen(ptr);
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index f49e6bb1578..a206926042e 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -248,7 +248,7 @@ parse_or_operator(TSQueryParserState pstate)
return false;
/* it shouldn't be a part of any word */
- if (t_iseq(ptr, '-') || t_iseq(ptr, '_') || t_isalpha(ptr) || t_isdigit(ptr))
+ if (t_iseq(ptr, '-') || t_iseq(ptr, '_') || t_isalnum(ptr))
return false;
for (;;)
diff --git a/src/include/tsearch/ts_locale.h b/src/include/tsearch/ts_locale.h
index d14cb4ed26d..10887290dc2 100644
--- a/src/include/tsearch/ts_locale.h
+++ b/src/include/tsearch/ts_locale.h
@@ -42,6 +42,7 @@ typedef struct
extern int t_isdigit(const char *ptr);
extern int t_isspace(const char *ptr);
extern int t_isalpha(const char *ptr);
+extern int t_isalnum(const char *ptr);
extern int t_isprint(const char *ptr);
extern char *lowerstr(const char *str);