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{

47 int cflags;

48 bool glob;

50

51

53{

54 text *orig_str;

55 int nmatches;

56 int npatterns;

57

58

59 int *match_locs;

60 int next_match;

61

63 bool *nulls;

65 char *conv_buf;

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{

105 char *cre_pat;

106 int cre_pat_len;

107 int cre_flags;

111

112static int num_res = 0;

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 {

1639 elems[i] = (Datum) 0;

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)