PostgreSQL Source Code: src/backend/access/gin/gininsert.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

36

37

38

39#define PARALLEL_KEY_GIN_SHARED UINT64CONST(0xB000000000000001)

40#define PARALLEL_KEY_TUPLESORT UINT64CONST(0xB000000000000002)

41#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xB000000000000003)

42#define PARALLEL_KEY_WAL_USAGE UINT64CONST(0xB000000000000004)

43#define PARALLEL_KEY_BUFFER_USAGE UINT64CONST(0xB000000000000005)

44

45

46

47

48

50{

51

52

53

54

55

60

61

62

63

64

65

66

68

69

70

71

72

73

74

76

77

78

79

80

81

82

83

84

85

86

90

91

92

93

94

95

97

98

99

100

101

102

103

104#define ParallelTableScanFromGinBuildShared(shared) \

105 (ParallelTableScanDesc) ((char *) (shared) + BUFFERALIGN(sizeof(GinBuildShared)))

106

107

108

109

111{

112

114

115

116

117

118

119

120

122

123

124

125

126

127

128

129

130

131

138

139typedef struct

140{

149

150

151

152

153

156

157

160

161

162

163

164

165

167

168

169

170

171

172

173

176

177

178

180 bool isconcurrent, int request);

192

195

200

201

202

203

204

205

206

207

213{

219 *oldItems;

220 int oldNPosting,

221 newNPosting;

223

225

228

229

231

233 oldItems, oldNPosting,

234 &newNPosting);

235

236

237 res = NULL;

239 NULL);

241 if (compressedList)

242 {

244 (char *) compressedList,

246 newNPosting,

247 false);

248 pfree(compressedList);

249 }

250 if (!res)

251 {

252

254

255

256

257

258

259

261 oldItems,

262 oldNPosting,

263 buildStats,

264 buffer);

265

266

269 buildStats);

270

271

274 }

276

277 return res;

278}

279

280

281

282

283

284

285

286

287

293{

296

297

299 if (compressedList)

300 {

302 (char *) compressedList,

304 nitem, false);

305 pfree(compressedList);

306 }

307 if (!res)

308 {

309

311

312

313

314

315

317

318

319

320

322 buildStats, buffer);

323

324

326 }

327

328 return res;

329}

330

331

332

333

334

335

336

337

338void

343{

349

351

353 btree.isBuild = (buildStats != NULL);

354

357

358 if (btree.findItem(&btree, stack))

359 {

360

362

364 {

365

367

368

371

372

375 buildStats);

376 return;

377 }

378

381

383 items, nitem, buildStats, stack->buffer);

384

386 }

387 else

388 {

391

393 items, nitem, buildStats, stack->buffer);

394

395

396

397

398

399 if (buildStats)

401 }

402

403

404 insertdata.entry = itup;

405 ginInsertValue(&btree, stack, &insertdata, buildStats);

407}

408

409

410

411

412

413

414

415static void

419{

424

428 &nentries, &categories);

430

432 entries, categories, nentries);

433

434 buildstate->indtuples += nentries;

435

437}

438

439static void

441 bool *isnull, bool tupleIsAlive, void *state)

442{

445 int i;

446

448

452

453

455 {

461

464 &attnum, &key, &category, &nlist)) != NULL)

465 {

466

470 }

471

474 }

475

477}

478

479

480

481

482

483static void

485{

492

495 &attnum, &key, &category, &nlist)) != NULL)

496 {

497

499

500

503

504

506

508 key, attr->attlen, attr->attbyval,

509 list, nlist, &tuplen);

510

512

514 }

515

518}

519

520

521

522

523

524

525

526

527

528

529

530

531

532static void

534 bool *isnull, bool tupleIsAlive, void *state)

535{

538 int i;

539

541

542

543

544

545

546

547

548

549

550

551

552

553

554

555

556

557

558

561

562

563 buildstate->tid = *tid;

564

568

569

570

571

572

573

576

578}

579

582{

584 double reltuples;

588 MetaBuffer;

595

597 elog(ERROR, "index \"%s\" already contains data",

599

603

604

609

610

612

613

615

621

622

626

627

629

630

631

632

633

635 "Gin build temporary context",

637

638

639

640

641

643 "Gin build temporary context for user-defined function",

645

648

649

652

653

654

655

656

657

658

659

660

661

665

666

667

668

669

670

671

672

673

674

675 if (state->bs_leader)

676 {

678

680 coordinate->isWorker = false;

682 state->bs_leader->nparticipanttuplesorts;

684

685

686

687

688

689

690

691

692

693

694

695

696

697

698

699

700

701

702

703

704

705

706

707 state->bs_sortstate =

711

712

714

716 }

717 else

718 {

719

720

721

722

725

726

730 &attnum, &key, &category, &nlist)) != NULL)

