PostgreSQL Source Code git master
Loading...
Searching...
No Matches
extended_stats_funcs.c File Reference
#include "postgres.h"
#include "access/heapam.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_database.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_statistic_ext_data.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/optimizer.h"
#include "statistics/extended_stats_internal.h"
#include "statistics/stat_utils.h"
#include "utils/acl.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
Include dependency graph for extended_stats_funcs.c:

Go to the source code of this file.

Data Structures

struct  StakindFlags
 

Enumerations

enum  extended_stats_argnum {
  RELSCHEMA_ARG = 0 , RELNAME_ARG , STATSCHEMA_ARG , STATNAME_ARG ,
  INHERITED_ARG , NDISTINCT_ARG , DEPENDENCIES_ARG , MOST_COMMON_VALS_ARG ,
  MOST_COMMON_FREQS_ARG , MOST_COMMON_BASE_FREQS_ARG , NUM_EXTENDED_STATS_ARGS
}
 

Functions

static bool extended_statistics_update (FunctionCallInfo fcinfo)
 
static HeapTuple get_pg_statistic_ext (Relation pg_stext, Oid nspoid, const char *stxname)
 
static bool delete_pg_statistic_ext_data (Oid stxoid, bool inherited)
 
static void expand_stxkind (HeapTuple tup, StakindFlags *enabled)
 
static void upsert_pg_statistic_ext_data (const Datum *values, const bool *nulls, const bool *replaces)
 
static bool check_mcvlist_array (const ArrayType *arr, int argindex, int required_ndims, int mcv_length)
 
static Datum import_mcv (const ArrayType *mcv_arr, const ArrayType *freqs_arr, const ArrayType *base_freqs_arr, Oid *atttypids, int32 *atttypmods, Oid *atttypcolls, int numattrs, bool *ok)
 
Datum pg_restore_extended_stats (PG_FUNCTION_ARGS)
 
Datum pg_clear_extended_stats (PG_FUNCTION_ARGS)
 

Variables

static struct StatsArgInfo extarginfo []
 

Enumeration Type Documentation

◆ extended_stats_argnum

Enumerator
RELSCHEMA_ARG 
RELNAME_ARG 
STATSCHEMA_ARG 
STATNAME_ARG 
INHERITED_ARG 
NDISTINCT_ARG 
DEPENDENCIES_ARG 
MOST_COMMON_VALS_ARG 
MOST_COMMON_FREQS_ARG 
MOST_COMMON_BASE_FREQS_ARG 
NUM_EXTENDED_STATS_ARGS 

Definition at line 42 of file extended_stats_funcs.c.

Function Documentation

◆ check_mcvlist_array()

static bool check_mcvlist_array ( const ArrayType arr,
int  argindex,
int  required_ndims,
int  mcv_length 
)
static

Definition at line 654 of file extended_stats_funcs.c.

656{
657 if (ARR_NDIM(arr) != required_ndims)
658 {
661 errmsg("could not parse array \"%s\": incorrect number of dimensions (%d required)",
662 extarginfo[argindex].argname, required_ndims));
663 return false;
664 }
665
666 if (array_contains_nulls(arr))
667 {
670 errmsg("could not parse array \"%s\": NULL value found",
671 extarginfo[argindex].argname));
672 return false;
673 }
674
675 if (ARR_DIMS(arr)[0] != mcv_length)
676 {
679 errmsg("could not parse array \"%s\": incorrect number of elements (same as \"%s\" required)",
680 extarginfo[argindex].argname,
682 return false;
683 }
684
685 return true;
686}
#define ARR_NDIM(a)
Definition array.h:290
#define ARR_DIMS(a)
Definition array.h:294
bool array_contains_nulls(const ArrayType *array)
int errcode(int sqlerrcode)
Definition elog.c:874
int errmsg(const char *fmt,...)
Definition elog.c:1093
#define WARNING
Definition elog.h:36
#define ereport(elevel,...)
Definition elog.h:150
static struct StatsArgInfo extarginfo[]
static int fb(int x)

