PostgreSQL Source Code git master
Loading...
Searching...
No Matches
gistfuncs.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/gist.h"
#include "access/htup.h"
#include "access/htup_details.h"
#include "access/relation.h"
#include "catalog/pg_am_d.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "pageinspect.h"
#include "storage/itemptr.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/pg_lsn.h"
#include "utils/rel.h"
#include "utils/ruleutils.h"
#include "utils/tuplestore.h"
Include dependency graph for gistfuncs.c:

Go to the source code of this file.

Macros

#define IS_GIST(r)   ((r)->rd_rel->relam == GIST_AM_OID)
 

Functions

 PG_FUNCTION_INFO_V1 (gist_page_opaque_info)
 
 PG_FUNCTION_INFO_V1 (gist_page_items)
 
 PG_FUNCTION_INFO_V1 (gist_page_items_bytea)
 
static Page verify_gist_page (bytea *raw_page)
 
Datum gist_page_opaque_info (PG_FUNCTION_ARGS)
 
Datum gist_page_items_bytea (PG_FUNCTION_ARGS)
 
Datum gist_page_items (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ IS_GIST

#define IS_GIST (   r)    ((r)->rd_rel->relam == GIST_AM_OID)

Definition at line 34 of file gistfuncs.c.

Function Documentation

◆ gist_page_items()

Datum gist_page_items ( PG_FUNCTION_ARGS  )

Definition at line 197 of file gistfuncs.c.

198{
201 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
202 Relation indexRel;
203 TupleDesc tupdesc;
204 Page page;
206 bits16 printflags = 0;
207 OffsetNumber offset;
209 char *index_columns;
210
211 if (!superuser())
214 errmsg("must be superuser to use raw page functions")));
215
216 InitMaterializedSRF(fcinfo, 0);
217
218 /* Open the relation */
220
221 if (!IS_GIST(indexRel))
224 errmsg("\"%s\" is not a %s index",
225 RelationGetRelationName(indexRel), "GiST")));
226
228
229 if (PageIsNew(page))
230 {
231 index_close(indexRel, AccessShareLock);
233 }
234
235 flagbits = GistPageGetOpaque(page)->flags;
236
237 /*
238 * Included attributes are added when dealing with leaf pages, discarded
239 * for non-leaf pages as these include only data for key attributes.
240 */
242 if (flagbits & F_LEAF)
243 {
244 tupdesc = RelationGetDescr(indexRel);
245 }
246 else
247 {
251 }
252
254 printflags);
255
256 /* Avoid bogus PageGetMaxOffsetNumber() call with deleted pages */
257 if (GistPageIsDeleted(page))
258 elog(NOTICE, "page is deleted");
259 else
260 maxoff = PageGetMaxOffsetNumber(page);
261
262 for (offset = FirstOffsetNumber;
263 offset <= maxoff;
264 offset++)
265 {
266 Datum values[5];
267 bool nulls[5];
268 ItemId id;
269 IndexTuple itup;
273 int i;
274
275 id = PageGetItemId(page, offset);
276
277 if (!ItemIdIsValid(id))
278 elog(ERROR, "invalid ItemId");
279
280 itup = (IndexTuple) PageGetItem(page, id);
281
282 index_deform_tuple(itup, tupdesc,
284
285 memset(nulls, 0, sizeof(nulls));
286
287 values[0] = UInt16GetDatum(offset);
288 values[1] = ItemPointerGetDatum(&itup->t_tid);
289 values[2] = Int32GetDatum((int) IndexTupleSize(itup));
291
292 if (index_columns)
293 {
296
297 /* Most of this is copied from record_out(). */
298 for (i = 0; i < tupdesc->natts; i++)
299 {
300 char *value;
301 char *tmp;
302 bool nq = false;
303
304 if (itup_isnull[i])
305 value = "null";
306 else
307 {
308 Oid foutoid;
309 bool typisvarlena;
310 Oid typoid;
311
312 typoid = TupleDescAttr(tupdesc, i)->atttypid;
313 getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
315 }
316
318 appendStringInfoString(&buf, ") INCLUDE (");
319 else if (i > 0)
321
322 /* Check whether we need double quotes for this value */
323 nq = (value[0] == '\0'); /* force quotes for empty string */
324 for (tmp = value; *tmp; tmp++)
325 {
326 char ch = *tmp;
327
328 if (ch == '"' || ch == '\\' ||
329 ch == '(' || ch == ')' || ch == ',' ||
330 isspace((unsigned char) ch))
331 {
332 nq = true;
333 break;
334 }
335 }
336
337 /* And emit the string */
338 if (nq)
340 for (tmp = value; *tmp; tmp++)
341 {
342 char ch = *tmp;
343
344 if (ch == '"' || ch == '\\')
347 }
348 if (nq)
350 }
351
353
354 values[4] = CStringGetTextDatum(buf.data);
355 nulls[4] = false;
356 }
357 else
358 {
359 values[4] = (Datum) 0;
360 nulls[4] = true;
361 }
362
363 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
364 }
365
366 index_close(indexRel, AccessShareLock);
367
368 return (Datum) 0;
369}
static Datum values[MAXATTR]
Definition bootstrap.c:188
static bool PageIsNew(const PageData *page)
Definition bufpage.h:259
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
Definition bufpage.h:269
static void * PageGetItem(PageData *page, const ItemIdData *itemId)
Definition bufpage.h:379
PageData * Page
Definition bufpage.h:81
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
Definition bufpage.h:397
#define CStringGetTextDatum(s)
Definition builtins.h:98
uint16 bits16
Definition c.h:626
uint16_t uint16
Definition c.h:617
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define NOTICE
Definition elog.h:35
#define ereport(elevel,...)
Definition elog.h:150
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition fmgr.c:1764
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_GETARG_BYTEA_P(n)
Definition fmgr.h:336
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition funcapi.c:76
#define F_LEAF
Definition gist.h:49
#define GistPageIsDeleted(page)
Definition gist.h:173
#define GistPageGetOpaque(page)
Definition gist.h:168
static Page verify_gist_page(bytea *raw_page)
Definition gistfuncs.c:44
#define IS_GIST(r)
Definition gistfuncs.c:34
void index_close(Relation relation, LOCKMODE lockmode)
Definition indexam.c:177
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition indexam.c:133
void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition indextuple.c:364
static struct @174 value
int i
Definition isn.c:77
#define ItemIdIsDead(itemId)
Definition itemid.h:113
#define ItemIdIsValid(itemId)
Definition itemid.h:86
static Datum ItemPointerGetDatum(const ItemPointerData *X)
Definition itemptr.h:237
IndexTupleData * IndexTuple
Definition itup.h:53
static Size IndexTupleSize(const IndexTupleData *itup)
Definition itup.h:71
#define AccessShareLock
Definition lockdefs.h:36
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition lsyscache.c:3129
static char * errmsg
#define InvalidOffsetNumber
Definition off.h:26
uint16 OffsetNumber
Definition off.h:24
#define FirstOffsetNumber
Definition off.h:27
#define INDEX_MAX_KEYS
static char buf[DEFAULT_XLOG_SEG_SIZE]
static Datum UInt16GetDatum(uint16 X)
Definition postgres.h:192
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
uint64_t Datum
Definition postgres.h:70
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
unsigned int Oid
static int fb(int x)
#define RelationGetDescr(relation)
Definition rel.h:540
#define RelationGetRelationName(relation)
Definition rel.h:548
#define IndexRelationGetNumberOfKeyAttributes(relation)
Definition rel.h:533
char * pg_get_indexdef_columns_extended(Oid indexrelid, bits16 flags)
Definition ruleutils.c:1258
#define RULE_INDEXDEF_PRETTY
Definition ruleutils.h:24
#define RULE_INDEXDEF_KEYS_ONLY
Definition ruleutils.h:25
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
#define appendStringInfoCharMacro(str, ch)
Definition stringinfo.h:231
ItemPointerData t_tid
Definition itup.h:37
Definition c.h:778
bool superuser(void)
Definition superuser.c:47
TupleDesc CreateTupleDescTruncatedCopy(TupleDesc tupdesc, int natts)
Definition tupdesc.c:288
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition tuplestore.c:785