731 {

732

736 }

738 }

739

742

743

744

745

748

749

750

751

752

754 {

757 true);

758 }

759

760

761

762

764

767

768 return result;

769}

770

771

772

773

774void

776{

778 MetaBuffer;

779

780

785

786

795

796

799}

800

801

802

803

804

805static void

809{

813 nentries;

814

816 &nentries, &categories);

817

818 for (i = 0; i < nentries; i++)

820 item, 1, NULL);

821}

822

823bool

827 bool indexUnchanged,

829{

833 int i;

834

835

836 if (ginstate == NULL)

837 {

843 }

844

846 "Gin insert temporary context",

848

850

852 {

854

856

861 ht_ctid);

862

864 }

865 else

866 {

870 ht_ctid);

871 }

872

875

876 return false;

877}

878

879

880

881

882

883

884

885

886

887

888

889

890

891

892

893

894

895static void

897 bool isconcurrent, int request)

898{

900 int scantuplesortstates;

902 Size estginshared;

903 Size estsort;

909 bool leaderparticipates = true;

910 int querylen;

911

912#ifdef DISABLE_LEADER_PARTICIPATION

913 leaderparticipates = false;

914#endif

915

916

917

918

922 request);

923

924 scantuplesortstates = leaderparticipates ? request + 1 : request;

925

926

927

928

929

930

931

932

933 if (!isconcurrent)

935 else

937

938

939

940

945

947

948

949

950

951

952

953

954

955

962

963

965 {

969 }

970 else

971 querylen = 0;

972

973

975

976

977 if (pcxt->seg == NULL)

978 {

983 return;

984 }

985

986

988

993

996

997

1001

1004 snapshot);

1005

1006

1007

1008

1009

1012 pcxt->seg);

1013

1016

1017

1019 {

1020 char *sharedquery;

1021

1025 }

1026

1027

1028

1029

1030

1037

1038

1040 ginleader->pcxt = pcxt;

1042 if (leaderparticipates)

1044 ginleader->ginshared = ginshared;

1046 ginleader->snapshot = snapshot;

1047 ginleader->walusage = walusage;

1049

1050

1052 {

1054 return;

1055 }

1056

1057

1058 buildstate->bs_leader = ginleader;

1059

1060

1061 if (leaderparticipates)

1063

1064

1065

1066

1067

1069}

1070

1071

1072

1073

1074static void

1076{

1077 int i;

1078

1079

1081

1082

1083

1084

1085

1088

1089

1094}

1095

1096

1097

1098

1099

1100

1101

1102

1103

1104

1105static double

1107{

1109 int nparticipanttuplesorts;

1110

1111 nparticipanttuplesorts = state->bs_leader->nparticipanttuplesorts;

1112 for (;;)

1113 {

1116 {

1117

1120

1122 break;

1123 }

1125

1127 WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN);

1128 }

1129

1131

1132 return state->bs_reltuples;

1133}

1134

1135

1136

1137

1138

1139

1140

1141

1142

1143

1144

1145

1146

