PostgreSQL Source Code git master
Loading...
Searching...
No Matches
_int_selfuncs.c File Reference
#include "postgres.h"
#include "_int.h"
#include "access/htup_details.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "commands/extension.h"
#include "miscadmin.h"
#include "utils/fmgrprotos.h"
#include "utils/lsyscache.h"
#include "utils/selfuncs.h"
Include dependency graph for _int_selfuncs.c:

Go to the source code of this file.

Functions

 PG_FUNCTION_INFO_V1 (_int_overlap_sel)
 
 PG_FUNCTION_INFO_V1 (_int_contains_sel)
 
 PG_FUNCTION_INFO_V1 (_int_contained_sel)
 
 PG_FUNCTION_INFO_V1 (_int_overlap_joinsel)
 
 PG_FUNCTION_INFO_V1 (_int_contains_joinsel)
 
 PG_FUNCTION_INFO_V1 (_int_contained_joinsel)
 
 PG_FUNCTION_INFO_V1 (_int_matchsel)
 
static Selectivity int_query_opr_selec (ITEM *item, Datum *mcelems, float4 *mcefreqs, int nmcelems, float4 minfreq)
 
static int compare_val_int4 (const void *a, const void *b)
 
Datum _int_overlap_sel (PG_FUNCTION_ARGS)
 
Datum _int_contains_sel (PG_FUNCTION_ARGS)
 
Datum _int_contained_sel (PG_FUNCTION_ARGS)
 
Datum _int_overlap_joinsel (PG_FUNCTION_ARGS)
 
Datum _int_contains_joinsel (PG_FUNCTION_ARGS)
 
Datum _int_contained_joinsel (PG_FUNCTION_ARGS)
 
Datum _int_matchsel (PG_FUNCTION_ARGS)
 

Function Documentation

◆ _int_contained_joinsel()

Datum _int_contained_joinsel ( PG_FUNCTION_ARGS  )

Definition at line 108 of file _int_selfuncs.c.

109{
115 PG_GETARG_DATUM(4)));
116}
Datum arraycontjoinsel(PG_FUNCTION_ARGS)
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354
#define DirectFunctionCall5(func, arg1, arg2, arg3, arg4, arg5)
Definition fmgr.h:696
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static int fb(int x)

References arraycontjoinsel(), DirectFunctionCall5, fb(), ObjectIdGetDatum(), PG_GETARG_DATUM, and PG_RETURN_DATUM.

◆ _int_contained_sel()

Datum _int_contained_sel ( PG_FUNCTION_ARGS  )

Definition at line 76 of file _int_selfuncs.c.

77{
82 PG_GETARG_DATUM(3)));
83}
Datum arraycontsel(PG_FUNCTION_ARGS)
#define DirectFunctionCall4(func, arg1, arg2, arg3, arg4)
Definition fmgr.h:694

References arraycontsel(), DirectFunctionCall4, fb(), ObjectIdGetDatum(), PG_GETARG_DATUM, and PG_RETURN_DATUM.

◆ _int_contains_joinsel()

◆ _int_contains_sel()

◆ _int_matchsel()

Datum _int_matchsel ( PG_FUNCTION_ARGS  )

Definition at line 123 of file _int_selfuncs.c.

