PostgreSQL Source Code git master
brin_minmax.c File Reference
#include "postgres.h"
#include "access/brin_internal.h"
#include "access/brin_tuple.h"
#include "access/stratnum.h"
#include "catalog/pg_amop.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_minmax.c:

Go to the source code of this file.

Data Structures

struct  MinmaxOpaque
 

Typedefs

typedef struct MinmaxOpaque MinmaxOpaque
 

Functions

static FmgrInfominmax_get_strategy_procinfo (BrinDesc *bdesc, uint16 attno, Oid subtype, uint16 strategynum)
 
Datum brin_minmax_opcinfo (PG_FUNCTION_ARGS)
 
Datum brin_minmax_add_value (PG_FUNCTION_ARGS)
 
Datum brin_minmax_consistent (PG_FUNCTION_ARGS)
 
Datum brin_minmax_union (PG_FUNCTION_ARGS)
 

Typedef Documentation

◆ MinmaxOpaque

typedef struct MinmaxOpaque MinmaxOpaque

Function Documentation

◆ brin_minmax_add_value()

Datum brin_minmax_add_value ( PG_FUNCTION_ARGS  )

Definition at line 64 of file brin_minmax.c.

65{
66 BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
70 Oid colloid = PG_GET_COLLATION();
71 FmgrInfo *cmpFn;
72 Datum compar;
73 bool updated = false;
75 AttrNumber attno;
76
77 Assert(!isnull);
78
79 attno = column->bv_attno;
80 attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
81
82 /*
83 * If the recorded value is null, store the new value (which we know to be
84 * not null) as both minimum and maximum, and we're done.
85 */
86 if (column->bv_allnulls)
87 {
88 column->bv_values[0] = datumCopy(newval, attr->attbyval, attr->attlen);
89 column->bv_values[1] = datumCopy(newval, attr->attbyval, attr->attlen);
90 column->bv_allnulls = false;
91 PG_RETURN_BOOL(true);
92 }
93
94 /*
95 * Otherwise, need to compare the new value with the existing boundaries
96 * and update them accordingly. First check if it's less than the
97 * existing minimum.
98 */
99 cmpFn = minmax_get_strategy_procinfo(bdesc, attno, attr->atttypid,
101 compar = FunctionCall2Coll(cmpFn, colloid, newval, column->bv_values[0]);
102 if (DatumGetBool(compar))
103 {
104 if (!attr->attbyval)
105 pfree(DatumGetPointer(column->bv_values[0]));
106 column->bv_values[0] = datumCopy(newval, attr->attbyval, attr->attlen);
107 updated = true;
108 }
109
110 /*
111 * And now compare it to the existing maximum.
112 */
113 cmpFn = minmax_get_strategy_procinfo(bdesc, attno, attr->atttypid,
115 compar = FunctionCall2Coll(cmpFn, colloid, newval, column->bv_values[1]);
116 if (DatumGetBool(compar))
117 {
118 if (!attr->attbyval)
119 pfree(DatumGetPointer(column->bv_values[1]));
120 column->bv_values[1] = datumCopy(newval, attr->attbyval, attr->attlen);
121 updated = true;
122 }
123
124 PG_RETURN_BOOL(updated);
125}
int16 AttrNumber
Definition: attnum.h:21
static FmgrInfo * minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype, uint16 strategynum)
Definition: brin_minmax.c:261
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:204
#define Assert(condition)
Definition: c.h:815
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
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define newval
void pfree(void *pointer)
Definition: mcxt.c:1521
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 Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
unsigned int Oid
Definition: postgres_ext.h:32
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define BTLessStrategyNumber
Definition: stratnum.h:29
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
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:153

References Assert, BrinDesc::bd_tupdesc, BTGreaterStrategyNumber, BTLessStrategyNumber, BrinValues::bv_allnulls, BrinValues::bv_attno, BrinValues::bv_values, datumCopy(), DatumGetBool(), DatumGetPointer(), FunctionCall2Coll(), minmax_get_strategy_procinfo(), newval, pfree(), PG_GET_COLLATION, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_BOOL, PG_USED_FOR_ASSERTS_ONLY, and TupleDescAttr().

◆ brin_minmax_consistent()

Datum brin_minmax_consistent ( PG_FUNCTION_ARGS  )

Definition at line 137 of file brin_minmax.c.

138{
139 BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
140 BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1);
142 Oid colloid = PG_GET_COLLATION(),
143 subtype;
144 AttrNumber attno;
145 Datum value;
146 Datum matches;
147 FmgrInfo *finfo;
148
149 /* This opclass uses the old signature with only three arguments. */
150 Assert(PG_NARGS() == 3);
151
152 /* Should not be dealing with all-NULL ranges. */
153 Assert(!column->bv_allnulls);
154
155 attno = key->sk_attno;
156 subtype = key->sk_subtype;
157 value = key->sk_argument;
158 switch (key->sk_strategy)
159 {
162 finfo = minmax_get_strategy_procinfo(bdesc, attno, subtype,
163 key->sk_strategy);
164 matches = FunctionCall2Coll(finfo, colloid, column->bv_values[0],
165 value);
166 break;
168
169 /*
170 * In the equality case (WHERE col = someval), we want to return
171 * the current page range if the minimum value in the range <=
172 * scan key, and the maximum value >= scan key.
173 */
174 finfo = minmax_get_strategy_procinfo(bdesc, attno, subtype,
176 matches = FunctionCall2Coll(finfo, colloid, column->bv_values[0],
177 value);
178 if (!DatumGetBool(matches))
179 break;
180 /* max() >= scankey */
181 finfo = minmax_get_strategy_procinfo(bdesc, attno, subtype,
183 matches = FunctionCall2Coll(finfo, colloid, column->bv_values[1],
184 value);
185 break;
188 finfo = minmax_get_strategy_procinfo(bdesc, attno, subtype,
189 key->sk_strategy);
190 matches = FunctionCall2Coll(finfo, colloid, column->bv_values[1],
191 value);
192 break;
193 default:
194 /* shouldn't happen */
195 elog(ERROR, "invalid strategy number %d", key->sk_strategy);
196 matches = 0;
197 break;
198 }
199
200 PG_RETURN_DATUM(matches);
201}
#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
static struct @162 value
ScanKeyData * ScanKey
Definition: skey.h:75
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define BTLessEqualStrategyNumber
Definition: stratnum.h:30
#define BTGreaterEqualStrategyNumber
Definition: stratnum.h:32

References Assert, BTEqualStrategyNumber, BTGreaterEqualStrategyNumber, BTGreaterStrategyNumber, BTLessEqualStrategyNumber, BTLessStrategyNumber, BrinValues::bv_allnulls, BrinValues::bv_values, DatumGetBool(), elog, ERROR, FunctionCall2Coll(), sort-test::key, minmax_get_strategy_procinfo(), PG_GET_COLLATION, PG_GETARG_POINTER, PG_NARGS, PG_RETURN_DATUM, and value.

◆ brin_minmax_opcinfo()

Datum brin_minmax_opcinfo ( PG_FUNCTION_ARGS  )

Definition at line 34 of file brin_minmax.c.

35{
36 Oid typoid = PG_GETARG_OID(0);
37 BrinOpcInfo *result;
38
39 /*
40 * opaque->strategy_procinfos is initialized lazily; here it is set to
41 * all-uninitialized by palloc0 which sets fn_oid to InvalidOid.
42 */
43
45 sizeof(MinmaxOpaque));
46 result->oi_nstored = 2;
47 result->oi_regular_nulls = true;
48 result->oi_opaque = (MinmaxOpaque *)
49 MAXALIGN((char *) result + SizeofBrinOpcInfo(2));
50 result->oi_typcache[0] = result->oi_typcache[1] =
51 lookup_type_cache(typoid, 0);
52
53 PG_RETURN_POINTER(result);
54}
#define SizeofBrinOpcInfo(ncols)
Definition: brin_internal.h:41
#define MAXALIGN(LEN)
Definition: c.h:768
#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 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_minmax_union()

Datum brin_minmax_union ( PG_FUNCTION_ARGS  )

Definition at line 208 of file brin_minmax.c.

209{
210 BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
213 Oid colloid = PG_GET_COLLATION();
214 AttrNumber attno;
216 FmgrInfo *finfo;
217 bool needsadj;
218
219 Assert(col_a->bv_attno == col_b->bv_attno);
220 Assert(!col_a->bv_allnulls && !col_b->bv_allnulls);
221
222 attno = col_a->bv_attno;
223 attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
224
225 /* Adjust minimum, if B's min is less than A's min */
226 finfo = minmax_get_strategy_procinfo(bdesc, attno, attr->atttypid,
228 needsadj = FunctionCall2Coll(finfo, colloid, col_b->bv_values[0],
229 col_a->bv_values[0]);
230 if (needsadj)
231 {
232 if (!attr->attbyval)
233 pfree(DatumGetPointer(col_a->bv_values[0]));
234 col_a->bv_values[0] = datumCopy(col_b->bv_values[0],
235 attr->attbyval, attr->attlen);
236 }
237
238 /* Adjust maximum, if B's max is greater than A's max */
239 finfo = minmax_get_strategy_procinfo(bdesc, attno, attr->atttypid,
241 needsadj = FunctionCall2Coll(finfo, colloid, col_b->bv_values[1],
242 col_a->bv_values[1]);
243 if (needsadj)
244 {
245 if (!attr->attbyval)
246 pfree(DatumGetPointer(col_a->bv_values[1]));
247 col_a->bv_values[1] = datumCopy(col_b->bv_values[1],
248 attr->attbyval, attr->attlen);
249 }
250
252}
#define PG_RETURN_VOID()
Definition: fmgr.h:349

References Assert, BrinDesc::bd_tupdesc, BTGreaterStrategyNumber, BTLessStrategyNumber, BrinValues::bv_allnulls, BrinValues::bv_attno, BrinValues::bv_values, datumCopy(), DatumGetPointer(), FunctionCall2Coll(), minmax_get_strategy_procinfo(), pfree(), PG_GET_COLLATION, PG_GETARG_POINTER, PG_RETURN_VOID, and TupleDescAttr().

◆ minmax_get_strategy_procinfo()

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

Definition at line 261 of file brin_minmax.c.

263{
264 MinmaxOpaque *opaque;
265
266 Assert(strategynum >= 1 &&
267 strategynum <= BTMaxStrategyNumber);
268
269 opaque = (MinmaxOpaque *) bdesc->bd_info[attno - 1]->oi_opaque;
270
271 /*
272 * We cache the procedures for the previous subtype in the opaque struct,
273 * to avoid repetitive syscache lookups. If the subtype changed,
274 * invalidate all the cached entries.
275 */
276 if (opaque->cached_subtype != subtype)
277 {
278 uint16 i;
279
280 for (i = 1; i <= BTMaxStrategyNumber; i++)
281 opaque->strategy_procinfos[i - 1].fn_oid = InvalidOid;
282 opaque->cached_subtype = subtype;
283 }
284
285 if (opaque->strategy_procinfos[strategynum - 1].fn_oid == InvalidOid)
286 {
288 HeapTuple tuple;
289 Oid opfamily,
290 oprid;
291
292 opfamily = bdesc->bd_index->rd_opfamily[attno - 1];
293 attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1);
294 tuple = SearchSysCache4(AMOPSTRATEGY, ObjectIdGetDatum(opfamily),
295 ObjectIdGetDatum(attr->atttypid),
296 ObjectIdGetDatum(subtype),
297 Int16GetDatum(strategynum));
298
299 if (!HeapTupleIsValid(tuple))
300 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
301 strategynum, attr->atttypid, subtype, opfamily);
302
303 oprid = DatumGetObjectId(SysCacheGetAttrNotNull(AMOPSTRATEGY, tuple,
304 Anum_pg_amop_amopopr));
305 ReleaseSysCache(tuple);
307
309 &opaque->strategy_procinfos[strategynum - 1],
310 bdesc->bd_context);
311 }
312
313 return &opaque->strategy_procinfos[strategynum - 1];
314}
#define RegProcedureIsValid(p)
Definition: c.h:734
uint16_t uint16
Definition: c.h:487
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
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1285
Oid oprid(Operator op)
Definition: parse_oper.c:238
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 InvalidOid
Definition: postgres_ext.h:37
#define BTMaxStrategyNumber
Definition: stratnum.h:35
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 strategy_procinfos[BTMaxStrategyNumber]
Definition: brin_minmax.c:26
Oid cached_subtype
Definition: brin_minmax.c:25
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

References Assert, BrinDesc::bd_context, BrinDesc::bd_index, BrinDesc::bd_info, BrinDesc::bd_tupdesc, BTMaxStrategyNumber, MinmaxOpaque::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(), SearchSysCache4(), MinmaxOpaque::strategy_procinfos, SysCacheGetAttrNotNull(), and TupleDescAttr().

Referenced by brin_minmax_add_value(), brin_minmax_consistent(), and brin_minmax_union().