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};
166 (
errcode(ERRCODE_UNDEFINED_COLUMN),
167 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
218 do_range_length_histogram =
false;
224 &atttypid, &atttypmod,
225 &atttyptype, &atttypcoll,
229 if (do_mcelem || do_dechist)
232 &elemtypid, &elem_eq_opr))
236 errdetail(
"Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.")));
247 if ((do_histogram || do_correlation) && !
OidIsValid(lt_opr))
250 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
252 errdetail(
"Cannot set STATISTIC_KIND_HISTOGRAM or STATISTIC_KIND_CORRELATION.")));
254 do_histogram =
false;
255 do_correlation =
false;
260 if ((do_range_length_histogram || do_bounds_histogram) &&
261 !(atttyptype == TYPTYPE_RANGE || atttyptype == TYPTYPE_MULTIRANGE))
264 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
266 errdetail(
"Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM.")));
268 do_bounds_histogram =
false;
269 do_range_length_histogram =
false;
290 replaces[Anum_pg_statistic_stanullfrac - 1] =
true;
295 replaces[Anum_pg_statistic_stawidth - 1] =
true;
300 replaces[Anum_pg_statistic_stadistinct - 1] =
true;
319 stanumbers,
false, stavalues,
false);
329 bool converted =
false;
334 atttypid, atttypmod, elevel,
340 STATISTIC_KIND_HISTOGRAM,
342 0,
true, stavalues,
false);
356 STATISTIC_KIND_CORRELATION,
358 stanumbers,
false, 0,
true);
365 bool converted =
false;
371 elemtypid, atttypmod,
377 STATISTIC_KIND_MCELEM,
378 elem_eq_opr, atttypcoll,
379 stanumbers,
false, stavalues,
false);
391 STATISTIC_KIND_DECHIST,
392 elem_eq_opr, atttypcoll,
393 stanumbers,
false, 0,
true);
403 if (do_bounds_histogram)
405 bool converted =
false;
417 STATISTIC_KIND_BOUNDS_HISTOGRAM,
419 0,
true, stavalues,
false);
426 if (do_range_length_histogram)
433 bool converted =
false;
439 FLOAT8OID, 0, elevel, &converted);
444 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
446 stanumbers,
false, stavalues,
false);
470 if ((rel->
rd_rel->relkind == RELKIND_INDEX
471 || (rel->
rd_rel->relkind == RELKIND_PARTITIONED_INDEX))
478 if (rel->
rd_index->indkey.values[
i] == 0)
481 if (indexpr_item == NULL)
482 elog(
ERROR,
"too few entries in indexprs list");
495 char *atttyptype,
Oid *atttypcoll,
510 (
errcode(ERRCODE_UNDEFINED_COLUMN),
511 errmsg(
"attribute %d of relation \"%s\" does not exist",
516 if (attr->attisdropped)
518 (
errcode(ERRCODE_UNDEFINED_COLUMN),
519 errmsg(
"attribute %d of relation \"%s\" does not exist",
532 *atttypid = attr->atttypid;
533 *atttypmod = attr->atttypmod;
534 *atttypcoll = attr->attcollation;
542 *atttypcoll = attr->attcollation;
557 *atttyptype = typcache->
typtype;
558 *eq_opr = typcache->
eq_opr;
559 *lt_opr = typcache->
lt_opr;
565 if (*atttypid == TSVECTOROID)
566 *atttypcoll = DEFAULT_COLLATION_OID;
576 Oid *elemtypid,
Oid *elem_eq_opr)
580 if (atttypid == TSVECTOROID)
586 *elemtypid = TEXTOID;
602 *elem_eq_opr = elemtypcache->
eq_opr;
616 int32 typmod,
int elevel,
bool *ok)
628 (
Node *) &escontext, NULL);
631 fcinfo->args[0].isnull =
false;
633 fcinfo->args[1].isnull =
false;
635 fcinfo->args[2].isnull =
false;
653 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
654 errmsg(
"\"%s\" array cannot contain NULL values", staname)));
671 Datum stanumbers,
bool stanumbers_isnull,
672 Datum stavalues,
bool stavalues_isnull)
675 int first_empty = -1;
683 stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx;
685 if (first_empty < 0 &&
687 first_empty = slotidx;
693 slotidx = first_empty;
697 (
errmsg(
"maximum number of statistics slots exceeded: %d",
700 stakind_attnum = Anum_pg_statistic_stakind1 - 1 + slotidx;
701 staop_attnum = Anum_pg_statistic_staop1 - 1 + slotidx;
702 stacoll_attnum = Anum_pg_statistic_stacoll1 - 1 + slotidx;
707 replaces[stakind_attnum] =
true;
712 replaces[staop_attnum] =
true;
717 replaces[stacoll_attnum] =
true;
719 if (!stanumbers_isnull)
721 values[Anum_pg_statistic_stanumbers1 - 1 + slotidx] = stanumbers;
722 nulls[Anum_pg_statistic_stanumbers1 - 1 + slotidx] =
false;
723 replaces[Anum_pg_statistic_stanumbers1 - 1 + slotidx] =
true;
725 if (!stavalues_isnull)
727 values[Anum_pg_statistic_stavalues1 - 1 + slotidx] = stavalues;
728 nulls[Anum_pg_statistic_stavalues1 - 1 + slotidx] =
false;
729 replaces[Anum_pg_statistic_stavalues1 - 1 + slotidx] =
true;
791 memset(nulls,
true,
sizeof(
bool) * Natts_pg_statistic);
792 memset(replaces,
true,
sizeof(
bool) * Natts_pg_statistic);
797 nulls[Anum_pg_statistic_starelid - 1] =
false;
799 nulls[Anum_pg_statistic_staattnum - 1] =
false;
801 nulls[Anum_pg_statistic_stainherit - 1] =
false;
804 nulls[Anum_pg_statistic_stanullfrac - 1] =
false;
806 nulls[Anum_pg_statistic_stawidth - 1] =
false;
808 nulls[Anum_pg_statistic_stadistinct - 1] =
false;
813 values[Anum_pg_statistic_stakind1 + slotnum - 1] = (
Datum) 0;
814 nulls[Anum_pg_statistic_stakind1 + slotnum - 1] =
false;
816 nulls[Anum_pg_statistic_staop1 + slotnum - 1] =
false;
818 nulls[Anum_pg_statistic_stacoll1 + slotnum - 1] =
false;
870 (
errcode(ERRCODE_UNDEFINED_COLUMN),
871 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)
static Datum values[MAXATTR]
#define TextDatumGetCString(d)
#define OidIsValid(objectId)
int errdetail(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)
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_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)