PostgreSQL Source Code git master
Macros | Functions
gistfuncs.c File Reference
#include "postgres.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 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

 
 
 
static Page  verify_gist_page (bytea *raw_page)
 
 
 
 

Macro Definition Documentation

IS_GIST

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

Definition at line 32 of file gistfuncs.c.

Function Documentation

gist_page_items()

Datum gist_page_items ( PG_FUNCTION_ARGS  )

Definition at line 195 of file gistfuncs.c.

196{
197 bytea *raw_page = PG_GETARG_BYTEA_P(0);
198 Oid indexRelid = PG_GETARG_OID(1);
199 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
200 Relation indexRel;
201 TupleDesc tupdesc;
202 Page page;
203 uint16 flagbits;
204 bits16 printflags = 0;
205 OffsetNumber offset;
207 char *index_columns;
208
209 if (!superuser())
211 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
212 errmsg("must be superuser to use raw page functions")));
213
214 InitMaterializedSRF(fcinfo, 0);
215
216 /* Open the relation */
217 indexRel = index_open(indexRelid, AccessShareLock);
218
219 if (!IS_GIST(indexRel))
221 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
222 errmsg("\"%s\" is not a %s index",
223 RelationGetRelationName(indexRel), "GiST")));
224
225 page = verify_gist_page(raw_page);
226
227 if (PageIsNew(page))
228 {
229 index_close(indexRel, AccessShareLock);
231 }
232
233 flagbits = GistPageGetOpaque(page)->flags;
234
235 /*
236 * Included attributes are added when dealing with leaf pages, discarded
237 * for non-leaf pages as these include only data for key attributes.
238 */
239 printflags |= RULE_INDEXDEF_PRETTY;
240 if (flagbits & F_LEAF)
241 {
242 tupdesc = RelationGetDescr(indexRel);
243 }
244 else
245 {
248 printflags |= RULE_INDEXDEF_KEYS_ONLY;
249 }
250
251 index_columns = pg_get_indexdef_columns_extended(indexRelid,
252 printflags);
253
254 /* Avoid bogus PageGetMaxOffsetNumber() call with deleted pages */
255 if (GistPageIsDeleted(page))
256 elog(NOTICE, "page is deleted");
257 else
258 maxoff = PageGetMaxOffsetNumber(page);
259
260 for (offset = FirstOffsetNumber;
261 offset <= maxoff;
262 offset++)
263 {
264 Datum values[5];
265 bool nulls[5];
266 ItemId id;
267 IndexTuple itup;
268 Datum itup_values[INDEX_MAX_KEYS];
269 bool itup_isnull[INDEX_MAX_KEYS];
271 int i;
272
273 id = PageGetItemId(page, offset);
274
275 if (!ItemIdIsValid(id))
276 elog(ERROR, "invalid ItemId");
277
278 itup = (IndexTuple) PageGetItem(page, id);
279
280 index_deform_tuple(itup, tupdesc,
281 itup_values, itup_isnull);
282
283 memset(nulls, 0, sizeof(nulls));
284
285 values[0] = Int16GetDatum(offset);
286 values[1] = ItemPointerGetDatum(&itup->t_tid);
287 values[2] = Int32GetDatum((int) IndexTupleSize(itup));
289
290 if (index_columns)
291 {
293 appendStringInfo(&buf, "(%s)=(", index_columns);
294
295 /* Most of this is copied from record_out(). */
296 for (i = 0; i < tupdesc->natts; i++)
297 {
298 char *value;
299 char *tmp;
300 bool nq = false;
301
302 if (itup_isnull[i])
303 value = "null";
304 else
305 {
306 Oid foutoid;
307 bool typisvarlena;
308 Oid typoid;
309
310 typoid = TupleDescAttr(tupdesc, i)->atttypid;
311 getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
312 value = OidOutputFunctionCall(foutoid, itup_values[i]);
313 }
314
316 appendStringInfoString(&buf, ") INCLUDE (");
317 else if (i > 0)
319
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++)
323 {
324 char ch = *tmp;
325
326 if (ch == '"' || ch == '\\' ||
327 ch == '(' || ch == ')' || ch == ',' ||
328 isspace((unsigned char) ch))
329 {
330 nq = true;
331 break;
332 }
333 }
334
335 /* And emit the string */
336 if (nq)
338 for (tmp = value; *tmp; tmp++)
339 {
340 char ch = *tmp;
341
342 if (ch == '"' || ch == '\\')
345 }
346 if (nq)
348 }
349
351
352 values[4] = CStringGetTextDatum(buf.data);
353 nulls[4] = false;
354 }
355 else
356 {
357 values[4] = (Datum) 0;
358 nulls[4] = true;
359 }
360
361 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
362 }
363
365
366 return (Datum) 0;
367}
static Datum values[MAXATTR]
Definition: bootstrap.c:153
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
Definition: bufpage.h:354
static bool PageIsNew(const PageData *page)
Definition: bufpage.h:234
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
Definition: bufpage.h:244
PageData * Page
Definition: bufpage.h:82
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
Definition: bufpage.h:372
#define CStringGetTextDatum(s)
Definition: builtins.h:97
uint16 bits16
Definition: c.h:546
uint16_t uint16
Definition: c.h:537
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#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:1763
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_GETARG_BYTEA_P(n)
Definition: fmgr.h:335
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:42
#define IS_GIST(r)
Definition: gistfuncs.c:32
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:456
static struct @169 value
i
int i
Definition: isn.c:77
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
#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:3074
#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
Definition: pg_test_fsync.c:72
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:182
static Datum BoolGetDatum(bool X)
Definition: postgres.h:112
uint64_t Datum
Definition: postgres.h:70
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:222
unsigned int Oid
Definition: postgres_ext.h:32
#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:1249
#define RULE_INDEXDEF_PRETTY
Definition: ruleutils.h:24
#define RULE_INDEXDEF_KEYS_ONLY
Definition: ruleutils.h:25
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:205
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: itemid.h:26
Definition: rel.h:56
TupleDesc setDesc
Definition: execnodes.h:364
Tuplestorestate * setResult
Definition: execnodes.h:363
Definition: c.h:692
bool superuser(void)
Definition: superuser.c:46
TupleDesc CreateTupleDescTruncatedCopy(TupleDesc tupdesc, int natts)
Definition: tupdesc.c:296
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition: tuplestore.c:784

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

