if (RecoveryInProgress())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("recovery is in progress"),
errhint("Statistics cannot be modified during recovery.")));
/* lock before looking up attribute */
reloid = RangeVarGetRelidExtended(makeRangeVar(nspname, relname, -1),
ShareUpdateExclusiveLock, 0,
RangeVarCallbackForStats, &locked_table);
/* user can specify either attname or attnum, but not both */ if (!PG_ARGISNULL(ATTNAME_ARG))
{ if (!PG_ARGISNULL(ATTNUM_ARG))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("cannot specify both \"%s\" and \"%s\"", "attname", "attnum")));
attname = TextDatumGetCString(PG_GETARG_DATUM(ATTNAME_ARG));
attnum = get_attnum(reloid, attname); /* note that this test covers attisdropped cases too: */ if (attnum == InvalidAttrNumber)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
attname, relname)));
} elseif (!PG_ARGISNULL(ATTNUM_ARG))
{
attnum = PG_GETARG_INT16(ATTNUM_ARG);
attname = get_attname(reloid, attnum, true); /* annoyingly, get_attname doesn't check attisdropped */ if (attname == NULL ||
!SearchSysCacheExistsAttName(reloid, attname))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column %d of relation \"%s\" does not exist",
attnum, relname)));
} else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("must specify either \"%s\" or \"%s\"", "attname", "attnum")));
attname = NULL; /* keep compiler quiet */
attnum = 0;
}
if (attnum < 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot modify statistics on system column \"%s\"",
attname)));
if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_FREQS_ARG))
{
do_mcv = false;
result = false;
}
if (!stats_check_arg_array(fcinfo, attarginfo, MOST_COMMON_ELEM_FREQS_ARG))
{
do_mcelem = false;
result = false;
} if (!stats_check_arg_array(fcinfo, attarginfo, ELEM_COUNT_HISTOGRAM_ARG))
{
do_dechist = false;
result = false;
}
if (!stats_check_arg_pair(fcinfo, attarginfo,
MOST_COMMON_VALS_ARG, MOST_COMMON_FREQS_ARG))
{
do_mcv = false;
result = false;
}
if (!stats_check_arg_pair(fcinfo, attarginfo,
MOST_COMMON_ELEMS_ARG,
MOST_COMMON_ELEM_FREQS_ARG))
{
do_mcelem = false;
result = false;
}
if (!stats_check_arg_pair(fcinfo, attarginfo,
RANGE_LENGTH_HISTOGRAM_ARG,
RANGE_EMPTY_FRAC_ARG))
{
do_range_length_histogram = false;
result = false;
}
/* derive information from attribute */
get_attr_stat_type(reloid, attnum,
&atttypid, &atttypmod,
&atttyptype, &atttypcoll,
&eq_opr, <_opr);
/* if needed, derive element type */ if (do_mcelem || do_dechist)
{ if (!get_elem_stat_type(atttypid, atttyptype,
&elemtypid, &elem_eq_opr))
{
ereport(WARNING,
(errmsg("could not determine element type of column \"%s\"", attname),
errdetail("Cannot set %s or %s.", "STATISTIC_KIND_MCELEM", "STATISTIC_KIND_DECHIST")));
elemtypid = InvalidOid;
elem_eq_opr = InvalidOid;
/* histogram and correlation require less-than operator */ if ((do_histogram || do_correlation) && !OidIsValid(lt_opr))
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("could not determine less-than operator for column \"%s\"", attname),
errdetail("Cannot set %s or %s.", "STATISTIC_KIND_HISTOGRAM", "STATISTIC_KIND_CORRELATION")));
do_histogram = false;
do_correlation = false;
result = false;
}
/* only range types can have range stats */ if ((do_range_length_histogram || do_bounds_histogram) &&
!(atttyptype == TYPTYPE_RANGE || atttyptype == TYPTYPE_MULTIRANGE))
{
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("column \"%s\" is not a range type", attname),
errdetail("Cannot set %s or %s.", "STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM", "STATISTIC_KIND_BOUNDS_HISTOGRAM")));
do_bounds_histogram = false;
do_range_length_histogram = false;
result = false;
}
if (converted)
{
set_stats_slot(values, nulls, replaces,
STATISTIC_KIND_BOUNDS_HISTOGRAM,
InvalidOid, InvalidOid, 0, true, stavalues, false);
} else
result = false;
}
/* STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM */ if (do_range_length_histogram)
{ /* The anyarray is always a float8[] for this stakind */
Datum elems[] = {PG_GETARG_DATUM(RANGE_EMPTY_FRAC_ARG)};
ArrayType *arry = construct_array_builtin(elems, 1, FLOAT4OID);
Datum stanumbers = PointerGetDatum(arry);
/* Attribute not found */ if (!HeapTupleIsValid(atup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column %d of relation \"%s\" does not exist",
attnum, RelationGetRelationName(rel))));
attr = (Form_pg_attribute) GETSTRUCT(atup);
if (attr->attisdropped)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column %d of relation \"%s\" does not exist",
attnum, RelationGetRelationName(rel))));
/* *Ifit'samultirange,stepdowntotherangetype,asisdoneby *multirange_typanalyze().
*/ if (type_is_multirange(*atttypid))
*atttypid = get_multirange_range(*atttypid);
/* finds the right operators even if atttypid is a domain */
typcache = lookup_type_cache(*atttypid, TYPECACHE_LT_OPR | TYPECACHE_EQ_OPR);
*atttyptype = typcache->typtype;
*eq_opr = typcache->eq_opr;
*lt_opr = typcache->lt_opr;
/* *Deriveelementtypeinformationfromtheattributetype.
*/ staticbool
get_elem_stat_type(Oid atttypid, char atttyptype,
Oid *elemtypid, Oid *elem_eq_opr)
{
TypeCacheEntry *elemtypcache;
if (atttypid == TSVECTOROID)
{ /* *Specialcase:elementtypefortsvectoristext.See *compute_tsvector_stats().
*/
*elemtypid = TEXTOID;
} else
{ /* find underlying element type through any domain */
*elemtypid = get_base_element_type(atttypid);
}
if (!OidIsValid(*elemtypid)) returnfalse;
/* finds the right operator even if elemtypid is a domain */
elemtypcache = lookup_type_cache(*elemtypid, TYPECACHE_EQ_OPR); if (!OidIsValid(elemtypcache->eq_opr)) returnfalse;
*elem_eq_opr = elemtypcache->eq_opr;
returntrue;
}
/* *Castatextdatumintoanarraywithelementtypeelemtypid. * *Ifanerrorisencountered,captureitandre-throwaWARNING,andsetok *tofalse.IftheresultingarraycontainsNULLs,raiseaWARNINGandsetok *tofalse.Otherwise,setoktotrue.
*/ static Datum
text_to_stavalues(constchar *staname, FmgrInfo *array_in, Datum d, Oid typid,
int32 typmod, bool *ok)
{
LOCAL_FCINFO(fcinfo, 8); char *s;
Datum result;
ErrorSaveContext escontext = {T_ErrorSaveContext};
/* Is there already a pg_statistic tuple for this attribute? */
oldtup = SearchSysCache3(STATRELATTINH,
ObjectIdGetDatum(reloid),
Int16GetDatum(attnum),
BoolGetDatum(stainherit));
if (HeapTupleIsValid(oldtup))
{
CatalogTupleDelete(sd, &oldtup->t_self);
ReleaseSysCache(oldtup);
result = true;
}
if (RecoveryInProgress())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("recovery is in progress"),
errhint("Statistics cannot be modified during recovery.")));
if (attnum < 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot clear statistics on system column \"%s\"",
attname)));
if (attnum == InvalidAttrNumber)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
attname, get_rel_name(reloid))));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.