PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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-2024, 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);
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);
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);
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);
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);
225 Assert(finfo != NULL);
226 result = FunctionCall2Coll(finfo, colloid,
228 if (!attr->attbyval &&
230 {
232
233 if (result == newval)
234 result = datumCopy(result, attr->attbyval, attr->attlen);
235 }
236 column->bv_values[INCLUSION_UNION] = result;
237
238 PG_RETURN_BOOL(true);
239}
240
241/*
242 * BRIN inclusion consistent function
243 *
244 * We're no longer dealing with NULL keys in the consistent function, that is
245 * now handled by the AM code. That means we should not get any all-NULL ranges
246 * either, because those can't be consistent with regular (not [IS] NULL) keys.
247 *
248 * All of the strategies are optional.
249 */
250Datum
252{
253 BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
254 BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1);
256 Oid colloid = PG_GET_COLLATION(),
257 subtype;
258 Datum unionval;
259 AttrNumber attno;
260 Datum query;
261 FmgrInfo *finfo;
262 Datum result;
263
264 /* This opclass uses the old signature with only three arguments. */
265 Assert(PG_NARGS() == 3);
266
267 /* Should not be dealing with all-NULL ranges. */
268 Assert(!column->bv_allnulls);
269
270 /* It has to be checked, if it contains elements that are not mergeable. */
272 PG_RETURN_BOOL(true);
273
274 attno = key->sk_attno;
275 subtype = key->sk_subtype;
276 query = key->sk_argument;
277 unionval = column->bv_values[INCLUSION_UNION];
278 switch (key->sk_strategy)
279 {
280 /*
281 * Placement strategies
282 *
283 * These are implemented by logically negating the result of the
284 * converse placement operator; for this to work, the converse
285 * operator must be part of the opclass. An error will be thrown
286 * by inclusion_get_strategy_procinfo() if the required strategy
287 * is not part of the opclass.
288 *
289 * These all return false if either argument is empty, so there is
290 * no need to check for empty elements.
291 */
292
294 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
296 result = FunctionCall2Coll(finfo, colloid, unionval, query);
298
300 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
302 result = FunctionCall2Coll(finfo, colloid, unionval, query);
304
306 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
308 result = FunctionCall2Coll(finfo, colloid, unionval, query);
310
312 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
314 result = FunctionCall2Coll(finfo, colloid, unionval, query);
316
318 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
320 result = FunctionCall2Coll(finfo, colloid, unionval, query);
322
324 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
326 result = FunctionCall2Coll(finfo, colloid, unionval, query);
328
330 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
332 result = FunctionCall2Coll(finfo, colloid, unionval, query);
334
336 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
338 result = FunctionCall2Coll(finfo, colloid, unionval, query);
340
341 /*
342 * Overlap and contains strategies
343 *
344 * These strategies are simple enough that we can simply call the
345 * operator and return its result. Empty elements don't change
346 * the result.
347 */
348
354 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
355 key->sk_strategy);
356 result = FunctionCall2Coll(finfo, colloid, unionval, query);
357 PG_RETURN_DATUM(result);
358
359 /*
360 * Contained by strategies
361 *
362 * We cannot just call the original operator for the contained by
363 * strategies because some elements can be contained even though
364 * the union is not; instead we use the overlap operator.
365 *
366 * We check for empty elements separately as they are not merged
367 * to the union but contained by everything.
368 */
369
373 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
375 result = FunctionCall2Coll(finfo, colloid, unionval, query);
376 if (DatumGetBool(result))
377 PG_RETURN_BOOL(true);
378
380
381 /*
382 * Adjacent strategy
383 *
384 * We test for overlap first but to be safe we need to call the
385 * actual adjacent operator also.
386 *
387 * An empty element cannot be adjacent to any other, so there is
388 * no need to check for it.
389 */
390
392 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
394 result = FunctionCall2Coll(finfo, colloid, unionval, query);
395 if (DatumGetBool(result))
396 PG_RETURN_BOOL(true);
397
398 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
400 result = FunctionCall2Coll(finfo, colloid, unionval, query);
401 PG_RETURN_DATUM(result);
402
403 /*
404 * Basic comparison strategies
405 *
406 * It is straightforward to support the equality strategies with
407 * the contains operator. Generally, inequality strategies do not
408 * make much sense for the types which will be used with the
409 * inclusion BRIN family of opclasses, but it is possible to
410 * implement them with logical negation of the left-of and
411 * right-of operators.
412 *
413 * NB: These strategies cannot be used with geometric datatypes
414 * that use comparison of areas! The only exception is the "same"
415 * strategy.
416 *
417 * Empty elements are considered to be less than the others. We
418 * cannot use the empty support function to check the query is an
419 * empty element, because the query can be another data type than
420 * the empty support function argument. So we will return true,
421 * if there is a possibility that empty elements will change the
422 * result.
423 */
424
427 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
429 result = FunctionCall2Coll(finfo, colloid, unionval, query);
430 if (!DatumGetBool(result))
431 PG_RETURN_BOOL(true);
432
434
437 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
439 result = FunctionCall2Coll(finfo, colloid, unionval, query);
440 if (DatumGetBool(result))
441 PG_RETURN_BOOL(true);
442
444
446 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
448 result = FunctionCall2Coll(finfo, colloid, unionval, query);
449 if (!DatumGetBool(result))
450 PG_RETURN_BOOL(true);
451
453
455 /* no need to check for empty elements */
456 finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
458 result = FunctionCall2Coll(finfo, colloid, unionval, query);
460
461 default:
462 /* shouldn't happen */
463 elog(ERROR, "invalid strategy number %d", key->sk_strategy);
464 PG_RETURN_BOOL(false);
465 }
466}
467
468/*
469 * BRIN inclusion union function
470 *
471 * Given two BrinValues, update the first of them as a union of the summary
472 * values contained in both. The second one is untouched.
473 */
474Datum
476{
477 BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
480 Oid colloid = PG_GET_COLLATION();
481 AttrNumber attno;
482 CompactAttribute *attr;
483 FmgrInfo *finfo;
484 Datum result;
485
486 Assert(col_a->bv_attno == col_b->bv_attno);
487 Assert(!col_a->bv_allnulls && !col_b->bv_allnulls);
488
489 attno = col_a->bv_attno;
490 attr = TupleDescCompactAttr(bdesc->bd_tupdesc, attno - 1);
491
492 /* If B includes empty elements, mark A similarly, if needed. */
496
497 /* Check if A includes elements that are not mergeable. */
500
501 /* If B includes elements that are not mergeable, mark A similarly. */
503 {
506 }
507
508 /* Check if A and B are mergeable; if not, mark A unmergeable. */
509 finfo = inclusion_get_procinfo(bdesc, attno, PROCNUM_MERGEABLE);
510 if (finfo != NULL &&
511 !DatumGetBool(FunctionCall2Coll(finfo, colloid,
513 col_b->bv_values[INCLUSION_UNION])))
514 {
517 }
518
519 /* Finally, merge B to A. */
520 finfo = inclusion_get_procinfo(bdesc, attno, PROCNUM_MERGE);
521 Assert(finfo != NULL);
522 result = FunctionCall2Coll(finfo, colloid,
524 col_b->bv_values[INCLUSION_UNION]);
525 if (!attr->attbyval &&
527 {
529
530 if (result == col_b->bv_values[INCLUSION_UNION])
531 result = datumCopy(result, attr->attbyval, attr->attlen);
532 }
533 col_a->bv_values[INCLUSION_UNION] = result;
534
536}
537
538/*
539 * Cache and return inclusion opclass support procedure
540 *
541 * Return the procedure corresponding to the given function support number
542 * or null if it is not exists.
543 */
544static FmgrInfo *
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 {
568 fmgr_info_copy(&opaque->extra_procinfos[basenum],
569 index_getprocinfo(bdesc->bd_index, attno, procnum),
570 bdesc->bd_context);
571 }
572 else
573 {
574 opaque->extra_proc_missing[basenum] = true;
575 return NULL;
576 }
577 }
578
579 return &opaque->extra_procinfos[basenum];
580}
581
582/*
583 * Cache and return the procedure of the given strategy
584 *
585 * Return the procedure corresponding to the given sub-type and strategy
586 * number. The data type of the index will be used as the left hand side of
587 * the operator and the given sub-type will be used as the right hand side.
588 * Throws an error if the pg_amop row does not exist, but that should not
589 * happen with a properly configured opclass.
590 *
591 * It always throws an error when the data type of the opclass is different
592 * from the data type of the column or the expression. That happens when the
593 * column data type has implicit cast to the opclass data type. We don't
594 * bother casting types, because this situation can easily be avoided by
595 * setting storage data type to that of the opclass. The same problem does not
596 * apply to the data type of the right hand side, because the type in the
597 * ScanKey always matches the opclass' one.
598 *
599 * Note: this function mirrors minmax_get_strategy_procinfo; if changes are
600 * made here, see that function too.
601 */
602static FmgrInfo *
604 uint16 strategynum)
605{
606 InclusionOpaque *opaque;
607
608 Assert(strategynum >= 1 &&
609 strategynum <= RTMaxStrategyNumber);
610
611 opaque = (InclusionOpaque *) bdesc->bd_info[attno - 1]->oi_opaque;
612
613 /*
614 * We cache the procedures for the last sub-type in the opaque struct, to
615 * avoid repetitive syscache lookups. If the sub-type is changed,
616 * invalidate all the cached entries.
617 */
618 if (opaque->cached_subtype != subtype)
619 {
620 uint16 i;
621
622 for (i = 1; i <= RTMaxStrategyNumber; i++)
623 opaque->strategy_procinfos[i - 1].fn_oid = InvalidOid;
624 opaque->cached_subtype = subtype;
625 }
626
627 if (opaque->strategy_procinfos[strategynum - 1].fn_oid == InvalidOid)
628 {
630 HeapTuple tuple;
631 Oid opfamily,
632 oprid;
633
634 opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
635 attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
636 tuple = SearchSysCache4(AMOPSTRATEGY, ObjectIdGetDatum(opfamily),
637 ObjectIdGetDatum(attr->atttypid),
638 ObjectIdGetDatum(subtype),
639 Int16GetDatum(strategynum));
640
641 if (!HeapTupleIsValid(tuple))
642 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
643 strategynum, attr->atttypid, subtype, opfamily);
644
645 oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
646 Anum_pg_amop_amopopr));
647 ReleaseSysCache(tuple);
649
651 &opaque->strategy_procinfos[strategynum - 1],
652 bdesc->bd_context);
653 }
654
655 return &opaque->strategy_procinfos[strategynum - 1];
656}
int16 AttrNumber
Definition: attnum.h:21
#define PROCNUM_MERGEABLE
#define PROCNUM_EMPTY
Datum brin_inclusion_union(PG_FUNCTION_ARGS)
#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
static FmgrInfo * inclusion_get_procinfo(BrinDesc *bdesc, uint16 attno, uint16 procnum)
#define PROCNUM_MERGE
#define SizeofBrinOpcInfo(ncols)
Definition: brin_internal.h:41
#define RegProcedureIsValid(p)
Definition: c.h:731
#define MAXALIGN(LEN)
Definition: c.h:765
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:201
#define Assert(condition)
Definition: c.h:812
uint16_t uint16
Definition: c.h:484
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
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
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:862
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:828
int i
Definition: isn.c:72
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1285
void pfree(void *pointer)
Definition: mcxt.c:1521
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:90
uintptr_t Datum
Definition: postgres.h:64
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
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:69
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:152
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:169
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:386