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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

25#include "utils/fmgrprotos.h"

29

30

38 bool unlockbuf, bool unlockleftchild);

40 GISTSTATE *giststate, List *splitinfo, bool unlockbuf);

43

44

45#define ROTATEDIST(d) do { \

46 SplitPageLayout *tmp = (SplitPageLayout *) palloc0(sizeof(SplitPageLayout)); \

47 tmp->block.blkno = InvalidBlockNumber; \

48 tmp->buffer = InvalidBuffer; \

49 tmp->next = (d); \

50 (d)=tmp; \

51} while(0)

52

53

54

55

56

57

60{

62

88

115

117}

118

119

120

121

122

123

124

125

126

129{

131 "GiST temporary context",

133}

134

135

136

137

138void

140{

142

143

146

147

153

154

156}

157

158

159

160

161

162

163

164bool

168 bool indexUnchanged,

170{

174

175

176 if (giststate == NULL)

177 {

183 }

184

186

188 itup->t_tid = *ht_ctid;

189

190 gistdoinsert(r, itup, 0, giststate, heapRel, false);

191

192

195

196 return false;

197}

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229bool

235 List **splitinfo,

236 bool markfollowright,

238 bool is_build)

239{

242 bool is_leaf = (GistPageIsLeaf(page)) ? true : false;

244 bool is_split;

245

246

247

248

249

250

251

252

253

254

256 elog(ERROR, "concurrent GiST page split was incomplete");

257

258

260

261 *splitinfo = NIL;

262

263

264

265

266

267

268

269

270

271

272

273 is_split = gistnospace(page, itup, ntup, oldoffnum, freespace);

274

275

276

277

278

280 {

282 is_split = gistnospace(page, itup, ntup, oldoffnum, freespace);

283 }

284

285 if (is_split)

286 {

287

289 int tlen;

291 *ptr;

295 bool is_rootsplit;

296 int npage;

297

299

300

301

302

303

306 {

307

309

310 tlen--;

311 if (pos != tlen)

312 memmove(itvec + pos, itvec + pos + 1, sizeof(IndexTuple) * (tlen - pos));

313 }

315 dist = gistSplit(rel, page, itvec, tlen, giststate);

316

317

318

319

320 npage = 0;

321 for (ptr = dist; ptr; ptr = ptr->next)

322 npage++;

323

324 if (is_rootsplit)

325 npage++;

327 elog(ERROR, "GiST page split into too many halves (%d, maximum %d)",

329

330

331

332

333

334

335

336

337

338

339 ptr = dist;

340 if (!is_rootsplit)

341 {

342

345

346 dist->buffer = buffer;

349

350

352

353 ptr = ptr->next;

354 }

355 for (; ptr; ptr = ptr->next)

356 {

357

365 }

366

367

368

369

370

371 for (ptr = dist; ptr; ptr = ptr->next)

372 {

375 }

376

377

378

379

380

381

382 if (is_rootsplit)

383 {

385 int ndownlinks = 0;

386 int i;

387

388 rootpg.buffer = buffer;

391

392

393 for (ptr = dist; ptr; ptr = ptr->next)

394 ndownlinks++;

396 for (i = 0, ptr = dist; ptr; ptr = ptr->next)

397 downlinks[i++] = ptr->itup;

398

400 rootpg.block.num = ndownlinks;

403 rootpg.itup = NULL;

404

405 rootpg.next = dist;

406 dist = &rootpg;

407 }

408 else

409 {

410

411 for (ptr = dist; ptr; ptr = ptr->next)

412 {

414

415 si->buf = ptr->buffer;

417 *splitinfo = lappend(*splitinfo, si);

418 }

419 }

420

421

422

423

424

425 for (ptr = dist; ptr; ptr = ptr->next)

426 {

427 char *data = (char *) (ptr->list);

428

429 for (int i = 0; i < ptr->block.num; i++)

430 {

432

435

436

437

438

439

441 *newblkno = ptr->block.blkno;

442

444 }

445

446

449 ptr->next->block.blkno;

450 else

452

453

454

455

456

457

458

459

460

461 if (ptr->next && !is_rootsplit && markfollowright)

463 else

465

466

467

468

469

470

472 }

473

474

475

476

477

478

481

483

484

485

486

487

488 for (ptr = dist; ptr; ptr = ptr->next)

492

493

494

495

496

499

500

501

502

503

504

505

506

507

508

509

510 if (is_build)

512 else

513 {

516 dist, oldrlink, oldnsn, leftchildbuf,

517 markfollowright);

518 else

520 }

521

522 for (ptr = dist; ptr; ptr = ptr->next)

524

525

526

527

528

529

530

531

532 if (is_rootsplit)

533 {

534 for (ptr = dist->next; ptr; ptr = ptr->next)

536 }

537 }

538 else

539 {

540

541

542

544

545

546

547

548

550 {

551 if (ntup == 1)

552 {

553

556 elog(ERROR, "failed to add item to index page in \"%s\"",

558 }

559 else

560 {

561

564 }

565 }

566 else

567 {

568

570 }

571

573

576

577 if (is_build)

579 else

580 {

582 {

584 deloffs[1];

585

587 {

588 deloffs[0] = oldoffnum;

589 ndeloffs = 1;

590 }

591

593 deloffs, ndeloffs, itup, ntup,

594 leftchildbuf);

595 }

596 else

598 }

600

601 if (newblkno)

602 *newblkno = blkno;

603 }

604

605

606

607

608

609

610

611

612

613

614

615

616

617

619 {

621

624

626 }

627

629

630 return is_split;

631}

