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)
83 char *atttyptype,
Oid *atttypcoll,
86 Oid *elemtypid,
Oid *elem_eq_opr);
88 Oid typid,
int32 typmod,
int elevel,
bool *ok);
91 Datum stanumbers,
bool stanumbers_isnull,
92 Datum stavalues,
bool stavalues_isnull);
150 bool nulls[Natts_pg_statistic] = {0};
151 bool replaces[Natts_pg_statistic] = {0};
160 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
161 errmsg(
"recovery is in progress"),
162 errhint(
"Statistics cannot be modified during recovery.")));
173 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
174 errmsg(
"cannot modify statistics on system column \"%s\"",
179 (
errcode(ERRCODE_UNDEFINED_COLUMN),
180 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
231 do_range_length_histogram =
false;
237 &atttypid, &atttypmod,
238 &atttyptype, &atttypcoll,
242 if (do_mcelem || do_dechist)
245 &elemtypid, &elem_eq_opr))
249 errdetail(
"Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.")));
260 if ((do_histogram || do_correlation) && !
OidIsValid(lt_opr))
263 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
265 errdetail(
"Cannot set STATISTIC_KIND_HISTOGRAM or STATISTIC_KIND_CORRELATION.")));
267 do_histogram =
false;
268 do_correlation =
false;
273 if ((do_range_length_histogram || do_bounds_histogram) &&
274 !(atttyptype == TYPTYPE_RANGE || atttyptype == TYPTYPE_MULTIRANGE))
277 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
279 errdetail(
"Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM.")));
281 do_bounds_histogram =
false;
282 do_range_length_histogram =
false;
303 replaces[Anum_pg_statistic_stanullfrac - 1] =
true;
308 replaces[Anum_pg_statistic_stawidth - 1] =
true;
313 replaces[Anum_pg_statistic_stadistinct - 1] =
true;
332 stanumbers,
false, stavalues,
false);
342 bool converted =
false;
347 atttypid, atttypmod, elevel,
353 STATISTIC_KIND_HISTOGRAM,
355 0,
true, stavalues,
false);
369 STATISTIC_KIND_CORRELATION,
371 stanumbers,
false, 0,
true);
378 bool converted =
false;
384 elemtypid, atttypmod,
390 STATISTIC_KIND_MCELEM,
391 elem_eq_opr, atttypcoll,
392 stanumbers,
false, stavalues,
false);
404 STATISTIC_KIND_DECHIST,
405 elem_eq_opr, atttypcoll,
406 stanumbers,
false, 0,
true);
416 if (do_bounds_histogram)
418 bool converted =
false;
430 STATISTIC_KIND_BOUNDS_HISTOGRAM,
432 0,
true, stavalues,
false);
439 if (do_range_length_histogram)
446 bool converted =
false;
452 FLOAT8OID, 0, elevel, &converted);
457 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
459 stanumbers,
false, stavalues,
false);
483 if ((rel->
rd_rel->relkind == RELKIND_INDEX
484 || (rel->
rd_rel->relkind == RELKIND_PARTITIONED_INDEX))
491 if (rel->
rd_index->indkey.values[
i] == 0)
494 if (indexpr_item == NULL)
495 elog(
ERROR,
"too few entries in indexprs list");
508 char *atttyptype,
Oid *atttypcoll,
523 (
errcode(ERRCODE_UNDEFINED_COLUMN),
524 errmsg(
"attribute %d of relation \"%s\" does not exist",
529 if (attr->attisdropped)
531 (
errcode(ERRCODE_UNDEFINED_COLUMN),
532 errmsg(
"attribute %d of relation \"%s\" does not exist",
545 *atttypid = attr->atttypid;
546 *atttypmod = attr->atttypmod;
547 *atttypcoll = attr->attcollation;
555 *atttypcoll = attr->attcollation;
570 *atttyptype = typcache->
typtype;
571 *eq_opr = typcache->
eq_opr;
572 *lt_opr = typcache->
lt_opr;
578 if (*atttypid == TSVECTOROID)
579 *atttypcoll = DEFAULT_COLLATION_OID;
589 Oid *elemtypid,
Oid *elem_eq_opr)
593 if (atttypid == TSVECTOROID)
599 *elemtypid = TEXTOID;
615 *elem_eq_opr = elemtypcache->
eq_opr;
629 int32 typmod,
int elevel,
bool *ok)
641 (
Node *) &escontext, NULL);
644 fcinfo->args[0].isnull =
false;
646 fcinfo->args[1].isnull =
false;
648 fcinfo->args[2].isnull =
false;
666 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
667 errmsg(
"\"%s\" array cannot contain NULL values", staname)));
684 Datum stanumbers,
bool stanumbers_isnull,
685 Datum stavalues,
bool stavalues_isnull)
688 int first_empty = -1;
696 stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx;
698 if (first_empty < 0 &&
700 first_empty = slotidx;
706 slotidx = first_empty;
710 (
errmsg(
"maximum number of statistics slots exceeded: %d",
713 stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx;
714 staop_attnum = Anum_pg_statistic_staop1 - 1 + slotidx;
715 stacoll_attnum = Anum_pg_statistic_stacoll1 - 1 + slotidx;
720 replaces[stakind_attnum] =
true;
725 replaces[staop_attnum] =
true;
730 replaces[stacoll_attnum] =
true;
732 if (!stanumbers_isnull)
734 values[Anum_pg_statistic_stanumbers1 - 1 + slotidx] = stanumbers;
735 nulls[Anum_pg_statistic_stanumbers1 - 1 + slotidx] =
false;
736 replaces[Anum_pg_statistic_stanumbers1 - 1 + slotidx] =
true;
738 if (!stavalues_isnull)
740 values[Anum_pg_statistic_stavalues1 - 1 + slotidx] = stavalues;
741 nulls[Anum_pg_statistic_stavalues1 - 1 + slotidx] =
false;
742 replaces[Anum_pg_statistic_stavalues1 - 1 + slotidx] =
true;
809 memset(nulls,
true,
sizeof(
bool) * Natts_pg_statistic);
810 memset(replaces,
true,
sizeof(
bool) * Natts_pg_statistic);
815 nulls[Anum_pg_statistic_starelid - 1] =
false;
817 nulls[Anum_pg_statistic_staattnum - 1] =
false;
819 nulls[Anum_pg_statistic_stainherit - 1] =
false;
822 nulls[Anum_pg_statistic_stanullfrac - 1] =
false;
824 nulls[Anum_pg_statistic_stawidth - 1] =
false;
826 nulls[Anum_pg_statistic_stadistinct - 1] =
false;
831 values[Anum_pg_statistic_stakind1 + slotnum - 1] = (
Datum) 0;
832 nulls[Anum_pg_statistic_stakind1 + slotnum - 1] =
false;
834 nulls[Anum_pg_statistic_staop1 + slotnum - 1] =
false;
836 nulls[Anum_pg_statistic_stacoll1 + slotnum - 1] =
false;
883 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
884 errmsg(
"recovery is in progress"),
885 errhint(
"Statistics cannot be modified during recovery.")));
895 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
896 errmsg(
"cannot clear statistics on system column \"%s\"",
901 (
errcode(ERRCODE_UNDEFINED_COLUMN),
902 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
#define DatumGetArrayTypeP(X)
bool array_contains_nulls(ArrayType *array)
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
Datum array_in(PG_FUNCTION_ARGS)
#define InvalidAttrNumber
static Datum text_to_stavalues(const char *staname, FmgrInfo *array_in, Datum d, Oid typid, int32 typmod, int elevel, bool *ok)
static bool get_elem_stat_type(Oid atttypid, char atttyptype, int elevel, Oid *elemtypid, Oid *elem_eq_opr)
static bool delete_pg_statistic(Oid reloid, AttrNumber attnum, bool stainherit)
static bool attribute_statistics_update(FunctionCallInfo fcinfo, int elevel)
@ RANGE_LENGTH_HISTOGRAM_ARG
@ RANGE_BOUNDS_HISTOGRAM_ARG
@ NUM_ATTRIBUTE_STATS_ARGS
@ ELEM_COUNT_HISTOGRAM_ARG
@ MOST_COMMON_ELEM_FREQS_ARG
#define DEFAULT_NULL_FRAC
static struct StatsArgInfo attarginfo[]
#define DEFAULT_N_DISTINCT
Datum pg_clear_attribute_stats(PG_FUNCTION_ARGS)
static Node * get_attr_expr(Relation rel, int attnum)
Datum pg_set_attribute_stats(PG_FUNCTION_ARGS)
#define DEFAULT_AVG_WIDTH
static void get_attr_stat_type(Oid reloid, AttrNumber attnum, int elevel, Oid *atttypid, int32 *atttypmod, char *atttyptype, Oid *atttypcoll, Oid *eq_opr, Oid *lt_opr)
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 PG_GETARG_NAME(n)
#define FunctionCallInvoke(fcinfo)
#define PG_GETARG_BOOL(n)
#define PG_RETURN_BOOL(x)
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)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
AttrNumber get_attnum(Oid relid, const char *attname)
Oid get_multirange_range(Oid multirangeOid)
char * get_rel_name(Oid relid)
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)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
bool stats_check_arg_array(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum, int elevel)
void stats_check_required_arg(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum)
bool stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo, FunctionCallInfo positional_fcinfo, struct StatsArgInfo *arginfo, int elevel)
bool stats_check_arg_pair(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum1, int argnum2, int elevel)
void stats_lock_check_privileges(Oid reloid)
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
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)