PostgreSQL Source Code: src/backend/utils/adt/regexp.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
31
39
40#define PG_GETARG_TEXT_PP_IF_EXISTS(_n) \
41 (PG_NARGS() > (_n) ? PG_GETARG_TEXT_PP(_n) : NULL)
42
43
44
46{
50
51
53{
57
58
59 int *match_locs;
60 int next_match;
61
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94#ifndef MAX_CACHED_RES
95#define MAX_CACHED_RES 32
96#endif
97
98
100
101
103{
106 int cre_pat_len;
111
114
115
116
119 int start_search,
120 Oid collation,
121 bool use_subpatterns,
122 bool ignore_degenerate,
123 bool fetching_unmatched);
126
127
128
129
130
131
132
133
134
135
136
137
138
139
142{
144 char *text_re_val = VARDATA_ANY(text_re);
146 int pattern_len;
147 int i;
148 int regcomp_result;
150 char errMsg[100];
152
153
154
155
156
157
159 {
160 if (re_array[i].cre_pat_len == text_re_len &&
161 re_array[i].cre_flags == cflags &&
162 re_array[i].cre_collation == collation &&
163 memcmp(re_array[i].cre_pat, text_re_val, text_re_len) == 0)
164 {
165
166
167
168 if (i > 0)
169 {
173 }
174
176 }
177 }
178
179
183 "RegexpCacheMemoryContext",
185
186
187
188
189
190
191
194 pattern,
195 text_re_len);
196
197
198
199
200
201
202
203
205 "RegexpMemoryContext",
208
210 pattern,
211 pattern_len,
212 cflags,
213 collation);
214
216
217 if (regcomp_result != REG_OKAY)
218 {
219
220 pg_regerror(regcomp_result, &re_temp.cre_re, errMsg, sizeof(errMsg));
222 (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
223 errmsg("invalid regular expression: %s", errMsg)));
224 }
225
226
228 memcpy(re_temp.cre_pat, text_re_val, text_re_len);
229
230
231
232
233
234 re_temp.cre_pat[text_re_len] = 0;
236
240
241
242
243
244
246 {
249
251 }
252
253
255
258
261
263
265}
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281static bool
283 int start_search, int nmatch, regmatch_t *pmatch)
284{
285 int regexec_result;
286 char errMsg[100];
287
288
291 data_len,
292 start_search,
293 NULL,
294 nmatch,
295 pmatch,
296 0);
297
299 {
300
301 pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
303 (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
304 errmsg("regular expression failed: %s", errMsg)));
305 }
306
307 return (regexec_result == REG_OKAY);
308}
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323static bool
326{
328 int data_len;
329 bool match;
330
331
334
335
337
339 return match;
340}
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357bool
359 int cflags, Oid collation,
361{
363
364
365 if (nmatch < 2)
367
368
370
371 return RE_execute(re, dat, dat_len, nmatch, pmatch);
372}
373
374
375
376
377
378
379
380
381
382
383
384static void
386{
387
389 flags->glob = false;
390
392 {
395 int i;
396
397 for (i = 0; i < opt_len; i++)
398 {
399 switch (opt_p[i])
400 {
401 case 'g':
402 flags->glob = true;
403 break;
404 case 'b':
406 break;
407 case 'c':
408 flags->cflags &= ~REG_ICASE;
409 break;
410 case 'e':
413 break;
414 case 'i':
416 break;
417 case 'm':
418 case 'n':
420 break;
421 case 'p':
423 flags->cflags &= ~REG_NLANCH;
424 break;
425 case 'q':
428 break;
429 case 's':
430 flags->cflags &= ~REG_NEWLINE;
431 break;
432 case 't':
433 flags->cflags &= ~REG_EXPANDED;
434 break;
435 case 'w':
436 flags->cflags &= ~REG_NLSTOP;
438 break;
439 case 'x':
441 break;
442 default:
444 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
445 errmsg("invalid regular expression option: \"%.*s\"",
447 break;
448 }
449 }
450 }
451}
452
453
454
455
456
457
460{
463
469 0, NULL));
470}
471
474{
477
483 0, NULL));
484}
485
488{
491
497 0, NULL));
498}
499
502{
505
511 0, NULL));
512}
513
514
515
516
517
518
519
520
523{
526
532 0, NULL));
533}
534
537{
540
546 0, NULL));
547}
548
551{
554
560 0, NULL));
561}
562
565{
568
574 0, NULL));
575}
576
577
578
579
580
581
584{
589 int so,
590 eo;
591
592
594
595
596
597
598
599
600
603 2, pmatch))
605
606 if (re->re_nsub > 0)
607 {
608
609 so = pmatch[1].rm_so;
610 eo = pmatch[1].rm_eo;
611 }
612 else
613 {
614
615 so = pmatch[0].rm_so;
616 eo = pmatch[0].rm_eo;
617 }
618
619
620
621
622
623
624
625 if (so < 0 || eo < 0)
627
632}
633
634
635
636
637
638
639
640
643{
647
650 0, 1));
651}
652
653
654
655
656
659{
665
666
667
668
669
670
671
672
674 {
676
677 if (*opt_p >= '0' && *opt_p <= '9')
679 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
680 errmsg("invalid regular expression option: \"%.*s\"",
682 errhint("If you meant to use regexp_replace() with a start parameter, cast the fourth argument to integer explicitly.")));
683 }
684
686
689 0, flags.glob ? 0 : 1));
690}
691
692
693
694
695
696
697
700{
705 int n = 1;
708
709
711 {
715 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
716 errmsg("invalid value for parameter \"%s\": %d",
717 "start", start)));
718 }
720 {
722 if (n < 0)
724 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
725 errmsg("invalid value for parameter \"%s\": %d",
726 "n", n)));
727 }
728
729
731
732
734 n = re_flags.glob ? 0 : 1;
735
736
740}
741
742
745{
747}
748
749
752{
754}
755
756
757
758
759
760
761
762
763
764
765
768{
769 text *result;
770 char *p,
771 *e,
772 *r;
773 int plen,
774 elen;
775 bool afterescape = false;
776 bool incharclass = false;
777 int nquotes = 0;
778
781 if (esc_text == NULL)
782 {
783
784 e = "\\";
785 elen = 1;
786 }
787 else
788 {
791 if (elen == 0)
792 e = NULL;
793 else if (elen > 1)
794 {
796
797 if (escape_mblen > 1)
799 (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),
800 errmsg("invalid escape string"),
801 errhint("Escape string must be empty or one character.")));
802 }
803 }
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
846
847 *r++ = '^';
848 *r++ = '(';
849 *r++ = '?';
850 *r++ = ':';
851
852 while (plen > 0)
853 {
854 char pchar = *p;
855
856
857
858
859
860
861
862
863
864
865
866
867 if (elen > 1)
868 {
870
871 if (mblen > 1)
872 {
873
874 if (afterescape)
875 {
876 *r++ = '\\';
877 memcpy(r, p, mblen);
878 r += mblen;
879 afterescape = false;
880 }
881 else if (e && elen == mblen && memcmp(e, p, mblen) == 0)
882 {
883
884 afterescape = true;
885 }
886 else
887 {
888
889
890
891
892
893 memcpy(r, p, mblen);
894 r += mblen;
895 }
896
897 p += mblen;
898 plen -= mblen;
899
900 continue;
901 }
902 }
903
904
905 if (afterescape)
906 {
907 if (pchar == '"' && !incharclass)
908 {
909
910 if (nquotes == 0)
911 {
912 *r++ = ')';
913 *r++ = '{';
914 *r++ = '1';
915 *r++ = ',';
916 *r++ = '1';
917 *r++ = '}';
918 *r++ = '?';
919 *r++ = '(';
920 }
921 else if (nquotes == 1)
922 {
923 *r++ = ')';
924 *r++ = '{';
925 *r++ = '1';
926 *r++ = ',';
927 *r++ = '1';
928 *r++ = '}';
929 *r++ = '(';
930 *r++ = '?';
931 *r++ = ':';
932 }
933 else
935 (errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER),
936 errmsg("SQL regular expression may not contain more than two escape-double-quote separators")));
937 nquotes++;
938 }
939 else
940 {
941
942
943
944
945
946 *r++ = '\\';
947 *r++ = pchar;
948 }
949 afterescape = false;
950 }
951 else if (e && pchar == *e)
952 {
953
954 afterescape = true;
955 }
956 else if (incharclass)
957 {
958 if (pchar == '\\')
959 *r++ = '\\';
960 *r++ = pchar;
961 if (pchar == ']')
962 incharclass = false;
963 }
964 else if (pchar == '[')
965 {
966 *r++ = pchar;
967 incharclass = true;
968 }
969 else if (pchar == '%')
970 {
971 *r++ = '.';
972 *r++ = '*';
973 }
974 else if (pchar == '_')
975 *r++ = '.';
976 else if (pchar == '(')
977 {
978
979 *r++ = '(';
980 *r++ = '?';
981 *r++ = ':';
982 }
983 else if (pchar == '\\' || pchar == '.' ||
984 pchar == '^' || pchar == '$')
985 {
986 *r++ = '\\';
987 *r++ = pchar;
988 }
989 else
990 *r++ = pchar;
991 p++, plen--;
992 }
993
994 *r++ = ')';
995 *r++ = '$';
996
997 SET_VARSIZE(result, r - ((char *) result));
998
999 return result;
1000}
1001
1002
1003
1004
1007{
1010 text *result;
1011
1013
1015}
1016
1017
1018
1019
1020
1023{
1025 text *result;
1026
1028
1030}
1031
1032
1033
1034
1035
1036
1037
1038
1041{
1042 text *pat_text;
1043 text *esc_text;
1044 text *result;
1045
1046
1050
1052 esc_text = NULL;
1053 else
1055
1057
1059}
1060
1061
1062
1063
1064
1067{
1074
1075
1077 {
1081 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1082 errmsg("invalid value for parameter \"%s\": %d",
1083 "start", start)));
1084 }
1085
1086
1088
1089 if (re_flags.glob)
1091 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1092
1093 errmsg("%s does not support the \"global\" option",
1094 "regexp_count()")));
1095
1096 re_flags.glob = true;
1097
1098
1101 false,
1102 false, false);
1103
1105}
1106
1107
1110{
1112}
1113
1114
1117{
1119}
1120
1121
1122
1123
1124
1127{
1131 int n = 1;
1132 int endoption = 0;
1134 int subexpr = 0;
1135 int pos;
1138
1139
1141 {
1145 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1146 errmsg("invalid value for parameter \"%s\": %d",
1147 "start", start)));
1148 }
1150 {
1152 if (n <= 0)
1154 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1155 errmsg("invalid value for parameter \"%s\": %d",
1156 "n", n)));
1157 }
1159 {
1161 if (endoption != 0 && endoption != 1)
1163 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1164 errmsg("invalid value for parameter \"%s\": %d",
1165 "endoption", endoption)));
1166 }
1168 {
1170 if (subexpr < 0)
1172 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1173 errmsg("invalid value for parameter \"%s\": %d",
1174 "subexpr", subexpr)));
1175 }
1176
1177
1179
1180 if (re_flags.glob)
1182 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1183
1184 errmsg("%s does not support the \"global\" option",
1185 "regexp_instr()")));
1186
1187 re_flags.glob = true;
1188
1189
1192 (subexpr > 0),
1193 false, false);
1194
1195
1198
1199
1200 if (subexpr > matchctx->npatterns)
1202
1203
1204 pos = (n - 1) * matchctx->npatterns;
1205 if (subexpr > 0)
1206 pos += subexpr - 1;
1207 pos *= 2;
1208 if (endoption == 1)
1209 pos += 1;
1210
1213 else
1215}
1216
1217
1220{
1222}
1223
1224
1227{
1229}
1230
1231
1234{
1236}
1237
1238
1241{
1243}
1244
1245
1248{
1250}
1251
1252
1253
1254
1255
1258{
1263
1264
1266
1267 if (re_flags.glob)
1269 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1270
1271 errmsg("%s does not support the \"global\" option",
1272 "regexp_like()")));
1273
1274
1280 0, NULL));
1281}
1282
1283
1286{
1288}
1289
1290
1291
1292
1293
1296{
1302
1303
1305
1306 if (re_flags.glob)
1308 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1309
1310 errmsg("%s does not support the \"global\" option",
1311 "regexp_match()"),
1312 errhint("Use the regexp_matches function instead.")));
1313
1316
1317 if (matchctx->nmatches == 0)
1319
1321
1322
1325
1327}
1328
1329
1332{
1334}
1335
1336
1337
1338
1339
1342{
1345
1347 {
1352
1355
1356
1358
1359
1361 &re_flags, 0,
1363 true, false, false);
1364
1365
1368
1371 }
1372
1375
1377 {
1379
1383 }
1384
1386}
1387
1388
1391{
1393}
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1417 int start_search,
1418 Oid collation,
1419 bool use_subpatterns,
1420 bool ignore_degenerate,
1421 bool fetching_unmatched)
1422{
1425 int orig_len;
1427 int wide_len;
1428 int cflags;
1431 int pmatch_len;
1432 int array_len;
1433 int array_idx;
1434 int prev_match_end;
1435 int prev_valid_match_end;
1436 int maxlen = 0;
1437
1438
1439 matchctx->orig_str = orig_str;
1440
1441
1445
1446
1447 cflags = re_flags->cflags;
1448 if (!use_subpatterns)
1451
1452
1453 if (use_subpatterns && cpattern->re_nsub > 0)
1454 {
1455 matchctx->npatterns = cpattern->re_nsub;
1456 pmatch_len = cpattern->re_nsub + 1;
1457 }
1458 else
1459 {
1460 use_subpatterns = false;
1462 pmatch_len = 1;
1463 }
1464
1465
1467
1468
1469
1470
1471
1472
1473
1474 array_len = re_flags->glob ? 255 : 31;
1475 matchctx->match_locs = (int *) palloc(sizeof(int) * array_len);
1476 array_idx = 0;
1477
1478
1479 prev_match_end = 0;
1480 prev_valid_match_end = 0;
1481 while (RE_wchar_execute(cpattern, wide_str, wide_len, start_search,
1482 pmatch_len, pmatch))
1483 {
1484
1485
1486
1487
1488
1489 if (!ignore_degenerate ||
1490 (pmatch[0].rm_so < wide_len &&
1491 pmatch[0].rm_eo > prev_match_end))
1492 {
1493
1494 while (array_idx + matchctx->npatterns * 2 + 1 > array_len)
1495 {
1496 array_len += array_len + 1;
1499 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1500 errmsg("too many regular expression matches")));
1502 sizeof(int) * array_len);
1503 }
1504
1505
1506 if (use_subpatterns)
1507 {
1508 int i;
1509
1511 {
1512 int so = pmatch[i].rm_so;
1513 int eo = pmatch[i].rm_eo;
1514
1515 matchctx->match_locs[array_idx++] = so;
1516 matchctx->match_locs[array_idx++] = eo;
1517 if (so >= 0 && eo >= 0 && (eo - so) > maxlen)
1518 maxlen = (eo - so);
1519 }
1520 }
1521 else
1522 {
1523 int so = pmatch[0].rm_so;
1524 int eo = pmatch[0].rm_eo;
1525
1526 matchctx->match_locs[array_idx++] = so;
1527 matchctx->match_locs[array_idx++] = eo;
1528 if (so >= 0 && eo >= 0 && (eo - so) > maxlen)
1529 maxlen = (eo - so);
1530 }
1532
1533
1534
1535
1536
1537
1538 if (fetching_unmatched &&
1539 pmatch[0].rm_so >= 0 &&
1540 (pmatch[0].rm_so - prev_valid_match_end) > maxlen)
1541 maxlen = (pmatch[0].rm_so - prev_valid_match_end);
1542 prev_valid_match_end = pmatch[0].rm_eo;
1543 }
1544 prev_match_end = pmatch[0].rm_eo;
1545
1546
1547 if (!re_flags->glob)
1548 break;
1549
1550
1551
1552
1553
1554
1555
1556 start_search = prev_match_end;
1557 if (pmatch[0].rm_so == pmatch[0].rm_eo)
1558 start_search++;
1559 if (start_search > wide_len)
1560 break;
1561 }
1562
1563
1564
1565
1566
1567 if (fetching_unmatched &&
1568 (wide_len - prev_valid_match_end) > maxlen)
1569 maxlen = (wide_len - prev_valid_match_end);
1570
1571
1572
1573
1574
1575 matchctx->match_locs[array_idx] = wide_len;
1576
1577 if (eml > 1)
1578 {
1579 int64 maxsiz = eml * (int64) maxlen;
1580 int conv_bufsiz;
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592 if (maxsiz > orig_len)
1593 conv_bufsiz = orig_len + 1;
1594 else
1595 conv_bufsiz = maxsiz + 1;
1596
1599 matchctx->wide_str = wide_str;
1600 }
1601 else
1602 {
1603
1604 pfree(wide_str);
1608 }
1609
1610
1612
1613 return matchctx;
1614}
1615
1616
1617
1618
1621{
1624 bool *nulls = matchctx->nulls;
1625 int dims[1];
1626 int lbs[1];
1627 int loc;
1628 int i;
1629
1630
1633 {
1634 int so = matchctx->match_locs[loc++];
1635 int eo = matchctx->match_locs[loc++];
1636
1637 if (so < 0 || eo < 0)
1638 {
1640 nulls[i] = true;
1641 }
1642 else if (buf)
1643 {
1646 eo - so);
1647
1648 Assert(len < matchctx->conv_bufsiz);
1650 nulls[i] = false;
1651 }
1652 else
1653 {
1658 nulls[i] = false;
1659 }
1660 }
1661
1662
1664 lbs[0] = 1;
1665
1667 TEXTOID, -1, false, TYPALIGN_INT);
1668}
1669
1670
1671
1672
1673
1674
1677{
1680
1682 {
1687
1690
1691
1693
1694 if (re_flags.glob)
1696 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1697
1698 errmsg("%s does not support the \"global\" option",
1699 "regexp_split_to_table()")));
1700
1701 re_flags.glob = true;
1702
1703
1705 &re_flags, 0,
1707 false, true, true);
1708
1711 }
1712
1715
1717 {
1719
1722 }
1723
1725}
1726
1727
1730{
1732}
1733
1734
1735
1736
1737
1738
1741{
1745
1746
1748
1749 if (re_flags.glob)
1751 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1752
1753 errmsg("%s does not support the \"global\" option",
1754 "regexp_split_to_array()")));
1755
1756 re_flags.glob = true;
1757
1760 &re_flags, 0,
1762 false, true, true);
1763
1765 {
1768 false,
1769 TEXTOID,
1772 }
1773
1775}
1776
1777
1780{
1782}
1783
1784
1785
1786
1787
1788
1789
1792{
1796
1799 else
1802 elog(ERROR, "invalid match ending position");
1803
1806 elog(ERROR, "invalid match starting position");
1807
1808 if (buf)
1809 {
1810 int len;
1811
1815 Assert(len < splitctx->conv_bufsiz);
1817 }
1818 else
1819 {
1824 }
1825}
1826
1827
1828
1829
1830
1833{
1837 int n = 1;
1839 int subexpr = 0;
1840 int so,
1841 eo,
1842 pos;
1845
1846
1848 {
1852 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1853 errmsg("invalid value for parameter \"%s\": %d",
1854 "start", start)));
1855 }
1857 {
1859 if (n <= 0)
1861 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1862 errmsg("invalid value for parameter \"%s\": %d",
1863 "n", n)));
1864 }
1866 {
1868 if (subexpr < 0)
1870 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1871 errmsg("invalid value for parameter \"%s\": %d",
1872 "subexpr", subexpr)));
1873 }
1874
1875
1877
1878 if (re_flags.glob)
1880 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1881
1882 errmsg("%s does not support the \"global\" option",
1883 "regexp_substr()")));
1884
1885 re_flags.glob = true;
1886
1887
1890 (subexpr > 0),
1891 false, false);
1892
1893
1896
1897
1898 if (subexpr > matchctx->npatterns)
1900
1901
1902 pos = (n - 1) * matchctx->npatterns;
1903 if (subexpr > 0)
1904 pos += subexpr - 1;
1905 pos *= 2;
1908
1909 if (so < 0 || eo < 0)
1911
1916}
1917
1918
1921{
1923}
1924
1925
1928{
1930}
1931
1932
1935{
1937}
1938
1939
1942{
1944}
1945
1946
1947
1948
1949
1950
1951
1952char *
1954 bool *exact)
1955{
1956 char *result;
1958 int cflags;
1959 int re_result;
1961 size_t slen;
1962 size_t maxlen;
1963 char errMsg[100];
1964
1965 *exact = false;
1966
1967
1969 if (case_insensitive)
1971
1973
1974
1976
1977 switch (re_result)
1978 {
1980 return NULL;
1981
1983
1984 break;
1985
1987 *exact = true;
1988
1989 break;
1990
1991 default:
1992
1993 pg_regerror(re_result, re, errMsg, sizeof(errMsg));
1995 (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
1996 errmsg("regular expression failed: %s", errMsg)));
1997 break;
1998 }
1999
2000
2002 result = (char *) palloc(maxlen);
2004 Assert(slen < maxlen);
2005
2007
2008 return result;
2009}
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PG_GETARG_TEXT_PP(n)
#define PG_GETARG_NAME(n)
#define PG_RETURN_TEXT_P(x)
#define PG_RETURN_INT32(x)
#define PG_GETARG_INT32(n)
#define PG_RETURN_DATUM(x)
#define DirectFunctionCall3(func, arg1, arg2, arg3)
#define PG_GET_COLLATION()
#define PG_GETARG_TEXT_P_COPY(n)
#define PG_RETURN_BOOL(x)
#define SRF_IS_FIRSTCALL()
#define SRF_PERCALL_SETUP()
#define SRF_RETURN_NEXT(_funcctx, _result)
#define SRF_FIRSTCALL_INIT()
#define SRF_RETURN_DONE(_funcctx)
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
int pg_mbstrlen_with_len(const char *mbstr, int limit)
int pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len)
int pg_database_encoding_max_length(void)
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
int pg_mblen(const char *mbstr)
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext TopMemoryContext
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
#define AllocSetContextCreate
#define ALLOCSET_SMALL_SIZES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static AmcheckOptions opts
static XLogRecPtr startpos
static Datum PointerGetDatum(const void *X)
static Datum Int32GetDatum(int32 X)
int pg_regcomp(regex_t *re, const chr *string, size_t len, int flags, Oid collation)
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
int pg_regexec(regex_t *re, const chr *string, size_t len, size_t search_start, rm_detail_t *details, size_t nmatch, regmatch_t pmatch[], int flags)
struct regexp_matches_ctx regexp_matches_ctx
static MemoryContext RegexpCacheMemoryContext
regex_t * RE_compile_and_cache(text *text_re, int cflags, Oid collation)
Datum regexp_match_no_flags(PG_FUNCTION_ARGS)
Datum textregexreplace(PG_FUNCTION_ARGS)
Datum texticregexne(PG_FUNCTION_ARGS)
Datum regexp_substr_no_start(PG_FUNCTION_ARGS)
struct pg_re_flags pg_re_flags
Datum regexp_split_to_array(PG_FUNCTION_ARGS)
Datum texticregexeq(PG_FUNCTION_ARGS)
Datum regexp_substr_no_n(PG_FUNCTION_ARGS)
Datum regexp_instr_no_subexpr(PG_FUNCTION_ARGS)
Datum similar_to_escape_2(PG_FUNCTION_ARGS)
bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, int cflags, Oid collation, int nmatch, regmatch_t *pmatch)
char * regexp_fixed_prefix(text *text_re, bool case_insensitive, Oid collation, bool *exact)
static bool RE_wchar_execute(regex_t *re, pg_wchar *data, int data_len, int start_search, int nmatch, regmatch_t *pmatch)
Datum regexp_substr(PG_FUNCTION_ARGS)
Datum nameicregexne(PG_FUNCTION_ARGS)
Datum textregexsubstr(PG_FUNCTION_ARGS)
static Datum build_regexp_split_result(regexp_matches_ctx *splitctx)
Datum regexp_split_to_array_no_flags(PG_FUNCTION_ARGS)
Datum textregexreplace_extended_no_n(PG_FUNCTION_ARGS)
static regexp_matches_ctx * setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, int start_search, Oid collation, bool use_subpatterns, bool ignore_degenerate, bool fetching_unmatched)
Datum nameregexne(PG_FUNCTION_ARGS)
Datum regexp_instr(PG_FUNCTION_ARGS)
static ArrayType * build_regexp_match_result(regexp_matches_ctx *matchctx)
Datum similar_to_escape_1(PG_FUNCTION_ARGS)
Datum regexp_substr_no_flags(PG_FUNCTION_ARGS)
Datum regexp_matches(PG_FUNCTION_ARGS)
#define PG_GETARG_TEXT_PP_IF_EXISTS(_n)
Datum nameicregexeq(PG_FUNCTION_ARGS)
Datum regexp_matches_no_flags(PG_FUNCTION_ARGS)
Datum regexp_split_to_table_no_flags(PG_FUNCTION_ARGS)
Datum regexp_match(PG_FUNCTION_ARGS)
Datum textregexreplace_extended(PG_FUNCTION_ARGS)
Datum nameregexeq(PG_FUNCTION_ARGS)
Datum regexp_instr_no_n(PG_FUNCTION_ARGS)
Datum regexp_count_no_start(PG_FUNCTION_ARGS)
struct cached_re_str cached_re_str
static cached_re_str re_array[MAX_CACHED_RES]
static bool RE_execute(regex_t *re, char *dat, int dat_len, int nmatch, regmatch_t *pmatch)
static void parse_re_flags(pg_re_flags *flags, text *opts)
Datum regexp_split_to_table(PG_FUNCTION_ARGS)
Datum textregexreplace_noopt(PG_FUNCTION_ARGS)
Datum regexp_like_no_flags(PG_FUNCTION_ARGS)
Datum regexp_instr_no_flags(PG_FUNCTION_ARGS)
Datum textregexeq(PG_FUNCTION_ARGS)
Datum textregexne(PG_FUNCTION_ARGS)
Datum regexp_count_no_flags(PG_FUNCTION_ARGS)
Datum similar_escape(PG_FUNCTION_ARGS)
Datum regexp_instr_no_start(PG_FUNCTION_ARGS)
Datum regexp_instr_no_endoption(PG_FUNCTION_ARGS)
Datum textregexreplace_extended_no_flags(PG_FUNCTION_ARGS)
Datum regexp_like(PG_FUNCTION_ARGS)
Datum regexp_substr_no_subexpr(PG_FUNCTION_ARGS)
static text * similar_escape_internal(text *pat_text, text *esc_text)
Datum regexp_count(PG_FUNCTION_ARGS)
int pg_regprefix(regex_t *re, chr **string, size_t *slength)
MemoryContext multi_call_memory_ctx
MemoryContext cre_context
#define SET_VARSIZE(PTR, len)
#define VARSIZE_ANY_EXHDR(PTR)
Datum text_substr(PG_FUNCTION_ARGS)
text * cstring_to_text_with_len(const char *s, int len)
text * replace_text_regexp(text *src_text, text *pattern_text, text *replace_text, int cflags, Oid collation, int search_start, int n)