632

633

634

635

636

637

638void

641{

647 bool xlocked = false;

648

650 state.freespace = freespace;

652 state.heapRel = heapRel;

653 state.is_build = is_build;

654

655

657 firststack.lsn = 0;

659 firststack.parent = NULL;

661 state.stack = stack = &firststack;

662

663

664

665

666

667

668

669 for (;;)

670 {

671

672

673

674

675

676

678 {

679 if (xlocked)

681 xlocked = false;

684 }

685

688

689

690

691

692

693 if (!xlocked)

694 {

697 }

698

700 stack->lsn = xlocked ?

703

704

705

706

707

708

710 {

711 if (!xlocked)

712 {

715 xlocked = true;

716

718 continue;

719 }

721

723 xlocked = false;

725 continue;

726 }

727

731 {

732

733

734

735

736

737

739 xlocked = false;

741 continue;

742 }

743

745 {

746

747

748

749

754

759

760

761

762

765 (errmsg("index \"%s\" contains an inner tuple marked as invalid",

767 errdetail("This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1."),

768 errhint("Please REINDEX it.")));

769

770

771

772

773

775 if (newtup)

776 {

777

778

779

780

781 if (!xlocked)

782 {

785 xlocked = true;

787

789 {

790

791 continue;

792 }

793 }

794

795

796

797

798

799

800

801

802

803

804

806 downlinkoffnum))

807 {

808

809

810

811

812

813

815 {

817 xlocked = false;

819 }

820 continue;

821 }

822 }

824 xlocked = false;

825

826

828 item->blkno = childblkno;

829 item->parent = stack;

831 state.stack = stack = item;

832 }

833 else

834 {

835

836

837

838

839

840

841

842

843

844

845 if (!xlocked)

846 {

849 xlocked = true;

852

854 {

855

856

857

858

860 {

861

862

863

864

866 xlocked = false;

867 continue;

868 }

869

870

871

872

873

874 }

878 {

879

880

881

882

884 xlocked = false;

886 continue;

887 }

888 }

889

890

891

895

896

897 for (; stack; stack = stack->parent)

899 break;

900 }

901 }

902}

903

904

905

906

907

908

909

910

911

912

