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 int nquotes = 0;

777 int bracket_depth = 0;

778 int charclass_pos = 0;

779

782 if (esc_text == NULL)

783 {

784

785 e = "\\";

786 elen = 1;

787 }

788 else

789 {

792 if (elen == 0)

793 e = NULL;

794 else if (elen > 1)

795 {

797

798 if (escape_mblen > 1)

800 (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),

801 errmsg("invalid escape string"),

802 errhint("Escape string must be empty or one character.")));

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

844

845

846

847

848

849

850

851

852

853

854

855

858

859 *r++ = '^';

860 *r++ = '(';

861 *r++ = '?';

862 *r++ = ':';

863

864 while (plen > 0)

865 {

866 char pchar = *p;

867

868

869

870

871

872

873

874

875

876

877

878

879 if (elen > 1)

880 {

882

883 if (mblen > 1)

884 {

885

886 if (afterescape)

887 {

888 *r++ = '\\';

889 memcpy(r, p, mblen);

890 r += mblen;

891 afterescape = false;

892 }

893 else if (e && elen == mblen && memcmp(e, p, mblen) == 0)

894 {

895

896 afterescape = true;

897 }

898 else

899 {

900

901

902

903

904

905 memcpy(r, p, mblen);

906 r += mblen;

907 }

908

909 p += mblen;

910 plen -= mblen;

911

912 continue;

913 }

914 }

915

916

917 if (afterescape)

918 {

919 if (pchar == '"' && bracket_depth < 1)

920 {

921

922 if (nquotes == 0)

923 {

924 *r++ = ')';

925 *r++ = '{';

926 *r++ = '1';

927 *r++ = ',';

928 *r++ = '1';

929 *r++ = '}';

930 *r++ = '?';

931 *r++ = '(';

932 }

933 else if (nquotes == 1)

934 {

935 *r++ = ')';

936 *r++ = '{';

937 *r++ = '1';

938 *r++ = ',';

939 *r++ = '1';

940 *r++ = '}';

941 *r++ = '(';

942 *r++ = '?';

943 *r++ = ':';

944 }

945 else

947 (errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER),

948 errmsg("SQL regular expression may not contain more than two escape-double-quote separators")));

949 nquotes++;

950 }

951 else

952 {

953

954

955

956

957

958 *r++ = '\\';

959 *r++ = pchar;

960

961

962

963

964

965 charclass_pos = 3;

966 }

967 afterescape = false;

968 }

969 else if (e && pchar == *e)

970 {

971

972 afterescape = true;

973 }

974 else if (bracket_depth > 0)

975 {

976

977 if (pchar == '\\')

978 {

979

980

981

982

983

984

985 *r++ = '\\';

986 }

987 *r++ = pchar;

988

989

990 if (pchar == ']' && charclass_pos > 2)

991 {

992

993 bracket_depth--;

994

995 }

996 else if (pchar == '[')

997 {

998

999 bracket_depth++;

1000

1001

1002

1003

1004

1005

1006 charclass_pos = 3;

1007 }

1008 else if (pchar == '^')

1009 {

1010

1011

1012

1013

1014

1015

1016

1017

1018

1019 charclass_pos++;

1020 }

1021 else

1022 {

1023

1024

1025

1026

1027

1028 charclass_pos = 3;

1029 }

1030 }

1031 else if (pchar == '[')

1032 {

1033

1034 *r++ = pchar;

1035 bracket_depth = 1;

1036 charclass_pos = 1;

1037 }

1038 else if (pchar == '%')

1039 {

1040 *r++ = '.';

1041 *r++ = '*';

1042 }

1043 else if (pchar == '_')

1044 *r++ = '.';

1045 else if (pchar == '(')

1046 {

1047

1048 *r++ = '(';

1049 *r++ = '?';

1050 *r++ = ':';

1051 }

1052 else if (pchar == '\\' || pchar == '.' ||

1053 pchar == '^' || pchar == '$')

1054 {

1055 *r++ = '\\';

1056 *r++ = pchar;

1057 }

1058 else

1059 *r++ = pchar;

1060 p++, plen--;

1061 }

1062

1063 *r++ = ')';

1064 *r++ = '$';

1065

1066 SET_VARSIZE(result, r - ((char *) result));

1067

1068 return result;

1069}

1070

1071

1072

