29#include "utils/fmgroids.h"
33#define DEFAULT_NULL_FRAC Float4GetDatum(0.0)
34#define DEFAULT_AVG_WIDTH Int32GetDatum(0)
35#define DEFAULT_N_DISTINCT Float4GetDatum(0.0)
105 char *atttyptype,
Oid *atttypcoll,
106 Oid *eq_opr,
Oid *lt_opr);
108 Oid *elemtypid,
Oid *elem_eq_opr);
113 Datum stanumbers,
bool stanumbers_isnull,
114 Datum stavalues,
bool stavalues_isnull);
174 bool nulls[Natts_pg_statistic] = {0};
175 bool replaces[Natts_pg_statistic] = {0};
189 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
190 errmsg(
"recovery is in progress"),
191 errhint(
"Statistics cannot be modified during recovery.")));
201 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
202 errmsg(
"cannot specify both attname and attnum")));
208 (
errcode(ERRCODE_UNDEFINED_COLUMN),
209 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
220 (
errcode(ERRCODE_UNDEFINED_COLUMN),
221 errmsg(
"column %d of relation \"%s\" does not exist",
227 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
228 errmsg(
"must specify either attname or attnum")));
235 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
236 errmsg(
"cannot modify statistics on system column \"%s\"",
283 do_range_length_histogram =
false;
289 &atttypid, &atttypmod,
290 &atttyptype, &atttypcoll,
294 if (do_mcelem || do_dechist)
297 &elemtypid, &elem_eq_opr))
300 (
errmsg(
"unable to determine element type of attribute \"%s\"",
attname),
301 errdetail(
"Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.")));
312 if ((do_histogram || do_correlation) && !
OidIsValid(lt_opr))
315 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
316 errmsg(
"could not determine less-than operator for attribute \"%s\"",
attname),
317 errdetail(
"Cannot set STATISTIC_KIND_HISTOGRAM or STATISTIC_KIND_CORRELATION.")));
319 do_histogram =
false;
320 do_correlation =
false;
325 if ((do_range_length_histogram || do_bounds_histogram) &&
326 !(atttyptype == TYPTYPE_RANGE || atttyptype == TYPTYPE_MULTIRANGE))
329 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
331 errdetail(
"Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM.")));
333 do_bounds_histogram =
false;
334 do_range_length_histogram =
false;
355 replaces[Anum_pg_statistic_stanullfrac - 1] =
true;
360 replaces[Anum_pg_statistic_stawidth - 1] =
true;
365 replaces[Anum_pg_statistic_stadistinct - 1] =
true;
384 stanumbers,
false, stavalues,
false);
394 bool converted =
false;
405 STATISTIC_KIND_HISTOGRAM,
407 0,
true, stavalues,
false);
421 STATISTIC_KIND_CORRELATION,
423 stanumbers,
false, 0,
true);
430 bool converted =
false;
436 elemtypid, atttypmod,
442 STATISTIC_KIND_MCELEM,
443 elem_eq_opr, atttypcoll,
444 stanumbers,
false, stavalues,
false);
456 STATISTIC_KIND_DECHIST,
457 elem_eq_opr, atttypcoll,
458 stanumbers,
false, 0,
true);
468 if (do_bounds_histogram)
470 bool converted =
false;
482 STATISTIC_KIND_BOUNDS_HISTOGRAM,
484 0,
true, stavalues,
false);
491 if (do_range_length_histogram)
498 bool converted =
false;
504 FLOAT8OID, 0, &converted);
509 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
511 stanumbers,
false, stavalues,
false);
539 if (rel->
rd_rel->relkind != RELKIND_INDEX &&
540 rel->
rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
546 if (index_exprs ==
NIL)
559 if (rel->
rd_index->indkey.values[
i] == 0)
562 if (indexpr_item == NULL)
563 elog(
ERROR,
"too few entries in indexprs list");
574 char *atttyptype,
Oid *atttypcoll,
589 (
errcode(ERRCODE_UNDEFINED_COLUMN),
590 errmsg(
"attribute %d of relation \"%s\" does not exist",
595 if (attr->attisdropped)
597 (
errcode(ERRCODE_UNDEFINED_COLUMN),
598 errmsg(
"attribute %d of relation \"%s\" does not exist",
611 *atttypid = attr->atttypid;
612 *atttypmod = attr->atttypmod;
613 *atttypcoll = attr->attcollation;
621 *atttypcoll = attr->attcollation;
636 *atttyptype = typcache->
typtype;
637 *eq_opr = typcache->
eq_opr;
638 *lt_opr = typcache->
lt_opr;
644 if (*atttypid == TSVECTOROID)
645 *atttypcoll = DEFAULT_COLLATION_OID;
655 Oid *elemtypid,
Oid *elem_eq_opr)
659 if (atttypid == TSVECTOROID)
665 *elemtypid = TEXTOID;
681 *elem_eq_opr = elemtypcache->
eq_opr;
695 int32 typmod,
bool *ok)
707 (
Node *) &escontext, NULL);
710 fcinfo->args[0].isnull =
false;
712 fcinfo->args[1].isnull =
false;
714 fcinfo->args[2].isnull =
false;
731 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
732 errmsg(
"\"%s\" array cannot contain NULL values", staname)));
749 Datum stanumbers,
bool stanumbers_isnull,
750 Datum stavalues,
bool stavalues_isnull)
753 int first_empty = -1;
761 stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx;
763 if (first_empty < 0 &&
765 first_empty = slotidx;
771 slotidx = first_empty;
775 (
errmsg(
"maximum number of statistics slots exceeded: %d",
778 stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx;
779 staop_attnum = Anum_pg_statistic_staop1 - 1 + slotidx;
780 stacoll_attnum = Anum_pg_statistic_stacoll1 - 1 + slotidx;
785 replaces[stakind_attnum] =
true;
790 replaces[staop_attnum] =
true;
795 replaces[stacoll_attnum] =
true;
797 if (!stanumbers_isnull)
799 values[Anum_pg_statistic_stanumbers1 - 1 + slotidx] = stanumbers;
800 nulls[Anum_pg_statistic_stanumbers1 - 1 + slotidx] =
false;
801 replaces[Anum_pg_statistic_stanumbers1 - 1 + slotidx] =
true;
803 if (!stavalues_isnull)
805 values[Anum_pg_statistic_stavalues1 - 1 + slotidx] = stavalues;
806 nulls[Anum_pg_statistic_stavalues1 - 1 + slotidx] =
false;
807 replaces[Anum_pg_statistic_stavalues1 - 1 + slotidx] =
true;
874 memset(nulls,
true,
sizeof(
bool) * Natts_pg_statistic);
875 memset(replaces,
true,
sizeof(
bool) * Natts_pg_statistic);
880 nulls[Anum_pg_statistic_starelid - 1] =
false;
882 nulls[Anum_pg_statistic_staattnum - 1] =
false;
884 nulls[Anum_pg_statistic_stainherit - 1] =
false;
887 nulls[Anum_pg_statistic_stanullfrac - 1] =
false;
889 nulls[Anum_pg_statistic_stawidth - 1] =
false;
891 nulls[Anum_pg_statistic_stadistinct - 1] =
false;
896 values[Anum_pg_statistic_stakind1 + slotnum - 1] = (
Datum) 0;
897 nulls[Anum_pg_statistic_stakind1 + slotnum - 1] =
false;
899 nulls[Anum_pg_statistic_staop1 + slotnum - 1] =
false;
901 nulls[Anum_pg_statistic_stacoll1 + slotnum - 1] =
false;
930 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
931 errmsg(
"recovery is in progress"),
932 errhint(
"Statistics cannot be modified during recovery.")));
941 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
942 errmsg(
"cannot clear statistics on system column \"%s\"",
947 (
errcode(ERRCODE_UNDEFINED_COLUMN),
948 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
#define DatumGetArrayTypeP(X)
bool array_contains_nulls(ArrayType *array)
Datum array_in(PG_FUNCTION_ARGS)
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
#define InvalidAttrNumber
static void get_attr_stat_type(Oid reloid, AttrNumber attnum, Oid *atttypid, int32 *atttypmod, char *atttyptype, Oid *atttypcoll, Oid *eq_opr, Oid *lt_opr)
static bool delete_pg_statistic(Oid reloid, AttrNumber attnum, bool stainherit)
@ RANGE_LENGTH_HISTOGRAM_ARG
@ RANGE_BOUNDS_HISTOGRAM_ARG
@ NUM_ATTRIBUTE_STATS_ARGS
@ ELEM_COUNT_HISTOGRAM_ARG
@ MOST_COMMON_ELEM_FREQS_ARG
static struct StatsArgInfo cleararginfo[]
#define DEFAULT_NULL_FRAC
static struct StatsArgInfo attarginfo[]
static Datum text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid, int32 typmod, bool *ok)
static bool get_elem_stat_type(Oid atttypid, char atttyptype, Oid *elemtypid, Oid *elem_eq_opr)
static bool attribute_statistics_update(FunctionCallInfo fcinfo)
clear_attribute_stats_argnum
@ C_NUM_ATTRIBUTE_STATS_ARGS
#define DEFAULT_N_DISTINCT
Datum pg_clear_attribute_stats(PG_FUNCTION_ARGS)
static Node * get_attr_expr(Relation rel, int attnum)
#define DEFAULT_AVG_WIDTH
static void init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited, Datum *values, bool *nulls, bool *replaces)
static void set_stats_slot(Datum *values, bool *nulls, bool *replaces, int16 stakind, Oid staop, Oid stacoll, Datum stanumbers, bool stanumbers_isnull, Datum stavalues, bool stavalues_isnull)
static void upsert_pg_statistic(Relation starel, HeapTuple oldtup, Datum *values, bool *nulls, bool *replaces)
Datum pg_restore_attribute_stats(PG_FUNCTION_ARGS)
static Datum values[MAXATTR]
#define TextDatumGetCString(d)
#define OidIsValid(objectId)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
void ThrowErrorData(ErrorData *edata)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
#define PG_GETARG_DATUM(n)
#define LOCAL_FCINFO(name, nargs)
#define FunctionCallInvoke(fcinfo)
#define PG_GETARG_BOOL(n)
#define PG_RETURN_BOOL(x)
#define PG_GETARG_INT16(n)
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
char * get_rel_name(Oid relid)
AttrNumber get_attnum(Oid relid, const char *attname)
Oid get_multirange_range(Oid multirangeOid)
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Oid get_base_element_type(Oid typid)
bool type_is_multirange(Oid typid)
void pfree(void *pointer)
Oid exprType(const Node *expr)
int32 exprTypmod(const Node *expr)
Oid exprCollation(const Node *expr)
FormData_pg_attribute * Form_pg_attribute
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
#define STATISTIC_NUM_SLOTS
static Datum PointerGetDatum(const void *X)
static Oid DatumGetObjectId(Datum X)
static Datum Int16GetDatum(int16 X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum CStringGetDatum(const char *X)
static Datum Int32GetDatum(int32 X)
static int16 DatumGetInt16(Datum X)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
List * RelationGetIndexExpressions(Relation relation)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
bool stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo, FunctionCallInfo positional_fcinfo, struct StatsArgInfo *arginfo)
bool stats_check_arg_array(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum)
void stats_check_required_arg(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum)
void stats_lock_check_privileges(Oid reloid)
Oid stats_lookup_relid(const char *nspname, const char *relname)
bool stats_check_arg_pair(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum1, int argnum2)
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
bool SearchSysCacheExistsAttName(Oid relid, const char *attname)
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
void CommandCounterIncrement(void)
bool RecoveryInProgress(void)