References AccessShareLock, appendStringInfo(), appendStringInfoChar(), appendStringInfoCharMacro, appendStringInfoString(), BoolGetDatum(), buf, CreateTupleDescTruncatedCopy(), CStringGetTextDatum, elog, ereport, errcode(), errmsg, ERROR, F_LEAF, fb(), FirstOffsetNumber, getTypeOutputInfo(), GistPageGetOpaque, GistPageIsDeleted, i, index_close(), index_deform_tuple(), INDEX_MAX_KEYS, index_open(), IndexRelationGetNumberOfKeyAttributes, IndexTupleSize(), InitMaterializedSRF(), initStringInfo(), Int32GetDatum(), InvalidOffsetNumber, IS_GIST, ItemIdIsDead, ItemIdIsValid, ItemPointerGetDatum(), TupleDescData::natts, NOTICE, OidOutputFunctionCall(), PageGetItem(), PageGetItemId(), PageGetMaxOffsetNumber(), PageIsNew(), pg_get_indexdef_columns_extended(), PG_GETARG_BYTEA_P, PG_GETARG_OID, PG_RETURN_NULL, RelationGetDescr, RelationGetRelationName, RULE_INDEXDEF_KEYS_ONLY, RULE_INDEXDEF_PRETTY, superuser(), IndexTupleData::t_tid, TupleDescAttr(), tuplestore_putvalues(), UInt16GetDatum(), value, values, and verify_gist_page().

