PostgreSQL Source Code git master
regc_pg_locale.c File Reference
Include dependency graph for regc_pg_locale.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  pg_ctype_cache
 

Typedefs

typedef int(* regc_wc_probefunc) (pg_wchar c)
 
typedef struct pg_ctype_cache pg_ctype_cache
 

Functions

void pg_set_regex_collation (Oid collation)
 
static int regc_wc_isdigit (pg_wchar c)
 
static int regc_wc_isalpha (pg_wchar c)
 
static int regc_wc_isalnum (pg_wchar c)
 
static int regc_wc_isword (pg_wchar c)
 
static int regc_wc_isupper (pg_wchar c)
 
static int regc_wc_islower (pg_wchar c)
 
static int regc_wc_isgraph (pg_wchar c)
 
static int regc_wc_isprint (pg_wchar c)
 
static int regc_wc_ispunct (pg_wchar c)
 
static int regc_wc_isspace (pg_wchar c)
 
static pg_wchar regc_wc_toupper (pg_wchar c)
 
static pg_wchar regc_wc_tolower (pg_wchar c)
 
static bool store_match (pg_ctype_cache *pcc, pg_wchar chr1, int nchrs)
 
static struct cvecregc_ctype_get_cache (regc_wc_probefunc probefunc, int cclasscode)
 

Variables

static pg_locale_t pg_regex_locale
 
static pg_ctype_cachepg_ctype_cache_list = NULL
 

Typedef Documentation

◆ pg_ctype_cache

◆ regc_wc_probefunc

typedef int(* regc_wc_probefunc) (pg_wchar c)

Definition at line 205 of file regc_pg_locale.c.

Function Documentation

◆ pg_set_regex_collation()

void pg_set_regex_collation ( Oid  collation)

Definition at line 35 of file regc_pg_locale.c.

36{
38
39 if (!OidIsValid(collation))
40 {
41 /*
42 * This typically means that the parser could not resolve a conflict
43 * of implicit collations, so report it that way.
44 */
46 (errcode(ERRCODE_INDETERMINATE_COLLATION),
47 errmsg("could not determine which collation to use for regular expression"),
48 errhint("Use the COLLATE clause to set the collation explicitly.")));
49 }
50
52
53 if (!locale->deterministic)
55 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
56 errmsg("nondeterministic collations are not supported for regular expressions")));
57
59}
#define OidIsValid(objectId)
Definition: c.h:777
int errhint(const char *fmt,...)
Definition: elog.c:1330
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
static char * locale
Definition: initdb.c:140
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1186
static pg_locale_t pg_regex_locale

References ereport, errcode(), errhint(), errmsg(), ERROR, locale, OidIsValid, pg_newlocale_from_collation(), and pg_regex_locale.

Referenced by pg_regcomp(), pg_regexec(), and pg_regprefix().

◆ regc_ctype_get_cache()

static struct cvec * regc_ctype_get_cache ( regc_wc_probefunc  probefunc,
int  cclasscode 
)
static

Definition at line 265 of file regc_pg_locale.c.

