PostgreSQL Source Code: src/backend/access/index/indexam.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
45
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75#define RELATION_CHECKS \
76do { \
77 Assert(RelationIsValid(indexRelation)); \
78 Assert(PointerIsValid(indexRelation->rd_indam)); \
79 if (unlikely(ReindexIsProcessingIndex(RelationGetRelid(indexRelation)))) \
80 ereport(ERROR, \
81 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
82 errmsg("cannot access index \"%s\" while it is being reindexed", \
83 RelationGetRelationName(indexRelation)))); \
84} while(0)
85
86#define SCAN_CHECKS \
87( \
88 AssertMacro(IndexScanIsValid(scan)), \
89 AssertMacro(RelationIsValid(scan->indexRelation)), \
90 AssertMacro(PointerIsValid(scan->indexRelation->rd_indam)) \
92
93#define CHECK_REL_PROCEDURE(pname) \
94do { \
95 if (indexRelation->rd_indam->pname == NULL) \
96 elog(ERROR, "function \"%s\" is not defined for index \"%s\"", \
97 CppAsString(pname), RelationGetRelationName(indexRelation)); \
98} while(0)
99
100#define CHECK_SCAN_PROCEDURE(pname) \
101do { \
102 if (scan->indexRelation->rd_indam->pname == NULL) \
103 elog(ERROR, "function \"%s\" is not defined for index \"%s\"", \
104 CppAsString(pname), RelationGetRelationName(scan->indexRelation)); \
105} while(0)
106
108 int nkeys, int norderbys, Snapshot snapshot,
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
134{
136
138
140
141 return r;
142}
143
144
145
146
147
148
149
150
153{
155
157
158
159 if (!r)
160 return NULL;
161
163
164 return r;
165}
166
167
168
169
170
171
172
173
174
175
176void
178{
180
182
183
185
186 if (lockmode != NoLock)
188}
189
190
191
192
193
194
195
196static inline void
198{
199 if (r->rd_rel->relkind != RELKIND_INDEX &&
200 r->rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
202 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
203 errmsg("\"%s\" is not an index",
205}
206
207
208
209
210
211
212bool
215 bool *isnull,
219 bool indexUnchanged,
221{
224
229
231 heap_t_ctid, heapRelation,
232 checkUnique, indexUnchanged,
233 indexInfo);
234}
235
236
237
238
239
240void
243{
245
248}
249
250
251
252
253
254
260 int nkeys, int norderbys)
261{
263
265
267
268
269
270
271
275
276
278
279 return scan;
280}
281
282
283
284
285
286
287
292 int nkeys)
293{
295
297
299
300
301
302
303
306
307 return scan;
308}
309
310
311
312
315 int nkeys, int norderbys, Snapshot snapshot,
317{
319
322
325
326
327
328
330
331
332
333
335 norderbys);
336
339
340 return scan;
341}
342
343
344
345
346
347
348
349
350
351
352
353
354
355void
358 ScanKey orderbys, int norderbys)
359{
362
365
366
369
372
374 orderbys, norderbys);
375}
376
377
378
379
380
381void
383{
386
387
389 {
392 }
393
394
396
397
399
402
403
405}
406
407
408
409
410
411void
413{
416
418}
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435void
437{
439
442
443
446
449
451}
452
453
454
455
456
457
458
459
462 Snapshot snapshot, bool instrument,
463 bool parallel_aware, int nworkers)
464{
466
467 Assert(instrument || parallel_aware);
468
470
474
475 if (instrument)
476 {
477 Size sharedinfosz;
478
481 nbytes = add_size(nbytes, sharedinfosz);
483 }
484
485
486
487
488
489 if (parallel_aware &&
493 nkeys,
494 norderbys));
495
496 return nbytes;
497}
498
499
500
501
502
503
504
505
506
507
508
509void
511 Snapshot snapshot, bool instrument,
512 bool parallel_aware, int nworkers,
515{
517
518 Assert(instrument || parallel_aware);
519
521
525
531
532 if (instrument)
533 {
534 Size sharedinfosz;
535
539 offset = add_size(offset, sharedinfosz);
541
542
545 memset(*sharedinfo, 0, sharedinfosz);
546 (*sharedinfo)->num_workers = nworkers;
547 }
548
549
551 {
552 void *amtarget;
553
557 }
558}
559
560
561
562
563
564void
566{
568
571
572
575}
576
577
578
579
580
581
585 int nkeys, int norderbys,
587{
590
593
597 pscan, true);
598
599
600
601
602
606
607
609
610 return scan;
611}
612
613
614
615
616
617
618
619
622{
623 bool found;
624
627
628
630
631
632
633
634
635
636
638
639
642
643
644 if (!found)
645 {
646
649
650 return NULL;
651 }
653
655
656
658}
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678bool
680{
681 bool all_dead = false;
682 bool found;
683
687
688 if (found)
690
691
692
693
694
695
696
697
700
701 return found;
702}
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719bool
721{
722 for (;;)
723 {
725 {
727
728
730
731
732 if (tid == NULL)
733 break;
734
736 }
737
738
739
740
741
742
745 return true;
746 }
747
748 return false;
749}
750
751
752
753
754
755
756
757
758
759
760
761
762
763
766{
768
771
772
774
775
776
777
779
781
782 return ntids;
783}
784
785
786
787
788
789
790
791
792
793
798 void *callback_state)
799{
801
804
807}
808
809
810
811
812
813
814
818{
820
823
825}
826
827
828
829
830
831
832
833
834bool
836{
838
839
841 return false;
842
844}
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
876{
878 int nproc;
879 int procindex;
880
882
883 Assert(procnum > 0 && procnum <= (uint16) nproc);
884
885 procindex = (nproc * (attnum - 1)) + (procnum - 1);
886
888
890
891 return loc[procindex];
892}
893
894
895
896
897
898
899
900
901
902
903
904
905
910{
912 int nproc;
913 int optsproc;
914 int procindex;
915
918
919 Assert(procnum > 0 && procnum <= (uint16) nproc);
920
921 procindex = (nproc * (attnum - 1)) + (procnum - 1);
922
924
925 Assert(locinfo != NULL);
926
927 locinfo += procindex;
928
929
931 {
934
936
937 procId = loc[procindex];
938
939
940
941
942
943
944
946 elog(ERROR, "missing support function %d for attribute %d of index \"%s\"",
948
950
951 if (procnum != optsproc)
952 {
953
956
958
960 }
961 }
962
963 return locinfo;
964}
965
966
967
968
969
970
971
972
973
974void
977 bool recheckOrderBy)
978{
979 int i;
980
981 Assert(distances || !recheckOrderBy);
982
984
986 {
987 if (orderByTypes[i] == FLOAT8OID)
988 {
989#ifndef USE_FLOAT8_BYVAL
990
993#endif
994 if (distances && !distances[i].isnull)
995 {
998 }
999 else
1000 {
1003 }
1004 }
1005 else if (orderByTypes[i] == FLOAT4OID)
1006 {
1007
1008 if (distances && !distances[i].isnull)
1009 {
1012 }
1013 else
1014 {
1017 }
1018 }
1019 else
1020 {
1021
1022
1023
1024
1025
1026
1027
1028
1030 elog(ERROR, "ORDER BY operator must return float8 or float4 if the distance function is lossy");
1032 }
1033 }
1034}
1035
1036
1037
1038
1039
1040
1041
1045{
1050
1051
1052 if (amoptsprocnum != 0)
1054
1056 {
1057 Oid opclass;
1058 Datum indclassDatum;
1060
1062 return NULL;
1063
1064
1065
1066
1067
1069 Anum_pg_index_indclass);
1072
1074 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1075 errmsg("operator class %s has no options",
1077 }
1078
1080
1082
1084
1086}
static bool validate(Port *port, const char *auth)
#define InvalidBlockNumber
static Datum values[MAXATTR]
#define OffsetToPointer(base, offset)
#define RegProcedureIsValid(p)
#define OidIsValid(objectId)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void set_fn_opclass_options(FmgrInfo *flinfo, bytea *options)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Datum Float8GetDatum(float8 X)
#define FunctionCall1(flinfo, arg1)
void IndexScanEnd(IndexScanDesc scan)
bool(* IndexBulkDeleteCallback)(ItemPointer itemptr, void *state)
struct IndexScanInstrumentation IndexScanInstrumentation
Assert(PointerIsAligned(start, uint64))
void index_parallelscan_initialize(Relation heapRelation, Relation indexRelation, Snapshot snapshot, bool instrument, bool parallel_aware, int nworkers, SharedIndexScanInstrumentation **sharedinfo, ParallelIndexScanDesc target)
bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction, TupleTableSlot *slot)
#define CHECK_REL_PROCEDURE(pname)
static void validate_relation_kind(Relation r)
bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique, bool indexUnchanged, IndexInfo *indexInfo)
IndexScanDesc index_beginscan_parallel(Relation heaprel, Relation indexrel, IndexScanInstrumentation *instrument, int nkeys, int norderbys, ParallelIndexScanDesc pscan)
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
void index_restrpos(IndexScanDesc scan)
IndexBulkDeleteResult * index_vacuum_cleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *istat)
bytea * index_opclass_options(Relation indrel, AttrNumber attnum, Datum attoptions, bool validate)
static IndexScanDesc index_beginscan_internal(Relation indexRelation, int nkeys, int norderbys, Snapshot snapshot, ParallelIndexScanDesc pscan, bool temp_snap)
IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, IndexScanInstrumentation *instrument, int nkeys, int norderbys)
IndexBulkDeleteResult * index_bulk_delete(IndexVacuumInfo *info, IndexBulkDeleteResult *istat, IndexBulkDeleteCallback callback, void *callback_state)
void index_insert_cleanup(Relation indexRelation, IndexInfo *indexInfo)
void index_close(Relation relation, LOCKMODE lockmode)
bool index_can_return(Relation indexRelation, int attno)
ItemPointer index_getnext_tid(IndexScanDesc scan, ScanDirection direction)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
bool index_fetch_heap(IndexScanDesc scan, TupleTableSlot *slot)
void index_markpos(IndexScanDesc scan)
Relation try_index_open(Oid relationId, LOCKMODE lockmode)
void index_endscan(IndexScanDesc scan)
IndexScanDesc index_beginscan_bitmap(Relation indexRelation, Snapshot snapshot, IndexScanInstrumentation *instrument, int nkeys)
Size index_parallelscan_estimate(Relation indexRelation, int nkeys, int norderbys, Snapshot snapshot, bool instrument, bool parallel_aware, int nworkers)
Relation index_open(Oid relationId, LOCKMODE lockmode)
int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap)
void index_parallelrescan(IndexScanDesc scan)
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
#define CHECK_SCAN_PROCEDURE(pname)
void index_store_float8_orderby_distances(IndexScanDesc scan, Oid *orderByTypes, IndexOrderByDistance *distances, bool recheckOrderBy)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
static bool ItemPointerIsValid(const ItemPointerData *pointer)
void UnlockRelationId(LockRelId *relid, LOCKMODE lockmode)
void pfree(void *pointer)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define pgstat_count_index_tuples(rel, n)
#define pgstat_count_heap_fetch(rel)
static Datum PointerGetDatum(const void *X)
static Datum Float4GetDatum(float4 X)
static Pointer DatumGetPointer(Datum X)
void CheckForSerializableConflictIn(Relation relation, ItemPointer tid, BlockNumber blkno)
void PredicateLockRelation(Relation relation, Snapshot snapshot)
#define RelationGetRelationName(relation)
void RelationDecrementReferenceCount(Relation rel)
void RelationIncrementReferenceCount(Relation rel)
bytea ** RelationGetIndexAttOptions(Relation relation, bool copy)
void RelationClose(Relation relation)
#define RelFileLocatorEquals(locator1, locator2)
void init_local_reloptions(local_relopts *relopts, Size relopt_struct_size)
void * build_local_reloptions(local_relopts *relopts, Datum options, bool validate)
char * generate_opclass_name(Oid opclass)
Size add_size(Size s1, Size s2)
void SerializeSnapshot(Snapshot snapshot, char *start_address)
void UnregisterSnapshot(Snapshot snapshot)
Snapshot RestoreSnapshot(char *start_address)
Snapshot RegisterSnapshot(Snapshot snapshot)
Size EstimateSnapshotSpace(Snapshot snapshot)
#define IsMVCCSnapshot(snapshot)
Relation try_relation_open(Oid relationId, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
amvacuumcleanup_function amvacuumcleanup
amestimateparallelscan_function amestimateparallelscan
amrestrpos_function amrestrpos
aminsert_function aminsert
amendscan_function amendscan
amparallelrescan_function amparallelrescan
amgettuple_function amgettuple
amcanreturn_function amcanreturn
amgetbitmap_function amgetbitmap
ambulkdelete_function ambulkdelete
ammarkpos_function ammarkpos
ambeginscan_function ambeginscan
amrescan_function amrescan
aminitparallelscan_function aminitparallelscan
aminsertcleanup_function aminsertcleanup
struct ParallelIndexScanDescData * parallel_scan
IndexFetchTableData * xs_heapfetch
bool xactStartedInRecovery
struct IndexScanInstrumentation * instrument
ItemPointerData xs_heaptid
struct SnapshotData * xs_snapshot
RelFileLocator ps_indexlocator
RelFileLocator ps_locator
char ps_snapshot_data[FLEXIBLE_ARRAY_MEMBER]
struct IndexAmRoutine * rd_indam
RegProcedure * rd_support
struct HeapTupleData * rd_indextuple
MemoryContext rd_indexcxt
RelFileLocator rd_locator
struct FmgrInfo * rd_supportinfo
Oid values[FLEXIBLE_ARRAY_MEMBER]
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
static void table_index_fetch_reset(struct IndexFetchTableData *scan)
static IndexFetchTableData * table_index_fetch_begin(Relation rel)
static void table_index_fetch_end(struct IndexFetchTableData *scan)
static bool table_index_fetch_tuple(struct IndexFetchTableData *scan, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot, bool *call_again, bool *all_dead)
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
#define TransactionIdIsValid(xid)