References StatsArgInfo::argname, ARR_DIMS, ARR_NDIM, array_contains_nulls(), ereport, errcode(), errmsg(), extarginfo, fb(), MOST_COMMON_VALS_ARG, and WARNING.

Referenced by import_mcv().

◆ delete_pg_statistic_ext_data()

static bool delete_pg_statistic_ext_data ( Oid  stxoid,
bool  inherited 
)
static

Definition at line 766 of file extended_stats_funcs.c.

767{
770 bool result = false;
771
772 /* Is there already a pg_statistic_ext_data tuple for this attribute? */
776
778 {
779 CatalogTupleDelete(sed, &oldtup->t_self);
781 result = true;
782 }
783
785
787
788 return result;
789}
#define HeapTupleIsValid(tuple)
Definition htup.h:78
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
#define RowExclusiveLock
Definition lockdefs.h:38
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:230
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
void CommandCounterIncrement(void)
Definition xact.c:1101

References BoolGetDatum(), CatalogTupleDelete(), CommandCounterIncrement(), fb(), HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), RowExclusiveLock, SearchSysCache2(), table_close(), and table_open().

Referenced by pg_clear_extended_stats().

◆ expand_stxkind()

static void expand_stxkind ( HeapTuple  tup,
StakindFlags enabled 
)
static

Definition at line 161 of file extended_stats_funcs.c.

162{
163 Datum datum;
164 ArrayType *arr;
165 char *kinds;
166
168 tup,
170 arr = DatumGetArrayTypeP(datum);
171 if (ARR_NDIM(arr) != 1 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != CHAROID)
172 elog(ERROR, "stxkind is not a one-dimension char array");
173
174 kinds = (char *) ARR_DATA_PTR(arr);
175
176 for (int i = 0; i < ARR_DIMS(arr)[0]; i++)
177 {
178 switch (kinds[i])
179 {
181 enabled->ndistinct = true;
182 break;
184 enabled->dependencies = true;
185 break;
186 case STATS_EXT_MCV:
187 enabled->mcv = true;
188 break;
190 enabled->expressions = true;
191 break;
192 default:
193 elog(ERROR, "incorrect stxkind %c found", kinds[i]);
194 break;
195 }
196 }
197}
#define ARR_DATA_PTR(a)
Definition array.h:322
#define DatumGetArrayTypeP(X)
Definition array.h:261
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define ARR_HASNULL(a)
Definition array.h:291
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
int i
Definition isn.c:77
uint64_t Datum
Definition postgres.h:70
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:625

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, DatumGetArrayTypeP, StakindFlags::dependencies, elog, ERROR, StakindFlags::expressions, fb(), i, StakindFlags::mcv, StakindFlags::ndistinct, and SysCacheGetAttrNotNull().

Referenced by extended_statistics_update().

◆ extended_statistics_update()

static bool extended_statistics_update ( FunctionCallInfo  fcinfo)
static

Definition at line 249 of file extended_stats_funcs.c.