◆ gist_page_items_bytea()

Datum gist_page_items_bytea ( PG_FUNCTION_ARGS  )

Definition at line 133 of file gistfuncs.c.

134{
136 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
137 Page page;
138 OffsetNumber offset;
140
141 if (!superuser())
144 errmsg("must be superuser to use raw page functions")));
145
146 InitMaterializedSRF(fcinfo, 0);
147
149
150 if (PageIsNew(page))
152
153 /* Avoid bogus PageGetMaxOffsetNumber() call with deleted pages */
154 if (GistPageIsDeleted(page))
155 elog(NOTICE, "page is deleted");
156 else
157 maxoff = PageGetMaxOffsetNumber(page);
158
159 for (offset = FirstOffsetNumber;
160 offset <= maxoff;
161 offset++)
162 {
163 Datum values[5];
164 bool nulls[5];
165 ItemId id;
166 IndexTuple itup;
168 int tuple_len;
169
170 id = PageGetItemId(page, offset);
171
172 if (!ItemIdIsValid(id))
173 elog(ERROR, "invalid ItemId");
174
175 itup = (IndexTuple) PageGetItem(page, id);
176 tuple_len = IndexTupleSize(itup);
177
178 memset(nulls, 0, sizeof(nulls));
179
180 values[0] = UInt16GetDatum(offset);
181 values[1] = ItemPointerGetDatum(&itup->t_tid);
182 values[2] = Int32GetDatum((int) IndexTupleSize(itup));
183
184 tuple_bytea = (bytea *) palloc(tuple_len + VARHDRSZ);
185 SET_VARSIZE(tuple_bytea, tuple_len + VARHDRSZ);
186 memcpy(VARDATA(tuple_bytea), itup, tuple_len);
189
190 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
191 }
192
193 return (Datum) 0;
194}
#define VARHDRSZ
Definition c.h:783
void * palloc(Size size)
Definition mcxt.c:1387
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
static char * VARDATA(const void *PTR)
Definition varatt.h:305
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432

References BoolGetDatum(), elog, ereport, errcode(), errmsg, ERROR, fb(), FirstOffsetNumber, GistPageIsDeleted, IndexTupleSize(), InitMaterializedSRF(), Int32GetDatum(), InvalidOffsetNumber, ItemIdIsDead, ItemIdIsValid, ItemPointerGetDatum(), NOTICE, PageGetItem(), PageGetItemId(), PageGetMaxOffsetNumber(), PageIsNew(), palloc(), PG_GETARG_BYTEA_P, PG_RETURN_NULL, PointerGetDatum(), SET_VARSIZE(), superuser(), IndexTupleData::t_tid, tuplestore_putvalues(), UInt16GetDatum(), values, VARDATA(), VARHDRSZ, and verify_gist_page().

◆ gist_page_opaque_info()

Datum gist_page_opaque_info ( PG_FUNCTION_ARGS  )

Definition at line 74 of file gistfuncs.c.

