PostgreSQL Source Code git master
brin_inclusion.c
Go to the documentation of this file.
1/*
2 * brin_inclusion.c
3 * Implementation of inclusion opclasses for BRIN
4 *
5 * This module provides framework BRIN support functions for the "inclusion"
6 * operator classes. A few SQL-level support functions are also required for
7 * each opclass.
8 *
9 * The "inclusion" BRIN strategy is useful for types that support R-Tree
10 * operations. This implementation is a straight mapping of those operations
11 * to the block-range nature of BRIN, with two exceptions: (a) we explicitly
12 * support "empty" elements: at least with range types, we need to consider
13 * emptiness separately from regular R-Tree strategies; and (b) we need to
14 * consider "unmergeable" elements, that is, a set of elements for whose union
15 * no representation exists. The only case where that happens as of this
16 * writing is the INET type, where IPv6 values cannot be merged with IPv4
17 * values.
18 *
19 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
20 * Portions Copyright (c) 1994, Regents of the University of California
21 *
22 * IDENTIFICATION
23 * src/backend/access/brin/brin_inclusion.c
24 */
25#include "postgres.h"
26
28#include "access/brin_tuple.h"
29#include "access/genam.h"
30#include "access/skey.h"
31#include "catalog/pg_amop.h"
32#include "catalog/pg_type.h"
33#include "utils/datum.h"
34#include "utils/fmgrprotos.h"
35#include "utils/lsyscache.h"
36#include "utils/rel.h"
37#include "utils/syscache.h"
38
39
40/*
41 * Additional SQL level support functions
42 *
43 * Procedure numbers must not use values reserved for BRIN itself; see
44 * brin_internal.h.
45 */
46#define INCLUSION_MAX_PROCNUMS 4 /* maximum support procs we need */
47#define PROCNUM_MERGE 11 /* required */
48#define PROCNUM_MERGEABLE 12 /* optional */
49#define PROCNUM_CONTAINS 13 /* optional */
50#define PROCNUM_EMPTY 14 /* optional */
51
52
53/*
54 * Subtract this from procnum to obtain index in InclusionOpaque arrays
55 * (Must be equal to minimum of private procnums).
56 */
57#define PROCNUM_BASE 11
58
59/*-
60 * The values stored in the bv_values arrays correspond to:
61 *
62 * INCLUSION_UNION
63 * the union of the values in the block range
64 * INCLUSION_UNMERGEABLE
65 * whether the values in the block range cannot be merged
66 * (e.g. an IPv6 address amidst IPv4 addresses)
67 * INCLUSION_CONTAINS_EMPTY
68 * whether an empty value is present in any tuple
69 * in the block range
70 */
71#define INCLUSION_UNION 0
72#define INCLUSION_UNMERGEABLE 1
73#define INCLUSION_CONTAINS_EMPTY 2
74
75
76typedef struct InclusionOpaque
77{
83
85 uint16 procnum, bool missing_ok);
87 Oid subtype, uint16 strategynum);
88
89
90/*
91 * BRIN inclusion OpcInfo function
92 */
95{
96 Oid typoid = PG_GETARG_OID(0);
97 BrinOpcInfo *result;
98 TypeCacheEntry *bool_typcache = lookup_type_cache(BOOLOID, 0);
99
100 /*
101 * All members of opaque are initialized lazily; both procinfo arrays
102 * start out as non-initialized by having fn_oid be InvalidOid, and
103 * "missing" to false, by zeroing here. strategy_procinfos elements can
104 * be invalidated when cached_subtype changes by zeroing fn_oid.
105 * extra_procinfo entries are never invalidated, but if a lookup fails
106 * (which is expected), extra_proc_missing is set to true, indicating not
107 * to look it up again.
108 */
109 result = palloc0(MAXALIGN(SizeofBrinOpcInfo(3)) + sizeof(InclusionOpaque));
110 result->oi_nstored = 3;
111 result->oi_regular_nulls = true;
112 result->oi_opaque = (InclusionOpaque *)
113 MAXALIGN((char *) result + SizeofBrinOpcInfo(3));
114
115 /* the union */
117 lookup_type_cache(typoid, 0);
118
119 /* includes elements that are not mergeable */
120 result->oi_typcache[INCLUSION_UNMERGEABLE] = bool_typcache;
121
122 /* includes the empty element */
123 result->oi_typcache[INCLUSION_CONTAINS_EMPTY] = bool_typcache;
124
125 PG_RETURN_POINTER(result);
126}
127
128/*
129 * BRIN inclusion add value function
130 *
131 * Examine the given index tuple (which contains partial status of a certain
132 * page range) by comparing it to the given value that comes from another heap
133 * tuple. If the new value is outside the union specified by the existing
134 * tuple values, update the index tuple and return true. Otherwise, return
135 * false and do not modify in this case.
136 */
137Datum
139{
140 BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
141 BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1);
144 Oid colloid = PG_GET_COLLATION();
145 FmgrInfo *finfo;
146 Datum result;
147 bool new = false;
148 AttrNumber attno;
149 CompactAttribute *attr;
150
151 Assert(!isnull);
152
153 attno = column->bv_attno;
154 attr = TupleDescCompactAttr(bdesc->bd_tupdesc, attno - 1);
155
156 /*
157 * If the recorded value is null, copy the new value (which we know to be
158 * not null), and we're almost done.
159 */
160 if (column->bv_allnulls)
161 {
162 column->bv_values[INCLUSION_UNION] =
163 datumCopy(newval, attr->attbyval, attr->attlen);
166 column->bv_allnulls = false;
167 new = true;
168 }
169
170 /*
171 * No need for further processing if the block range is marked as
172 * containing unmergeable values.
173 */
175 PG_RETURN_BOOL(false);
176
177 /*
178 * If the opclass supports the concept of empty values, test the passed
179 * new value for emptiness; if it returns true, we need to set the
180 * "contains empty" flag in the element (unless already set).
181 */
182 finfo = inclusion_get_procinfo(bdesc, attno, PROCNUM_EMPTY, true);
183 if (finfo != NULL && DatumGetBool(FunctionCall1Coll(finfo, colloid, newval)))
184 {
186 {
188 PG_RETURN_BOOL(true);
189 }
190
191 PG_RETURN_BOOL(false);
192 }
193
194 if (new)
195 PG_RETURN_BOOL(true);
196
197 /* Check if the new value is already contained. */
198 finfo = inclusion_get_procinfo(bdesc, attno, PROCNUM_CONTAINS, true);
199 if (finfo != NULL &&
200 DatumGetBool(FunctionCall2Coll(finfo, colloid,
201 column->bv_values[INCLUSION_UNION],
202 newval)))
203 PG_RETURN_BOOL(false);
204
205 /*
206 * Check if the new value is mergeable to the existing union. If it is
207 * not, mark the value as containing unmergeable elements and get out.
208 *
209 * Note: at this point we could remove the value from the union, since
210 * it's not going to be used any longer. However, the BRIN framework
211 * doesn't allow for the value not being present. Improve someday.
212 */
213 finfo = inclusion_get_procinfo(bdesc, attno, PROCNUM_MERGEABLE, true);
214 if (finfo != NULL &&
215 !DatumGetBool(FunctionCall2Coll(finfo, colloid,
216 column->bv_values[INCLUSION_UNION],
217 newval)))
218 {
220 PG_RETURN_BOOL(true);
221 }
222
223 /* Finally, merge the new value to the existing union. */
224 finfo = inclusion_get_procinfo(bdesc, attno, PROCNUM_MERGE, false);
225 result = FunctionCall2Coll(finfo, colloid,
227 if (!attr->attbyval &&
229 {
231
232 if (result == newval)
233 result = datumCopy(result, attr->attbyval, attr->attlen);
234 }
235 column->bv_values[INCLUSION_UNION] = result;
236
237 PG_RETURN_BOOL(true);
238}
239
240/*
241 * BRIN inclusion consistent function
242 *
243 * We're no longer dealing with NULL keys in the consistent function, that is
244 * now handled by the AM code. That means we should not get any all-NULL ranges
245 * either, because those can't be consistent with regular (not [IS] NULL) keys.
246 *
247 * All of the strategies are optional.
248 */
249Datum
251{
252 BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
253 BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1);
255 Oid colloid = PG_GET_COLLATION(),
256 subtype;
257 Datum unionval;
258 AttrNumber attno;
259 Datum query;
260 FmgrInfo *finfo;
261 Datum result;
262
263 /* This opclass uses the old signature with only three arguments. */
264 Assert(PG_NARGS() == 3);
265
266 /* Should not be dealing with all-NULL ranges. */
267 Assert(!column->bv_allnulls);
268
269 /* It has to be checked, if it contains elements that are not mergeable. */
271 PG_RETURN_BOOL(true);
272
273 attno = key->sk_attno;
274 subtype = key->sk_subtype;
275 query = key->sk_argument;
276 unionval = column->bv_values[INCLUSION_UNION];
277 switch (key->sk_strategy)
278 {
279 /*
280 * Placement strategies
281 *
282 * These are implemented by logically negating the result of the
283 * converse placement operator; for this to work, the converse
284 * operator must be part of the opclass. An error will be thrown
285 * by inclusion_get_strategy_procinfo() if the required strategy
286 * is not part of the opclass.
287 *
288 * These all return false if either argument is empty, so there is
289 * no need to check for empty elements.
290 */
291
293 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
295 result = FunctionCall2Coll(finfo, colloid, unionval, query);
297
299 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
301 result = FunctionCall2Coll(finfo, colloid, unionval, query);
303
305 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
307 result = FunctionCall2Coll(finfo, colloid, unionval, query);
309
311 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
313 result = FunctionCall2Coll(finfo, colloid, unionval, query);
315
317 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
319 result = FunctionCall2Coll(finfo, colloid, unionval, query);
321
323 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
325 result = FunctionCall2Coll(finfo, colloid, unionval, query);
327
329 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
331 result = FunctionCall2Coll(finfo, colloid, unionval, query);
333
335 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
337 result = FunctionCall2Coll(finfo, colloid, unionval, query);
339
340 /*
341 * Overlap and contains strategies
342 *
343 * These strategies are simple enough that we can simply call the
344 * operator and return its result. Empty elements don't change
345 * the result.
346 */
347
353 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
354 key->sk_strategy);
355 result = FunctionCall2Coll(finfo, colloid, unionval, query);
356 PG_RETURN_DATUM(result);
357
358 /*
359 * Contained by strategies
360 *
361 * We cannot just call the original operator for the contained by
362 * strategies because some elements can be contained even though
363 * the union is not; instead we use the overlap operator.
364 *
365 * We check for empty elements separately as they are not merged
366 * to the union but contained by everything.
367 */
368
372 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
374 result = FunctionCall2Coll(finfo, colloid, unionval, query);
375 if (DatumGetBool(result))
376 PG_RETURN_BOOL(true);
377
379
380 /*
381 * Adjacent strategy
382 *
383 * We test for overlap first but to be safe we need to call the
384 * actual adjacent operator also.
385 *
386 * An empty element cannot be adjacent to any other, so there is
387 * no need to check for it.
388 */
389
391 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
393 result = FunctionCall2Coll(finfo, colloid, unionval, query);
394 if (DatumGetBool(result))
395 PG_RETURN_BOOL(true);
396
397 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
399 result = FunctionCall2Coll(finfo, colloid, unionval, query);
400 PG_RETURN_DATUM(result);
401
402 /*
403 * Basic comparison strategies
404 *
405 * It is straightforward to support the equality strategies with
406 * the contains operator. Generally, inequality strategies do not
407 * make much sense for the types which will be used with the
408 * inclusion BRIN family of opclasses, but it is possible to
409 * implement them with logical negation of the left-of and
410 * right-of operators.
411 *
412 * NB: These strategies cannot be used with geometric datatypes
413 * that use comparison of areas! The only exception is the "same"
414 * strategy.
415 *
416 * Empty elements are considered to be less than the others. We
417 * cannot use the empty support function to check the query is an
418 * empty element, because the query can be another data type than
419 * the empty support function argument. So we will return true,
420 * if there is a possibility that empty elements will change the
421 * result.
422 */
423
426 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
428 result = FunctionCall2Coll(finfo, colloid, unionval, query);
429 if (!DatumGetBool(result))
430 PG_RETURN_BOOL(true);
431
433
436 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
438 result = FunctionCall2Coll(finfo, colloid, unionval, query);
439 if (DatumGetBool(result))
440 PG_RETURN_BOOL(true);
441
443
445 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
447 result = FunctionCall2Coll(finfo, colloid, unionval, query);
448 if (!DatumGetBool(result))
449 PG_RETURN_BOOL(true);
450
452
454 /* no need to check for empty elements */
455 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
457 result = FunctionCall2Coll(finfo, colloid, unionval, query);
459
460 default:
461 /* shouldn't happen */
462 elog(ERROR, "invalid strategy number %d", key->sk_strategy);
463 PG_RETURN_BOOL(false);
464 }
465}
466
467/*
468 * BRIN inclusion union function
469 *
470 * Given two BrinValues, update the first of them as a union of the summary
471 * values contained in both. The second one is untouched.
472 */
473Datum
475{
476 BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
479 Oid colloid = PG_GET_COLLATION();
480 AttrNumber attno;
481 CompactAttribute *attr;
482 FmgrInfo *finfo;
483 Datum result;
484
485 Assert(col_a->bv_attno == col_b->bv_attno);
486 Assert(!col_a->bv_allnulls && !col_b->bv_allnulls);
487
488 attno = col_a->bv_attno;
489 attr = TupleDescCompactAttr(bdesc->bd_tupdesc, attno - 1);
490
491 /* If B includes empty elements, mark A similarly, if needed. */
495
496 /* Check if A includes elements that are not mergeable. */
499
500 /* If B includes elements that are not mergeable, mark A similarly. */
502 {
505 }
506
507 /* Check if A and B are mergeable; if not, mark A unmergeable. */
508 finfo = inclusion_get_procinfo(bdesc, attno, PROCNUM_MERGEABLE, true);
509 if (finfo != NULL &&
510 !DatumGetBool(FunctionCall2Coll(finfo, colloid,
512 col_b->bv_values[INCLUSION_UNION])))
513 {
516 }
517
518 /* Finally, merge B to A. */
519 finfo = inclusion_get_procinfo(bdesc, attno, PROCNUM_MERGE, false);
520 result = FunctionCall2Coll(finfo, colloid,
522 col_b->bv_values[INCLUSION_UNION]);
523 if (!attr->attbyval &&
525 {
527
528 if (result == col_b->bv_values[INCLUSION_UNION])
529 result = datumCopy(result, attr->attbyval, attr->attlen);
530 }
531 col_a->bv_values[INCLUSION_UNION] = result;
532
534}
535
536/*
537 * Cache and return inclusion opclass support procedure
538 *
539 * Return the procedure corresponding to the given function support number
540 * or null if it is not exists. If missing_ok is true and the procedure
541 * isn't set up for this opclass, return NULL instead of raising an error.
542 */
543static FmgrInfo *
545 bool missing_ok)
546{
547 InclusionOpaque *opaque;
548 uint16 basenum = procnum - PROCNUM_BASE;
549
550 /*
551 * We cache these in the opaque struct, to avoid repetitive syscache
552 * lookups.
553 */
554 opaque = (InclusionOpaque *) bdesc->bd_info[attno - 1]->oi_opaque;
555
556 /*
557 * If we already searched for this proc and didn't find it, don't bother
558 * searching again.
559 */
560 if (opaque->extra_proc_missing[basenum])
561 return NULL;
562
563 if (opaque->extra_procinfos[basenum].fn_oid == InvalidOid)
564 {
566 procnum)))
567 fmgr_info_copy(&opaque->extra_procinfos[basenum],
568 index_getprocinfo(bdesc->bd_index, attno, procnum),
569 bdesc->bd_context);
570 else
571 {
572 if (!missing_ok)
574 errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
575 errmsg_internal("invalid opclass definition"),
576 errdetail_internal("The operator class is missing support function %d for column %d.",
577 procnum, attno));
578
579 opaque->extra_proc_missing[basenum] = true;
580 return NULL;
581 }
582 }
583
584 return &opaque->extra_procinfos[basenum];
585}
586
587/*
588 * Cache and return the procedure of the given strategy
589 *
590 * Return the procedure corresponding to the given sub-type and strategy
591 * number. The data type of the index will be used as the left hand side of
592 * the operator and the given sub-type will be used as the right hand side.
593 * Throws an error if the pg_amop row does not exist, but that should not
594 * happen with a properly configured opclass.
595 *
596 * It always throws an error when the data type of the opclass is different
597 * from the data type of the column or the expression. That happens when the
598 * column data type has implicit cast to the opclass data type. We don't
599 * bother casting types, because this situation can easily be avoided by
600 * setting storage data type to that of the opclass. The same problem does not
601 * apply to the data type of the right hand side, because the type in the
602 * ScanKey always matches the opclass' one.
603 *
604 * Note: this function mirrors minmax_get_strategy_procinfo; if changes are
605 * made here, see that function too.
606 */
607static FmgrInfo *
609 uint16 strategynum)
610{
611 InclusionOpaque *opaque;
612
613 Assert(strategynum >= 1 &&
614 strategynum <= RTMaxStrategyNumber);
615
616 opaque = (InclusionOpaque *) bdesc->bd_info[attno - 1]->oi_opaque;
617
618 /*
619 * We cache the procedures for the last sub-type in the opaque struct, to
620 * avoid repetitive syscache lookups. If the sub-type is changed,
621 * invalidate all the cached entries.
622 */
623 if (opaque->cached_subtype != subtype)
624 {
625 uint16 i;
626
627 for (i = 1; i <= RTMaxStrategyNumber; i++)
628 opaque->strategy_procinfos[i - 1].fn_oid = InvalidOid;
629 opaque->cached_subtype = subtype;
630 }
631
632 if (opaque->strategy_procinfos[strategynum - 1].fn_oid == InvalidOid)
633 {
635 HeapTuple tuple;
636 Oid opfamily,
637 oprid;
638
639 opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
640 attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
641 tuple = SearchSysCache4(AMOPSTRATEGY, ObjectIdGetDatum(opfamily),
642 ObjectIdGetDatum(attr->atttypid),
643 ObjectIdGetDatum(subtype),
644 Int16GetDatum(strategynum));
645
646 if (!HeapTupleIsValid(tuple))
647 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
648 strategynum, attr->atttypid, subtype, opfamily);
649
650 oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
651 Anum_pg_amop_amopopr));
652 ReleaseSysCache(tuple);
654
656 &opaque->strategy_procinfos[strategynum - 1],
657 bdesc->bd_context);
658 }
659
660 return &opaque->strategy_procinfos[strategynum - 1];
661}
int16 AttrNumber
Definition: attnum.h:21
#define PROCNUM_MERGEABLE
#define PROCNUM_EMPTY
Datum brin_inclusion_union(PG_FUNCTION_ARGS)
static FmgrInfo * inclusion_get_procinfo(BrinDesc *bdesc, uint16 attno, uint16 procnum, bool missing_ok)
#define INCLUSION_UNMERGEABLE
Datum brin_inclusion_opcinfo(PG_FUNCTION_ARGS)
static FmgrInfo * inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype, uint16 strategynum)
Datum brin_inclusion_consistent(PG_FUNCTION_ARGS)
Datum brin_inclusion_add_value(PG_FUNCTION_ARGS)
#define INCLUSION_UNION
#define INCLUSION_MAX_PROCNUMS
#define PROCNUM_BASE
struct InclusionOpaque InclusionOpaque
#define PROCNUM_CONTAINS
#define INCLUSION_CONTAINS_EMPTY
#define PROCNUM_MERGE
#define SizeofBrinOpcInfo(ncols)
Definition: brin_internal.h:41
#define RegProcedureIsValid(p)
Definition: c.h:748
#define MAXALIGN(LEN)
Definition: c.h:782
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:224
uint16_t uint16
Definition: c.h:501
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1230
int errcode(int sqlerrcode)
Definition: elog.c:853
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1149
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:137
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Definition: fmgr.c:1129
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
Definition: fmgr.c:580
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_NARGS()
Definition: fmgr.h:203
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define newval
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:906
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:872
int i
Definition: isn.c:74
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:78
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1368
void pfree(void *pointer)
Definition: mcxt.c:1524
void * palloc0(Size size)
Definition: mcxt.c:1347
Oid oprid(Operator op)
Definition: parse_oper.c:238
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
static bool DatumGetBool(Datum X)
Definition: postgres.h:95
uintptr_t Datum
Definition: postgres.h:69
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:247
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:177
static Datum BoolGetDatum(bool X)
Definition: postgres.h:107
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32
ScanKeyData * ScanKey
Definition: skey.h:75
#define RTSubStrategyNumber
Definition: stratnum.h:74
#define RTOverlapStrategyNumber
Definition: stratnum.h:53
#define RTLeftStrategyNumber
Definition: stratnum.h:51
#define RTSubEqualStrategyNumber
Definition: stratnum.h:75
#define RTSuperEqualStrategyNumber
Definition: stratnum.h:77
#define RTOverRightStrategyNumber
Definition: stratnum.h:54
#define RTRightStrategyNumber
Definition: stratnum.h:55
#define RTSameStrategyNumber
Definition: stratnum.h:56
#define RTEqualStrategyNumber
Definition: stratnum.h:68
#define RTOverAboveStrategyNumber
Definition: stratnum.h:62
#define RTMaxStrategyNumber
Definition: stratnum.h:82
#define RTLessEqualStrategyNumber
Definition: stratnum.h:71
#define RTGreaterEqualStrategyNumber
Definition: stratnum.h:73
#define RTContainsStrategyNumber
Definition: stratnum.h:57
#define RTOverBelowStrategyNumber
Definition: stratnum.h:59
#define RTBelowStrategyNumber
Definition: stratnum.h:60
#define RTGreaterStrategyNumber
Definition: stratnum.h:72
#define RTSuperStrategyNumber
Definition: stratnum.h:76
#define RTAboveStrategyNumber
Definition: stratnum.h:61
#define RTOverLeftStrategyNumber
Definition: stratnum.h:52
#define RTContainedByStrategyNumber
Definition: stratnum.h:58
#define RTLessStrategyNumber
Definition: stratnum.h:70
#define RTContainsElemStrategyNumber
Definition: stratnum.h:66
#define RTAdjacentStrategyNumber
Definition: stratnum.h:67
TupleDesc bd_tupdesc
Definition: brin_internal.h:53
BrinOpcInfo * bd_info[FLEXIBLE_ARRAY_MEMBER]
Definition: brin_internal.h:62
Relation bd_index
Definition: brin_internal.h:50
MemoryContext bd_context
Definition: brin_internal.h:47
TypeCacheEntry * oi_typcache[FLEXIBLE_ARRAY_MEMBER]
Definition: brin_internal.h:37
uint16 oi_nstored
Definition: brin_internal.h:28
bool oi_regular_nulls
Definition: brin_internal.h:31
void * oi_opaque
Definition: brin_internal.h:34
Datum * bv_values
Definition: brin_tuple.h:34
AttrNumber bv_attno
Definition: brin_tuple.h:31
bool bv_allnulls
Definition: brin_tuple.h:33
int16 attlen
Definition: tupdesc.h:71
Definition: fmgr.h:57
Oid fn_oid
Definition: fmgr.h:59
FmgrInfo extra_procinfos[INCLUSION_MAX_PROCNUMS]
FmgrInfo strategy_procinfos[RTMaxStrategyNumber]
bool extra_proc_missing[INCLUSION_MAX_PROCNUMS]
Oid * rd_opfamily
Definition: rel.h:207
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:254
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:631
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:154
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:169
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:386