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)
117 char *atttyptype,
Oid *atttypcoll,
118 Oid *eq_opr,
Oid *lt_opr);
120 Oid *elemtypid,
Oid *elem_eq_opr);
125 Datum stanumbers,
bool stanumbers_isnull,
126 Datum stavalues,
bool stavalues_isnull);
128 const Datum *
values,
const bool *nulls,
const bool *replaces);
187 bool nulls[Natts_pg_statistic] = {0};
188 bool replaces[Natts_pg_statistic] = {0};
200 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
201 errmsg(
"recovery is in progress"),
202 errhint(
"Statistics cannot be modified during recovery.")));
214 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
215 errmsg(
"cannot specify both \"%s\" and \"%s\"",
"attname",
"attnum")));
221 (
errcode(ERRCODE_UNDEFINED_COLUMN),
222 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
233 (
errcode(ERRCODE_UNDEFINED_COLUMN),
234 errmsg(
"column %d of relation \"%s\" does not exist",
240 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
241 errmsg(
"must specify either \"%s\" or \"%s\"",
"attname",
"attnum")));
248 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
249 errmsg(
"cannot modify statistics on system column \"%s\"",
296 do_range_length_histogram =
false;
302 &atttypid, &atttypmod,
303 &atttyptype, &atttypcoll,
307 if (do_mcelem || do_dechist)
310 &elemtypid, &elem_eq_opr))
313 (
errmsg(
"could not determine element type of column \"%s\"",
attname),
315 "STATISTIC_KIND_MCELEM",
"STATISTIC_KIND_DECHIST")));
326 if ((do_histogram || do_correlation) && !
OidIsValid(lt_opr))
329 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
330 errmsg(
"could not determine less-than operator for column \"%s\"",
attname),
332 "STATISTIC_KIND_HISTOGRAM",
"STATISTIC_KIND_CORRELATION")));
334 do_histogram =
false;
335 do_correlation =
false;
340 if ((do_range_length_histogram || do_bounds_histogram) &&
341 !(atttyptype == TYPTYPE_RANGE || atttyptype == TYPTYPE_MULTIRANGE))
344 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
347 "STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM",
"STATISTIC_KIND_BOUNDS_HISTOGRAM")));
349 do_bounds_histogram =
false;
350 do_range_length_histogram =
false;
371 replaces[Anum_pg_statistic_stanullfrac - 1] =
true;
376 replaces[Anum_pg_statistic_stawidth - 1] =
true;
381 replaces[Anum_pg_statistic_stadistinct - 1] =
true;
400 stanumbers,
false, stavalues,
false);
410 bool converted =
false;
421 STATISTIC_KIND_HISTOGRAM,
423 0,
true, stavalues,
false);
437 STATISTIC_KIND_CORRELATION,
439 stanumbers,
false, 0,
true);
446 bool converted =
false;
452 elemtypid, atttypmod,
458 STATISTIC_KIND_MCELEM,
459 elem_eq_opr, atttypcoll,
460 stanumbers,
false, stavalues,
false);
472 STATISTIC_KIND_DECHIST,
473 elem_eq_opr, atttypcoll,
474 stanumbers,
false, 0,
true);
484 if (do_bounds_histogram)
486 bool converted =
false;
498 STATISTIC_KIND_BOUNDS_HISTOGRAM,
500 0,
true, stavalues,
false);
507 if (do_range_length_histogram)
514 bool converted =
false;
520 FLOAT8OID, 0, &converted);
525 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
527 stanumbers,
false, stavalues,
false);
555 if (rel->
rd_rel->relkind != RELKIND_INDEX &&
556 rel->
rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
562 if (index_exprs ==
NIL)
575 if (rel->
rd_index->indkey.values[
i] == 0)
578 if (indexpr_item == NULL)
579 elog(
ERROR,
"too few entries in indexprs list");
590 char *atttyptype,
Oid *atttypcoll,
605 (
errcode(ERRCODE_UNDEFINED_COLUMN),
606 errmsg(
"column %d of relation \"%s\" does not exist",
611 if (attr->attisdropped)
613 (
errcode(ERRCODE_UNDEFINED_COLUMN),
614 errmsg(
"column %d of relation \"%s\" does not exist",
627 *atttypid = attr->atttypid;
628 *atttypmod = attr->atttypmod;
629 *atttypcoll = attr->attcollation;
637 *atttypcoll = attr->attcollation;
652 *atttyptype = typcache->
typtype;
653 *eq_opr = typcache->
eq_opr;
654 *lt_opr = typcache->
lt_opr;
660 if (*atttypid == TSVECTOROID)
661 *atttypcoll = DEFAULT_COLLATION_OID;
671 Oid *elemtypid,
Oid *elem_eq_opr)
675 if (atttypid == TSVECTOROID)
681 *elemtypid = TEXTOID;
697 *elem_eq_opr = elemtypcache->
eq_opr;
711 int32 typmod,
bool *ok)
723 (
Node *) &escontext, NULL);
726 fcinfo->args[0].isnull =
false;
728 fcinfo->args[1].isnull =
false;
730 fcinfo->args[2].isnull =
false;
747 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
748 errmsg(
"\"%s\" array must not contain null values", staname)));
765 Datum stanumbers,
bool stanumbers_isnull,
766 Datum stavalues,
bool stavalues_isnull)
769 int first_empty = -1;
777 stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx;
779 if (first_empty < 0 &&
781 first_empty = slotidx;
787 slotidx = first_empty;
791 (
errmsg(
"maximum number of statistics slots exceeded: %d",
794 stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx;
795 staop_attnum = Anum_pg_statistic_staop1 - 1 + slotidx;
796 stacoll_attnum = Anum_pg_statistic_stacoll1 - 1 + slotidx;
801 replaces[stakind_attnum] =
true;
806 replaces[staop_attnum] =
true;
811 replaces[stacoll_attnum] =
true;
813 if (!stanumbers_isnull)
815 values[Anum_pg_statistic_stanumbers1 - 1 + slotidx] = stanumbers;
816 nulls[Anum_pg_statistic_stanumbers1 - 1 + slotidx] =
false;
817 replaces[Anum_pg_statistic_stanumbers1 - 1 + slotidx] =
true;
819 if (!stavalues_isnull)
821 values[Anum_pg_statistic_stavalues1 - 1 + slotidx] = stavalues;
822 nulls[Anum_pg_statistic_stavalues1 - 1 + slotidx] =
false;
823 replaces[Anum_pg_statistic_stavalues1 - 1 + slotidx] =
true;
832 const Datum *
values,
const bool *nulls,
const bool *replaces)
890 memset(nulls,
true,
sizeof(
bool) * Natts_pg_statistic);
891 memset(replaces,
true,
sizeof(
bool) * Natts_pg_statistic);
896 nulls[Anum_pg_statistic_starelid - 1] =
false;
898 nulls[Anum_pg_statistic_staattnum - 1] =
false;
900 nulls[Anum_pg_statistic_stainherit - 1] =
false;
903 nulls[Anum_pg_statistic_stanullfrac - 1] =
false;
905 nulls[Anum_pg_statistic_stawidth - 1] =
false;
907 nulls[Anum_pg_statistic_stadistinct - 1] =
false;
912 values[Anum_pg_statistic_stakind1 + slotnum - 1] = (
Datum) 0;
913 nulls[Anum_pg_statistic_stakind1 + slotnum - 1] =
false;
915 nulls[Anum_pg_statistic_staop1 + slotnum - 1] =
false;
917 nulls[Anum_pg_statistic_stacoll1 + slotnum - 1] =
false;
945 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
946 errmsg(
"recovery is in progress"),
947 errhint(
"Statistics cannot be modified during recovery.")));
958 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
959 errmsg(
"cannot clear statistics on system column \"%s\"",
964 (
errcode(ERRCODE_UNDEFINED_COLUMN),
965 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
#define DatumGetArrayTypeP(X)
bool array_contains_nulls(const 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 void upsert_pg_statistic(Relation starel, HeapTuple oldtup, const Datum *values, const bool *nulls, const bool *replaces)
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)
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, const ItemPointerData *otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *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)