diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/statistics/attribute_stats.c | 61 | ||||
-rw-r--r-- | src/backend/statistics/relation_stats.c | 54 | ||||
-rw-r--r-- | src/backend/statistics/stat_utils.c | 22 |
3 files changed, 94 insertions, 43 deletions
diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c index 6bcbee0edba..f5eb17ba42d 100644 --- a/src/backend/statistics/attribute_stats.c +++ b/src/backend/statistics/attribute_stats.c @@ -36,7 +36,8 @@ enum attribute_stats_argnum { - ATTRELATION_ARG = 0, + ATTRELSCHEMA_ARG = 0, + ATTRELNAME_ARG, ATTNAME_ARG, ATTNUM_ARG, INHERITED_ARG, @@ -58,8 +59,9 @@ enum attribute_stats_argnum static struct StatsArgInfo attarginfo[] = { - [ATTRELATION_ARG] = {"relation", REGCLASSOID}, - [ATTNAME_ARG] = {"attname", NAMEOID}, + [ATTRELSCHEMA_ARG] = {"schemaname", TEXTOID}, + [ATTRELNAME_ARG] = {"relname", TEXTOID}, + [ATTNAME_ARG] = {"attname", TEXTOID}, [ATTNUM_ARG] = {"attnum", INT2OID}, [INHERITED_ARG] = {"inherited", BOOLOID}, [NULL_FRAC_ARG] = {"null_frac", FLOAT4OID}, @@ -80,7 +82,8 @@ static struct StatsArgInfo attarginfo[] = enum clear_attribute_stats_argnum { - C_ATTRELATION_ARG = 0, + C_ATTRELSCHEMA_ARG = 0, + C_ATTRELNAME_ARG, C_ATTNAME_ARG, C_INHERITED_ARG, C_NUM_ATTRIBUTE_STATS_ARGS @@ -88,8 +91,9 @@ enum clear_attribute_stats_argnum static struct StatsArgInfo cleararginfo[] = { - [C_ATTRELATION_ARG] = {"relation", REGCLASSOID}, - [C_ATTNAME_ARG] = {"attname", NAMEOID}, + [C_ATTRELSCHEMA_ARG] = {"relation", TEXTOID}, + [C_ATTRELNAME_ARG] = {"relation", TEXTOID}, + [C_ATTNAME_ARG] = {"attname", TEXTOID}, [C_INHERITED_ARG] = {"inherited", BOOLOID}, [C_NUM_ATTRIBUTE_STATS_ARGS] = {0} }; @@ -133,6 +137,8 @@ static void init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited, static bool attribute_statistics_update(FunctionCallInfo fcinfo) { + char *nspname; + char *relname; Oid reloid; char *attname; AttrNumber attnum; @@ -170,8 +176,13 @@ attribute_statistics_update(FunctionCallInfo fcinfo) bool result = true; - stats_check_required_arg(fcinfo, attarginfo, ATTRELATION_ARG); - reloid = PG_GETARG_OID(ATTRELATION_ARG); + stats_check_required_arg(fcinfo, attarginfo, ATTRELSCHEMA_ARG); + stats_check_required_arg(fcinfo, attarginfo, ATTRELNAME_ARG); + + nspname = TextDatumGetCString(PG_GETARG_DATUM(ATTRELSCHEMA_ARG)); + relname = TextDatumGetCString(PG_GETARG_DATUM(ATTRELNAME_ARG)); + + reloid = stats_lookup_relid(nspname, relname); if (RecoveryInProgress()) ereport(ERROR, @@ -185,21 +196,18 @@ attribute_statistics_update(FunctionCallInfo fcinfo) /* user can specify either attname or attnum, but not both */ if (!PG_ARGISNULL(ATTNAME_ARG)) { - Name attnamename; - if (!PG_ARGISNULL(ATTNUM_ARG)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("cannot specify both attname and attnum"))); - attnamename = PG_GETARG_NAME(ATTNAME_ARG); - attname = NameStr(*attnamename); + 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, get_rel_name(reloid)))); + attname, relname))); } else if (!PG_ARGISNULL(ATTNUM_ARG)) { @@ -211,7 +219,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column %d of relation \"%s\" does not exist", - attnum, get_rel_name(reloid)))); + attnum, relname))); } else { @@ -900,13 +908,22 @@ init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited, Datum pg_clear_attribute_stats(PG_FUNCTION_ARGS) { + char *nspname; + char *relname; Oid reloid; - Name attname; + char *attname; AttrNumber attnum; bool inherited; - stats_check_required_arg(fcinfo, cleararginfo, C_ATTRELATION_ARG); - reloid = PG_GETARG_OID(C_ATTRELATION_ARG); + stats_check_required_arg(fcinfo, cleararginfo, C_ATTRELSCHEMA_ARG); + stats_check_required_arg(fcinfo, cleararginfo, C_ATTRELNAME_ARG); + stats_check_required_arg(fcinfo, cleararginfo, C_ATTNAME_ARG); + stats_check_required_arg(fcinfo, cleararginfo, C_INHERITED_ARG); + + nspname = TextDatumGetCString(PG_GETARG_DATUM(C_ATTRELSCHEMA_ARG)); + relname = TextDatumGetCString(PG_GETARG_DATUM(C_ATTRELNAME_ARG)); + + reloid = stats_lookup_relid(nspname, relname); if (RecoveryInProgress()) ereport(ERROR, @@ -916,23 +933,21 @@ pg_clear_attribute_stats(PG_FUNCTION_ARGS) stats_lock_check_privileges(reloid); - stats_check_required_arg(fcinfo, cleararginfo, C_ATTNAME_ARG); - attname = PG_GETARG_NAME(C_ATTNAME_ARG); - attnum = get_attnum(reloid, NameStr(*attname)); + attname = TextDatumGetCString(PG_GETARG_DATUM(C_ATTNAME_ARG)); + attnum = get_attnum(reloid, attname); if (attnum < 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot clear statistics on system column \"%s\"", - NameStr(*attname)))); + attname))); if (attnum == InvalidAttrNumber) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" of relation \"%s\" does not exist", - NameStr(*attname), get_rel_name(reloid)))); + attname, get_rel_name(reloid)))); - stats_check_required_arg(fcinfo, cleararginfo, C_INHERITED_ARG); inherited = PG_GETARG_BOOL(C_INHERITED_ARG); delete_pg_statistic(reloid, attnum, inherited); diff --git a/src/backend/statistics/relation_stats.c b/src/backend/statistics/relation_stats.c index 52dfa477187..cd3a75b621a 100644 --- a/src/backend/statistics/relation_stats.c +++ b/src/backend/statistics/relation_stats.c @@ -19,9 +19,12 @@ #include "access/heapam.h" #include "catalog/indexing.h" +#include "catalog/namespace.h" #include "statistics/stat_utils.h" +#include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/fmgrprotos.h" +#include "utils/lsyscache.h" #include "utils/syscache.h" @@ -32,7 +35,8 @@ enum relation_stats_argnum { - RELATION_ARG = 0, + RELSCHEMA_ARG = 0, + RELNAME_ARG, RELPAGES_ARG, RELTUPLES_ARG, RELALLVISIBLE_ARG, @@ -42,7 +46,8 @@ enum relation_stats_argnum static struct StatsArgInfo relarginfo[] = { - [RELATION_ARG] = {"relation", REGCLASSOID}, + [RELSCHEMA_ARG] = {"schemaname", TEXTOID}, + [RELNAME_ARG] = {"relname", TEXTOID}, [RELPAGES_ARG] = {"relpages", INT4OID}, [RELTUPLES_ARG] = {"reltuples", FLOAT4OID}, [RELALLVISIBLE_ARG] = {"relallvisible", INT4OID}, @@ -59,6 +64,8 @@ static bool relation_statistics_update(FunctionCallInfo fcinfo) { bool result = true; + char *nspname; + char *relname; Oid reloid; Relation crel; BlockNumber relpages = 0; @@ -76,6 +83,22 @@ relation_statistics_update(FunctionCallInfo fcinfo) bool nulls[4] = {0}; int nreplaces = 0; + stats_check_required_arg(fcinfo, relarginfo, RELSCHEMA_ARG); + stats_check_required_arg(fcinfo, relarginfo, RELNAME_ARG); + + nspname = TextDatumGetCString(PG_GETARG_DATUM(RELSCHEMA_ARG)); + relname = TextDatumGetCString(PG_GETARG_DATUM(RELNAME_ARG)); + + reloid = stats_lookup_relid(nspname, relname); + + if (RecoveryInProgress()) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("recovery is in progress"), + errhint("Statistics cannot be modified during recovery."))); + + stats_lock_check_privileges(reloid); + if (!PG_ARGISNULL(RELPAGES_ARG)) { relpages = PG_GETARG_UINT32(RELPAGES_ARG); @@ -108,17 +131,6 @@ relation_statistics_update(FunctionCallInfo fcinfo) update_relallfrozen = true; } - stats_check_required_arg(fcinfo, relarginfo, RELATION_ARG); - reloid = PG_GETARG_OID(RELATION_ARG); - - if (RecoveryInProgress()) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("recovery is in progress"), - errhint("Statistics cannot be modified during recovery."))); - - stats_lock_check_privileges(reloid); - /* * Take RowExclusiveLock on pg_class, consistent with * vac_update_relstats(). @@ -187,20 +199,22 @@ relation_statistics_update(FunctionCallInfo fcinfo) Datum pg_clear_relation_stats(PG_FUNCTION_ARGS) { - LOCAL_FCINFO(newfcinfo, 5); + LOCAL_FCINFO(newfcinfo, 6); - InitFunctionCallInfoData(*newfcinfo, NULL, 5, InvalidOid, NULL, NULL); + InitFunctionCallInfoData(*newfcinfo, NULL, 6, InvalidOid, NULL, NULL); - newfcinfo->args[0].value = PG_GETARG_OID(0); + newfcinfo->args[0].value = PG_GETARG_DATUM(0); newfcinfo->args[0].isnull = PG_ARGISNULL(0); - newfcinfo->args[1].value = UInt32GetDatum(0); - newfcinfo->args[1].isnull = false; - newfcinfo->args[2].value = Float4GetDatum(-1.0); + newfcinfo->args[1].value = PG_GETARG_DATUM(1); + newfcinfo->args[1].isnull = PG_ARGISNULL(1); + newfcinfo->args[2].value = UInt32GetDatum(0); newfcinfo->args[2].isnull = false; - newfcinfo->args[3].value = UInt32GetDatum(0); + newfcinfo->args[3].value = Float4GetDatum(-1.0); newfcinfo->args[3].isnull = false; newfcinfo->args[4].value = UInt32GetDatum(0); newfcinfo->args[4].isnull = false; + newfcinfo->args[5].value = UInt32GetDatum(0); + newfcinfo->args[5].isnull = false; relation_statistics_update(newfcinfo); PG_RETURN_VOID(); diff --git a/src/backend/statistics/stat_utils.c b/src/backend/statistics/stat_utils.c index 9647f5108b3..a9a3224efe6 100644 --- a/src/backend/statistics/stat_utils.c +++ b/src/backend/statistics/stat_utils.c @@ -18,6 +18,7 @@ #include "access/relation.h" #include "catalog/index.h" +#include "catalog/namespace.h" #include "catalog/pg_database.h" #include "funcapi.h" #include "miscadmin.h" @@ -214,6 +215,27 @@ stats_lock_check_privileges(Oid reloid) } /* + * Lookup relation oid from schema and relation name. + */ +Oid +stats_lookup_relid(const char *nspname, const char *relname) +{ + Oid nspoid; + Oid reloid; + + nspoid = LookupExplicitNamespace(nspname, false); + reloid = get_relname_relid(relname, nspoid); + if (!OidIsValid(reloid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("relation \"%s.%s\" does not exist", + nspname, relname))); + + return reloid; +} + + +/* * Find the argument number for the given argument name, returning -1 if not * found. */ |