75{
77 TupleDesc tupdesc;
78 Page page;
80 Datum values[4];
81 bool nulls[4];
82 Datum flags[16];
83 int nflags = 0;
85
86 if (!superuser())
89 errmsg("must be superuser to use raw page functions")));
90
92
93 if (PageIsNew(page))
95
96 /* Build a tuple descriptor for our result type */
97 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
98 elog(ERROR, "return type must be a row type");
99
100 /* Convert the flags bitmask to an array of human-readable names */
101 flagbits = GistPageGetOpaque(page)->flags;
102 if (flagbits & F_LEAF)
103 flags[nflags++] = CStringGetTextDatum("leaf");
104 if (flagbits & F_DELETED)
105 flags[nflags++] = CStringGetTextDatum("deleted");
107 flags[nflags++] = CStringGetTextDatum("tuples_deleted");
109 flags[nflags++] = CStringGetTextDatum("follow_right");
111 flags[nflags++] = CStringGetTextDatum("has_garbage");
113 if (flagbits)
114 {
115 /* any flags we don't recognize are printed in hex */
117 }
118
119 memset(nulls, 0, sizeof(nulls));
120
121 values[0] = LSNGetDatum(PageGetLSN(page));
123 values[2] = Int64GetDatum(GistPageGetOpaque(page)->rightlink);
125
126 /* Build and return the result tuple. */
127 resultTuple = heap_form_tuple(tupdesc, values, nulls);
128
130}
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
static XLogRecPtr PageGetLSN(const PageData *page)
Definition bufpage.h:411
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:276
@ TYPEFUNC_COMPOSITE
Definition funcapi.h:149
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition funcapi.h:230
#define F_TUPLES_DELETED
Definition gist.h:51
#define F_FOLLOW_RIGHT
Definition gist.h:52
#define F_HAS_GARBAGE
Definition gist.h:53
#define F_DELETED
Definition gist.h:50
#define GistPageGetNSN(page)
Definition gist.h:187
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1037
static Datum LSNGetDatum(XLogRecPtr X)
Definition pg_lsn.h:31
static Datum Int64GetDatum(int64 X)
Definition postgres.h:413
Datum to_hex32(PG_FUNCTION_ARGS)
Definition varlena.c:4128

References construct_array_builtin(), CStringGetTextDatum, DirectFunctionCall1, elog, ereport, errcode(), errmsg, ERROR, F_DELETED, F_FOLLOW_RIGHT, F_HAS_GARBAGE, F_LEAF, F_TUPLES_DELETED, fb(), get_call_result_type(), GistPageGetNSN, GistPageGetOpaque, heap_form_tuple(), HeapTupleGetDatum(), Int32GetDatum(), Int64GetDatum(), LSNGetDatum(), PageGetLSN(), PageIsNew(), PG_GETARG_BYTEA_P, PG_RETURN_NULL, PointerGetDatum(), superuser(), to_hex32(), TYPEFUNC_COMPOSITE, values, and verify_gist_page().

◆ PG_FUNCTION_INFO_V1() [1/3]

PG_FUNCTION_INFO_V1 ( gist_page_items  )

◆ PG_FUNCTION_INFO_V1() [2/3]

PG_FUNCTION_INFO_V1 ( gist_page_items_bytea  )

◆ PG_FUNCTION_INFO_V1() [3/3]

PG_FUNCTION_INFO_V1 ( gist_page_opaque_info  )

◆ verify_gist_page()

static Page verify_gist_page ( bytea raw_page)
static

Definition at line 44 of file gistfuncs.c.

45{
48
49 if (PageIsNew(page))
50 return page;
51
52 /* verify the special space has the expected size */
56 errmsg("input page is not a valid %s page", "GiST"),
57 errdetail("Expected special size %d, got %d.",
58 (int) MAXALIGN(sizeof(GISTPageOpaqueData)),
59 (int) PageGetSpecialSize(page))));
60
61 opaq = GistPageGetOpaque(page);
62 if (opaq->gist_page_id != GIST_PAGE_ID)
65 errmsg("input page is not a valid %s page", "GiST"),
66 errdetail("Expected %08x, got %08x.",
68 opaq->gist_page_id)));
69
70 return page;
71}
static uint16 PageGetSpecialSize(const PageData *page)
Definition bufpage.h:342
#define MAXALIGN(LEN)
Definition c.h:898
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define GIST_PAGE_ID
Definition gist.h:112
Page get_page_from_raw(bytea *raw_page)
Definition rawpage.c:216

References ereport, errcode(), errdetail(), errmsg, ERROR, fb(), get_page_from_raw(), GIST_PAGE_ID, GistPageGetOpaque, MAXALIGN, PageGetSpecialSize(), and PageIsNew().

Referenced by gist_page_items(), gist_page_items_bytea(), and gist_page_opaque_info().