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 = palloc0_object(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

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

557 }

558 else

559 {

560

563 }

564 }

565 else

566 {

567

569 }

570

572

575

576 if (is_build)

578 else

579 {

581 {

583 deloffs[1];

584

586 {

587 deloffs[0] = oldoffnum;

588 ndeloffs = 1;

589 }

590

592 deloffs, ndeloffs, itup, ntup,

593 leftchildbuf);

594 }

595 else

597 }

599

600 if (newblkno)

601 *newblkno = blkno;

602 }

603

604

605

606

607

608

609

610

611

612

613

614

615

616

618 {

620

623

625 }

626

628

629 return is_split;

630}

631

632

633

634

635

636

637void

640{

646 bool xlocked = false;

647

649 state.freespace = freespace;

651 state.heapRel = heapRel;

652 state.is_build = is_build;

653

654

656 firststack.lsn = 0;

658 firststack.parent = NULL;

660 state.stack = stack = &firststack;

661

662

663

664

665

666

667

668 for (;;)

669 {

670

671

672

673

674

675

677 {

678 if (xlocked)

680 xlocked = false;

683 }

684

687

688

689

690

691

692 if (!xlocked)

693 {

696 }

697

699 stack->lsn = xlocked ?

702

703

704

705

706

707

709 {

710 if (!xlocked)

711 {

714 xlocked = true;

715

717 continue;

718 }

720

722 xlocked = false;

724 continue;

725 }

726

730 {

731

732

733

734

735

736

738 xlocked = false;

740 continue;

741 }

742

744 {

745

746

747

748

753

758

759

760

761

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

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

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

768

769

770

771

772

774 if (newtup)

775 {

776

777

778

779

780 if (!xlocked)

781 {

784 xlocked = true;

786

788 {

789

790 continue;

791 }

792 }

793

794

795

796

797

798

799

800

801

802

803

805 downlinkoffnum))

806 {

807

808

809

810

811

812

814 {

816 xlocked = false;

818 }

819 continue;

820 }

821 }

823 xlocked = false;

824

825

827 item->blkno = childblkno;

828 item->parent = stack;

830 state.stack = stack = item;

831 }

832 else

833 {

834

835

836

837

838

839

840

841

842

843

844 if (!xlocked)

845 {

848 xlocked = true;

851

853 {

854

855

856

857

859 {

860

861

862

863

865 xlocked = false;

866 continue;

867 }

868

869

870

871

872

873 }

877 {

878

879

880

881

883 xlocked = false;

885 continue;

886 }

887 }

888

889

890

894

895

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

898 break;

899 }

900 }

901}

902

903

904

905

906

907

908

909

910

911

914{

918 maxoff;

923 *ptr;

925

929

931 while (fifo != NIL)

932 {

933

936

941

943 {

944

945

946

947

949 break;

950 }

951

952

954

956

957

958

959

960

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

963

966 {

967

968

969

970

971

972

973

974

975

976

977

982

983 fifo = lcons(ptr, fifo);

984 }

985

987

989 {

993 if (blkno == child)

994 {

995

997 *downlinkoffnum = i;

998 return top;

999 }

1000 else

1001 {

1002

1004 ptr->blkno = blkno;

1007

1008 fifo = lappend(fifo, ptr);

1009 }

1010 }

1011

1013 }

1014

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

1017 return NULL;

1018}

1019

1020

1021

1022

1023

1024

1025static void

1027{

1033

1037

1038

1040 {

1044 return;

1045 }

1046

1047

1048

1049

1050

1051

1052

1053

1054

1055

1056

1057

1058

1059

1060

1063

1064

1065

1066

1067

1068

1069 while (true)

1070 {

1072

1075 {

1079 {

1080

1082 return;

1083 }

1084 }

1085

1090 {

1091

1092

1093

1094

1095 break;

1096 }

1101 }

1102

1103

1104

1105

1106

1107

1108 ptr = child->parent->parent;

1109 while (ptr)

1110 {

1113 }

1114

1115

1117

1118

1119

1120 while (ptr)

1121 {

1125 }

1126

1127

1128 child->parent = parent;

1129

1130

1133}

1134

1135

1136

1137

1141{

1146

1149 {

1152

1153 if (downlink == NULL)

1155 else

1156 {

1158

1160 giststate);

1161 if (newdownlink)

1162 downlink = newdownlink;

1163 }

1164 }

1165

1166

1167

1168

1169

1170

1171

1172

1173

1174

1175

1176 if (!downlink)

1177 {

1179

1186 }

1187

1190

1191 return downlink;

1192}

1193

1194

1195

1196

1197

1198static void