1148{

1151 Datum key;

1153

1154

1157

1158

1160

1161

1167

1168

1169

1170

1171

1172static void

1174{

1175#ifdef USE_ASSERT_CHECKING

1176

1179

1180 for (int i = 0; i < buffer->nitems; i++)

1181 {

1183

1184

1185 if (i == 0)

1186 continue;

1187

1189 }

1190#endif

1191}

1192

1193

1194

1195

1196

1197

1198

1199static void

1201{

1202#ifdef USE_ASSERT_CHECKING

1203

1205

1206

1207

1208

1209

1210 if (buffer->nitems == 0)

1211 return;

1212

1213

1215#endif

1216}

1217

1218

1219

1220

1221

1222

1223

1224

1225

1226

1227

1230{

1232 int i,

1233 nKeys;

1235

1236

1237

1238

1239

1240

1242

1244

1246

1247

1248

1249

1250

1251 for (i = 0; i < nKeys; i++)

1252 {

1253 Oid cmpFunc;

1256

1259

1262

1266

1268

1269

1270

1271

1272

1275 {

1277

1282 (errcode(ERRCODE_UNDEFINED_FUNCTION),

1283 errmsg("could not identify a comparison function for type %s",

1285

1287 }

1288

1290 }

1291

1292 return buffer;

1293}

1294

1295

1296static bool

1298{

1299 return (buffer->nitems == 0);

1300}

1301

1302

1303

1304

1305

1306

1307

1308

1309

1310

1311

1312static bool

1314{

1315 int r;

1317

1319

1321 return false;

1322

1323

1326

1328 return false;

1329

1330

1331

1332

1333

1335 return true;

1336

1337

1338

1339

1340

1342

1344 tupkey, false,

1346

1347 return (r == 0);

1348}

1349

1350

1351

1352

1353

1354

1355

1356

1357

1358

1359

1360

1361

1362

1363

1364

1365

1366

1367

1368

1369

1370

1371

1372

1373

1374static bool

1376{

1377

1378 if (buffer->nfrozen < 1024)

1379 return false;

1380

1381

1383 return false;

1384

1385

1386

1387

1388

1389 return true;

1390}

1391

1392

1393

1394

1395

1396

1397

1398

1399

1400

1401

1402

1403

1404

1405

1406

1407

1408

1409

1410

1411

1412

1413

1414

1415static void

1417{

1420

1422

1425

1426

1428 {

1432

1435

1438 else

1440 }

1441

1442

1443

1444

1445

1446

1447

1448

1449

1450

1451

1452

1453

1454

1455

1456 if ((buffer->nitems > 0) &&

1460

1461

1462

1463

1464

1465

1466

1467

1468

1469

1470

1471

1472

1473

1475 {

1476

1479 break;

1480

1482 }

1483

1484

1485 {

1486 int nnew;

1488

1489

1490

1491

1492

1493

1494 if (buffer->items == NULL)

1496 else

1499

1501 (buffer->nitems - buffer->nfrozen),

1503

1505

1506 memcpy(&buffer->items[buffer->nfrozen], new,

1508

1510

1512

1514 }

1515

1516

1518}

1519

1520

1521

1522

1523

1524static void

1526{

1528

1529

1532

1533

1534

1535

1536

1538

1544

1547}

1548

1549

1550

1551

1552

1553

1554static void

1556{

1558

1561

1564}

1565

1566

1567

1568

1569

1570static void

1572{

1573 if (buffer->items)

1575

1576

1580

1582}

1583

1584

1585

1586

1587

1588

1589

1590static bool

1592{

1593

1595 return true;

1596

1597

1599}

1600

1601

1602

1603

1604

1605

1606

1607

1608

1609

1610

1611

1612static double

1614{

1616 Size tuplen;

1617 double reltuples = 0;

1619

1620

1621 double numtuples = 0;

1622

1623

1625

1626

1629

1630

1632

1633

1634

1635

1636

1637

1638

1640

1641

1642

1643

1644

1645 {

1646 const int progress_index[] = {

1651 };

1652 const int64 progress_vals[] = {

1654 state->bs_numtuples,

1655 0, 0

1656 };

1657

1659 }

1660

1661

1662

1663

1664

1665

1666

1667

1668

1669

1671 {

1673

1675

1676

1677

1678

1679

1680

1682 {

1683

1684

1685

1686

1687

1689

1691

1695

1698

1699

1701 }

1702

1703

1704

1705

1706

1707

1708

1709

1711 {

1713

1714

1715

1716

1717

1718

1720

1722

1726

1729

1730

1732 }

1733

1734

1735

1736

1737

1739

1740

1742 ++numtuples);

1743 }

1744

1745

1747 {

1749

1753

1754

1756

1757

1759 ++numtuples);

1760 }

1761

1762

1764

1766

1767 return reltuples;

1768}

1769

1770

1771

1772

1773

1776{

1777

1780}

1781

1782

1783

1784

1785static void

1787{

1789 int sortmem;

1790

1791

1792

1793

1794

1795

1797

1798

1801 sortmem, true);

1802}

1803

1804

1805

1806

1807

1808

1809

1810

1811

1812

1813

1814

1815

1816

1817

1818static void

1821{

1823 Size tuplen;

1824

1826

1827

1828

1829

1830

1831

1832

1833

1835

1836

1840

1842

1843

1844 state->bs_numtuples = 0;

1845

1849

1850

1851

1852

1853

1855 {

1856

1858

1859

1860

1861

1862

1863

1865 {

1867 Size ntuplen;

1868

1869

1870

1871

1872

1873

1875

1878 buffer->items, buffer->nitems, &ntuplen);

1879

1881 state->bs_numtuples++;

1882

1884

1885

1887 }

1888

1889

1890

1891

1892

1893

1894

1895

1897 {

1899 Size ntuplen;

1900

1902

1903

1904

1905

1906

1907

1909

1913

1915

1917

1918

1920 }

1921

1922

1923

1924

1925

1927 }

1928

1929

1931 {

1933 Size ntuplen;

1934

1936

1939 buffer->items, buffer->nitems, &ntuplen);

1940

1942 state->bs_numtuples++;

1943

1945

1946

1948 }

1949

1950

1952

1954}