gist_page_items_bytea()

Datum gist_page_items_bytea ( PG_FUNCTION_ARGS  )

Definition at line 131 of file gistfuncs.c.

132{
133 bytea *raw_page = PG_GETARG_BYTEA_P(0);
134 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
135 Page page;
136 OffsetNumber offset;
138
139 if (!superuser())
141 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
142 errmsg("must be superuser to use raw page functions")));
143
144 InitMaterializedSRF(fcinfo, 0);
145
146 page = verify_gist_page(raw_page);
147
148 if (PageIsNew(page))
150
151 /* Avoid bogus PageGetMaxOffsetNumber() call with deleted pages */
152 if (GistPageIsDeleted(page))
153 elog(NOTICE, "page is deleted");
154 else
155 maxoff = PageGetMaxOffsetNumber(page);
156
157 for (offset = FirstOffsetNumber;
158 offset <= maxoff;
159 offset++)
160 {
161 Datum values[5];
162 bool nulls[5];
163 ItemId id;
164 IndexTuple itup;
165 bytea *tuple_bytea;
166 int tuple_len;
167
168 id = PageGetItemId(page, offset);
169
170 if (!ItemIdIsValid(id))
171 elog(ERROR, "invalid ItemId");
172
173 itup = (IndexTuple) PageGetItem(page, id);
174 tuple_len = IndexTupleSize(itup);
175
176 memset(nulls, 0, sizeof(nulls));
177
178 values[0] = Int16GetDatum(offset);
179 values[1] = ItemPointerGetDatum(&itup->t_tid);
180 values[2] = Int32GetDatum((int) IndexTupleSize(itup));
181
182 tuple_bytea = (bytea *) palloc(tuple_len + VARHDRSZ);
183 SET_VARSIZE(tuple_bytea, tuple_len + VARHDRSZ);
184 memcpy(VARDATA(tuple_bytea), itup, tuple_len);
186 values[4] = PointerGetDatum(tuple_bytea);
187
188 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
189 }
190
191 return (Datum) 0;
192}
#define VARHDRSZ
Definition: c.h:697
void * palloc(Size size)
Definition: mcxt.c:1365
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
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, FirstOffsetNumber, GistPageIsDeleted, if(), IndexTupleSize(), InitMaterializedSRF(), Int16GetDatum(), Int32GetDatum(), InvalidOffsetNumber, ItemIdIsDead, ItemIdIsValid, ItemPointerGetDatum(), NOTICE, PageGetItem(), PageGetItemId(), PageGetMaxOffsetNumber(), PageIsNew(), palloc(), PG_GETARG_BYTEA_P, PG_RETURN_NULL, PointerGetDatum(), SET_VARSIZE(), ReturnSetInfo::setDesc, ReturnSetInfo::setResult, superuser(), IndexTupleData::t_tid, tuplestore_putvalues(), values, VARDATA(), VARHDRSZ, and verify_gist_page().