1073

1076{

1079 text *result;

1080

1082

1084}

1085

1086

1087

1088

1089

1092{

1094 text *result;

1095

1097

1099}

1100

1101

1102

1103

1104

1105

1106

1107

1110{

1111 text *pat_text;

1112 text *esc_text;

1113 text *result;

1114

1115

1119

1121 esc_text = NULL;

1122 else

1124

1126

1128}

1129

1130

1131

1132

1133

1136{

1143

1144

1146 {

1150 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1151 errmsg("invalid value for parameter \"%s\": %d",

1152 "start", start)));

1153 }

1154

1155

1157

1158 if (re_flags.glob)

1160 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1161

1162 errmsg("%s does not support the \"global\" option",

1163 "regexp_count()")));

1164

1165 re_flags.glob = true;

1166

1167

1170 false,

1171 false, false);

1172

1174}

1175

1176

1179{

1181}

1182

1183

1186{

1188}

1189

1190

1191

1192

1193

1196{

1200 int n = 1;

1201 int endoption = 0;

1203 int subexpr = 0;

1204 int pos;

1207

1208

1210 {

1214 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1215 errmsg("invalid value for parameter \"%s\": %d",

1216 "start", start)));

1217 }

1219 {

1221 if (n <= 0)

1223 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1224 errmsg("invalid value for parameter \"%s\": %d",

1225 "n", n)));

1226 }

1228 {

1230 if (endoption != 0 && endoption != 1)

1232 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1233 errmsg("invalid value for parameter \"%s\": %d",

1234 "endoption", endoption)));

1235 }

1237 {

1239 if (subexpr < 0)

1241 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1242 errmsg("invalid value for parameter \"%s\": %d",

1243 "subexpr", subexpr)));

1244 }

1245

1246

1248

1249 if (re_flags.glob)

1251 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1252

1253 errmsg("%s does not support the \"global\" option",

1254 "regexp_instr()")));

1255

1256 re_flags.glob = true;

1257

1258

1261 (subexpr > 0),

1262 false, false);

1263

1264

1267

1268

1269 if (subexpr > matchctx->npatterns)

1271

1272

1273 pos = (n - 1) * matchctx->npatterns;

1274 if (subexpr > 0)

1275 pos += subexpr - 1;

1276 pos *= 2;

1277 if (endoption == 1)

1278 pos += 1;

1279

1282 else

1284}

1285

1286

1289{

1291}

1292

1293

1296{

1298}

1299

1300

1303{

1305}

1306

1307

1310{

1312}

1313

1314

1317{

1319}

1320

1321

1322

1323

1324

1327{

1332

1333

1335

1336 if (re_flags.glob)

1338 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1339

1340 errmsg("%s does not support the \"global\" option",

1341 "regexp_like()")));

1342

1343

1349 0, NULL));

1350}

1351

1352

1355{

1357}

1358

1359

1360

1361

1362

1365{

1371

1372

1374

1375 if (re_flags.glob)

1377 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1378

1379 errmsg("%s does not support the \"global\" option",

1380 "regexp_match()"),

1381 errhint("Use the regexp_matches function instead.")));

1382

1385

1386 if (matchctx->nmatches == 0)

1388

1390

1391

1394

1396}

1397

1398

1401{

1403}

1404

1405

1406

1407

1408

1411{

1414

1416 {

1421

1424

1425

1427

1428

1430 &re_flags, 0,

1432 true, false, false);

1433

1434

1437

1440 }

1441

1444

1446 {

1448

1452 }

1453

1455}

1456

1457

1460{

1462}

1463

1464

1465

1466

1467

1468

1469

1470

1471

1472

1473

1474

1475

1476

1477

1478

1479

1480

1481

1482

1483

1486 int start_search,

1487 Oid collation,

1488 bool use_subpatterns,

1489 bool ignore_degenerate,

1490 bool fetching_unmatched)