124{
126
128 int varRelid = PG_GETARG_INT32(3);
130 Node *other;
131 bool varonleft;
133 QUERYTYPE *query;
134 Datum *mcelems = NULL;
136 int nmcelems = 0;
137 float4 minfreq = 0.0;
138 float4 nullfrac = 0.0;
140
141 /*
142 * If expression is not "variable @@ something" or "something @@ variable"
143 * then punt and return a default estimate.
144 */
145 if (!get_restriction_variable(root, args, varRelid,
146 &vardata, &other, &varonleft))
148
149 /*
150 * Variable should be int[]. We don't support cases where variable is
151 * query_int.
152 */
153 if (vardata.vartype != INT4ARRAYOID)
154 {
157 }
158
159 /*
160 * Can't do anything useful if the something is not a constant, either.
161 */
162 if (!IsA(other, Const))
163 {
166 }
167
168 /*
169 * The "@@" operator is strict, so we can cope with NULL right away.
170 */
171 if (((Const *) other)->constisnull)
172 {
174 PG_RETURN_FLOAT8(0.0);
175 }
176
177 /*
178 * Verify that the Const is a query_int, else return a default estimate.
179 * (This could only fail if someone attached this estimator to the wrong
180 * operator.)
181 */
182 if (((Const *) other)->consttype !=
183 get_function_sibling_type(fcinfo->flinfo->fn_oid, "query_int"))
184 {
187 }
188
190
191 /* Empty query matches nothing */
192 if (query->size == 0)
193 {
195 PG_RETURN_FLOAT8(0.0);
196 }
197
198 /*
199 * Get the statistics for the intarray column.
200 *
201 * We're interested in the Most-Common-Elements list, and the NULL
202 * fraction.
203 */
204 if (HeapTupleIsValid(vardata.statsTuple))
205 {
206 Form_pg_statistic stats;
207
208 stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple);
209 nullfrac = stats->stanullfrac;
210
211 /*
212 * For an int4 array, the default array type analyze function will
213 * collect a Most Common Elements list, which is an array of int4s.
214 */
215 if (get_attstatsslot(&sslot, vardata.statsTuple,
218 {
219 Assert(sslot.valuetype == INT4OID);
220
221 /*
222 * There should be three more Numbers than Values, because the
223 * last three (for intarray) cells are taken for minimal, maximal
224 * and nulls frequency. Punt if not.
225 */
226 if (sslot.nnumbers == sslot.nvalues + 3)
227 {
228 /* Grab the minimal MCE frequency. */
229 minfreq = sslot.numbers[sslot.nvalues];
230
231 mcelems = sslot.values;
232 mcefreqs = sslot.numbers;
233 nmcelems = sslot.nvalues;
234 }
235 }
236 }
237 else
238 memset(&sslot, 0, sizeof(sslot));
239
240 /* Process the logical expression in the query, using the stats */
241 selec = int_query_opr_selec(GETQUERY(query) + query->size - 1,
243
244 /* MCE stats count only non-null rows, so adjust for null rows. */
245 selec *= (1.0 - nullfrac);
246
249
251
253}
#define GETQUERY(x)
Definition _int.h:157
#define DatumGetQueryTypeP(X)
Definition _int.h:168
static Selectivity int_query_opr_selec(ITEM *item, Datum *mcelems, float4 *mcefreqs, int nmcelems, float4 minfreq)
#define Assert(condition)
Definition c.h:943
double float8
Definition c.h:714
float float4
Definition c.h:713
Oid get_function_sibling_type(Oid funcoid, const char *typname)
Definition extension.c:313
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
void free_attstatsslot(AttStatsSlot *sslot)
Definition lsyscache.c:3577
bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)
Definition lsyscache.c:3467
#define ATTSTATSSLOT_NUMBERS
Definition lsyscache.h:44
#define ATTSTATSSLOT_VALUES
Definition lsyscache.h:43
#define IsA(nodeptr, _type_)
Definition nodes.h:164
double Selectivity
Definition nodes.h:260
FormData_pg_statistic * Form_pg_statistic
uint64_t Datum
Definition postgres.h:70
#define InvalidOid
tree ctl root
Definition radixtree.h:1857
bool get_restriction_variable(PlannerInfo *root, List *args, int varRelid, VariableStatData *vardata, Node **other, bool *varonleft)
Definition selfuncs.c:5512
#define ReleaseVariableStats(vardata)
Definition selfuncs.h:101
#define CLAMP_PROBABILITY(p)
Definition selfuncs.h:63
#define DEFAULT_EQ_SEL
Definition selfuncs.h:34
Definition pg_list.h:54
Definition nodes.h:135
int32 size
Definition _int.h:150

References Assert, ATTSTATSSLOT_NUMBERS, ATTSTATSSLOT_VALUES, CLAMP_PROBABILITY, DatumGetQueryTypeP, DEFAULT_EQ_SEL, fb(), free_attstatsslot(), get_attstatsslot(), get_function_sibling_type(), get_restriction_variable(), GETQUERY, GETSTRUCT(), HeapTupleIsValid, int_query_opr_selec(), InvalidOid, IsA, PG_GETARG_INT32, PG_GETARG_POINTER, PG_RETURN_FLOAT8, ReleaseVariableStats, root, and QUERYTYPE::size.

◆ _int_overlap_joinsel()

◆ _int_overlap_sel()

◆ compare_val_int4()

static int compare_val_int4 ( const void a,
const void b 
)
static

Definition at line 344 of file _int_selfuncs.c.

345{
346 int32 key = *(const int32 *) a;
347 int32 value = DatumGetInt32(*(const Datum *) b);
348
349 if (key < value)
350 return -1;
351 else if (key > value)
352 return 1;
353 else
354 return 0;
355}
int32_t int32
Definition c.h:620
static struct @177 value
int b
Definition isn.c:74
int a
Definition isn.c:73
static int32 DatumGetInt32(Datum X)
Definition postgres.h:202

References a, b, DatumGetInt32(), and value.

Referenced by int_query_opr_selec().

◆ int_query_opr_selec()

static Selectivity int_query_opr_selec ( ITEM item,
Datum mcelems,
float4 mcefreqs,
int  nmcelems,
float4  minfreq 
)
static

Definition at line 259 of file _int_selfuncs.c.

261{
263
264 /* since this function recurses, it could be driven to stack overflow */
266
267 if (item->type == VAL)
268 {
270
271 if (mcelems == NULL)
273
274 searchres = (Datum *) bsearch(&item->val, mcelems, nmcelems,
275 sizeof(Datum), compare_val_int4);
276 if (searchres)
277 {
278 /*
279 * The element is in MCELEM. Return precise selectivity (or at
280 * least as precise as ANALYZE could find out).
281 */
283 }
284 else
285 {
286 /*
287 * The element is not in MCELEM. Estimate its frequency as half
288 * that of the least-frequent MCE. (We know it cannot be more
289 * than minfreq, and it could be a great deal less. Half seems
290 * like a good compromise.) For probably-historical reasons,
291 * clamp to not more than DEFAULT_EQ_SEL.
292 */
294 }
295 }
296 else if (item->type == OPR)
297 {
298 /* Current query node is an operator */
300 s2;
301
303 minfreq);
304 switch (item->val)
305 {
306 case (int32) '!':
307 selec = 1.0 - s1;
308 break;
309
310 case (int32) '&':
311 s2 = int_query_opr_selec(item + item->left, mcelems, mcefreqs,
313 selec = s1 * s2;
314 break;
315
316 case (int32) '|':
317 s2 = int_query_opr_selec(item + item->left, mcelems, mcefreqs,
319 selec = s1 + s2 - s1 * s2;
320 break;
321
322 default:
323 elog(ERROR, "unrecognized operator: %d", item->val);
324 selec = 0; /* keep compiler quiet */
325 break;
326 }
327 }
328 else
329 {
330 elog(ERROR, "unrecognized int query item type: %u", item->type);
331 selec = 0; /* keep compiler quiet */
332 }
333
334 /* Clamp intermediate results to stay sane despite roundoff error */
336
337 return selec;
338}
#define OPR
Definition _int.h:163
#define VAL
Definition _int.h:162
static int compare_val_int4(const void *a, const void *b)
#define Min(x, y)
Definition c.h:1091
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
char * s1
char * s2
void check_stack_depth(void)
Definition stack_depth.c:96
int16 left
Definition _int.h:143
int32 val
Definition _int.h:144
int16 type
Definition _int.h:142

References check_stack_depth(), CLAMP_PROBABILITY, compare_val_int4(), DEFAULT_EQ_SEL, elog, ERROR, fb(), int_query_opr_selec(), ITEM::left, Min, OPR, s1, s2, ITEM::type, ITEM::val, and VAL.

Referenced by _int_matchsel(), and int_query_opr_selec().

◆ PG_FUNCTION_INFO_V1() [1/7]

PG_FUNCTION_INFO_V1 ( _int_contained_joinsel  )

◆ PG_FUNCTION_INFO_V1() [2/7]

PG_FUNCTION_INFO_V1 ( _int_contained_sel  )

◆ PG_FUNCTION_INFO_V1() [3/7]

PG_FUNCTION_INFO_V1 ( _int_contains_joinsel  )

◆ PG_FUNCTION_INFO_V1() [4/7]

PG_FUNCTION_INFO_V1 ( _int_contains_sel  )

◆ PG_FUNCTION_INFO_V1() [5/7]

PG_FUNCTION_INFO_V1 ( _int_matchsel  )

◆ PG_FUNCTION_INFO_V1() [6/7]

PG_FUNCTION_INFO_V1 ( _int_overlap_joinsel  )

◆ PG_FUNCTION_INFO_V1() [7/7]

PG_FUNCTION_INFO_V1 ( _int_overlap_sel  )