1955

1956

1957

1958

1959

1960

1961

1962

1963

1964

1965

1966

1967

1968

1969

1970

1971

1972

1973

1974

1975

1976

1977

1978

1979

1980

1981

1982

1983

1984

1985

1986

1987

1988

1989

1990

1991

1992

1993

1994

1995

1996static void

2001{

2004 double reltuples;

2006

2007

2009 coordinate->isWorker = true;

2011 coordinate->sharedsort = sharedsort;

2012

2013

2014 state->work_mem = (sortmem / 2);

2015

2016

2018 state->work_mem,

2019 coordinate,

2021

2022

2024 state->work_mem,

2025 NULL,

2027

2028

2031

2034

2037

2038

2040

2041

2042

2043

2044

2045

2047

2048

2050

2051 state->bs_reltuples += reltuples;

2052

2053

2054

2055

2061

2062

2064

2066}

2067

2068

2069

2070

2071void

2073{

2074 char *sharedquery;

2084 int sortmem;

2085

2086

2087

2088

2089

2092

2093

2096

2097

2099

2100

2102

2103

2105 {

2108 }

2109 else

2110 {

2113 }

2114

2115

2118

2119

2124

2125

2126

2127

2128

2130 "Gin build temporary context",

2132

2133

2134

2135

2136

2138 "Gin build temporary context for user-defined function",

2140

2143

2144

2145

2148

2149

2151

2152

2153

2154

2155

2156

2158

2160 heapRel, indexRel, sortmem, false);

2161

2162

2167

2170}

2171

2172

2173

2174

2175typedef struct

2176{

2180

2181

2182

2183

2184

2185

2186

2187

2188

2189

2190

2191

2192

2193

2194

2195

2196

2197

2198

2204{

2206 char *ptr;

2207

2208 Size tuplen;

2209 int keylen;

2210

2213 int ncompressed;

2214 Size compresslen;

2215

2216

2217

2218

2219

2220

2221

2222

2223

2224

2225

2226

2227

2228

2230 keylen = 0;

2231 else if (typbyval)

2232 keylen = sizeof(Datum);

2233 else if (typlen > 0)

2234 keylen = typlen;

2235 else if (typlen == -1)

2237 else if (typlen == -2)

2239 else

2240 elog(ERROR, "unexpected typlen value (%d)", typlen);

2241

2242

2243 ncompressed = 0;

2244 compresslen = 0;

2246

2247

2248 while (ncompressed < nitems)

2249 {

2250 int cnt;

2252

2254 (nitems - ncompressed),

2255 UINT16_MAX,

2256 &cnt);

2257

2258 ncompressed += cnt;

2260

2262 }

2263

2264

2265

2266

2267

2268

2270

2271 *len = tuplen;

2272

2273

2274

2275

2276

2277

2278

2279

2280 tuple = palloc0(tuplen);

2281

2282 tuple->tuplen = tuplen;

2283 tuple->attrnum = attrnum;

2285 tuple->keylen = keylen;

2287

2288

2289 tuple->typlen = typlen;

2291

2292

2293

2294

2295

2297 {

2298 if (typbyval)

2299 {

2301 }

2302 else if (typlen > 0)

2303 {

2305 }

2306 else if (typlen == -1)

2307 {

2309 }

2310 else if (typlen == -2)

2311 {

2313 }

2314 }

2315

2316

2318

2319

2321 {

2323

2325

2327

2329

2332 }

2333

2334 return tuple;

2335}