1200{

1205

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

1209

1212

1214

1215

1216

1217

1218

1219 for (;;)

1220 {

1223

1225

1226

1228

1231

1232 splitinfo = lappend(splitinfo, si);

1233

1235 {

1236

1239 }

1240 else

1241 break;

1242 }

1243

1244

1246}

1247

1248

1249

1250

1251

1252

1253

1254

1255

1256

1257

1258static bool

1261{

1264}

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

1292static bool

1297 bool unlockbuf, bool unlockleftchild)

1298{

1299 List *splitinfo;

1300 bool is_split;

1301

1302

1303

1304

1305

1307

1308

1311 tuples, ntup,

1312 oldoffnum, NULL,

1314 &splitinfo,

1315 true,

1317 state->is_build);

1318

1319

1320

1321

1322

1323

1328

1329

1330

1331

1332

1333

1334

1335 if (splitinfo)

1337 else if (unlockbuf)

1339

1340 return is_split;

1341}

1342

1343

1344

1345

1346

1347

1348

1349

1350

1351

1352static void

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

1355{

1359

1360

1362

1363

1364

1365

1366

1367

1368

1369

1371

1372

1373

1374

1375

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

1377 {

1380

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

1386 {

1387

1388

1389

1390

1392 }

1393

1394 }

1395

1398

1399

1400

1401

1402

1403

1405 tuples[1] = right->downlink;

1408 tuples, 2,

1410 left->buf, right->buf,

1411 true,

1412 unlockbuf

1413

1414 );

1415

1416

1417

1418

1419

1420

1422

1424

1425

1426

1427

1428

1429

1430

1431

1432

1433

1434

1435

1436

1437

1438

1439

1441}

1442

1443

1444

1445

1446

1447

1451 IndexTuple *itup,

1452 int len,

1454{

1456 *rvectup;

1458 int i;

1460

1461

1463

1464

1466

1467

1468

1469

1470

1471 if (len == 1)

1473 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

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

1477

1483

1484

1487

1490

1493

1494

1496 {

1498 }

1499 else

1500 {

1505 }

1506

1508 {

1510 *subres;

1511

1513

1514

1515 while (resptr->next)

1516 resptr = resptr->next;

1517

1518 resptr->next = res;

1519 res = subres;

1520 }

1521 else

1522 {

1527 }

1528

1529 return res;

1530}

1531

1532

1533

1534

1537{

1541 int i;

1542

1543

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

1547

1548

1550 "GiST scan context",

1553

1554

1556

1557 giststate->scanCxt = scanCxt;

1558 giststate->tempCxt = scanCxt;

1560

1561

1562

1563

1564

1565

1566

1567

1568

1569

1570

1573

1575 {

1578 scanCxt);

1581 scanCxt);

1582

1583

1587 scanCxt);

1588 else

1590

1591

1595 scanCxt);

1596 else

1598

1601 scanCxt);

1604 scanCxt);

1607 scanCxt);

1608

1609

1613 scanCxt);

1614 else

1616

1617

1621 scanCxt);

1622 else

1624

1625

1626

1627

1628

1629

1630

1631

1632

1633

1634

1635

1638 else

1640 }

1641

1642

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

1644 {

1655 }

1656

1658

1659 return giststate;

1660}

1661

1662void

1664{

1665

1667}

1668

1669

1670

1671

1672

1673static void

1675{

1677 int ndeletable = 0;

1679 maxoff;

1680

1682

1683

1684

1685

1686

1689 offnum <= maxoff;

1691 {

1693

1695 deletable[ndeletable++] = offnum;

1696 }

1697

1698 if (ndeletable > 0)

1699 {

1701

1703 snapshotConflictHorizon =

1705 deletable, ndeletable);

1706

1708

1710

1711

1712

1713

1714

1715

1716

1717

1719

1721

1722

1724 {

1726

1728 deletable, ndeletable,

1729 snapshotConflictHorizon,

1730 heapRel);

1731

1733 }

1734 else

1736

1738 }

1739

1740

1741

1742

1743

1744

1745

1746}

#define InvalidBlockNumber

static Datum values[MAXATTR]

BlockNumber BufferGetBlockNumber(Buffer buffer)

void LockBuffer(Buffer buffer, BufferLockMode mode)

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)

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, const void *newtup, Size newsize)

void PageIndexTupleDelete(Page page, OffsetNumber offnum)

Page PageGetTempPageCopySpecial(const PageData *page)

static void * 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,...)

#define palloc_object(type)

#define palloc_array(type, count)

#define palloc0_object(type)

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(const ItemPointerData *pointer1, const ItemPointerData *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)

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)

static char buf[DEFAULT_XLOG_SEG_SIZE]

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

void CheckForSerializableConflictIn(Relation relation, const ItemPointerData *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 XLogRecPtrIsValid(r)

XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)

void XLogEnsureRecordSpace(int max_block_id, int ndatas)