915{

919 maxoff;

924 *ptr;

926

930

932 while (fifo != NIL)

933 {

934

937

942

944 {

945

946

947

948

950 break;

951 }

952

953

955

957

958

959

960

961

963 elog(ERROR, "concurrent GiST page split was incomplete");

964

967 {

968

969

970

971

972

973

974

975

976

977

978

983

984 fifo = lcons(ptr, fifo);

985 }

986

988

990 {

994 if (blkno == child)

995 {

996

998 *downlinkoffnum = i;

999 return top;

1000 }

1001 else

1002 {

1003

1005 ptr->blkno = blkno;

1008

1009 fifo = lappend(fifo, ptr);

1010 }

1011 }

1012

1014 }

1015

1016 elog(ERROR, "failed to re-find parent of a page in index \"%s\", block %u",

1018 return NULL;

1019}

1020

1021

1022

1023

1024

1025

1026static void

1028{

1034

1038

1039

1041 {

1045 return;

1046 }

1047

1048

1049

1050

1051

1052

1053

1054

1055

1056

1057

1058

1059

1060

1061

1064

1065

1066

1067

1068

1069

1070 while (true)

1071 {

1073

1076 {

1080 {

1081

1083 return;

1084 }

1085 }

1086

1091 {

1092

1093

1094

1095

1096 break;

1097 }

1102 }

1103

1104

1105

1106

1107

1108

1109 ptr = child->parent->parent;

1110 while (ptr)

1111 {

1114 }

1115

1116

1118

1119

1120

1121 while (ptr)

1122 {

1126 }

1127

1128

1129 child->parent = parent;

1130

1131

1134}

1135

1136

1137

1138

1142{

1147

1150 {

1153

1154 if (downlink == NULL)

1156 else

1157 {

1159

1161 giststate);

1162 if (newdownlink)

1163 downlink = newdownlink;

1164 }

1165 }

1166

1167

1168

1169

1170

1171

1172

1173

1174

1175

1176

1177 if (!downlink)

1178 {

1180

1187 }

1188

1191

1192 return downlink;

1193}

1194

1195

1196

1197

1198

1199static void

1201{

1206

1208 (errmsg("fixing incomplete split in index \"%s\", block %u",

1210

1213

1215

1216

1217

1218

1219

1220 for (;;)

1221 {

1224

1226

1227

1229

1232

1233 splitinfo = lappend(splitinfo, si);

1234

1236 {

1237

1240 }

1241 else

1242 break;

1243 }

1244

1245

1247}

1248

1249

1250

1251

1252

1253

1254

1255

1256

1257

1258

1259static bool

1262{

1265}

1266

1267

1268

1269

1270

1271

1272

1273

1274

1275

1276

1277

1278

1279

1280

1281

1282

1283

1284

1285

1286

1287

1288

1289

1290

1291

1292

1293static bool

1298 bool unlockbuf, bool unlockleftchild)

1299{

1300 List *splitinfo;

1301 bool is_split;

1302

1303

1304

1305

1306

1308

1309

1312 tuples, ntup,

1313 oldoffnum, NULL,

1315 &splitinfo,

1316 true,

1318 state->is_build);

1319

1320

1321

1322

1323

1324

1329

1330

1331

1332

1333

1334

1335

1336 if (splitinfo)

1338 else if (unlockbuf)

1340

1341 return is_split;

1342}

1343

1344

1345

1346

1347

1348

1349

1350

1351

1352

1353static void

1355 GISTSTATE *giststate, List *splitinfo, bool unlockbuf)

1356{

1360

1361

1363

1364

1365

1366

1367

1368

1369

1370

1372

1373

1374

1375

1376

1377 for (int pos = list_length(splitinfo) - 1; pos > 1; pos--)

1378 {

1381

1386 left->buf, right->buf, false, false))

1387 {

1388

1389

1390

1391

1393 }

1394

1395 }

1396

1399

1400

1401

1402

1403

1404

1406 tuples[1] = right->downlink;

1409 tuples, 2,

1411 left->buf, right->buf,

1412 true,

1413 unlockbuf

1414

1415 );

1416

1417

1418

1419

1420

1421

1423

1425

1426

1427

1428

1429

1430

1431

1432

1433

1434

1435

1436

1437

1438

1439

1440

1442}

1443

1444

1445

1446

1447

1448

1452 IndexTuple *itup,

1453 int len,