2336

2337

2338

2339

2340

2341

2342

2343

2344

2345

2346

2347

2350{

2352

2354 return (Datum) 0;

2355

2356 if (a->typbyval)

2357 {

2358 memcpy(&key, a->data, a->keylen);

2359 return key;

2360 }

2361

2363}

2364

2365

2366

2367

2368

2371{

2372 int len;

2373 char *ptr;

2374 int ndecoded;

2376

2379

2381

2382 Assert(ndecoded == a->nitems);

2383

2385}

2386

2387

2388

2389

2390

2391

2392

2393

2394

2395

2396

2397

2398

2399

2400

2401int

2403{

2404 int r;

2406 keyb;

2407

2408 if (a->attrnum < b->attrnum)

2409 return -1;

2410

2411 if (a->attrnum > b->attrnum)

2412 return 1;

2413

2414 if (a->category < b->category)

2415 return -1;

2416

2417 if (a->category > b->category)

2418 return 1;

2419

2421 {

2424

2426 keyb, false,

2427 &ssup[a->attrnum - 1]);

2428

2429

2432 }

2433

2436}

void InitializeParallelDSM(ParallelContext *pcxt)

void WaitForParallelWorkersToFinish(ParallelContext *pcxt)

void LaunchParallelWorkers(ParallelContext *pcxt)

void DestroyParallelContext(ParallelContext *pcxt)

ParallelContext * CreateParallelContext(const char *library_name, const char *function_name, int nworkers)

void WaitForParallelWorkersToAttach(ParallelContext *pcxt)

void pgstat_progress_update_param(int index, int64 val)

void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)

void pgstat_report_activity(BackendState state, const char *cmd_str)

static Datum values[MAXATTR]

BlockNumber BufferGetBlockNumber(Buffer buffer)

Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)

void UnlockReleaseBuffer(Buffer buffer)

void MarkBufferDirty(Buffer buffer)

void LockBuffer(Buffer buffer, int mode)

#define RelationGetNumberOfBlocks(reln)

static Page BufferGetPage(Buffer buffer)

static Item PageGetItem(const PageData *page, const ItemIdData *itemId)

static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)

#define OidIsValid(objectId)

bool ConditionVariableCancelSleep(void)

void ConditionVariableInit(ConditionVariable *cv)

void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)

void ConditionVariableSignal(ConditionVariable *cv)

Datum datumCopy(Datum value, bool typByVal, int typLen)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

char * format_type_be(Oid type_oid)

#define PROGRESS_GIN_PHASE_PERFORMSORT_2

#define PROGRESS_GIN_PHASE_MERGE_1

#define PROGRESS_GIN_PHASE_PERFORMSORT_1

#define PROGRESS_GIN_PHASE_MERGE_2

#define PROGRESS_GIN_PHASE_INDEXBUILD_TABLESCAN

#define GinGetUseFastUpdate(relation)

static ItemPointer GinTupleGetFirst(GinTuple *tup)

#define GinIsPostingTree(itup)

#define SizeOfGinPostingList(plist)

#define GinGetPostingTree(itup)

signed char GinNullCategory

#define GinSetPostingTree(itup, blkno)

void freeGinBtreeStack(GinBtreeStack *stack)

void ginInsertValue(GinBtree btree, GinBtreeStack *stack, void *insertdata, GinStatsData *buildStats)

GinBtreeStack * ginFindLeafPage(GinBtree btree, bool searchMode, bool rootConflictCheck)

void ginBeginBAScan(BuildAccumulator *accum)

ItemPointerData * ginGetBAEntry(BuildAccumulator *accum, OffsetNumber *attnum, Datum *key, GinNullCategory *category, uint32 *n)

void ginInsertBAEntries(BuildAccumulator *accum, ItemPointer heapptr, OffsetNumber attnum, Datum *entries, GinNullCategory *categories, int32 nentries)

void ginInitBA(BuildAccumulator *accum)

BlockNumber createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, GinStatsData *buildStats, Buffer entrybuffer)

void ginInsertItemPointers(Relation index, BlockNumber rootBlkno, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats)

ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum, IndexTuple itup, int *nitems)

IndexTuple GinFormTuple(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, Pointer data, Size dataSize, int nipd, bool errorTooBig)

void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum, Datum key, GinNullCategory category, GinState *ginstate)

