PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
brin_inclusion.c File Reference
#include "postgres.h"
#include "access/brin_internal.h"
#include "access/brin_tuple.h"
#include "access/genam.h"
#include "access/skey.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_type.h"
#include "utils/datum.h"
#include "utils/fmgrprotos.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Include dependency graph for brin_inclusion.c:

Go to the source code of this file.

Data Structures

struct  InclusionOpaque
 

Macros

#define INCLUSION_MAX_PROCNUMS   4 /* maximum support procs we need */
 
#define PROCNUM_MERGE   11 /* required */
 
#define PROCNUM_MERGEABLE   12 /* optional */
 
#define PROCNUM_CONTAINS   13 /* optional */
 
#define PROCNUM_EMPTY   14 /* optional */
 
#define PROCNUM_BASE   11
 
#define INCLUSION_UNION   0
 
#define INCLUSION_UNMERGEABLE   1
 
#define INCLUSION_CONTAINS_EMPTY   2
 

Typedefs

typedef struct InclusionOpaque InclusionOpaque
 

Functions

static FmgrInfoinclusion_get_procinfo (BrinDesc *bdesc, uint16 attno, uint16 procnum, bool missing_ok)
 
static FmgrInfoinclusion_get_strategy_procinfo (BrinDesc *bdesc, uint16 attno, Oid subtype, uint16 strategynum)
 
Datum brin_inclusion_opcinfo (PG_FUNCTION_ARGS)
 
Datum brin_inclusion_add_value (PG_FUNCTION_ARGS)
 
Datum brin_inclusion_consistent (PG_FUNCTION_ARGS)
 
Datum brin_inclusion_union (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ INCLUSION_CONTAINS_EMPTY

#define INCLUSION_CONTAINS_EMPTY   2

Definition at line 73 of file brin_inclusion.c.

◆ INCLUSION_MAX_PROCNUMS

#define INCLUSION_MAX_PROCNUMS   4 /* maximum support procs we need */

Definition at line 46 of file brin_inclusion.c.

◆ INCLUSION_UNION

#define INCLUSION_UNION   0

Definition at line 71 of file brin_inclusion.c.

◆ INCLUSION_UNMERGEABLE

#define INCLUSION_UNMERGEABLE   1

Definition at line 72 of file brin_inclusion.c.

◆ PROCNUM_BASE

#define PROCNUM_BASE   11

Definition at line 57 of file brin_inclusion.c.

◆ PROCNUM_CONTAINS

#define PROCNUM_CONTAINS   13 /* optional */

Definition at line 49 of file brin_inclusion.c.

◆ PROCNUM_EMPTY

#define PROCNUM_EMPTY   14 /* optional */

Definition at line 50 of file brin_inclusion.c.

◆ PROCNUM_MERGE

#define PROCNUM_MERGE   11 /* required */

Definition at line 47 of file brin_inclusion.c.

◆ PROCNUM_MERGEABLE

#define PROCNUM_MERGEABLE   12 /* optional */

Definition at line 48 of file brin_inclusion.c.

Typedef Documentation

◆ InclusionOpaque

Function Documentation

◆ brin_inclusion_add_value()

Datum brin_inclusion_add_value ( PG_FUNCTION_ARGS  )

Definition at line 138 of file brin_inclusion.c.

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}
int16 AttrNumber
Definition: attnum.h:21
#define PROCNUM_MERGEABLE
#define PROCNUM_EMPTY
static FmgrInfo * inclusion_get_procinfo(BrinDesc *bdesc, uint16 attno, uint16 procnum, bool missing_ok)
#define INCLUSION_UNMERGEABLE
#define INCLUSION_UNION
#define PROCNUM_CONTAINS
#define INCLUSION_CONTAINS_EMPTY
#define PROCNUM_MERGE
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:224
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1149
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Definition: fmgr.c:1129
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define newval
Assert(PointerIsAligned(start, uint64))
void pfree(void *pointer)
Definition: mcxt.c:1524
static bool DatumGetBool(Datum X)
Definition: postgres.h:95
uintptr_t Datum
Definition: postgres.h:69
static Datum BoolGetDatum(bool X)
Definition: postgres.h:107
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
unsigned int Oid
Definition: postgres_ext.h:32
TupleDesc bd_tupdesc
Definition: brin_internal.h:53
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
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:169

References Assert(), CompactAttribute::attbyval, CompactAttribute::attlen, BrinDesc::bd_tupdesc, BoolGetDatum(), BrinValues::bv_allnulls, BrinValues::bv_attno, BrinValues::bv_values, datumCopy(), DatumGetBool(), DatumGetPointer(), FunctionCall1Coll(), FunctionCall2Coll(), INCLUSION_CONTAINS_EMPTY, inclusion_get_procinfo(), INCLUSION_UNION, INCLUSION_UNMERGEABLE, newval, pfree(), PG_GET_COLLATION, PG_GETARG_BOOL, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_BOOL, PG_USED_FOR_ASSERTS_ONLY, PROCNUM_CONTAINS, PROCNUM_EMPTY, PROCNUM_MERGE, PROCNUM_MERGEABLE, and TupleDescCompactAttr().

◆ brin_inclusion_consistent()

Datum brin_inclusion_consistent ( PG_FUNCTION_ARGS  )

Definition at line 250 of file brin_inclusion.c.

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}
static FmgrInfo * inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype, uint16 strategynum)
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define PG_NARGS()
Definition: fmgr.h:203
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
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 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