1455{

1457 *rvectup;

1459 int i;

1461

1462

1464

1465

1467

1468

1469

1470

1471

1472 if (len == 1)

1474 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

1475 errmsg("index row size %zu exceeds maximum %zu for index \"%s\"",

1478

1484

1485

1488

1491

1494

1495

1497 {

1499 }

1500 else

1501 {

1506 }

1507

1509 {

1511 *subres;

1512

1514

1515

1516 while (resptr->next)

1517 resptr = resptr->next;

1518

1519 resptr->next = res;

1520 res = subres;

1521 }

1522 else

1523 {

1528 }

1529

1530 return res;

1531}

1532

1533

1534

1535

1538{

1542 int i;

1543

1544

1546 elog(ERROR, "numberOfAttributes %d > %d",

1548

1549

1551 "GiST scan context",

1554

1555

1557

1558 giststate->scanCxt = scanCxt;

1559 giststate->tempCxt = scanCxt;

1561

1562

1563

1564

1565

1566

1567

1568

1569

1570

1571

1574

1576 {

1579 scanCxt);

1582 scanCxt);

1583

1584

1588 scanCxt);

1589 else

1591

1592

1596 scanCxt);

1597 else

1599

1602 scanCxt);

1605 scanCxt);

1608 scanCxt);

1609

1610

1614 scanCxt);

1615 else

1617

1618

1622 scanCxt);

1623 else

1625

1626

1627

1628

1629

1630

1631

1632

1633

1634

1635

1636

1639 else

1641 }

1642

1643

1644 for (; i < index->rd_att->natts; i++)

1645 {

1656 }

1657

1659

1660 return giststate;

1661}

1662

1663void

1665{

1666

1668}

1669

1670

1671

1672

1673

1674static void

1676{

1678 int ndeletable = 0;

1680 maxoff;

1681

1683

1684

1685

1686

1687

1690 offnum <= maxoff;

1692 {

1694

1696 deletable[ndeletable++] = offnum;

1697 }

1698

1699 if (ndeletable > 0)

1700 {

1702

1704 snapshotConflictHorizon =

1706 deletable, ndeletable);

1707

1709

1711

1712

1713

1714

1715

1716

1717

1718

1720

1722

1723

1725 {

1727

1729 deletable, ndeletable,

1730 snapshotConflictHorizon,

1731 heapRel);

1732

1734 }

1735 else

1737

1739 }

1740

1741

1742

1743

1744

1745

1746

1747}

#define InvalidBlockNumber

static Datum values[MAXATTR]

BlockNumber BufferGetBlockNumber(Buffer buffer)

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

void ReleaseBuffer(Buffer buffer)

XLogRecPtr BufferGetLSNAtomic(Buffer buffer)

void UnlockReleaseBuffer(Buffer buffer)

void MarkBufferDirty(Buffer buffer)

void LockBuffer(Buffer buffer, int mode)

Buffer ReadBuffer(Relation reln, BlockNumber blockNum)

static Page BufferGetPage(Buffer buffer)

static bool BufferIsValid(Buffer bufnum)

void PageRestoreTempPage(Page tempPage, Page oldPage)

void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)

bool PageIndexTupleOverwrite(Page page, OffsetNumber offnum, Item newtup, Size newsize)

void PageIndexTupleDelete(Page page, OffsetNumber offnum)

Page PageGetTempPageCopySpecial(const PageData *page)

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

static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)

static void PageSetLSN(Page page, XLogRecPtr lsn)

static XLogRecPtr PageGetLSN(const PageData *page)

#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)

static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)

#define OidIsValid(objectId)

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

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

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)

#define PG_RETURN_POINTER(x)

TransactionId index_compute_xid_horizon_for_tuples(Relation irel, Relation hrel, Buffer ibuf, OffsetNumber *itemnos, int nitems)

SplitPageLayout * gistSplit(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate)

GISTSTATE * initGISTstate(Relation index)

static GISTInsertStack * gistFindPath(Relation r, BlockNumber child, OffsetNumber *downlinkoffnum)

void gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate, Relation heapRel, bool is_build)

static void gistfixsplit(GISTInsertState *state, GISTSTATE *giststate)

