PostgreSQL Source Code: contrib/pageinspect/btreefuncs.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
29
42
50
51#define IS_INDEX(r) ((r)->rd_rel->relkind == RELKIND_INDEX)
52#define IS_BTREE(r) ((r)->rd_rel->relam == BTREE_AM_OID)
53
54
55
56
57
59{
68
69
76
77
78
79
81{
87
88
89
90
92{
99
100
101
102
103
104
105
106
107static void
109{
114 int item_size = 0;
115 int off;
116
117 stat->blkno = blkno;
118
120
121 stat->dead_items = stat->live_items = 0;
122
124
125
127 {
128
130 stat->type = 'd';
131 else
132 stat->type = 'D';
133
134
135
136
137
138
139
140
142 {
144
145 elog(DEBUG2, "deleted page from block %u has safexid %u:%u",
148 }
149 else
150 elog(DEBUG2, "deleted page from block %u has safexid %u",
152
153
155 }
157 stat->type = 'e';
159 stat->type = 'l';
161 stat->type = 'r';
162 else
163 stat->type = 'i';
164
165
171
172
174 {
176
178
180
182
184 stat->live_items++;
185 else
186 stat->dead_items++;
187 }
189
190 if ((stat->live_items + stat->dead_items) > 0)
191 stat->avg_item_size = item_size / (stat->live_items + stat->dead_items);
192 else
193 stat->avg_item_size = 0;
194}
195
196
197
198
199
200
201
202static void
204{
205
208 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
209 errmsg("invalid block number %" PRId64, blkno)));
210
213 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
214 errmsg("block number %" PRId64 " is out of range", blkno)));
215}
216
217
218
219
220
221
222
223
224static void
226{
229 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
230 errmsg("\"%s\" is not a %s index",
232
233
234
235
236
237
240 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
241 errmsg("cannot access temporary tables of other sessions")));
242
243 if (blkno == 0)
245 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
246 errmsg("block 0 is a meta page")));
247
249}
250
251
252
253
254
255
256
257
260{
269 int j;
272
275 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
276 errmsg("must be superuser to use pageinspect functions")));
277
280
282
285
286
288 stat.btpo_flags = stat.free_size = stat.avg_item_size = 0;
289
291
294
295
297 elog(ERROR, "return type must be a row type");
298
299 j = 0;
311
314
316
318}
319
322{
324}
325
326
329{
331}
332
333
334
335
336
337
338
339
340
341
344{
349
352 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
353 errmsg("must be superuser to use pageinspect functions")));
354
356 {
361
363
366
367
369
370
371
372
373
374
375 if (blk_count > 1)
377
378
380
382
384 uargs->blkno = blkno;
386 uargs->allpages = (blk_count < 0);
387
389
391
392
393
394
395
396
397
398
400 }
401
404
405
407
408
411
413 {
414
418 int j;
422
425
426
428 stat.btpo_flags = stat.free_size = stat.avg_item_size = 0;
429
431
434
435
437 elog(ERROR, "return type must be a row type");
438
439 j = 0;
451
452
455
457
458
459
460
461
464
466 }
467
468
471}
472
473
474
475
476
477
478
481{
484 bool leafpage = uargs->leafpage;
485 bool rightmost = uargs->rightmost;
486 bool ispivottuple;
488 bool nulls[9];
492 int j;
493 int off;
494 int dlen;
495 char *dump,
496 *datacstring;
497 char *ptr;
499
501
504
506
507 j = 0;
508 memset(nulls, 0, sizeof(nulls));
514
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
545
547 elog(ERROR, "invalid tuple length %d for tuple at offset number %u",
548 dlen, offset);
549 dump = palloc0(dlen * 3 + 1);
550 datacstring = dump;
551 for (off = 0; off < dlen; off++)
552 {
553 if (off > 0)
554 *dump++ = ' ';
555 sprintf(dump, "%02x", *(ptr + off) & 0xff);
556 dump += 2;
557 }
559 pfree(datacstring);
560
561
562
563
564
565
566
567 ispivottuple = (!leafpage || (!rightmost && offset == P_HIKEY));
568
569
570 if (!ispivottuple)
572 else
573 {
575 nulls[j++] = true;
576 }
577
580 {
581
582 htid = NULL;
583 }
584
585 if (htid)
587 else
588 nulls[j++] = true;
589
591 {
592
594 Datum *tids_datum;
595 int nposting;
596
600 for (int i = 0; i < nposting; i++)
603 pfree(tids_datum);
604 }
605 else
606 nulls[j++] = true;
607
608
610
612}
613
614
615
616
617
618
619
620
621
624{
631
634 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
635 errmsg("must be superuser to use pageinspect functions")));
636
638 {
644
646
649
651
654
655
656
657
658
659
661
663
666
669
671
673
676 else
677 {
678
681 }
684
685
687 elog(ERROR, "return type must be a row type");
689
690 uargs->tupd = tupleDesc;
691
693
695 }
696
699
701 {
705 }
706
708}
709
712{
714}
715
716
719{
721}
722
723
724
725
726
727
728
729
730
731
734{
739
742 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
743 errmsg("must be superuser to use raw page functions")));
744
746 {
750
753
755
757
759 {
762 }
763
765
766
769 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
770 errmsg("input page is not a valid %s page", "btree"),
771 errdetail("Expected special size %d, got %d.",
774
776
779 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
780 errmsg("block is a meta page")));
781
784 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
785 errmsg("block is not a valid btree leaf page")));
786
789
792 else
793 {
794
795 elog(NOTICE, "page from block is deleted");
797 }
800
801
803 elog(ERROR, "return type must be a row type");
805
806 uargs->tupd = tupleDesc;
807
809
811 }
812
815
817 {
821 }
822
824}
825
826
827#define BT_METAP_COLS_V1_8 9
828
829
830
831
832
833
834
835
836
839{
846 int j;
851
854 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
855 errmsg("must be superuser to use pageinspect functions")));
856
859
862 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
863 errmsg("\"%s\" is not a %s index",
865
866
867
868
869
870
873 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
874 errmsg("cannot access temporary tables of other sessions")));
875
878
881
882
884 elog(ERROR, "return type must be a row type");
885
886
887
888
889
890
891
892
893
896 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
897 errmsg("function has wrong number of declared columns"),
898 errhint("To resolve the problem, update the \"pageinspect\" extension to the latest version.")));
899
900 j = 0;
907
908
909
910
911
912
913
915 {
920 }
921 else
922 {
926 }
927
930
932
935
937}
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
#define InvalidBlockNumber
static Datum values[MAXATTR]
struct BTPageStat BTPageStat
Datum bt_page_stats(PG_FUNCTION_ARGS)
Datum bt_page_items(PG_FUNCTION_ARGS)
Datum bt_page_stats_1_9(PG_FUNCTION_ARGS)
Datum bt_page_items_1_9(PG_FUNCTION_ARGS)
Datum bt_page_items_bytea(PG_FUNCTION_ARGS)
#define BT_METAP_COLS_V1_8
static Datum bt_page_stats_internal(PG_FUNCTION_ARGS, enum pageinspect_version ext_version)
static void bt_index_block_validate(Relation rel, int64 blkno)
Datum bt_metap(PG_FUNCTION_ARGS)
static void check_relation_block_range(Relation rel, int64 blkno)
struct ua_page_items ua_page_items
PG_FUNCTION_INFO_V1(bt_metap)
struct ua_page_stats ua_page_stats
static Datum bt_page_print_tuples(ua_page_items *uargs)
static void GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat *stat)
static Datum bt_page_items_internal(PG_FUNCTION_ARGS, enum pageinspect_version ext_version)
Datum bt_multi_page_stats(PG_FUNCTION_ARGS)
void UnlockReleaseBuffer(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define BUFFER_LOCK_SHARE
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
Size PageGetFreeSpace(const PageData *page)
PageHeaderData * PageHeader
static uint16 PageGetSpecialSize(const PageData *page)
static Size PageGetPageSize(const PageData *page)
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
static bool PageIsNew(const PageData *page)
#define SizeOfPageHeaderData
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
#define CStringGetTextDatum(s)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
#define PG_GETARG_TEXT_PP(n)
#define PG_GETARG_UINT32(n)
#define PG_GETARG_INT64(n)
#define PG_RETURN_DATUM(x)
#define PG_GETARG_BYTEA_P(n)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
#define SRF_IS_FIRSTCALL()
#define SRF_PERCALL_SETUP()
#define SRF_RETURN_NEXT(_funcctx, _result)
#define SRF_FIRSTCALL_INIT()
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
#define SRF_RETURN_DONE(_funcctx)
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
#define ItemIdIsDead(itemId)
#define ItemIdIsValid(itemId)
static Datum ItemPointerGetDatum(const ItemPointerData *X)
static bool IndexTupleHasVarwidths(const IndexTupleData *itup)
IndexTupleData * IndexTuple
static bool IndexTupleHasNulls(const IndexTupleData *itup)
static Size IndexTupleSize(const IndexTupleData *itup)
static Size IndexInfoFindDataOffset(unsigned short t_info)
void pfree(void *pointer)
void * palloc0(Size size)
RangeVar * makeRangeVarFromNameList(const List *names)
#define P_HAS_FULLXID(opaque)
static uint16 BTreeTupleGetNPosting(IndexTuple posting)
static bool BTreeTupleIsPivot(IndexTuple itup)
static FullTransactionId BTPageGetDeleteXid(Page page)
#define BTPageGetOpaque(page)
#define P_ISDELETED(opaque)
static ItemPointer BTreeTupleGetPosting(IndexTuple posting)
static uint32 BTreeTupleGetPostingOffset(IndexTuple posting)
#define P_RIGHTMOST(opaque)
static bool BTreeTupleIsPosting(IndexTuple itup)
#define BTREE_NOVAC_VERSION
static ItemPointer BTreeTupleGetHeapTID(IndexTuple itup)
#define InvalidOffsetNumber
#define FirstOffsetNumber
Page get_page_from_raw(bytea *raw_page)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static Datum PointerGetDatum(const void *X)
static Datum BoolGetDatum(bool X)
static Datum Int32GetDatum(int32 X)
static int16 DatumGetInt16(Datum X)
char * psprintf(const char *fmt,...)
#define RelationGetRelid(relation)
#define RelationGetRelationName(relation)
#define RELATION_IS_OTHER_TEMP(relation)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
uint32 btm_last_cleanup_num_delpages
float8 btm_last_cleanup_num_heap_tuples
MemoryContext multi_call_memory_ctx
#define EpochFromFullTransactionId(x)
#define XidFromFullTransactionId(x)
List * textToQualifiedNameList(text *textval)