summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorJeff Davis2025-03-25 18:16:06 +0000
committerJeff Davis2025-03-25 18:16:06 +0000
commit650ab8aaf1957863ae14c80265e79f5d903b49fd (patch)
tree6ea530310dc773d82160cc6cc6d66893ab8ec910 /src/backend
parent2a420f7995e415f4813fccf1c42ab29a3a32182f (diff)
Stats: use schemaname/relname instead of regclass.
For import and export, use schemaname/relname rather than regclass. This is more natural during export, fits with the other arguments better, and it gives better control over error handling in case we need to downgrade more errors to warnings. Also, use text for the argument types for schemaname, relname, and attname so that casts to "name" are not required. Author: Corey Huinker <[email protected]> Discussion: https://postgr.es/m/CADkLM=ceOSsx_=oe73QQ-BxUFR2Cwqum7-UP_fPe22DBY0NerA@mail.gmail.com
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/statistics/attribute_stats.c61
-rw-r--r--src/backend/statistics/relation_stats.c54
-rw-r--r--src/backend/statistics/stat_utils.c22
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.
*/