@@ -18,6 +18,7 @@ PG_MODULE_MAGIC;
1818 */
1919
2020static int32 citextcmp (text * left , text * right , Oid collid );
21+ static int32 internal_citext_pattern_cmp (text * left , text * right , Oid collid );
2122
2223/*
2324 * =================
@@ -58,6 +59,41 @@ citextcmp(text *left, text *right, Oid collid)
5859 return result ;
5960}
6061
62+ /*
63+ * citext_pattern_cmp()
64+ * Internal character-by-character comparison function for citext strings.
65+ * Returns int32 negative, zero, or positive.
66+ */
67+ static int32
68+ internal_citext_pattern_cmp (text * left , text * right , Oid collid )
69+ {
70+ char * lcstr ,
71+ * rcstr ;
72+ int llen ,
73+ rlen ;
74+ int32 result ;
75+
76+ lcstr = str_tolower (VARDATA_ANY (left ), VARSIZE_ANY_EXHDR (left ), DEFAULT_COLLATION_OID );
77+ rcstr = str_tolower (VARDATA_ANY (right ), VARSIZE_ANY_EXHDR (right ), DEFAULT_COLLATION_OID );
78+
79+ llen = strlen (lcstr );
80+ rlen = strlen (rcstr );
81+
82+ result = memcmp ((void * ) lcstr , (void * ) rcstr , Min (llen , rlen ));
83+ if (result == 0 )
84+ {
85+ if (llen < rlen )
86+ result = -1 ;
87+ else if (llen > rlen )
88+ result = 1 ;
89+ }
90+
91+ pfree (lcstr );
92+ pfree (rcstr );
93+
94+ return result ;
95+ }
96+
6197/*
6298 * ==================
6399 * INDEXING FUNCTIONS
@@ -81,6 +117,23 @@ citext_cmp(PG_FUNCTION_ARGS)
81117 PG_RETURN_INT32 (result );
82118}
83119
120+ PG_FUNCTION_INFO_V1 (citext_pattern_cmp );
121+
122+ Datum
123+ citext_pattern_cmp (PG_FUNCTION_ARGS )
124+ {
125+ text * left = PG_GETARG_TEXT_PP (0 );
126+ text * right = PG_GETARG_TEXT_PP (1 );
127+ int32 result ;
128+
129+ result = internal_citext_pattern_cmp (left , right , PG_GET_COLLATION ());
130+
131+ PG_FREE_IF_COPY (left , 0 );
132+ PG_FREE_IF_COPY (right , 1 );
133+
134+ PG_RETURN_INT32 (result );
135+ }
136+
84137PG_FUNCTION_INFO_V1 (citext_hash );
85138
86139Datum
@@ -234,6 +287,74 @@ citext_ge(PG_FUNCTION_ARGS)
234287 PG_RETURN_BOOL (result );
235288}
236289
290+ PG_FUNCTION_INFO_V1 (citext_pattern_lt );
291+
292+ Datum
293+ citext_pattern_lt (PG_FUNCTION_ARGS )
294+ {
295+ text * left = PG_GETARG_TEXT_PP (0 );
296+ text * right = PG_GETARG_TEXT_PP (1 );
297+ bool result ;
298+
299+ result = internal_citext_pattern_cmp (left , right , PG_GET_COLLATION ()) < 0 ;
300+
301+ PG_FREE_IF_COPY (left , 0 );
302+ PG_FREE_IF_COPY (right , 1 );
303+
304+ PG_RETURN_BOOL (result );
305+ }
306+
307+ PG_FUNCTION_INFO_V1 (citext_pattern_le );
308+
309+ Datum
310+ citext_pattern_le (PG_FUNCTION_ARGS )
311+ {
312+ text * left = PG_GETARG_TEXT_PP (0 );
313+ text * right = PG_GETARG_TEXT_PP (1 );
314+ bool result ;
315+
316+ result = internal_citext_pattern_cmp (left , right , PG_GET_COLLATION ()) <= 0 ;
317+
318+ PG_FREE_IF_COPY (left , 0 );
319+ PG_FREE_IF_COPY (right , 1 );
320+
321+ PG_RETURN_BOOL (result );
322+ }
323+
324+ PG_FUNCTION_INFO_V1 (citext_pattern_gt );
325+
326+ Datum
327+ citext_pattern_gt (PG_FUNCTION_ARGS )
328+ {
329+ text * left = PG_GETARG_TEXT_PP (0 );
330+ text * right = PG_GETARG_TEXT_PP (1 );
331+ bool result ;
332+
333+ result = internal_citext_pattern_cmp (left , right , PG_GET_COLLATION ()) > 0 ;
334+
335+ PG_FREE_IF_COPY (left , 0 );
336+ PG_FREE_IF_COPY (right , 1 );
337+
338+ PG_RETURN_BOOL (result );
339+ }
340+
341+ PG_FUNCTION_INFO_V1 (citext_pattern_ge );
342+
343+ Datum
344+ citext_pattern_ge (PG_FUNCTION_ARGS )
345+ {
346+ text * left = PG_GETARG_TEXT_PP (0 );
347+ text * right = PG_GETARG_TEXT_PP (1 );
348+ bool result ;
349+
350+ result = internal_citext_pattern_cmp (left , right , PG_GET_COLLATION ()) >= 0 ;
351+
352+ PG_FREE_IF_COPY (left , 0 );
353+ PG_FREE_IF_COPY (right , 1 );
354+
355+ PG_RETURN_BOOL (result );
356+ }
357+
237358/*
238359 * ===================
239360 * AGGREGATE FUNCTIONS
0 commit comments