PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 struct pg_locale_struct dummy_c_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 231 of file regc_pg_locale.c.

Function Documentation

◆ pg_set_regex_collation()

void pg_set_regex_collation ( Oid  collation)

Definition at line 40 of file regc_pg_locale.c.

41{
43
44 if (!OidIsValid(collation))
45 {
46 /*
47 * This typically means that the parser could not resolve a conflict
48 * of implicit collations, so report it that way.
49 */
51 (errcode(ERRCODE_INDETERMINATE_COLLATION),
52 errmsg("could not determine which collation to use for regular expression"),
53 errhint("Use the COLLATE clause to set the collation explicitly.")));
54 }
55
56 if (collation == C_COLLATION_OID)
57 {
58 /*
59 * Some callers expect regexes to work for C_COLLATION_OID before
60 * catalog access is available, so we can't call
61 * pg_newlocale_from_collation().
62 */
64 }
65 else
66 {
68
69 if (!locale->deterministic)
71 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
72 errmsg("nondeterministic collations are not supported for regular expressions")));
73
74 if (locale->ctype_is_c)
75 {
76 /*
77 * C/POSIX collations use this path regardless of database
78 * encoding
79 */
81 }
82 }
83
85}
#define OidIsValid(objectId)
Definition: c.h:778
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:1180
static struct pg_locale_struct dummy_c_locale
static pg_locale_t pg_regex_locale

References dummy_c_locale, 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 291 of file regc_pg_locale.c.