gist_page_opaque_info()

Datum gist_page_opaque_info ( PG_FUNCTION_ARGS  )

Definition at line 72 of file gistfuncs.c.

73{
74 bytea *raw_page = PG_GETARG_BYTEA_P(0);
75 TupleDesc tupdesc;
76 Page page;
77 HeapTuple resultTuple;
78 Datum values[4];
79 bool nulls[4];
80 Datum flags[16];
81 int nflags = 0;
82 uint16 flagbits;
83
84 if (!superuser())
86 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
87 errmsg("must be superuser to use raw page functions")));
88
89 page = verify_gist_page(raw_page);
90
91 if (PageIsNew(page))
93
94 /* Build a tuple descriptor for our result type */
95 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
96 elog(ERROR, "return type must be a row type");
97
98 /* Convert the flags bitmask to an array of human-readable names */
99 flagbits = GistPageGetOpaque(page)->flags;
100 if (flagbits & F_LEAF)
101 flags[nflags++] = CStringGetTextDatum("leaf");
102 if (flagbits & F_DELETED)
103 flags[nflags++] = CStringGetTextDatum("deleted");
104 if (flagbits & F_TUPLES_DELETED)
105 flags[nflags++] = CStringGetTextDatum("tuples_deleted");
106 if (flagbits & F_FOLLOW_RIGHT)
107 flags[nflags++] = CStringGetTextDatum("follow_right");
108 if (flagbits & F_HAS_GARBAGE)
109 flags[nflags++] = CStringGetTextDatum("has_garbage");
111 if (flagbits)
112 {
113 /* any flags we don't recognize are printed in hex */
114 flags[nflags++] = DirectFunctionCall1(to_hex32, Int32GetDatum(flagbits));
115 }
116
117 memset(nulls, 0, sizeof(nulls));
118
119 values[0] = LSNGetDatum(PageGetLSN(page));
121 values[2] = Int64GetDatum(GistPageGetOpaque(page)->rightlink);
122 values[3] = PointerGetDatum(construct_array_builtin(flags, nflags, TEXTOID));
123
124 /* Build and return the result tuple. */
125 resultTuple = heap_form_tuple(tupdesc, values, nulls);
126
127 return HeapTupleGetDatum(resultTuple);
128}
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
Definition: arrayfuncs.c:3382
static XLogRecPtr PageGetLSN(const PageData *page)
Definition: bufpage.h:386
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:682
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:1117
static Datum LSNGetDatum(XLogRecPtr X)
Definition: pg_lsn.h:31
static Datum Int64GetDatum(int64 X)
Definition: postgres.h:403
Datum to_hex32(PG_FUNCTION_ARGS)
Definition: varlena.c:4090

References construct_array_builtin(), CStringGetTextDatum, DirectFunctionCall1, elog, ereport, errcode(), errmsg(), ERROR, F_DELETED, F_FOLLOW_RIGHT, F_HAS_GARBAGE, F_LEAF, F_TUPLES_DELETED, 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 ( bytearaw_page )
static

Definition at line 42 of file gistfuncs.c.

43{
44 Page page = get_page_from_raw(raw_page);
45 GISTPageOpaque opaq;
46
47 if (PageIsNew(page))
48 return page;
49
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.",
56 (int) MAXALIGN(sizeof(GISTPageOpaqueData)),
57 (int) PageGetSpecialSize(page))));
58
59 opaq = GistPageGetOpaque(page);
60 if (opaq->gist_page_id != GIST_PAGE_ID)
62 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
63 errmsg("input page is not a valid %s page", "GiST"),
64 errdetail("Expected %08x, got %08x.",
66 opaq->gist_page_id)));
67
68 return page;
69}
static uint16 PageGetSpecialSize(const PageData *page)
Definition: bufpage.h:317
#define MAXALIGN(LEN)
Definition: c.h:810
int errdetail(const char *fmt,...)
Definition: elog.c:1207
#define GIST_PAGE_ID
Definition: gist.h:112
Page get_page_from_raw(bytea *raw_page)
Definition: rawpage.c:218
uint16 gist_page_id
Definition: gist.h:83

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

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

AltStyle によって変換されたページ (->オリジナル) /