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