266{
267 pg_ctype_cache *pcc;
268 pg_wchar max_chr;
269 pg_wchar cur_chr;
270 int nmatches;
271 chr *newchrs;
272
273 /*
274 * Do we already have the answer cached?
275 */
276 for (pcc = pg_ctype_cache_list; pcc != NULL; pcc = pcc->next)
277 {
278 if (pcc->probefunc == probefunc &&
279 pcc->locale == pg_regex_locale)
280 return &pcc->cv;
281 }
282
283 /*
284 * Nope, so initialize some workspace ...
285 */
286 pcc = (pg_ctype_cache *) malloc(sizeof(pg_ctype_cache));
287 if (pcc == NULL)
288 return NULL;
289 pcc->probefunc = probefunc;
290 pcc->locale = pg_regex_locale;
291 pcc->cv.nchrs = 0;
292 pcc->cv.chrspace = 128;
293 pcc->cv.chrs = (chr *) malloc(pcc->cv.chrspace * sizeof(chr));
294 pcc->cv.nranges = 0;
295 pcc->cv.rangespace = 64;
296 pcc->cv.ranges = (chr *) malloc(pcc->cv.rangespace * sizeof(chr) * 2);
297 if (pcc->cv.chrs == NULL || pcc->cv.ranges == NULL)
298 goto out_of_memory;
299 pcc->cv.cclasscode = cclasscode;
300
301 /*
302 * Decide how many character codes we ought to look through. In general
303 * we don't go past MAX_SIMPLE_CHR; chr codes above that are handled at
304 * runtime using the "high colormap" mechanism. However, in C locale
305 * there's no need to go further than 127, and if we only have a 1-byte
306 * <ctype.h> API there's no need to go further than that can handle.
307 *
308 * If it's not MAX_SIMPLE_CHR that's constraining the search, mark the
309 * output cvec as not having any locale-dependent behavior, since there
310 * will be no need to do any run-time locale checks. (The #if's here
311 * would always be true for production values of MAX_SIMPLE_CHR, but it's
312 * useful to allow it to be small for testing purposes.)
313 */
315 {
316#if MAX_SIMPLE_CHR >= 127
317 max_chr = (pg_wchar) 127;
318 pcc->cv.cclasscode = -1;
319#else
320 max_chr = (pg_wchar) MAX_SIMPLE_CHR;
321#endif
322 }
323 else if (GetDatabaseEncoding() == PG_UTF8)
324 {
325 max_chr = (pg_wchar) MAX_SIMPLE_CHR;
326 }
327 else
328 {
329#if MAX_SIMPLE_CHR >= UCHAR_MAX
330 max_chr = (pg_wchar) UCHAR_MAX;
331 pcc->cv.cclasscode = -1;
332#else
333 max_chr = (pg_wchar) MAX_SIMPLE_CHR;
334#endif
335 }
336
337 /*
338 * And scan 'em ...
339 */
340 nmatches = 0; /* number of consecutive matches */
341
342 for (cur_chr = 0; cur_chr <= max_chr; cur_chr++)
343 {
344 if ((*probefunc) (cur_chr))
345 nmatches++;
346 else if (nmatches > 0)
347 {
348 if (!store_match(pcc, cur_chr - nmatches, nmatches))
349 goto out_of_memory;
350 nmatches = 0;
351 }
352 }
353
354 if (nmatches > 0)
355 if (!store_match(pcc, cur_chr - nmatches, nmatches))
356 goto out_of_memory;
357
358 /*
359 * We might have allocated more memory than needed, if so free it
360 */
361 if (pcc->cv.nchrs == 0)
362 {
363 free(pcc->cv.chrs);
364 pcc->cv.chrs = NULL;
365 pcc->cv.chrspace = 0;
366 }
367 else if (pcc->cv.nchrs < pcc->cv.chrspace)
368 {
369 newchrs = (chr *) realloc(pcc->cv.chrs,
370 pcc->cv.nchrs * sizeof(chr));
371 if (newchrs == NULL)
372 goto out_of_memory;
373 pcc->cv.chrs = newchrs;
374 pcc->cv.chrspace = pcc->cv.nchrs;
375 }
376 if (pcc->cv.nranges == 0)
377 {
378 free(pcc->cv.ranges);
379 pcc->cv.ranges = NULL;
380 pcc->cv.rangespace = 0;
381 }
382 else if (pcc->cv.nranges < pcc->cv.rangespace)
383 {
384 newchrs = (chr *) realloc(pcc->cv.ranges,
385 pcc->cv.nranges * sizeof(chr) * 2);
386 if (newchrs == NULL)
387 goto out_of_memory;
388 pcc->cv.ranges = newchrs;
389 pcc->cv.rangespace = pcc->cv.nranges;
390 }
391
392 /*
393 * Success, link it into cache chain
394 */
397
398 return &pcc->cv;
399
400 /*
401 * Failure, clean up
402 */
403out_of_memory:
404 free(pcc->cv.chrs);
405 free(pcc->cv.ranges);
406 free(pcc);
407
408 return NULL;
409}
#define realloc(a, b)
Definition: header.h:60
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
unsigned int pg_wchar
Definition: mbprint.c:31
int GetDatabaseEncoding(void)
Definition: mbutils.c:1262
@ PG_UTF8
Definition: pg_wchar.h:232
static pg_ctype_cache * pg_ctype_cache_list
static bool store_match(pg_ctype_cache *pcc, pg_wchar chr1, int nchrs)
#define MAX_SIMPLE_CHR
Definition: regcustom.h:87
pg_wchar chr
Definition: regcustom.h:59
int chrspace
Definition: regguts.h:281
int nchrs
Definition: regguts.h:280
int rangespace
Definition: regguts.h:284
chr * chrs
Definition: regguts.h:282
chr * ranges
Definition: regguts.h:285
int cclasscode
Definition: regguts.h:286
int nranges
Definition: regguts.h:283
regc_wc_probefunc probefunc
struct pg_ctype_cache * next
pg_locale_t locale
struct cvec cv

