PostgreSQL Source Code  git master
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)
 
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);
143  bool isnull PG_USED_FOR_ASSERTS_ONLY = PG_GETARG_BOOL(3);
144  Oid colloid = PG_GET_COLLATION();
145  FmgrInfo *finfo;
146  Datum result;
147  bool new = false;
148  AttrNumber attno;
149  Form_pg_attribute attr;
150 
151  Assert(!isnull);
152 
153  attno = column->bv_attno;
154  attr = TupleDescAttr(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);
164  column->bv_values[INCLUSION_UNMERGEABLE] = BoolGetDatum(false);
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,
227  column->bv_values[INCLUSION_UNION], newval);
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 }
int16 AttrNumber
Definition: attnum.h:21
#define PROCNUM_MERGEABLE
#define PROCNUM_EMPTY
#define INCLUSION_UNMERGEABLE
#define INCLUSION_UNION
#define PROCNUM_CONTAINS
#define INCLUSION_CONTAINS_EMPTY
static FmgrInfo * inclusion_get_procinfo(BrinDesc *bdesc, uint16 attno, uint16 procnum)
#define PROCNUM_MERGE
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:169
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(fmt[strlen(fmt) - 1] !='\n')
void pfree(void *pointer)
Definition: mcxt.c:1508
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
uintptr_t Datum
Definition: postgres.h:64
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
unsigned int Oid
Definition: postgres_ext.h:31
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
Definition: fmgr.h:57
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92

References Assert(), 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 TupleDescAttr.

◆ brin_inclusion_consistent()

Datum brin_inclusion_consistent ( PG_FUNCTION_ARGS  )

Definition at line 251 of file brin_inclusion.c.

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);
297  PG_RETURN_BOOL(!DatumGetBool(result));
298 
300  finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
302  result = FunctionCall2Coll(finfo, colloid, unionval, query);
303  PG_RETURN_BOOL(!DatumGetBool(result));
304 
306  finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
308  result = FunctionCall2Coll(finfo, colloid, unionval, query);
309  PG_RETURN_BOOL(!DatumGetBool(result));
310 
312  finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
314  result = FunctionCall2Coll(finfo, colloid, unionval, query);
315  PG_RETURN_BOOL(!DatumGetBool(result));
316 
318  finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
320  result = FunctionCall2Coll(finfo, colloid, unionval, query);
321  PG_RETURN_BOOL(!DatumGetBool(result));
322 
324  finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
326  result = FunctionCall2Coll(finfo, colloid, unionval, query);
327  PG_RETURN_BOOL(!DatumGetBool(result));
328 
330  finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
332  result = FunctionCall2Coll(finfo, colloid, unionval, query);
333  PG_RETURN_BOOL(!DatumGetBool(result));
334 
336  finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
338  result = FunctionCall2Coll(finfo, colloid, unionval, query);
339  PG_RETURN_BOOL(!DatumGetBool(result));
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 
352  case RTSubStrategyNumber:
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);
459  PG_RETURN_BOOL(!DatumGetBool(result));
460 
461  default:
462  /* shouldn't happen */
463  elog(ERROR, "invalid strategy number %d", key->sk_strategy);
464  PG_RETURN_BOOL(false);
465  }
466 }
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:224
#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 */
116  result->oi_typcache[INCLUSION_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:798
#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:1334
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:346

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 475 of file brin_inclusion.c.

476 {
477  BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
478  BrinValues *col_a = (BrinValues *) PG_GETARG_POINTER(1);
479  BrinValues *col_b = (BrinValues *) PG_GETARG_POINTER(2);
480  Oid colloid = PG_GET_COLLATION();
481  AttrNumber attno;
482  Form_pg_attribute 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 = TupleDescAttr(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. */
499  PG_RETURN_VOID();
500 
501  /* If B includes elements that are not mergeable, mark A similarly. */
503  {
505  PG_RETURN_VOID();
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,
512  col_a->bv_values[INCLUSION_UNION],
513  col_b->bv_values[INCLUSION_UNION])))
514  {
516  PG_RETURN_VOID();
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,
523  col_a->bv_values[INCLUSION_UNION],
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 
535  PG_RETURN_VOID();
536 }
#define PG_RETURN_VOID()
Definition: fmgr.h:349

References Assert(), 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 TupleDescAttr.

◆ inclusion_get_procinfo()

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

Definition at line 545 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  {
565  if (RegProcedureIsValid(index_getprocid(bdesc->bd_index, attno,
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 }
#define PROCNUM_BASE
unsigned short uint16
Definition: c.h:492
#define RegProcedureIsValid(p)
Definition: c.h:764
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:863
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:829
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
#define InvalidOid
Definition: postgres_ext.h:36
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, 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 603 of file brin_inclusion.c.

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  {
629  Form_pg_attribute attr;
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 }
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:73
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1263
Oid oprid(Operator op)
Definition: parse_oper.c:238
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
#define RTMaxStrategyNumber
Definition: stratnum.h:82
FmgrInfo strategy_procinfos[RTMaxStrategyNumber]
Oid * rd_opfamily
Definition: rel.h:207
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Definition: syscache.c:251
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:510

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().