summaryrefslogtreecommitdiffstats
path: root/contrib/pageinspect/fsmfuncs.c
blob: 099acbb2fe4b068b1b37b8ff4d1e2a81925cb523 (plain)
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*-------------------------------------------------------------------------
 *
 * fsmfuncs.c
 *	  Functions to investigate FSM pages
 *
 * These functions are restricted to superusers for the fear of introducing
 * security holes if the input checking isn't as water-tight as it should.
 * You'd need to be superuser to obtain a raw page image anyway, so
 * there's hardly any use case for using these without superuser-rights
 * anyway.
 *
 * Copyright (c) 2007-2020, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
 *	  contrib/pageinspect/fsmfuncs.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "funcapi.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
#include "pageinspect.h"
#include "storage/fsm_internals.h"
#include "utils/builtins.h"

/*
 * Dumps the contents of a FSM page.
 */
PG_FUNCTION_INFO_V1(fsm_page_contents);

Datum
fsm_page_contents(PG_FUNCTION_ARGS)
{
	bytea	   *raw_page = PG_GETARG_BYTEA_P(0);
	StringInfoData sinfo;
	FSMPage		fsmpage;
	int			i;

	if (!superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("must be superuser to use raw page functions")));

	fsmpage = (FSMPage) PageGetContents(VARDATA(raw_page));

	initStringInfo(&sinfo);

	for (i = 0; i < NodesPerPage; i++)
	{
		if (fsmpage->fp_nodes[i] != 0)
			appendStringInfo(&sinfo, "%d: %d\n", i, fsmpage->fp_nodes[i]);
	}
	appendStringInfo(&sinfo, "fp_next_slot: %d\n", fsmpage->fp_next_slot);

	PG_RETURN_TEXT_P(cstring_to_text_with_len(sinfo.data, sinfo.len));
}