1491{

1494 int orig_len;

1496 int wide_len;

1497 int cflags;

1500 int pmatch_len;

1501 int array_len;

1502 int array_idx;

1503 int prev_match_end;

1504 int prev_valid_match_end;

1505 int maxlen = 0;

1506

1507

1508 matchctx->orig_str = orig_str;

1509

1510

1514

1515

1516 cflags = re_flags->cflags;

1517 if (!use_subpatterns)

1520

1521

1522 if (use_subpatterns && cpattern->re_nsub > 0)

1523 {

1524 matchctx->npatterns = cpattern->re_nsub;

1525 pmatch_len = cpattern->re_nsub + 1;

1526 }

1527 else

1528 {

1529 use_subpatterns = false;

1531 pmatch_len = 1;

1532 }

1533

1534

1536

1537

1538

1539

1540

1541

1542

1543 array_len = re_flags->glob ? 255 : 31;

1545 array_idx = 0;

1546

1547

1548 prev_match_end = 0;

1549 prev_valid_match_end = 0;

1550 while (RE_wchar_execute(cpattern, wide_str, wide_len, start_search,

1551 pmatch_len, pmatch))

1552 {

1553

1554

1555

1556

1557

1558 if (!ignore_degenerate ||

1559 (pmatch[0].rm_so < wide_len &&

1560 pmatch[0].rm_eo > prev_match_end))

1561 {

1562

1563 while (array_idx + matchctx->npatterns * 2 + 1 > array_len)

1564 {

1565 array_len += array_len + 1;

1568 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

1569 errmsg("too many regular expression matches")));

1571 sizeof(int) * array_len);

1572 }

1573

1574

1575 if (use_subpatterns)

1576 {

1577 int i;

1578

1580 {

1581 int so = pmatch[i].rm_so;

1582 int eo = pmatch[i].rm_eo;

1583

1584 matchctx->match_locs[array_idx++] = so;

1585 matchctx->match_locs[array_idx++] = eo;

1586 if (so >= 0 && eo >= 0 && (eo - so) > maxlen)

1587 maxlen = (eo - so);

1588 }

1589 }

1590 else

1591 {

1592 int so = pmatch[0].rm_so;

1593 int eo = pmatch[0].rm_eo;

1594

1595 matchctx->match_locs[array_idx++] = so;

1596 matchctx->match_locs[array_idx++] = eo;

1597 if (so >= 0 && eo >= 0 && (eo - so) > maxlen)

1598 maxlen = (eo - so);

1599 }

1601

1602

1603

1604

1605

1606

1607 if (fetching_unmatched &&

1608 pmatch[0].rm_so >= 0 &&

1609 (pmatch[0].rm_so - prev_valid_match_end) > maxlen)

1610 maxlen = (pmatch[0].rm_so - prev_valid_match_end);

1611 prev_valid_match_end = pmatch[0].rm_eo;

1612 }

1613 prev_match_end = pmatch[0].rm_eo;

1614

1615

1616 if (!re_flags->glob)

1617 break;

1618

1619

1620

1621

1622

1623

1624

1625 start_search = prev_match_end;

1626 if (pmatch[0].rm_so == pmatch[0].rm_eo)

1627 start_search++;

1628 if (start_search > wide_len)

1629 break;

1630 }

1631

1632

1633

1634

1635

1636 if (fetching_unmatched &&

1637 (wide_len - prev_valid_match_end) > maxlen)

1638 maxlen = (wide_len - prev_valid_match_end);

1639

1640

1641

1642

1643

1644 matchctx->match_locs[array_idx] = wide_len;

1645

1646 if (eml > 1)

1647 {

1648 int64 maxsiz = eml * (int64) maxlen;

1649 int conv_bufsiz;

1650

1651

1652

1653

1654

1655

1656

1657

1658

1659

1660

1661 if (maxsiz > orig_len)

1662 conv_bufsiz = orig_len + 1;

1663 else

1664 conv_bufsiz = maxsiz + 1;

1665

1668 matchctx->wide_str = wide_str;

1669 }

1670 else

1671 {

1672

1673 pfree(wide_str);

1677 }

1678

1679

1681

1682 return matchctx;

1683}

1684

1685

1686

1687

1690{

1693 bool *nulls = matchctx->nulls;

1694 int dims[1];

1695 int lbs[1];

1696 int loc;

1697 int i;

1698

1699

1702 {

1703 int so = matchctx->match_locs[loc++];

1704 int eo = matchctx->match_locs[loc++];

1705

1706 if (so < 0 || eo < 0)

1707 {

1708 elems[i] = (Datum) 0;

1709 nulls[i] = true;

1710 }

1711 else if (buf)

1712 {

1715 eo - so);

1716

1717 Assert(len < matchctx->conv_bufsiz);

1719 nulls[i] = false;

1720 }

1721 else

1722 {

1727 nulls[i] = false;

1728 }

1729 }