void ginHeapTupleFastCollect(GinState *ginstate, GinTupleCollector *collector, OffsetNumber attnum, Datum value, bool isNull, ItemPointer ht_ctid)

void ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector)

static void ginBuildCallbackParallel(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)

#define PARALLEL_KEY_BUFFER_USAGE

static void AssertCheckItemPointers(GinBuffer *buffer)

int _gin_compare_tuples(GinTuple *a, GinTuple *b, SortSupport ssup)

struct GinBuffer GinBuffer

struct GinLeader GinLeader

static IndexTuple addItemPointersToLeafTuple(GinState *ginstate, IndexTuple old, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats, Buffer buffer)

static bool GinBufferIsEmpty(GinBuffer *buffer)

#define PARALLEL_KEY_GIN_SHARED

IndexBuildResult * ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)

static GinBuffer * GinBufferInit(Relation index)

static IndexTuple buildFreshLeafTuple(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats, Buffer buffer)

static void GinBufferReset(GinBuffer *buffer)

static void ginHeapTupleBulkInsert(GinBuildState *buildstate, OffsetNumber attnum, Datum value, bool isNull, ItemPointer heapptr)

static void AssertCheckGinBuffer(GinBuffer *buffer)

static void _gin_parallel_scan_and_build(GinBuildState *state, GinBuildShared *ginshared, Sharedsort *sharedsort, Relation heap, Relation index, int sortmem, bool progress)

void ginEntryInsert(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats)

static void GinBufferTrim(GinBuffer *buffer)

static Size _gin_parallel_estimate_shared(Relation heap, Snapshot snapshot)

static void _gin_end_parallel(GinLeader *ginleader, GinBuildState *state)

static void _gin_begin_parallel(GinBuildState *buildstate, Relation heap, Relation index, bool isconcurrent, int request)

static void ginFlushBuildState(GinBuildState *buildstate, Relation index)

struct GinBuildShared GinBuildShared

static void _gin_process_worker_data(GinBuildState *state, Tuplesortstate *worker_sort, bool progress)

static bool GinBufferKeyEquals(GinBuffer *buffer, GinTuple *tup)

static double _gin_parallel_merge(GinBuildState *state)

static void ginHeapTupleInsert(GinState *ginstate, OffsetNumber attnum, Datum value, bool isNull, ItemPointer item)

static bool GinBufferCanAddKey(GinBuffer *buffer, GinTuple *tup)

void _gin_parallel_build_main(dsm_segment *seg, shm_toc *toc)

void ginbuildempty(Relation index)

bool gininsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)

static void _gin_leader_participate_as_worker(GinBuildState *buildstate, Relation heap, Relation index)

static GinTuple * _gin_build_tuple(OffsetNumber attrnum, unsigned char category, Datum key, int16 typlen, bool typbyval, ItemPointerData *items, uint32 nitems, Size *len)

static Datum _gin_parse_tuple_key(GinTuple *a)

#define PARALLEL_KEY_TUPLESORT

static bool GinBufferShouldTrim(GinBuffer *buffer, GinTuple *tup)

#define PARALLEL_KEY_QUERY_TEXT

static void GinBufferFree(GinBuffer *buffer)

static ItemPointer _gin_parse_tuple_items(GinTuple *a)

#define ParallelTableScanFromGinBuildShared(shared)

#define PARALLEL_KEY_WAL_USAGE

static void GinBufferStoreTuple(GinBuffer *buffer, GinTuple *tup)

static void ginBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)

static double _gin_parallel_heapscan(GinBuildState *state)

ItemPointer ginPostingListDecodeAllSegments(GinPostingList *segment, int len, int *ndecoded_out)

GinPostingList * ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize, int *nwritten)

ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na, ItemPointerData *b, uint32 nb, int *nmerged)

OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple)

Buffer GinNewBuffer(Relation index)

void GinInitBuffer(Buffer b, uint32 f)

Datum * ginExtractEntries(GinState *ginstate, OffsetNumber attnum, Datum value, bool isNull, int32 *nentries, GinNullCategory **categories)

Datum gintuple_get_key(GinState *ginstate, IndexTuple tuple, GinNullCategory *category)

void GinInitMetabuffer(Buffer b)

void initGinState(GinState *state, Relation index)

void ginUpdateStats(Relation index, const GinStatsData *stats, bool is_build)

Assert(PointerIsAligned(start, uint64))

static void dlist_init(dlist_head *head)

