/* qsort comparator for the attnums in CreateStatistics */ staticint
compare_int16(constvoid *a, constvoid *b)
{ int av = *(const int16 *) a; int bv = *(const int16 *) b;
/* this can't overflow if int is wider than int16 */ return (av - bv);
}
/* *CREATESTATISTICS
*/
ObjectAddress
CreateStatistics(CreateStatsStmt *stmt, bool check_rights)
{
int16 attnums[STATS_MAX_DIMENSIONS]; int nattnums = 0; int numcols; char *namestr;
NameData stxname;
Oid statoid;
Oid namespaceId;
Oid stxowner = GetUserId();
HeapTuple htup;
Datum values[Natts_pg_statistic_ext]; bool nulls[Natts_pg_statistic_ext];
int2vector *stxkeys;
List *stxexprs = NIL;
Datum exprsDatum;
Relation statrel;
Relation rel = NULL;
Oid relid;
ObjectAddress parentobject,
myself;
Datum types[4]; /* one for each possible type of statistic */ int ntypes;
ArrayType *stxkind; bool build_ndistinct; bool build_dependencies; bool build_mcv; bool build_expressions; bool requested_type = false; int i;
ListCell *cell;
ListCell *cell2;
Assert(IsA(stmt, CreateStatsStmt));
/* *ExaminetheFROMclause.Currently,weonlyallowittobeasingle *simpletable,butlaterwe'llprobablyallowmultipletablesandJOIN *syntax.Thegrammarisalreadypreparedforthat,sowehavetocheck *herethatwhatwegotiswhatwecansupport.
*/ if (list_length(stmt->relations) != 1)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("only a single relation is allowed in CREATE STATISTICS")));
/* Creating statistics on system catalogs is not allowed */ if (!allowSystemTableMods && IsSystemRelation(rel))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied: \"%s\" is a system catalog",
RelationGetRelationName(rel))));
}
/* *MakesurenomorethanSTATS_MAX_DIMENSIONScolumnsareused.There *mightbeduplicatesandsoon,butwe'lldealwiththoselater.
*/
numcols = list_length(stmt->exprs); if (numcols > STATS_MAX_DIMENSIONS)
ereport(ERROR,
(errcode(ERRCODE_TOO_MANY_COLUMNS),
errmsg("cannot have more than %d columns in statistics",
STATS_MAX_DIMENSIONS)));
atttuple = SearchSysCacheAttName(relid, attname); if (!HeapTupleIsValid(atttuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" does not exist",
attname)));
attForm = (Form_pg_attribute) GETSTRUCT(atttuple);
/* Disallow use of system attributes in extended stats */ if (attForm->attnum <= 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("statistics creation on system columns is not supported")));
/* Disallow use of virtual generated columns in extended stats */ if (attForm->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("statistics creation on virtual generated columns is not supported")));
/* Disallow data types without a less-than operator */
type = lookup_type_cache(attForm->atttypid, TYPECACHE_LT_OPR); if (type->lt_opr == InvalidOid)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("column \"%s\" cannot be used in statistics because its type %s has no default btree operator class",
attname, format_type_be(attForm->atttypid))));
/* Disallow use of system attributes in extended stats */ if (var->varattno <= 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("statistics creation on system columns is not supported")));
/* Disallow use of virtual generated columns in extended stats */ if (get_attgenerated(relid, var->varattno) == ATTRIBUTE_GENERATED_VIRTUAL)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("statistics creation on virtual generated columns is not supported")));
/* Disallow data types without a less-than operator */
type = lookup_type_cache(var->vartype, TYPECACHE_LT_OPR); if (type->lt_opr == InvalidOid)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("column \"%s\" cannot be used in statistics because its type %s has no default btree operator class",
get_attname(relid, var->varattno, false), format_type_be(var->vartype))));
k = -1; while ((k = bms_next_member(attnums, k)) >= 0)
{
AttrNumber attnum = k + FirstLowInvalidHeapAttributeNumber;
/* Disallow expressions referencing system attributes. */ if (attnum <= 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("statistics creation on system columns is not supported")));
/* Disallow use of virtual generated columns in extended stats */ if (get_attgenerated(relid, attnum) == ATTRIBUTE_GENERATED_VIRTUAL)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("statistics creation on virtual generated columns is not supported")));
}
/* *Disallowdatatypeswithoutaless-thanoperator. * *Weignorethisforstatisticsonasingleexpression,inwhich *casewe'llbuildtheregularstatisticsonly(andthatcodecan *dealwithsuchdatatypes).
*/ if (list_length(stmt->exprs) > 1)
{
atttype = exprType(expr);
type = lookup_type_cache(atttype, TYPECACHE_LT_OPR); if (type->lt_opr == InvalidOid)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("expression cannot be used in multivariate statistics because its type %s has no default btree operator class",
format_type_be(atttype))));
}
stxexprs = lappend(stxexprs, expr);
}
}
/* *Parsethestatisticskinds. * *Firstcheckthatifthisisthecasewithasingleexpression,there *arenostatisticskindsspecified(wedon'tallowthatforthesimple *CREATESTATISTICSform).
*/ if ((list_length(stmt->exprs) == 1) && (list_length(stxexprs) == 1))
{ /* statistics kinds not specified */ if (stmt->stat_types != NIL)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("when building statistics on a single expression, statistics kinds may not be specified")));
}
/* OK, let's check that we recognize the statistics kinds. */
build_ndistinct = false;
build_dependencies = false;
build_mcv = false;
foreach(cell, stmt->stat_types)
{ char *type = strVal(lfirst(cell));
/* *Checkforduplicatesinthelistofcolumns.Theattnumsaresortedso *justcheckconsecutiveelements.
*/ for (i = 1; i < nattnums; i++)
{ if (attnums[i] == attnums[i - 1])
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_COLUMN),
errmsg("duplicate column name in statistics definition")));
}
/* *ALTERSTATISTICS
*/
ObjectAddress
AlterStatistics(AlterStatsStmt *stmt)
{
Relation rel;
Oid stxoid;
HeapTuple oldtup;
HeapTuple newtup;
Datum repl_val[Natts_pg_statistic_ext]; bool repl_null[Natts_pg_statistic_ext]; bool repl_repl[Natts_pg_statistic_ext];
ObjectAddress address; int newtarget = 0; bool newtarget_default;
/* -1 was used in previous versions for the default setting */ if (stmt->stxstattarget && intVal(stmt->stxstattarget) != -1)
{
newtarget = intVal(stmt->stxstattarget);
newtarget_default = false;
} else
newtarget_default = true;
if (!newtarget_default)
{ /* Limit statistics target to a sane range */ if (newtarget < 0)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("statistics target %d is too low",
newtarget)));
} elseif (newtarget > MAX_STATISTICS_TARGET)
{
newtarget = MAX_STATISTICS_TARGET;
ereport(WARNING,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("lowering statistics target to %d",
newtarget)));
}
}
/* lookup OID of the statistics object */
stxoid = get_statistics_object_oid(stmt->defnames, stmt->missing_ok);
if (schemaname)
ereport(NOTICE,
(errmsg("statistics object \"%s.%s\" does not exist, skipping",
schemaname, statname))); else
ereport(NOTICE,
(errmsg("statistics object \"%s\" does not exist, skipping",
statname)));
oldtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(stxoid)); if (!HeapTupleIsValid(oldtup))
elog(ERROR, "cache lookup failed for extended statistics object %u", stxoid);
/* Must be owner of the existing statistics object */ if (!object_ownercheck(StatisticExtRelationId, stxoid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_STATISTIC_EXT,
NameListToString(stmt->defnames));
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.