1730

1731

1733 lbs[0] = 1;

1734

1736 TEXTOID, -1, false, TYPALIGN_INT);

1737}

1738

1739

1740

1741

1742

1743

1746{

1749

1751 {

1756

1759

1760

1762

1763 if (re_flags.glob)

1765 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1766

1767 errmsg("%s does not support the \"global\" option",

1768 "regexp_split_to_table()")));

1769

1770 re_flags.glob = true;

1771

1772

1774 &re_flags, 0,

1776 false, true, true);

1777

1780 }

1781

1784

1786 {

1788

1791 }

1792

1794}

1795

1796

1799{

1801}

1802

1803

1804

1805

1806

1807

1810{

1814

1815

1817

1818 if (re_flags.glob)

1820 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1821

1822 errmsg("%s does not support the \"global\" option",

1823 "regexp_split_to_array()")));

1824

1825 re_flags.glob = true;

1826

1829 &re_flags, 0,

1831 false, true, true);

1832

1834 {

1837 false,

1838 TEXTOID,

1841 }

1842

1844}

1845

1846

1849{

1851}

1852

1853

1854

1855

1856

1857

1858

1861{

1865

1868 else

1871 elog(ERROR, "invalid match ending position");

1872

1875 elog(ERROR, "invalid match starting position");

1876

1877 if (buf)

1878 {

1879 int len;

1880

1884 Assert(len < splitctx->conv_bufsiz);

1886 }

1887 else

1888 {

1893 }

1894}

1895

1896

1897

1898

1899

1902{

1906 int n = 1;

1908 int subexpr = 0;

1909 int so,

1910 eo,

1911 pos;

1914

1915

1917 {

1921 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1922 errmsg("invalid value for parameter \"%s\": %d",

1923 "start", start)));

1924 }

1926 {

1928 if (n <= 0)

1930 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1931 errmsg("invalid value for parameter \"%s\": %d",

1932 "n", n)));

1933 }

1935 {

1937 if (subexpr < 0)

1939 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1940 errmsg("invalid value for parameter \"%s\": %d",

1941 "subexpr", subexpr)));

1942 }

1943

1944

1946

1947 if (re_flags.glob)

1949 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1950

1951 errmsg("%s does not support the \"global\" option",

1952 "regexp_substr()")));

1953

1954 re_flags.glob = true;

1955

1956

1959 (subexpr > 0),

1960 false, false);

1961

1962

1965

1966

1967 if (subexpr > matchctx->npatterns)

1969

1970

1971 pos = (n - 1) * matchctx->npatterns;

1972 if (subexpr > 0)

1973 pos += subexpr - 1;

1974 pos *= 2;

1977

1978 if (so < 0 || eo < 0)

1980

1985}

1986

1987

1990{

1992}

1993

1994

1997{

1999}

2000

2001

2004{

2006}

2007

2008

2011{

2013}

2014

2015

2016

2017

2018

2019

2020

2021char *

2023 bool *exact)

2024{

2025 char *result;

2027 int cflags;

2028 int re_result;

2030 size_t slen;

2031 size_t maxlen;

2032 char errMsg[100];

2033

2034 *exact = false;

2035

2036

2038 if (case_insensitive)

2040

2042

2043

2045

2046 switch (re_result)

2047 {

2049 return NULL;

2050

2052

2053 break;

2054

2056 *exact = true;

2057

2058 break;

2059

2060 default:

2061

2062 pg_regerror(re_result, re, errMsg, sizeof(errMsg));

2064 (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),

2065 errmsg("regular expression failed: %s", errMsg)));

2066 break;

2067 }

2068

2069

2071 result = (char *) palloc(maxlen);

2073 Assert(slen < maxlen);

2074

2076

2077 return result;

2078}

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 palloc_array(type, count)

#define palloc0_object(type)

#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)

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 char buf[DEFAULT_XLOG_SEG_SIZE]

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

static Size VARSIZE_ANY_EXHDR(const void *PTR)

static char * VARDATA(const void *PTR)

static char * VARDATA_ANY(const void *PTR)

static void SET_VARSIZE(void *PTR, Size len)

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)