References Assert(), BrinValues::bv_allnulls, BrinValues::bv_values, DatumGetBool(), elog, ERROR, FunctionCall2Coll(), INCLUSION_CONTAINS_EMPTY, inclusion_get_strategy_procinfo(), INCLUSION_UNION, INCLUSION_UNMERGEABLE, sort-test::key, PG_GET_COLLATION, PG_GETARG_POINTER, PG_NARGS, PG_RETURN_BOOL, PG_RETURN_DATUM, RTAboveStrategyNumber, RTAdjacentStrategyNumber, RTBelowStrategyNumber, RTContainedByStrategyNumber, RTContainsElemStrategyNumber, RTContainsStrategyNumber, RTEqualStrategyNumber, RTGreaterEqualStrategyNumber, RTGreaterStrategyNumber, RTLeftStrategyNumber, RTLessEqualStrategyNumber, RTLessStrategyNumber, RTOverAboveStrategyNumber, RTOverBelowStrategyNumber, RTOverlapStrategyNumber, RTOverLeftStrategyNumber, RTOverRightStrategyNumber, RTRightStrategyNumber, RTSameStrategyNumber, RTSubEqualStrategyNumber, RTSubStrategyNumber, RTSuperEqualStrategyNumber, and RTSuperStrategyNumber.

◆ brin_inclusion_opcinfo()

Datum brin_inclusion_opcinfo ( PG_FUNCTION_ARGS  )

Definition at line 94 of file brin_inclusion.c.

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}
#define SizeofBrinOpcInfo(ncols)
Definition: brin_internal.h:41
#define MAXALIGN(LEN)
Definition: c.h:782
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
void * palloc0(Size size)
Definition: mcxt.c:1347
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
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:386

References INCLUSION_CONTAINS_EMPTY, INCLUSION_UNION, INCLUSION_UNMERGEABLE, lookup_type_cache(), MAXALIGN, BrinOpcInfo::oi_nstored, BrinOpcInfo::oi_opaque, BrinOpcInfo::oi_regular_nulls, BrinOpcInfo::oi_typcache, palloc0(), PG_GETARG_OID, PG_RETURN_POINTER, and SizeofBrinOpcInfo.

◆ brin_inclusion_union()

Datum brin_inclusion_union ( PG_FUNCTION_ARGS  )

Definition at line 474 of file brin_inclusion.c.

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}
#define PG_RETURN_VOID()
Definition: fmgr.h:349

References Assert(), CompactAttribute::attbyval, CompactAttribute::attlen, BrinDesc::bd_tupdesc, BoolGetDatum(), BrinValues::bv_allnulls, BrinValues::bv_attno, BrinValues::bv_values, datumCopy(), DatumGetBool(), DatumGetPointer(), FunctionCall2Coll(), INCLUSION_CONTAINS_EMPTY, inclusion_get_procinfo(), INCLUSION_UNION, INCLUSION_UNMERGEABLE, pfree(), PG_GET_COLLATION, PG_GETARG_POINTER, PG_RETURN_VOID, PROCNUM_MERGE, PROCNUM_MERGEABLE, and TupleDescCompactAttr().

◆ inclusion_get_procinfo()

static FmgrInfo * inclusion_get_procinfo ( BrinDesc bdesc,
uint16  attno,
uint16  procnum,
bool  missing_ok 
)
static

Definition at line 544 of file brin_inclusion.c.

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}
#define PROCNUM_BASE
#define RegProcedureIsValid(p)
Definition: c.h:748
uint16_t uint16
Definition: c.h:501
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 ereport(elevel,...)
Definition: elog.h:149
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
Definition: fmgr.c:580
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
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
#define InvalidOid
Definition: postgres_ext.h:37
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
Oid fn_oid
Definition: fmgr.h:59
FmgrInfo extra_procinfos[INCLUSION_MAX_PROCNUMS]
bool extra_proc_missing[INCLUSION_MAX_PROCNUMS]

References BrinDesc::bd_context, BrinDesc::bd_index, BrinDesc::bd_info, ereport, errcode(), errdetail_internal(), errmsg_internal(), ERROR, InclusionOpaque::extra_proc_missing, InclusionOpaque::extra_procinfos, fmgr_info_copy(), FmgrInfo::fn_oid, if(), index_getprocid(), index_getprocinfo(), InvalidOid, BrinOpcInfo::oi_opaque, PROCNUM_BASE, and RegProcedureIsValid.

Referenced by brin_inclusion_add_value(), and brin_inclusion_union().

◆ inclusion_get_strategy_procinfo()

static FmgrInfo * inclusion_get_strategy_procinfo ( BrinDesc bdesc,
uint16  attno,
Oid  subtype,
uint16  strategynum 
)
static

Definition at line 608 of file brin_inclusion.c.

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}
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:137
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int i
Definition: isn.c:72
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1324
Oid oprid(Operator op)
Definition: parse_oper.c:238
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:247
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:177
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
#define RTMaxStrategyNumber
Definition: stratnum.h:82
FmgrInfo strategy_procinfos[RTMaxStrategyNumber]
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

References Assert(), BrinDesc::bd_context, BrinDesc::bd_index, BrinDesc::bd_info, BrinDesc::bd_tupdesc, InclusionOpaque::cached_subtype, DatumGetObjectId(), elog, ERROR, fmgr_info_cxt(), FmgrInfo::fn_oid, get_opcode(), HeapTupleIsValid, i, if(), Int16GetDatum(), InvalidOid, ObjectIdGetDatum(), BrinOpcInfo::oi_opaque, oprid(), RelationData::rd_opfamily, RegProcedureIsValid, ReleaseSysCache(), RTMaxStrategyNumber, SearchSysCache4(), InclusionOpaque::strategy_procinfos, SysCacheGetAttrNotNull(), and TupleDescAttr().

Referenced by brin_inclusion_consistent().