static void gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel)

bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, Buffer buffer, IndexTuple *itup, int ntup, OffsetNumber oldoffnum, BlockNumber *newblkno, Buffer leftchildbuf, List **splitinfo, bool markfollowright, Relation heapRel, bool is_build)

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

void gistbuildempty(Relation index)

static bool gistinserttuples(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, IndexTuple *tuples, int ntup, OffsetNumber oldoffnum, Buffer leftchild, Buffer rightchild, bool unlockbuf, bool unlockleftchild)

MemoryContext createTempGistContext(void)

void freeGISTstate(GISTSTATE *giststate)

static bool gistinserttuple(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, IndexTuple tuple, OffsetNumber oldoffnum)

static void gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, List *splitinfo, bool unlockbuf)

static void gistFindCorrectParent(Relation r, GISTInsertStack *child, bool is_build)

static IndexTuple gistformdownlink(Relation rel, Buffer buf, GISTSTATE *giststate, GISTInsertStack *stack, bool is_build)

Datum gisthandler(PG_FUNCTION_ARGS)

#define GIST_DECOMPRESS_PROC

#define GIST_PICKSPLIT_PROC

#define GistMarkFollowRight(page)

#define GIST_CONSISTENT_PROC

#define GistClearFollowRight(page)

#define GIST_COMPRESS_PROC

#define GistClearPageHasGarbage(page)

#define GIST_PENALTY_PROC

#define GistPageIsLeaf(page)

#define GistFollowRight(page)

#define GIST_OPTIONS_PROC

#define GIST_DISTANCE_PROC

#define GistPageSetNSN(page, val)

#define GistPageIsDeleted(page)

#define GistPageGetOpaque(page)

#define GistPageHasGarbage(page)

#define GistPageGetNSN(page)

#define GIST_MAX_SPLIT_PAGES

#define GistTupleSetValid(itup)

#define GistTupleIsInvalid(itup)

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

bool gistgettuple(IndexScanDesc scan, ScanDirection dir)

int64 gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)

bool gistcanreturn(Relation index, int attno)

IndexScanDesc gistbeginscan(Relation r, int nkeys, int norderbys)

void gistendscan(IndexScanDesc scan)

void gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, ScanKey orderbys, int norderbys)

void gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate, GistSplitVector *v, int attno)

bytea * gistoptions(Datum reloptions, bool validate)

Buffer gistNewBuffer(Relation r, Relation heaprel)

bool gistproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull)

bool gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace)

void gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off)

IndexTuple gistFormTuple(GISTSTATE *giststate, Relation r, const Datum *attdata, const bool *isnull, bool isleaf)

IndexTuple * gistextractpage(Page page, int *len)

bool gistfitpage(IndexTuple *itvec, int len)

IndexTuple gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *giststate)

OffsetNumber gistchoose(Relation r, Page p, IndexTuple it, GISTSTATE *giststate)

XLogRecPtr gistGetFakeLSN(Relation rel)

IndexTuple * gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)

void GISTInitBuffer(Buffer b, uint32 f)

StrategyNumber gisttranslatecmptype(CompareType cmptype, Oid opfamily)

void gistcheckpage(Relation rel, Buffer buf)

IndexTupleData * gistfillitupvec(IndexTuple *vec, int veclen, int *memlen)

IndexBulkDeleteResult * gistvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)

IndexBulkDeleteResult * gistbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)

void gistadjustmembers(Oid opfamilyoid, Oid opclassoid, List *operators, List *functions)

bool gistvalidate(Oid opclassoid)

XLogRecPtr gistXLogSplit(bool page_is_leaf, SplitPageLayout *dist, BlockNumber origrlink, GistNSN orignsn, Buffer leftchildbuf, bool markfollowright)

XLogRecPtr gistXLogDelete(Buffer buffer, OffsetNumber *todelete, int ntodelete, TransactionId snapshotConflictHorizon, Relation heaprel)

XLogRecPtr gistXLogUpdate(Buffer buffer, OffsetNumber *todelete, int ntodelete, IndexTuple *itup, int ituplen, Buffer leftchildbuf)

