3 * Functions to investigate the content of GiST indexes
5 * Copyright (c) 2014-2025, PostgreSQL Global Development Group
8 * contrib/pageinspect/gistfuncs.c
16#include "catalog/pg_am_d.h"
32 #define IS_GIST(r) ((r)->rd_rel->relam == GIST_AM_OID)
38 * Verify that the given bytea contains a GIST page or die in the attempt.
39 * A pointer to the page is returned.
50 /* verify the special space has the expected size */
53 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
54 errmsg(
"input page is not a valid %s page",
"GiST"),
55 errdetail(
"Expected special size %d, got %d.",
62 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
63 errmsg(
"input page is not a valid %s page",
"GiST"),
86 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
87 errmsg(
"must be superuser to use raw page functions")));
94 /* Build a tuple descriptor for our result type */
96 elog(
ERROR,
"return type must be a row type");
98 /* Convert the flags bitmask to an array of human-readable names */
113 /* any flags we don't recognize are printed in hex */
117 memset(nulls, 0,
sizeof(nulls));
124 /* Build and return the result tuple. */
141 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
142 errmsg(
"must be superuser to use raw page functions")));
151 /* Avoid bogus PageGetMaxOffsetNumber() call with deleted pages */
176 memset(nulls, 0,
sizeof(nulls));
184 memcpy(
VARDATA(tuple_bytea), itup, tuple_len);
211 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
212 errmsg(
"must be superuser to use raw page functions")));
216 /* Open the relation */
221 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
222 errmsg(
"\"%s\" is not a %s index",
236 * Included attributes are added when dealing with leaf pages, discarded
237 * for non-leaf pages as these include only data for key attributes.
254 /* Avoid bogus PageGetMaxOffsetNumber() call with deleted pages */
281 itup_values, itup_isnull);
283 memset(nulls, 0,
sizeof(nulls));
295 /* Most of this is copied from record_out(). */
296 for (
i = 0;
i < tupdesc->natts;
i++)
320 /* Check whether we need double quotes for this value */
321 nq = (
value[0] ==
'0円');
/* force quotes for empty string */
322 for (tmp =
value; *tmp; tmp++)
326 if (ch ==
'"' || ch ==
'\\' ||
327 ch ==
'(' || ch ==
')' || ch ==
',' ||
328 isspace((
unsigned char) ch))
335 /* And emit the string */
338 for (tmp =
value; *tmp; tmp++)
342 if (ch ==
'"' || ch ==
'\\')
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
static Datum values[MAXATTR]
static uint16 PageGetSpecialSize(const PageData *page)
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
static bool PageIsNew(const PageData *page)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static XLogRecPtr PageGetLSN(const PageData *page)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
#define CStringGetTextDatum(s)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
char * OidOutputFunctionCall(Oid functionId, Datum val)
#define DirectFunctionCall1(func, arg1)
#define PG_GETARG_BYTEA_P(n)
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
#define GistPageIsDeleted(page)
#define GistPageGetOpaque(page)
#define GistPageGetNSN(page)
PG_FUNCTION_INFO_V1(gist_page_opaque_info)
Datum gist_page_items_bytea(PG_FUNCTION_ARGS)
static Page verify_gist_page(bytea *raw_page)
Datum gist_page_items(PG_FUNCTION_ARGS)
Datum gist_page_opaque_info(PG_FUNCTION_ARGS)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, Datum *values, bool *isnull)
if(TABLE==NULL||TABLE_index==NULL)
#define ItemIdIsDead(itemId)
#define ItemIdIsValid(itemId)
static Datum ItemPointerGetDatum(const ItemPointerData *X)
IndexTupleData * IndexTuple
static Size IndexTupleSize(const IndexTupleData *itup)
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
#define InvalidOffsetNumber
#define FirstOffsetNumber
Page get_page_from_raw(bytea *raw_page)
static Datum LSNGetDatum(XLogRecPtr X)
static Datum Int64GetDatum(int64 X)
static Datum PointerGetDatum(const void *X)
static Datum Int16GetDatum(int16 X)
static Datum BoolGetDatum(bool X)
static Datum Int32GetDatum(int32 X)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
char * pg_get_indexdef_columns_extended(Oid indexrelid, bits16 flags)
#define RULE_INDEXDEF_PRETTY
#define RULE_INDEXDEF_KEYS_ONLY
void relation_close(Relation relation, LOCKMODE lockmode)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
#define appendStringInfoCharMacro(str, ch)
Tuplestorestate * setResult
TupleDesc CreateTupleDescTruncatedCopy(TupleDesc tupdesc, int natts)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
static char * VARDATA(const void *PTR)
static void SET_VARSIZE(void *PTR, Size len)
Datum to_hex32(PG_FUNCTION_ARGS)