250{
251 char *relnspname;
252 char *relname;
253 Oid nspoid;
254 char *nspname;
255 char *stxname;
256 bool inherited;
259
260 StakindFlags enabled = {false, false, false, false};
261 StakindFlags has = {false, false, false, false};
262
264
266 bool nulls[Natts_pg_statistic_ext_data] = {0};
268 bool success = true;
270 bool isnull;
271 List *exprs = NIL;
272 int numattnums = 0;
273 int numexprs = 0;
274 int numattrs = 0;
275
276 /* arrays of type info, if we need them */
277 Oid *atttypids = NULL;
278 int32 *atttypmods = NULL;
280 Oid relid;
282
283 /*
284 * Fill out the StakindFlags "has" structure based on which parameters
285 * were provided to the function.
286 *
287 * The MCV stats composite value is an array of record type, but this is
288 * externally represented as three arrays that must be interleaved into
289 * the array of records (pg_stats_ext stores four arrays,
290 * most_common_val_nulls is built from the contents of most_common_vals).
291 * Therefore, none of the three array values is meaningful unless the
292 * other two are also present and in sync in terms of array length.
293 */
297 has.ndistinct = !PG_ARGISNULL(NDISTINCT_ARG);
298 has.dependencies = !PG_ARGISNULL(DEPENDENCIES_ARG);
299
300 if (RecoveryInProgress())
301 {
304 errmsg("recovery is in progress"),
305 errhint("Statistics cannot be modified during recovery."));
306 return false;
307 }
308
309 /* relation arguments */
314
315 /* extended statistics arguments */
322
323 /*
324 * First open the relation where we expect to find the statistics. This
325 * is similar to relation and attribute statistics, so as ACL checks are
326 * done before any locks are taken, even before any attempts related to
327 * the extended stats object.
328 */
332
333 nspoid = get_namespace_oid(nspname, true);
334 if (nspoid == InvalidOid)
335 {
338 errmsg("could not find schema \"%s\"", nspname));
339 success = false;
340 goto cleanup;
341 }
342
345
346 if (!HeapTupleIsValid(tup))
347 {
350 errmsg("could not find extended statistics object \"%s.%s\"",
351 nspname, stxname));
352 success = false;
353 goto cleanup;
354 }
355
357
358 /*
359 * The relation tracked by the stats object has to match with the relation
360 * we have already locked.
361 */
362 if (stxform->stxrelid != relid)
363 {
366 errmsg("could not restore extended statistics object \"%s.%s\": incorrect relation \"%s.%s\" specified",
367 nspname, stxname,
369
370 success = false;
371 goto cleanup;
372 }
373
374 /* Find out what extended statistics kinds we should expect. */
375 expand_stxkind(tup, &enabled);
376 numattnums = stxform->stxkeys.dim1;
377
378 /* decode expression (if any) */
380 tup,
382 &isnull);
383 if (!isnull)
384 {
385 char *s;
386
388 exprs = (List *) stringToNode(s);
389 pfree(s);
390
391 /*
392 * Run the expressions through eval_const_expressions(). This is not
393 * just an optimization, but is necessary, because the planner will be
394 * comparing them to similarly-processed qual clauses, and may fail to
395 * detect valid matches without this.
396 *
397 * We must not use canonicalize_qual(), however, since these are not
398 * qual expressions.
399 */
400 exprs = (List *) eval_const_expressions(NULL, (Node *) exprs);
401
402 /* May as well fix opfuncids too */
403 fix_opfuncids((Node *) exprs);
404
405 /* Compute the number of expression, for input validation. */
406 numexprs = list_length(exprs);
407 }
408
410
411 /*
412 * If the object cannot support ndistinct, we should not have data for it.
413 */
414 if (has.ndistinct && !enabled.ndistinct)
415 {
418 errmsg("cannot specify parameter \"%s\"",
419 extarginfo[NDISTINCT_ARG].argname),
420 errhint("Extended statistics object \"%s.%s\" does not support statistics of this type.",
421 nspname, stxname));
422
423 has.ndistinct = false;
424 success = false;
425 }
426
427 /*
428 * If the object cannot support dependencies, we should not have data for
429 * it.
430 */
431 if (has.dependencies && !enabled.dependencies)
432 {
435 errmsg("cannot specify parameter \"%s\"",
437 errhint("Extended statistics object \"%s.%s\" does not support statistics of this type.",
438 nspname, stxname));
439 has.dependencies = false;
440 success = false;
441 }
442
443 /*
444 * If the object cannot hold an MCV value, but any of the MCV parameters
445 * are set, then issue a WARNING and ensure that we do not try to load MCV
446 * stats later. In pg_stats_ext, most_common_val_nulls, most_common_freqs
447 * and most_common_base_freqs are NULL if most_common_vals is NULL.
448 */
449 if (!enabled.mcv)
450 {
454 {
457 errmsg("cannot specify parameters \"%s\", \"%s\" or \"%s\"",
461 errhint("Extended statistics object \"%s.%s\" does not support statistics of this type.",
462 nspname, stxname));
463
464 has.mcv = false;
465 success = false;
466 }
467 }
468 else if (!has.mcv)
469 {
470 /*
471 * If we do not have all of the MCV arrays set while the extended
472 * statistics object expects something, something is wrong. This
473 * issues a WARNING if a partial input has been provided.
474 */
478 {
481 errmsg("could not use \"%s\", \"%s\" and \"%s\": missing one or more parameters",
485 success = false;
486 }
487 }
488
489 /*
490 * Either of these statistic types requires that we supply a semi-filled
491 * VacAttrStatP array.
492 *
493 * It is not possible to use the existing lookup_var_attr_stats() and
494 * examine_attribute() because these functions will skip attributes where
495 * attstattarget is 0, and we may have statistics data to import for those
496 * attributes.
497 */
498 if (has.mcv)
499 {
501 atttypmods = palloc0_array(int32, numattrs);
503
504 /*
505 * The leading stxkeys are attribute numbers up through numattnums.
506 * These keys must be in ascending AttNumber order, but we do not rely
507 * on that.
508 */
509 for (int i = 0; i < numattnums; i++)
510 {
511 AttrNumber attnum = stxform->stxkeys.values[i];
513 ObjectIdGetDatum(relid),
515
517
518 /* Attribute not found */
520 elog(ERROR, "stxkeys references nonexistent attnum %d", attnum);
521
523
524 if (attr->attisdropped)
525 elog(ERROR, "stxkeys references dropped attnum %d", attnum);
526
527 atttypids[i] = attr->atttypid;
528 atttypmods[i] = attr->atttypmod;
529 atttypcolls[i] = attr->attcollation;
531 }
532
533 /*
534 * After all the positive number attnums in stxkeys come the negative
535 * numbers (if any) which represent expressions in the order that they
536 * appear in stxdexpr. Because the expressions are always
537 * monotonically decreasing from -1, there is no point in looking at
538 * the values in stxkeys, it's enough to know how many of them there
539 * are.
540 */
541 for (int i = numattnums; i < numattrs; i++)
542 {
543 Node *expr = list_nth(exprs, i - numattnums);
544
545 atttypids[i] = exprType(expr);
546 atttypmods[i] = exprTypmod(expr);
547 atttypcolls[i] = exprCollation(expr);
548 }
549 }
550
551 /*
552 * Populate the pg_statistic_ext_data result tuple.
553 */
554
555 /* Primary Key: cannot be NULL or replaced. */
557 nulls[Anum_pg_statistic_ext_data_stxoid - 1] = false;
560
561 /* All unspecified parameters will be left unmodified */
564 nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
565 nulls[Anum_pg_statistic_ext_data_stxdexpr - 1] = true;
566
567 /*
568 * For each stats kind, deserialize the data at hand and perform a round
569 * of validation. The resulting tuple is filled with a set of updated
570 * values.
571 */
572
573 if (has.ndistinct)
574 {
578
579 if (statext_ndistinct_validate(ndistinct, &stxform->stxkeys,
581 {
585 }
586 else
587 success = false;
588
589 statext_ndistinct_free(ndistinct);
590 }
591
592 if (has.dependencies)
593 {
597
598 if (statext_dependencies_validate(dependencies, &stxform->stxkeys,
600 {
604 }
605 else
606 success = false;
607
608 statext_dependencies_free(dependencies);
609 }
610
611 if (has.mcv)
612 {
613 Datum datum;
614 bool val_ok = false;
615
619 atttypids, atttypmods, atttypcolls, numattrs,
620 &val_ok);
621
622 if (val_ok)
623 {
624 Assert(datum != (Datum) 0);
626 nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = false;
628 }
629 else
630 success = false;
631 }
632
634
635cleanup:
638 if (pg_stext != NULL)
640 if (atttypids != NULL)
642 if (atttypmods != NULL)
643 pfree(atttypmods);
644 if (atttypcolls != NULL)
646 return success;
647}
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
int16 AttrNumber
Definition attnum.h:21
static Datum values[MAXATTR]
Definition bootstrap.c:147
static void cleanup(void)
Definition bootstrap.c:838
#define TextDatumGetCString(d)
Definition builtins.h:99
#define Assert(condition)
Definition c.h:885
int32_t int32
Definition c.h:554
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition clauses.c:2267
MVDependencies * statext_dependencies_deserialize(bytea *data)
bool statext_dependencies_validate(const MVDependencies *dependencies, const int2vector *stxkeys, int numexprs, int elevel)
void statext_dependencies_free(MVDependencies *dependencies)
int errhint(const char *fmt,...) pg_attribute_printf(1
static void upsert_pg_statistic_ext_data(const Datum *values, const bool *nulls, const bool *replaces)
static void expand_stxkind(HeapTuple tup, StakindFlags *enabled)
static HeapTuple get_pg_statistic_ext(Relation pg_stext, Oid nspoid, const char *stxname)
static Datum import_mcv(const ArrayType *mcv_arr, const ArrayType *freqs_arr, const ArrayType *base_freqs_arr, Oid *atttypids, int32 *atttypmods, Oid *atttypcolls, int numattrs, bool *ok)
#define palloc0_array(type, count)
Definition fe_memutils.h:77
#define DatumGetByteaPP(X)
Definition fmgr.h:292
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1435
static void * GETSTRUCT(const HeapTupleData *tuple)
static bool success
Definition initdb.c:187
#define ShareUpdateExclusiveLock
Definition lockdefs.h:39
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition makefuncs.c:473
void pfree(void *pointer)
Definition mcxt.c:1616
void statext_ndistinct_free(MVNDistinct *ndistinct)
Definition mvdistinct.c:332
MVNDistinct * statext_ndistinct_deserialize(bytea *data)
Definition mvdistinct.c:247
bool statext_ndistinct_validate(const MVNDistinct *ndistinct, const int2vector *stxkeys, int numexprs, int elevel)
Definition mvdistinct.c:352
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition namespace.c:3607
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Definition namespace.c:442
Oid exprType(const Node *expr)
Definition nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:301
Oid exprCollation(const Node *expr)
Definition nodeFuncs.c:821
void fix_opfuncids(Node *node)
Definition nodeFuncs.c:1840
int16 attnum
FormData_pg_attribute * Form_pg_attribute
NameData relname
Definition pg_class.h:40
const void * data
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
static void * list_nth(const List *list, int n)
Definition pg_list.h:299
END_CATALOG_STRUCT typedef FormData_pg_statistic_ext * Form_pg_statistic_ext
static Datum Int16GetDatum(int16 X)
Definition postgres.h:182
#define InvalidOid
unsigned int Oid
void * stringToNode(const char *str)
Definition read.c:90
void RangeVarCallbackForStats(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
Definition stat_utils.c:142
void stats_check_required_arg(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum)
Definition stat_utils.c:51
Definition pg_list.h:54
Definition nodes.h:135
Definition c.h:718
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
bool RecoveryInProgress(void)
Definition xlog.c:6460

References StatsArgInfo::argname, Assert, attnum, BoolGetDatum(), cleanup(), data, DatumGetByteaPP, StakindFlags::dependencies, DEPENDENCIES_ARG, elog, ereport, errcode(), errhint(), errmsg(), ERROR, eval_const_expressions(), expand_stxkind(), exprCollation(), exprType(), exprTypmod(), extarginfo, fb(), fix_opfuncids(), Form_pg_statistic_ext, get_namespace_oid(), get_pg_statistic_ext(), GETSTRUCT(), heap_freetuple(), HeapTupleIsValid, i, import_mcv(), INHERITED_ARG, Int16GetDatum(), InvalidOid, list_length(), list_nth(), makeRangeVar(), StakindFlags::mcv, MOST_COMMON_BASE_FREQS_ARG, MOST_COMMON_FREQS_ARG, MOST_COMMON_VALS_ARG, StakindFlags::ndistinct, NDISTINCT_ARG, NIL, ObjectIdGetDatum(), palloc0_array, pfree(), PG_ARGISNULL, PG_GETARG_ARRAYTYPE_P, PG_GETARG_BOOL, PG_GETARG_DATUM, RangeVarCallbackForStats(), RangeVarGetRelidExtended(), RecoveryInProgress(), ReleaseSysCache(), relname, RELNAME_ARG, RELSCHEMA_ARG, RowExclusiveLock, SearchSysCache2(), ShareUpdateExclusiveLock, statext_dependencies_deserialize(), statext_dependencies_free(), statext_dependencies_validate(), statext_ndistinct_deserialize(), statext_ndistinct_free(), statext_ndistinct_validate(), STATNAME_ARG, stats_check_required_arg(), STATSCHEMA_ARG, stringToNode(), success, SysCacheGetAttr(), table_close(), table_open(), TextDatumGetCString, upsert_pg_statistic_ext_data(), values, and WARNING.

Referenced by pg_restore_extended_stats().

◆ get_pg_statistic_ext()

static HeapTuple get_pg_statistic_ext ( Relation  pg_stext,
Oid  nspoid,
const char stxname 
)
static

Definition at line 113 of file extended_stats_funcs.c.

114{
115 ScanKeyData key[2];
116 SysScanDesc scan;
119
120 ScanKeyInit(&key[0],
123 F_NAMEEQ,
125 ScanKeyInit(&key[1],
128 F_OIDEQ,
130
131 /*
132 * Try to find matching pg_statistic_ext row.
133 */
136 true,
137 NULL,
138 2,
139 key);
140
141 /* Lookup is based on a unique index, so we get either 0 or 1 tuple. */
142 tup = systable_getnext(scan);
143
146
147 systable_endscan(scan);
148
149 if (!OidIsValid(stxoid))
150 return NULL;
151
153}
#define OidIsValid(objectId)
Definition c.h:800
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31
#define SearchSysCacheCopy1(cacheId, key1)
Definition syscache.h:91

References BTEqualStrategyNumber, CStringGetDatum(), fb(), Form_pg_statistic_ext, GETSTRUCT(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum(), OidIsValid, ScanKeyInit(), SearchSysCacheCopy1, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by extended_statistics_update(), and pg_clear_extended_stats().

◆ import_mcv()

static Datum import_mcv ( const ArrayType mcv_arr,
const ArrayType freqs_arr,
const ArrayType base_freqs_arr,
Oid atttypids,
int32 atttypmods,
Oid atttypcolls,
int  numattrs,
bool ok 
)
static

Definition at line 694 of file extended_stats_funcs.c.

697{
698 int nitems;
700 bool *mcv_nulls;
701 int check_nummcv;
702 Datum mcv = (Datum) 0;
703
704 *ok = false;
705
706 /*
707 * mcv_arr is an array of arrays. Each inner array must have the same
708 * number of elements "numattrs".
709 */
710 if (ARR_NDIM(mcv_arr) != 2)
711 {
714 errmsg("could not parse array \"%s\": incorrect number of dimensions (%d required)",
715 extarginfo[MOST_COMMON_VALS_ARG].argname, 2));
716 goto mcv_error;
717 }
718
719 if (ARR_DIMS(mcv_arr)[1] != numattrs)
720 {
723 errmsg("could not parse array \"%s\": found %d attributes but expected %d",
726 goto mcv_error;
727 }
728
729 /*
730 * "most_common_freqs" and "most_common_base_freqs" arrays must be of the
731 * same length, one-dimension and cannot contain NULLs. We use mcv_arr as
732 * the reference array for determining their length.
733 */
734 nitems = ARR_DIMS(mcv_arr)[0];
737 {
738 /* inconsistent input arrays found */
739 goto mcv_error;
740 }
741
742 /*
743 * This part builds the contents for "most_common_val_nulls", based on the
744 * values from "most_common_vals".
745 */
748
750 atttypids, atttypmods, atttypcolls,
754
755 *ok = (mcv != (Datum) 0);
756
758 return mcv;
759}
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
double float8
Definition c.h:656
static bool check_mcvlist_array(const ArrayType *arr, int argindex, int required_ndims, int mcv_length)
#define nitems(x)
Definition indent.h:31
Datum statext_mcv_import(int elevel, int numattrs, Oid *atttypids, int32 *atttypmods, Oid *atttypcolls, int nitems, Datum *mcv_elems, bool *mcv_nulls, float8 *freqs, float8 *base_freqs)
Definition mcv.c:2204

References StatsArgInfo::argname, ARR_DATA_PTR, ARR_DIMS, ARR_NDIM, check_mcvlist_array(), deconstruct_array_builtin(), ereport, errcode(), errmsg(), extarginfo, fb(), MOST_COMMON_BASE_FREQS_ARG, MOST_COMMON_FREQS_ARG, MOST_COMMON_VALS_ARG, nitems, statext_mcv_import(), and WARNING.

Referenced by extended_statistics_update().

◆ pg_clear_extended_stats()

Datum pg_clear_extended_stats ( PG_FUNCTION_ARGS  )

Definition at line 820 of file extended_stats_funcs.c.

821{
822 char *relnspname;
823 char *relname;
824 char *nspname;
825 Oid nspoid;
826 Oid relid;
827 char *stxname;
828 bool inherited;
833
834 /* relation arguments */
839
840 /* extended statistics arguments */
847
848 if (RecoveryInProgress())
849 {
852 errmsg("recovery is in progress"),
853 errhint("Statistics cannot be modified during recovery."));
855 }
856
857 /*
858 * First open the relation where we expect to find the statistics. This
859 * is similar to relation and attribute statistics, so as ACL checks are
860 * done before any locks are taken, even before any attempts related to
861 * the extended stats object.
862 */
866
867 /* Now check if the namespace of the stats object exists. */
868 nspoid = get_namespace_oid(nspname, true);
869 if (nspoid == InvalidOid)
870 {
873 errmsg("could not find schema \"%s\"", nspname));
875 }
876
879
880 if (!HeapTupleIsValid(tup))
881 {
885 errmsg("could not find extended statistics object \"%s.%s\"",
886 nspname, stxname));
888 }
889
891
892 /*
893 * This should be consistent, based on the lock taken on the table when we
894 * started.
895 */
896 if (stxform->stxrelid != relid)
897 {
901 errmsg("could not clear extended statistics object \"%s.%s\": incorrect relation \"%s.%s\" specified",
905 }
906
909
911
913}
static bool delete_pg_statistic_ext_data(Oid stxoid, bool inherited)
#define PG_RETURN_VOID()
Definition fmgr.h:350
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3518

References delete_pg_statistic_ext_data(), ereport, errcode(), errhint(), errmsg(), extarginfo, fb(), Form_pg_statistic_ext, get_namespace_name(), get_namespace_oid(), get_pg_statistic_ext(), GETSTRUCT(), heap_freetuple(), HeapTupleIsValid, INHERITED_ARG, InvalidOid, makeRangeVar(), PG_GETARG_BOOL, PG_GETARG_DATUM, PG_RETURN_VOID, RangeVarCallbackForStats(), RangeVarGetRelidExtended(), RecoveryInProgress(), relname, RELNAME_ARG, RELSCHEMA_ARG, RowExclusiveLock, ShareUpdateExclusiveLock, STATNAME_ARG, stats_check_required_arg(), STATSCHEMA_ARG, table_close(), table_open(), TextDatumGetCString, and WARNING.

◆ pg_restore_extended_stats()

Datum pg_restore_extended_stats ( PG_FUNCTION_ARGS  )

Definition at line 799 of file extended_stats_funcs.c.

800{
802 bool result = true;
803
806
808 result = false;
809
811 result = false;
812
813 PG_RETURN_BOOL(result);
814}
static bool extended_statistics_update(FunctionCallInfo fcinfo)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition fmgr.h:150
#define LOCAL_FCINFO(name, nargs)
Definition fmgr.h:110
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
bool stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo, FunctionCallInfo positional_fcinfo, struct StatsArgInfo *arginfo)
Definition stat_utils.c:348

References extarginfo, extended_statistics_update(), fb(), InitFunctionCallInfoData, InvalidOid, LOCAL_FCINFO, NUM_EXTENDED_STATS_ARGS, PG_RETURN_BOOL, and stats_fill_fcinfo_from_arg_pairs().

◆ upsert_pg_statistic_ext_data()

static void upsert_pg_statistic_ext_data ( const Datum values,
const bool nulls,
const bool replaces 
)
static

Definition at line 203 of file extended_stats_funcs.c.

205{
209
211
215
217 {
220 values,
221 nulls,
222 replaces);
225 }
226 else
227 {
230 }
231
233
235
237}
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1210
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1117
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
#define RelationGetDescr(relation)
Definition rel.h:540

References CatalogTupleInsert(), CatalogTupleUpdate(), CommandCounterIncrement(), fb(), heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), HeapTupleIsValid, RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, SearchSysCache2(), table_close(), table_open(), and values.

Referenced by extended_statistics_update().

Variable Documentation

◆ extarginfo

struct StatsArgInfo extarginfo[]
static
Initial value:
=
{
[RELSCHEMA_ARG] = {"schemaname", TEXTOID},
[RELNAME_ARG] = {"relname", TEXTOID},
[STATSCHEMA_ARG] = {"statistics_schemaname", TEXTOID},
[STATNAME_ARG] = {"statistics_name", TEXTOID},
[INHERITED_ARG] = {"inherited", BOOLOID},
[NDISTINCT_ARG] = {"n_distinct", PG_NDISTINCTOID},
[DEPENDENCIES_ARG] = {"dependencies", PG_DEPENDENCIESOID},
[MOST_COMMON_VALS_ARG] = {"most_common_vals", TEXTARRAYOID},
[MOST_COMMON_FREQS_ARG] = {"most_common_freqs", FLOAT8ARRAYOID},
[MOST_COMMON_BASE_FREQS_ARG] = {"most_common_base_freqs", FLOAT8ARRAYOID},
}

Definition at line 61 of file extended_stats_funcs.c.

62{
63 [RELSCHEMA_ARG] = {"schemaname", TEXTOID},
64 [RELNAME_ARG] = {"relname", TEXTOID},
65 [STATSCHEMA_ARG] = {"statistics_schemaname", TEXTOID},
66 [STATNAME_ARG] = {"statistics_name", TEXTOID},
67 [INHERITED_ARG] = {"inherited", BOOLOID},
68 [NDISTINCT_ARG] = {"n_distinct", PG_NDISTINCTOID},
69 [DEPENDENCIES_ARG] = {"dependencies", PG_DEPENDENCIESOID},
70 [MOST_COMMON_VALS_ARG] = {"most_common_vals", TEXTARRAYOID},
71 [MOST_COMMON_FREQS_ARG] = {"most_common_freqs", FLOAT8ARRAYOID},
72 [MOST_COMMON_BASE_FREQS_ARG] = {"most_common_base_freqs", FLOAT8ARRAYOID},
74};

Referenced by check_mcvlist_array(), extended_statistics_update(), import_mcv(), pg_clear_extended_stats(), and pg_restore_extended_stats().