31#include "utils/fmgroids.h"
35#define DEFAULT_NULL_FRAC Float4GetDatum(0.0)
36#define DEFAULT_AVG_WIDTH Int32GetDatum(0)
37#define DEFAULT_N_DISTINCT Float4GetDatum(0.0)
107 char *atttyptype,
Oid *atttypcoll,
108 Oid *eq_opr,
Oid *lt_opr);
110 Oid *elemtypid,
Oid *elem_eq_opr);
115 Datum stanumbers,
bool stanumbers_isnull,
116 Datum stavalues,
bool stavalues_isnull);
177 bool nulls[Natts_pg_statistic] = {0};
178 bool replaces[Natts_pg_statistic] = {0};
190 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
191 errmsg(
"recovery is in progress"),
192 errhint(
"Statistics cannot be modified during recovery.")));
204 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
205 errmsg(
"cannot specify both \"%s\" and \"%s\"",
"attname",
"attnum")));
211 (
errcode(ERRCODE_UNDEFINED_COLUMN),
212 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
223 (
errcode(ERRCODE_UNDEFINED_COLUMN),
224 errmsg(
"column %d of relation \"%s\" does not exist",
230 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
231 errmsg(
"must specify either \"%s\" or \"%s\"",
"attname",
"attnum")));
238 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
239 errmsg(
"cannot modify statistics on system column \"%s\"",
286 do_range_length_histogram =
false;
292 &atttypid, &atttypmod,
293 &atttyptype, &atttypcoll,
297 if (do_mcelem || do_dechist)
300 &elemtypid, &elem_eq_opr))
303 (
errmsg(
"could not determine element type of column \"%s\"",
attname),
305 "STATISTIC_KIND_MCELEM",
"STATISTIC_KIND_DECHIST")));
316 if ((do_histogram || do_correlation) && !
OidIsValid(lt_opr))
319 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
320 errmsg(
"could not determine less-than operator for column \"%s\"",
attname),
322 "STATISTIC_KIND_HISTOGRAM",
"STATISTIC_KIND_CORRELATION")));
324 do_histogram =
false;
325 do_correlation =
false;
330 if ((do_range_length_histogram || do_bounds_histogram) &&
331 !(atttyptype == TYPTYPE_RANGE || atttyptype == TYPTYPE_MULTIRANGE))
334 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
337 "STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM",
"STATISTIC_KIND_BOUNDS_HISTOGRAM")));
339 do_bounds_histogram =
false;
340 do_range_length_histogram =
false;
361 replaces[Anum_pg_statistic_stanullfrac - 1] =
true;
366 replaces[Anum_pg_statistic_stawidth - 1] =
true;
371 replaces[Anum_pg_statistic_stadistinct - 1] =
true;
390 stanumbers,
false, stavalues,
false);
400 bool converted =
false;
411 STATISTIC_KIND_HISTOGRAM,
413 0,
true, stavalues,
false);
427 STATISTIC_KIND_CORRELATION,
429 stanumbers,
false, 0,
true);
436 bool converted =
false;
442 elemtypid, atttypmod,
448 STATISTIC_KIND_MCELEM,
449 elem_eq_opr, atttypcoll,
450 stanumbers,
false, stavalues,
false);
462 STATISTIC_KIND_DECHIST,
463 elem_eq_opr, atttypcoll,
464 stanumbers,
false, 0,
true);
474 if (do_bounds_histogram)
476 bool converted =
false;
488 STATISTIC_KIND_BOUNDS_HISTOGRAM,
490 0,
true, stavalues,
false);
497 if (do_range_length_histogram)
504 bool converted =
false;
510 FLOAT8OID, 0, &converted);
515 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
517 stanumbers,
false, stavalues,
false);
545 if (rel->
rd_rel->relkind != RELKIND_INDEX &&
546 rel->
rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
552 if (index_exprs ==
NIL)
565 if (rel->
rd_index->indkey.values[
i] == 0)
568 if (indexpr_item == NULL)
569 elog(
ERROR,
"too few entries in indexprs list");
580 char *atttyptype,
Oid *atttypcoll,
595 (
errcode(ERRCODE_UNDEFINED_COLUMN),
596 errmsg(
"column %d of relation \"%s\" does not exist",
601 if (attr->attisdropped)
603 (
errcode(ERRCODE_UNDEFINED_COLUMN),
604 errmsg(
"column %d of relation \"%s\" does not exist",
617 *atttypid = attr->atttypid;
618 *atttypmod = attr->atttypmod;
619 *atttypcoll = attr->attcollation;
627 *atttypcoll = attr->attcollation;
642 *atttyptype = typcache->
typtype;
643 *eq_opr = typcache->
eq_opr;
644 *lt_opr = typcache->
lt_opr;
650 if (*atttypid == TSVECTOROID)
651 *atttypcoll = DEFAULT_COLLATION_OID;
661 Oid *elemtypid,
Oid *elem_eq_opr)
665 if (atttypid == TSVECTOROID)
671 *elemtypid = TEXTOID;
687 *elem_eq_opr = elemtypcache->
eq_opr;
701 int32 typmod,
bool *ok)
713 (
Node *) &escontext, NULL);
716 fcinfo->args[0].isnull =
false;
718 fcinfo->args[1].isnull =
false;
720 fcinfo->args[2].isnull =
false;
737 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
738 errmsg(
"\"%s\" array must not contain null values", staname)));
755 Datum stanumbers,
bool stanumbers_isnull,
756 Datum stavalues,
bool stavalues_isnull)
759 int first_empty = -1;
767 stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx;
769 if (first_empty < 0 &&
771 first_empty = slotidx;
777 slotidx = first_empty;
781 (
errmsg(
"maximum number of statistics slots exceeded: %d",
784 stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx;
785 staop_attnum = Anum_pg_statistic_staop1 - 1 + slotidx;
786 stacoll_attnum = Anum_pg_statistic_stacoll1 - 1 + slotidx;
791 replaces[stakind_attnum] =
true;
796 replaces[staop_attnum] =
true;
801 replaces[stacoll_attnum] =
true;
803 if (!stanumbers_isnull)
805 values[Anum_pg_statistic_stanumbers1 - 1 + slotidx] = stanumbers;
806 nulls[Anum_pg_statistic_stanumbers1 - 1 + slotidx] =
false;
807 replaces[Anum_pg_statistic_stanumbers1 - 1 + slotidx] =
true;
809 if (!stavalues_isnull)
811 values[Anum_pg_statistic_stavalues1 - 1 + slotidx] = stavalues;
812 nulls[Anum_pg_statistic_stavalues1 - 1 + slotidx] =
false;
813 replaces[Anum_pg_statistic_stavalues1 - 1 + slotidx] =
true;
880 memset(nulls,
true,
sizeof(
bool) * Natts_pg_statistic);
881 memset(replaces,
true,
sizeof(
bool) * Natts_pg_statistic);
886 nulls[Anum_pg_statistic_starelid - 1] =
false;
888 nulls[Anum_pg_statistic_staattnum - 1] =
false;
890 nulls[Anum_pg_statistic_stainherit - 1] =
false;
893 nulls[Anum_pg_statistic_stanullfrac - 1] =
false;
895 nulls[Anum_pg_statistic_stawidth - 1] =
false;
897 nulls[Anum_pg_statistic_stadistinct - 1] =
false;
902 values[Anum_pg_statistic_stakind1 + slotnum - 1] = (
Datum) 0;
903 nulls[Anum_pg_statistic_stakind1 + slotnum - 1] =
false;
905 nulls[Anum_pg_statistic_staop1 + slotnum - 1] =
false;
907 nulls[Anum_pg_statistic_stacoll1 + slotnum - 1] =
false;
935 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
936 errmsg(
"recovery is in progress"),
937 errhint(
"Statistics cannot be modified during recovery.")));
948 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
949 errmsg(
"cannot clear statistics on system column \"%s\"",
954 (
errcode(ERRCODE_UNDEFINED_COLUMN),
955 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)
#define ShareUpdateExclusiveLock
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)
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
void pfree(void *pointer)
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
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)
void RangeVarCallbackForStats(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
bool stats_check_arg_array(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum)
void stats_check_required_arg(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum)
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)