References cvec::cclasscode, cvec::chrs, cvec::chrspace, pg_locale_struct::ctype_is_c, pg_ctype_cache::cv, free, GetDatabaseEncoding(), pg_ctype_cache::locale, malloc, MAX_SIMPLE_CHR, cvec::nchrs, pg_ctype_cache::next, cvec::nranges, pg_ctype_cache_list, pg_regex_locale, PG_UTF8, pg_ctype_cache::probefunc, cvec::ranges, cvec::rangespace, realloc, and store_match().

Referenced by cclasscvec().

◆ regc_wc_isalnum()

static int regc_wc_isalnum ( pg_wchar  c)
static

Definition at line 87 of file regc_pg_locale.c.

88{
90 return (c <= (pg_wchar) 127 &&
92 else
94}
#define PG_ISALNUM
Definition: pg_locale_c.h:21
static const unsigned char pg_char_properties[128]
Definition: pg_locale_c.h:29
char * c
bool(* wc_isalnum)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:117
const struct ctype_methods * ctype
Definition: pg_locale.h:161

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_char_properties, PG_ISALNUM, pg_regex_locale, and ctype_methods::wc_isalnum.

Referenced by cclass_column_index(), cclasscvec(), and regc_wc_isword().

◆ regc_wc_isalpha()

static int regc_wc_isalpha ( pg_wchar  c)
static

Definition at line 77 of file regc_pg_locale.c.

78{
80 return (c <= (pg_wchar) 127 &&
82 else
84}
#define PG_ISALPHA
Definition: pg_locale_c.h:20
bool(* wc_isalpha)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:116

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_char_properties, PG_ISALPHA, pg_regex_locale, and ctype_methods::wc_isalpha.

Referenced by cclass_column_index(), and cclasscvec().

◆ regc_wc_isdigit()

static int regc_wc_isdigit ( pg_wchar  c)
static

Definition at line 67 of file regc_pg_locale.c.

68{
70 return (c <= (pg_wchar) 127 &&
72 else
74}
#define PG_ISDIGIT
Definition: pg_locale_c.h:19
bool(* wc_isdigit)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:115

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_char_properties, PG_ISDIGIT, pg_regex_locale, and ctype_methods::wc_isdigit.

Referenced by cclass_column_index(), and cclasscvec().

◆ regc_wc_isgraph()

static int regc_wc_isgraph ( pg_wchar  c)
static

Definition at line 126 of file regc_pg_locale.c.

127{
129 return (c <= (pg_wchar) 127 &&
131 else
133}
#define PG_ISGRAPH
Definition: pg_locale_c.h:24
bool(* wc_isgraph)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:120

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_char_properties, PG_ISGRAPH, pg_regex_locale, and ctype_methods::wc_isgraph.

Referenced by cclass_column_index(), and cclasscvec().

◆ regc_wc_islower()

static int regc_wc_islower ( pg_wchar  c)
static

Definition at line 116 of file regc_pg_locale.c.

117{
119 return (c <= (pg_wchar) 127 &&
121 else
123}
#define PG_ISLOWER
Definition: pg_locale_c.h:23
bool(* wc_islower)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:119

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_char_properties, PG_ISLOWER, pg_regex_locale, and ctype_methods::wc_islower.

Referenced by cclass_column_index(), and cclasscvec().

◆ regc_wc_isprint()

static int regc_wc_isprint ( pg_wchar  c)
static

Definition at line 136 of file regc_pg_locale.c.

137{
139 return (c <= (pg_wchar) 127 &&
141 else
143}
#define PG_ISPRINT
Definition: pg_locale_c.h:25
bool(* wc_isprint)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:121

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_char_properties, PG_ISPRINT, pg_regex_locale, and ctype_methods::wc_isprint.

Referenced by cclass_column_index(), and cclasscvec().

◆ regc_wc_ispunct()

static int regc_wc_ispunct ( pg_wchar  c)
static

Definition at line 146 of file regc_pg_locale.c.

147{
149 return (c <= (pg_wchar) 127 &&
151 else
153}
#define PG_ISPUNCT
Definition: pg_locale_c.h:26
bool(* wc_ispunct)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:122

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_char_properties, PG_ISPUNCT, pg_regex_locale, and ctype_methods::wc_ispunct.

Referenced by cclass_column_index(), and cclasscvec().

◆ regc_wc_isspace()

static int regc_wc_isspace ( pg_wchar  c)
static

Definition at line 156 of file regc_pg_locale.c.

157{
159 return (c <= (pg_wchar) 127 &&
161 else
163}
#define PG_ISSPACE
Definition: pg_locale_c.h:27
bool(* wc_isspace)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:123

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_char_properties, PG_ISSPACE, pg_regex_locale, and ctype_methods::wc_isspace.

Referenced by cclass_column_index(), and cclasscvec().

◆ regc_wc_isupper()

static int regc_wc_isupper ( pg_wchar  c)
static

Definition at line 106 of file regc_pg_locale.c.

107{
109 return (c <= (pg_wchar) 127 &&
111 else
113}
#define PG_ISUPPER
Definition: pg_locale_c.h:22
bool(* wc_isupper)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:118

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_char_properties, PG_ISUPPER, pg_regex_locale, and ctype_methods::wc_isupper.

Referenced by cclass_column_index(), and cclasscvec().

◆ regc_wc_isword()

static int regc_wc_isword ( pg_wchar  c)
static

Definition at line 97 of file regc_pg_locale.c.

98{
99 /* We define word characters as alnum class plus underscore */
100 if (c == CHR('_'))
101 return 1;
102 return regc_wc_isalnum(c);
103}
static int regc_wc_isalnum(pg_wchar c)
#define CHR(c)
Definition: regcustom.h:62

References CHR, and regc_wc_isalnum().

Referenced by cclass_column_index(), and cclasscvec().

◆ regc_wc_tolower()

static pg_wchar regc_wc_tolower ( pg_wchar  c)
static

Definition at line 179 of file regc_pg_locale.c.

180{
182 {
183 if (c <= (pg_wchar) 127)
184 return pg_ascii_tolower((unsigned char) c);
185 return c;
186 }
187 else
189}
static unsigned char pg_ascii_tolower(unsigned char ch)
Definition: port.h:188
pg_wchar(* wc_tolower)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:126

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_ascii_tolower(), pg_regex_locale, and ctype_methods::wc_tolower.

Referenced by allcases(), casecmp(), and range().

◆ regc_wc_toupper()

static pg_wchar regc_wc_toupper ( pg_wchar  c)
static

Definition at line 166 of file regc_pg_locale.c.

167{
169 {
170 if (c <= (pg_wchar) 127)
171 return pg_ascii_toupper((unsigned char) c);
172 return c;
173 }
174 else
176}
static unsigned char pg_ascii_toupper(unsigned char ch)
Definition: port.h:177
pg_wchar(* wc_toupper)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:125

References pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_ascii_toupper(), pg_regex_locale, and ctype_methods::wc_toupper.

Referenced by allcases(), and range().

◆ store_match()

static bool store_match ( pg_ctype_cache pcc,
pg_wchar  chr1,
int  nchrs 
)
static

Definition at line 221 of file regc_pg_locale.c.

222{
223 chr *newchrs;
224
225 if (nchrs > 1)
226 {
227 if (pcc->cv.nranges >= pcc->cv.rangespace)
228 {
229 pcc->cv.rangespace *= 2;
230 newchrs = (chr *) realloc(pcc->cv.ranges,
231 pcc->cv.rangespace * sizeof(chr) * 2);
232 if (newchrs == NULL)
233 return false;
234 pcc->cv.ranges = newchrs;
235 }
236 pcc->cv.ranges[pcc->cv.nranges * 2] = chr1;
237 pcc->cv.ranges[pcc->cv.nranges * 2 + 1] = chr1 + nchrs - 1;
238 pcc->cv.nranges++;
239 }
240 else
241 {
242 assert(nchrs == 1);
243 if (pcc->cv.nchrs >= pcc->cv.chrspace)
244 {
245 pcc->cv.chrspace *= 2;
246 newchrs = (chr *) realloc(pcc->cv.chrs,
247 pcc->cv.chrspace * sizeof(chr));
248 if (newchrs == NULL)
249 return false;
250 pcc->cv.chrs = newchrs;
251 }
252 pcc->cv.chrs[pcc->cv.nchrs++] = chr1;
253 }
254 return true;
255}
#define assert(x)
Definition: regcustom.h:56

References assert, cvec::chrs, cvec::chrspace, pg_ctype_cache::cv, cvec::nchrs, cvec::nranges, cvec::ranges, cvec::rangespace, and realloc.

Referenced by regc_ctype_get_cache().

Variable Documentation

◆ pg_ctype_cache_list

pg_ctype_cache* pg_ctype_cache_list = NULL
static

Definition at line 215 of file regc_pg_locale.c.

Referenced by regc_ctype_get_cache().

◆ pg_regex_locale