Assert(PointerIsAligned(start, uint64))

FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)

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

IndexTuple CopyIndexTuple(IndexTuple source)

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

#define ItemIdIsDead(itemId)

bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)

static void ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber)

static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)

IndexTupleData * IndexTuple

static Size IndexTupleSize(const IndexTupleData *itup)

#define MaxIndexTuplesPerPage

List * lappend(List *list, void *datum)

List * list_delete_first(List *list)

List * lcons(void *datum, List *list)

void MemoryContextReset(MemoryContext context)

void * palloc0(Size size)

MemoryContext CurrentMemoryContext

void MemoryContextDelete(MemoryContext context)

#define AllocSetContextCreate

#define ALLOCSET_DEFAULT_SIZES

#define START_CRIT_SECTION()

#define END_CRIT_SECTION()

#define InvalidOffsetNumber

#define OffsetNumberIsValid(offsetNumber)

#define OffsetNumberNext(offsetNumber)

#define FirstOffsetNumber

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

static int list_length(const List *l)

static void * list_nth(const List *list, int n)

void PredicateLockPageSplit(Relation relation, BlockNumber oldblkno, BlockNumber newblkno)

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

#define RelationGetRelationName(relation)

#define RelationNeedsWAL(relation)

#define IndexRelationGetNumberOfKeyAttributes(relation)

void gistcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)

void check_stack_depth(void)

OffsetNumber downlinkoffnum

struct GISTInsertStack * parent

FmgrInfo fetchFn[INDEX_MAX_KEYS]

FmgrInfo penaltyFn[INDEX_MAX_KEYS]

Oid supportCollation[INDEX_MAX_KEYS]

FmgrInfo distanceFn[INDEX_MAX_KEYS]

FmgrInfo consistentFn[INDEX_MAX_KEYS]

FmgrInfo decompressFn[INDEX_MAX_KEYS]

FmgrInfo compressFn[INDEX_MAX_KEYS]

FmgrInfo equalFn[INDEX_MAX_KEYS]

FmgrInfo unionFn[INDEX_MAX_KEYS]

FmgrInfo picksplitFn[INDEX_MAX_KEYS]

GIST_SPLITVEC splitVector

Datum spl_lattr[INDEX_MAX_KEYS]

bool spl_lisnull[INDEX_MAX_KEYS]

Datum spl_rattr[INDEX_MAX_KEYS]

bool spl_risnull[INDEX_MAX_KEYS]

ambuildphasename_function ambuildphasename

ambuildempty_function ambuildempty

amvacuumcleanup_function amvacuumcleanup

amoptions_function amoptions

amestimateparallelscan_function amestimateparallelscan

amrestrpos_function amrestrpos

aminsert_function aminsert

amendscan_function amendscan

amtranslate_strategy_function amtranslatestrategy

amparallelrescan_function amparallelrescan

bool amconsistentordering

amtranslate_cmptype_function amtranslatecmptype

amcostestimate_function amcostestimate

amadjustmembers_function amadjustmembers

amgettuple_function amgettuple

amcanreturn_function amcanreturn

amgetbitmap_function amgetbitmap

amproperty_function amproperty

ambulkdelete_function ambulkdelete

amvalidate_function amvalidate

ammarkpos_function ammarkpos

bool amusemaintenanceworkmem

ambeginscan_function ambeginscan

amrescan_function amrescan

aminitparallelscan_function aminitparallelscan

uint8 amparallelvacuumoptions

aminsertcleanup_function aminsertcleanup

amgettreeheight_function amgettreeheight

bool amconsistentequality

struct SplitPageLayout * next

#define InvalidTransactionId

TupleDesc CreateTupleDescTruncatedCopy(TupleDesc tupdesc, int natts)

#define VACUUM_OPTION_PARALLEL_BULKDEL

#define VACUUM_OPTION_PARALLEL_COND_CLEANUP

#define XLogStandbyInfoActive()

#define XLogRecPtrIsInvalid(r)

XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)

void XLogEnsureRecordSpace(int max_block_id, int ndatas)