292{
293 pg_ctype_cache *pcc;
294 pg_wchar max_chr;
295 pg_wchar cur_chr;
296 int nmatches;
297 chr *newchrs;
298
299 /*
300 * Do we already have the answer cached?
301 */
302 for (pcc = pg_ctype_cache_list; pcc != NULL; pcc = pcc->next)
303 {
304 if (pcc->probefunc == probefunc &&
305 pcc->locale == pg_regex_locale)
306 return &pcc->cv;
307 }
308
309 /*
310 * Nope, so initialize some workspace ...
311 */
312 pcc = (pg_ctype_cache *) malloc(sizeof(pg_ctype_cache));
313 if (pcc == NULL)
314 return NULL;
315 pcc->probefunc = probefunc;
316 pcc->locale = pg_regex_locale;
317 pcc->cv.nchrs = 0;
318 pcc->cv.chrspace = 128;
319 pcc->cv.chrs = (chr *) malloc(pcc->cv.chrspace * sizeof(chr));
320 pcc->cv.nranges = 0;
321 pcc->cv.rangespace = 64;
322 pcc->cv.ranges = (chr *) malloc(pcc->cv.rangespace * sizeof(chr) * 2);
323 if (pcc->cv.chrs == NULL || pcc->cv.ranges == NULL)
324 goto out_of_memory;
325 pcc->cv.cclasscode = cclasscode;
326
327 /*
328 * Decide how many character codes we ought to look through. In general
329 * we don't go past MAX_SIMPLE_CHR; chr codes above that are handled at
330 * runtime using the "high colormap" mechanism. However, in C locale
331 * there's no need to go further than 127, and if we only have a 1-byte
332 * <ctype.h> API there's no need to go further than that can handle.
333 *
334 * If it's not MAX_SIMPLE_CHR that's constraining the search, mark the
335 * output cvec as not having any locale-dependent behavior, since there
336 * will be no need to do any run-time locale checks. (The #if's here
337 * would always be true for production values of MAX_SIMPLE_CHR, but it's
338 * useful to allow it to be small for testing purposes.)
339 */
341 {
342#if MAX_SIMPLE_CHR >= 127
343 max_chr = (pg_wchar) 127;
344 pcc->cv.cclasscode = -1;
345#else
346 max_chr = (pg_wchar) MAX_SIMPLE_CHR;
347#endif
348 }
349 else
350 {
351 if (pg_regex_locale->ctype->max_chr != 0 &&
353 {
354 max_chr = pg_regex_locale->ctype->max_chr;
355 pcc->cv.cclasscode = -1;
356 }
357 else
358 max_chr = (pg_wchar) MAX_SIMPLE_CHR;
359 }
360
361 /*
362 * And scan 'em ...
363 */
364 nmatches = 0; /* number of consecutive matches */
365
366 for (cur_chr = 0; cur_chr <= max_chr; cur_chr++)
367 {
368 if ((*probefunc) (cur_chr))
369 nmatches++;
370 else if (nmatches > 0)
371 {
372 if (!store_match(pcc, cur_chr - nmatches, nmatches))
373 goto out_of_memory;
374 nmatches = 0;
375 }
376 }
377
378 if (nmatches > 0)
379 if (!store_match(pcc, cur_chr - nmatches, nmatches))
380 goto out_of_memory;
381
382 /*
383 * We might have allocated more memory than needed, if so free it
384 */
385 if (pcc->cv.nchrs == 0)
386 {
387 free(pcc->cv.chrs);
388 pcc->cv.chrs = NULL;
389 pcc->cv.chrspace = 0;
390 }
391 else if (pcc->cv.nchrs < pcc->cv.chrspace)
392 {
393 newchrs = (chr *) realloc(pcc->cv.chrs,
394 pcc->cv.nchrs * sizeof(chr));
395 if (newchrs == NULL)
396 goto out_of_memory;
397 pcc->cv.chrs = newchrs;
398 pcc->cv.chrspace = pcc->cv.nchrs;
399 }
400 if (pcc->cv.nranges == 0)
401 {
402 free(pcc->cv.ranges);
403 pcc->cv.ranges = NULL;
404 pcc->cv.rangespace = 0;
405 }
406 else if (pcc->cv.nranges < pcc->cv.rangespace)
407 {
408 newchrs = (chr *) realloc(pcc->cv.ranges,
409 pcc->cv.nranges * sizeof(chr) * 2);
410 if (newchrs == NULL)
411 goto out_of_memory;
412 pcc->cv.ranges = newchrs;
413 pcc->cv.rangespace = pcc->cv.nranges;
414 }
415
416 /*
417 * Success, link it into cache chain
418 */
421
422 return &pcc->cv;
423
424 /*
425 * Failure, clean up
426 */
427out_of_memory:
428 free(pcc->cv.chrs);
429 free(pcc->cv.ranges);
430 free(pcc);
431
432 return NULL;
433}
#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
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
pg_wchar max_chr
Definition: pg_locale.h:128
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
const struct ctype_methods * ctype
Definition: pg_locale.h:153

References cvec::cclasscode, cvec::chrs, cvec::chrspace, pg_locale_struct::ctype, pg_locale_struct::ctype_is_c, pg_ctype_cache::cv, free, pg_ctype_cache::locale, malloc, ctype_methods::max_chr, MAX_SIMPLE_CHR, cvec::nchrs, pg_ctype_cache::next, cvec::nranges, pg_ctype_cache_list, pg_regex_locale, 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 113 of file regc_pg_locale.c.

114{
116 return (c <= (pg_wchar) 127 &&
118 else
120}
#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:103

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 103 of file regc_pg_locale.c.

104{
106 return (c <= (pg_wchar) 127 &&
108 else
110}
#define PG_ISALPHA
Definition: pg_locale_c.h:20
bool(* wc_isalpha)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:102

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 93 of file regc_pg_locale.c.

94{
96 return (c <= (pg_wchar) 127 &&
98 else
100}
#define PG_ISDIGIT
Definition: pg_locale_c.h:19
bool(* wc_isdigit)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:101

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 152 of file regc_pg_locale.c.

153{
155 return (c <= (pg_wchar) 127 &&
157 else
159}
#define PG_ISGRAPH
Definition: pg_locale_c.h:24
bool(* wc_isgraph)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:106

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 142 of file regc_pg_locale.c.

143{
145 return (c <= (pg_wchar) 127 &&
147 else
149}
#define PG_ISLOWER
Definition: pg_locale_c.h:23
bool(* wc_islower)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:105

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 162 of file regc_pg_locale.c.

163{
165 return (c <= (pg_wchar) 127 &&
167 else
169}
#define PG_ISPRINT
Definition: pg_locale_c.h:25
bool(* wc_isprint)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:107

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 172 of file regc_pg_locale.c.

173{
175 return (c <= (pg_wchar) 127 &&
177 else
179}
#define PG_ISPUNCT
Definition: pg_locale_c.h:26
bool(* wc_ispunct)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:108

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 182 of file regc_pg_locale.c.

183{
185 return (c <= (pg_wchar) 127 &&
187 else
189}
#define PG_ISSPACE
Definition: pg_locale_c.h:27
bool(* wc_isspace)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:109

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 132 of file regc_pg_locale.c.

133{
135 return (c <= (pg_wchar) 127 &&
137 else
139}
#define PG_ISUPPER
Definition: pg_locale_c.h:22
bool(* wc_isupper)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:104

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 123 of file regc_pg_locale.c.

124{
125 /* We define word characters as alnum class plus underscore */
126 if (c == CHR('_'))
127 return 1;
128 return regc_wc_isalnum(c);
129}
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 205 of file regc_pg_locale.c.

206{
208 {
209 if (c <= (pg_wchar) 127)
210 return pg_ascii_tolower((unsigned char) c);
211 return c;
212 }
213 else
215}
unsigned char pg_ascii_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:146
pg_wchar(* wc_tolower)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:112

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 192 of file regc_pg_locale.c.

193{
195 {
196 if (c <= (pg_wchar) 127)
197 return pg_ascii_toupper((unsigned char) c);
198 return c;
199 }
200 else
202}
unsigned char pg_ascii_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:135
pg_wchar(* wc_toupper)(pg_wchar wc, pg_locale_t locale)
Definition: pg_locale.h:111

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 247 of file regc_pg_locale.c.

248{
249 chr *newchrs;
250
251 if (nchrs > 1)
252 {
253 if (pcc->cv.nranges >= pcc->cv.rangespace)
254 {
255 pcc->cv.rangespace *= 2;
256 newchrs = (chr *) realloc(pcc->cv.ranges,
257 pcc->cv.rangespace * sizeof(chr) * 2);
258 if (newchrs == NULL)
259 return false;
260 pcc->cv.ranges = newchrs;
261 }
262 pcc->cv.ranges[pcc->cv.nranges * 2] = chr1;
263 pcc->cv.ranges[pcc->cv.nranges * 2 + 1] = chr1 + nchrs - 1;
264 pcc->cv.nranges++;
265 }
266 else
267 {
268 assert(nchrs == 1);
269 if (pcc->cv.nchrs >= pcc->cv.chrspace)
270 {
271 pcc->cv.chrspace *= 2;
272 newchrs = (chr *) realloc(pcc->cv.chrs,
273 pcc->cv.chrspace * sizeof(chr));
274 if (newchrs == NULL)
275 return false;
276 pcc->cv.chrs = newchrs;
277 }
278 pcc->cv.chrs[pcc->cv.nchrs++] = chr1;
279 }
280 return true;
281}
#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

◆ dummy_c_locale

struct pg_locale_struct dummy_c_locale
static
Initial value:
= {
.collate_is_c = true,
.ctype_is_c = true,
}

Definition at line 26 of file regc_pg_locale.c.

Referenced by pg_set_regex_collation().

◆ pg_ctype_cache_list

pg_ctype_cache* pg_ctype_cache_list = NULL
static

Definition at line 241 of file regc_pg_locale.c.

Referenced by regc_ctype_get_cache().

◆ pg_regex_locale