static void dlist_delete(dlist_node *node)

#define dlist_foreach_modify(iter, lhead)

static void dlist_push_tail(dlist_head *head, dlist_node *node)

#define dlist_container(type, membername, ptr)

IndexInfo * BuildIndexInfo(Relation index)

void index_close(Relation relation, LOCKMODE lockmode)

RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)

Relation index_open(Oid relationId, LOCKMODE lockmode)

void InstrAccumParallelQuery(BufferUsage *bufusage, WalUsage *walusage)

void InstrEndParallelQuery(BufferUsage *bufusage, WalUsage *walusage)

void InstrStartParallelQuery(void)

if(TABLE==NULL||TABLE_index==NULL)

int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)

static bool ItemPointerIsValid(const ItemPointerData *pointer)

IndexTupleData * IndexTuple

#define AccessExclusiveLock

#define ShareUpdateExclusiveLock

void MemoryContextReset(MemoryContext context)

void * repalloc(void *pointer, Size size)

void pfree(void *pointer)

void * palloc0(Size size)

MemoryContext CurrentMemoryContext

void MemoryContextDelete(MemoryContext context)

#define AllocSetContextCreate

#define ALLOCSET_DEFAULT_SIZES

#define START_CRIT_SECTION()

#define CHECK_FOR_INTERRUPTS()

#define END_CRIT_SECTION()

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

FormData_pg_attribute * Form_pg_attribute

const char * debug_query_string

static Datum PointerGetDatum(const void *X)

static Pointer DatumGetPointer(Datum X)

void CheckForSerializableConflictIn(Relation relation, ItemPointer tid, BlockNumber blkno)

#define PROGRESS_CREATEIDX_TUPLES_TOTAL

#define PROGRESS_SCAN_BLOCKS_DONE

#define PROGRESS_CREATEIDX_TUPLES_DONE

#define PROGRESS_CREATEIDX_SUBPHASE

#define PROGRESS_SCAN_BLOCKS_TOTAL

#define RelationGetRelid(relation)

#define RelationGetDescr(relation)

#define RelationGetRelationName(relation)

#define RelationNeedsWAL(relation)

#define IndexRelationGetNumberOfKeyAttributes(relation)

void * shm_toc_allocate(shm_toc *toc, Size nbytes)

void shm_toc_insert(shm_toc *toc, uint64 key, void *address)

void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)

#define shm_toc_estimate_chunk(e, sz)

#define shm_toc_estimate_keys(e, cnt)

Size add_size(Size s1, Size s2)

Size mul_size(Size s1, Size s2)

Snapshot GetTransactionSnapshot(void)

void UnregisterSnapshot(Snapshot snapshot)

Snapshot RegisterSnapshot(Snapshot snapshot)

#define IsMVCCSnapshot(snapshot)

void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)

static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)

#define SpinLockInit(lock)

#define SpinLockRelease(lock)

#define SpinLockAcquire(lock)

bool(* findItem)(GinBtree, GinBtreeStack *)

Tuplesortstate * bs_worker_sort

Tuplesortstate * bs_sortstate

int nparticipanttuplesorts

BufferUsage * bufferusage

GinBuildShared * ginshared

char data[FLEXIBLE_ARRAY_MEMBER]

shm_toc_estimator estimator

void table_close(Relation relation, LOCKMODE lockmode)

Relation table_open(Oid relationId, LOCKMODE lockmode)

TableScanDesc table_beginscan_parallel(Relation relation, ParallelTableScanDesc pscan)

Size table_parallelscan_estimate(Relation rel, Snapshot snapshot)

void table_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan, Snapshot snapshot)

static double table_index_build_scan(Relation table_rel, Relation index_rel, struct IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)

static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)

void tuplesort_performsort(Tuplesortstate *state)

void tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)

Size tuplesort_estimate_shared(int nWorkers)

void tuplesort_end(Tuplesortstate *state)

void tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)

struct SortCoordinateData * SortCoordinate

Tuplesortstate * tuplesort_begin_index_gin(Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)

GinTuple * tuplesort_getgintuple(Tuplesortstate *state, Size *len, bool forward)

void tuplesort_putgintuple(Tuplesortstate *state, GinTuple *tuple, Size size)

TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)

#define TYPECACHE_CMP_PROC_FINFO

void ExitParallelMode(void)

void EnterParallelMode(void)

void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std)

XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)