From cb22c5782c4652d76885cb8dd3a2753ccac01b24 Mon Sep 17 00:00:00 2001 From: Corey Huinker Date: Tue, 4 Mar 2025 22:16:52 -0500 Subject: [PATCH v6 3/4] Split relation into schemaname and relname. In order to further reduce potential error-failures in restores and upgrades, replace the numerous casts of fully qualified relation names into their schema+relname text components. Further remove the ::name casts on attname and change the expected datatype to text. --- src/include/catalog/pg_proc.dat | 8 +- src/backend/statistics/attribute_stats.c | 98 +++++-- src/backend/statistics/relation_stats.c | 70 +++-- src/bin/pg_dump/pg_dump.c | 25 +- src/bin/pg_dump/t/002_pg_dump.pl | 6 +- src/test/regress/expected/stats_import.out | 302 +++++++++++++-------- src/test/regress/sql/stats_import.sql | 271 +++++++++++------- doc/src/sgml/func.sgml | 41 +-- 8 files changed, 537 insertions(+), 284 deletions(-) diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 134b3dd8689..53aa4bc4df3 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -12424,8 +12424,8 @@ descr => 'clear statistics on relation', proname => 'pg_clear_relation_stats', provolatile => 'v', proisstrict => 'f', proparallel => 'u', prorettype => 'void', - proargtypes => 'regclass', - proargnames => '{relation}', + proargtypes => 'text text', + proargnames => '{schemaname,relname}', prosrc => 'pg_clear_relation_stats' }, { oid => '8461', descr => 'restore statistics on attribute', @@ -12440,8 +12440,8 @@ descr => 'clear statistics on attribute', proname => 'pg_clear_attribute_stats', provolatile => 'v', proisstrict => 'f', proparallel => 'u', prorettype => 'void', - proargtypes => 'regclass name bool', - proargnames => '{relation,attname,inherited}', + proargtypes => 'text text text bool', + proargnames => '{schemaname,relname,attname,inherited}', prosrc => 'pg_clear_attribute_stats' }, # GiST stratnum implementations diff --git a/src/backend/statistics/attribute_stats.c b/src/backend/statistics/attribute_stats.c index 6bcbee0edba..65456a04ae5 100644 --- a/src/backend/statistics/attribute_stats.c +++ b/src/backend/statistics/attribute_stats.c @@ -19,6 +19,7 @@ #include "access/heapam.h" #include "catalog/indexing.h" +#include "catalog/namespace.h" #include "catalog/pg_collation.h" #include "catalog/pg_operator.h" #include "nodes/nodeFuncs.h" @@ -36,7 +37,8 @@ enum attribute_stats_argnum { - ATTRELATION_ARG = 0, + ATTRELSCHEMA_ARG = 0, + ATTRELNAME_ARG, ATTNAME_ARG, ATTNUM_ARG, INHERITED_ARG, @@ -58,8 +60,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 +83,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 +92,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 +138,9 @@ static void init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited, static bool attribute_statistics_update(FunctionCallInfo fcinfo) { + char *nspname; + Oid nspoid; + char *relname; Oid reloid; char *attname; AttrNumber attnum; @@ -170,8 +178,28 @@ 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)); + nspoid = get_namespace_oid(nspname, true); + if (nspoid == InvalidOid) + { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Namespace \"%s\" not found.", nspname))); + return false; + } + + relname = TextDatumGetCString(PG_GETARG_DATUM(ATTRELNAME_ARG)); + reloid = get_relname_relid(relname, nspoid); + if (reloid == InvalidOid) + { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Relation \"%s\".\"%s\" not found.", nspname, relname))); + return false; + } if (RecoveryInProgress()) ereport(ERROR, @@ -185,21 +213,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)))); + errmsg("column \"%s\" of relation \"%s\".\"%s\" does not exist", + attname, nspname, relname))); } else if (!PG_ARGISNULL(ATTNUM_ARG)) { @@ -210,8 +235,8 @@ attribute_statistics_update(FunctionCallInfo fcinfo) !SearchSysCacheExistsAttName(reloid, attname)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column %d of relation \"%s\" does not exist", - attnum, get_rel_name(reloid)))); + errmsg("column %d of relation \"%s\".\"%s\" does not exist", + attnum, nspname, relname))); } else { @@ -900,13 +925,38 @@ init_empty_stats_tuple(Oid reloid, int16 attnum, bool inherited, Datum pg_clear_attribute_stats(PG_FUNCTION_ARGS) { + char *nspname; + Oid nspoid; + 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)); + nspoid = get_namespace_oid(nspname, true); + if (nspoid == InvalidOid) + { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Namespace \"%s\" not found.", nspname))); + return false; + } + + relname = TextDatumGetCString(PG_GETARG_DATUM(C_ATTRELNAME_ARG)); + reloid = get_relname_relid(relname, nspoid); + if (reloid == InvalidOid) + { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Relation \"%s\".\"%s\" not found.", nspname, relname))); + return false; + } if (RecoveryInProgress()) ereport(ERROR, @@ -916,23 +966,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 2c1cea3fc80..4c1e75a3c78 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,9 @@ static bool relation_statistics_update(FunctionCallInfo fcinfo) { bool result = true; + char *nspname; + Oid nspoid; + char *relname; Oid reloid; Relation crel; BlockNumber relpages = 0; @@ -76,6 +84,37 @@ 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)); + nspoid = get_namespace_oid(nspname, true); + if (nspoid == InvalidOid) + { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Namespace \"%s\" not found.", nspname))); + return false; + } + + relname = TextDatumGetCString(PG_GETARG_DATUM(RELNAME_ARG)); + reloid = get_relname_relid(relname, nspoid); + if (reloid == InvalidOid) + { + ereport(WARNING, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("Relation \"%s\".\"%s\" not found.", nspname, relname))); + return false; + } + + 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 +147,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(). @@ -193,20 +221,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/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 4f4ad2ee150..6cf2c7d1fe4 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -10492,7 +10492,6 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo) PQExpBuffer out; DumpId *deps = NULL; int ndeps = 0; - char *qualified_name; char reltuples_str[FLOAT_SHORTEST_DECIMAL_LEN]; int i_attname; int i_inherited; @@ -10558,15 +10557,16 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo) out = createPQExpBuffer(); - qualified_name = pg_strdup(fmtQualifiedDumpable(rsinfo)); - /* restore relation stats */ appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n"); appendPQExpBuffer(out, "\t'version', '%u'::integer,\n", fout->remoteVersion); - appendPQExpBufferStr(out, "\t'relation', "); - appendStringLiteralAH(out, qualified_name, fout); - appendPQExpBufferStr(out, "::regclass,\n"); + appendPQExpBufferStr(out, "\t'schemaname', "); + appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout); + appendPQExpBufferStr(out, ",\n"); + appendPQExpBufferStr(out, "\t'relname', "); + appendStringLiteralAH(out, rsinfo->dobj.name, fout); + appendPQExpBufferStr(out, ",\n"); appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages); float_to_shortest_decimal_buf(rsinfo->reltuples, reltuples_str); appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", reltuples_str); @@ -10606,9 +10606,10 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo) appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_attribute_stats(\n"); appendPQExpBuffer(out, "\t'version', '%u'::integer,\n", fout->remoteVersion); - appendPQExpBufferStr(out, "\t'relation', "); - appendStringLiteralAH(out, qualified_name, fout); - appendPQExpBufferStr(out, "::regclass"); + appendPQExpBufferStr(out, "\t'schemaname', "); + appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout); + appendPQExpBufferStr(out, ",\n\t'relname', "); + appendStringLiteralAH(out, rsinfo->dobj.name, fout); if (PQgetisnull(res, rownum, i_attname)) pg_fatal("attname cannot be NULL"); @@ -10620,7 +10621,10 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo) * their attnames are not necessarily stable across dump/reload. */ if (rsinfo->nindAttNames == 0) - appendNamedArgument(out, fout, "attname", "name", attname); + { + appendPQExpBuffer(out, ",\n\t'attname', "); + appendStringLiteralAH(out, attname, fout); + } else { bool found = false; @@ -10700,7 +10704,6 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo) .deps = deps, .nDeps = ndeps)); - free(qualified_name); destroyPQExpBuffer(out); destroyPQExpBuffer(query); } diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index c7bffc1b045..b037f239136 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -4725,14 +4725,16 @@ my %tests = ( regexp => qr/^ \QSELECT * FROM pg_catalog.pg_restore_relation_stats(\E\s+ 'version',\s'\d+'::integer,\s+ - 'relation',\s'dump_test.dup_test_post_data_ix'::regclass,\s+ + 'schemaname',\s'dump_test',\s+ + 'relname',\s'dup_test_post_data_ix',\s+ 'relpages',\s'\d+'::integer,\s+ 'reltuples',\s'\d+'::real,\s+ 'relallvisible',\s'\d+'::integer\s+ \);\s+ \QSELECT * FROM pg_catalog.pg_restore_attribute_stats(\E\s+ 'version',\s'\d+'::integer,\s+ - 'relation',\s'dump_test.dup_test_post_data_ix'::regclass,\s+ + 'schemaname',\s'dump_test',\s+ + 'relname',\s'dup_test_post_data_ix',\s+ 'attnum',\s'2'::smallint,\s+ 'inherited',\s'f'::boolean,\s+ 'null_frac',\s'0'::real,\s+ diff --git a/src/test/regress/expected/stats_import.out b/src/test/regress/expected/stats_import.out index ebba14c6a1d..ca7fe39660e 100644 --- a/src/test/regress/expected/stats_import.out +++ b/src/test/regress/expected/stats_import.out @@ -16,33 +16,54 @@ CREATE INDEX test_i ON stats_import.test(id); -- -- relstats tests -- ---- error: relation is wrong type +-- error: schemaname missing SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 0::oid, + 'relname', 'test', 'relpages', 17::integer); -WARNING: argument "relation" has type "oid", expected type "regclass" -ERROR: "relation" cannot be NULL +ERROR: "schemaname" cannot be NULL +-- error: relname missing +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relpages', 17::integer); +ERROR: "relname" cannot be NULL +--- error: schemaname is wrong type +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 3.6::float, + 'relname', 'test', + 'relpages', 17::integer); +WARNING: argument "schemaname" has type "double precision", expected type "text" +ERROR: "schemaname" cannot be NULL +--- error: relname is wrong type +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 0::oid, + 'relpages', 17::integer); +WARNING: argument "relname" has type "oid", expected type "text" +ERROR: "relname" cannot be NULL -- error: relation not found SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 0::oid::regclass, + 'schemaname', 'stats_import', + 'relname', 'nope', 'relpages', 17::integer); -ERROR: could not open relation with OID 0 +WARNING: Relation "stats_import"."nope" not found. + pg_restore_relation_stats +--------------------------- + f +(1 row) + -- error: odd number of variadic arguments cannot be pairs SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'relallvisible'); ERROR: variadic arguments must be name/value pairs HINT: Provide an even number of variadic arguments that can be divided into pairs. -- error: argument name is NULL SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', NULL, '17'::integer); -ERROR: name at variadic position 3 is NULL --- error: argument name is not a text type -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 17, '17'::integer); -ERROR: name at variadic position 3 has type "integer", expected type "text" +ERROR: name at variadic position 5 is NULL -- starting stats SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class @@ -55,7 +76,8 @@ WHERE oid = 'stats_import.test_i'::regclass; -- regular indexes have special case locking rules BEGIN; SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.test_i'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test_i', 'relpages', 18::integer); pg_restore_relation_stats --------------------------- @@ -103,7 +125,8 @@ WHERE oid = 'stats_import.part_parent'::regclass; -- BEGIN; SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.part_parent_i'::regclass, + 'schemaname', 'stats_import', + 'relname', 'part_parent_i', 'relpages', 2::integer); pg_restore_relation_stats --------------------------- @@ -137,7 +160,8 @@ WHERE oid = 'stats_import.part_parent_i'::regclass; -- ok: set all relstats, with version, no bounds checking SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'version', 150000::integer, 'relpages', '-17'::integer, 'reltuples', 400::real, @@ -158,7 +182,8 @@ WHERE oid = 'stats_import.test'::regclass; -- ok: set just relpages, rest stay same SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'relpages', '16'::integer); pg_restore_relation_stats --------------------------- @@ -175,7 +200,8 @@ WHERE oid = 'stats_import.test'::regclass; -- ok: set just reltuples, rest stay same SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'reltuples', '500'::real); pg_restore_relation_stats --------------------------- @@ -192,7 +218,8 @@ WHERE oid = 'stats_import.test'::regclass; -- ok: set just relallvisible, rest stay same SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'relallvisible', 5::integer); pg_restore_relation_stats --------------------------- @@ -209,7 +236,8 @@ WHERE oid = 'stats_import.test'::regclass; -- ok: just relallfrozen SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'version', 150000::integer, 'relallfrozen', 3::integer); pg_restore_relation_stats @@ -227,7 +255,8 @@ WHERE oid = 'stats_import.test'::regclass; -- warn: bad relpages type, rest updated SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'relpages', 'nope'::text, 'reltuples', 400.0::real, 'relallvisible', 4::integer, @@ -248,7 +277,8 @@ WHERE oid = 'stats_import.test'::regclass; -- unrecognized argument name, rest ok SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'relpages', '171'::integer, 'nope', 10::integer); WARNING: unrecognized argument name: "nope" @@ -266,8 +296,7 @@ WHERE oid = 'stats_import.test'::regclass; (1 row) -- ok: clear stats -SELECT pg_catalog.pg_clear_relation_stats( - relation => 'stats_import.test'::regclass); +SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'test'); pg_clear_relation_stats ------------------------- @@ -284,87 +313,123 @@ WHERE oid = 'stats_import.test'::regclass; -- invalid relkinds for statistics CREATE SEQUENCE stats_import.testseq; SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.testseq'::regclass); + 'schemaname', 'stats_import', + 'relname', 'testseq'); ERROR: cannot modify statistics for relation "testseq" DETAIL: This operation is not supported for sequences. -SELECT pg_catalog.pg_clear_relation_stats( - 'stats_import.testseq'::regclass); +SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testseq'); ERROR: cannot modify statistics for relation "testseq" DETAIL: This operation is not supported for sequences. CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test; -SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.testview'::regclass); -ERROR: cannot modify statistics for relation "testview" -DETAIL: This operation is not supported for views. -SELECT pg_catalog.pg_clear_relation_stats( - 'stats_import.testview'::regclass); +SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testview'); ERROR: cannot modify statistics for relation "testview" DETAIL: This operation is not supported for views. -- -- attribute stats -- --- error: object does not exist +-- error: schemaname missing SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', '0'::oid::regclass, - 'attname', 'id'::name, + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.1::real); -ERROR: could not open relation with OID 0 --- error: relation null +ERROR: "schemaname" cannot be NULL +-- error: schema does not exist SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', NULL::oid::regclass, - 'attname', 'id'::name, + 'schemaname', 'nope', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.1::real); -ERROR: "relation" cannot be NULL +WARNING: Namespace "nope" not found. + pg_restore_attribute_stats +---------------------------- + f +(1 row) + +-- error: relname missing +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); +ERROR: "relname" cannot be NULL +-- error: relname does not exist +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'nope', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); +WARNING: Relation "stats_import"."nope" not found. + pg_restore_attribute_stats +---------------------------- + f +(1 row) + +-- error: relname null +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', NULL, + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); +ERROR: "relname" cannot be NULL -- error: NULL attname SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', NULL::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', NULL, 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: must specify either attname or attnum -- error: attname doesn't exist SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'nope'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'nope', 'inherited', false::boolean, 'null_frac', 0.1::real, 'avg_width', 2::integer, 'n_distinct', 0.3::real); -ERROR: column "nope" of relation "test" does not exist +ERROR: column "nope" of relation "stats_import"."test" does not exist -- error: both attname and attnum SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'attnum', 1::smallint, 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: cannot specify both attname and attnum -- error: neither attname nor attnum SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: must specify either attname or attnum -- error: attribute is system column SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'xmin'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'xmin', 'inherited', false::boolean, 'null_frac', 0.1::real); ERROR: cannot modify statistics on system column "xmin" -- error: inherited null SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', NULL::boolean, 'null_frac', 0.1::real); ERROR: "inherited" cannot be NULL -- ok: just the fixed values, with version, no stakinds SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'version', 150000::integer, 'null_frac', 0.2::real, @@ -392,7 +457,8 @@ AND attname = 'id'; -- for any stat-having relation. -- SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'attnum', 1::smallint, 'inherited', false::boolean, 'null_frac', 0.4::real); @@ -414,8 +480,9 @@ AND attname = 'id'; -- warn: unrecognized argument name, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.2::real, 'nope', 0.5::real); @@ -438,8 +505,9 @@ AND attname = 'id'; -- warn: mcv / mcf null mismatch part 1, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.21::real, 'most_common_freqs', '{0.1,0.2,0.3}'::real[] @@ -463,8 +531,9 @@ AND attname = 'id'; -- warn: mcv / mcf null mismatch part 2, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.21::real, 'most_common_vals', '{1,2,3}'::text @@ -488,8 +557,9 @@ AND attname = 'id'; -- warn: mcf type mismatch, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.22::real, 'most_common_vals', '{2,1,3}'::text, @@ -515,8 +585,9 @@ AND attname = 'id'; -- warn: mcv cast failure, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.23::real, 'most_common_vals', '{2,four,3}'::text, @@ -541,8 +612,9 @@ AND attname = 'id'; -- ok: mcv+mcf SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'most_common_vals', '{2,1,3}'::text, 'most_common_freqs', '{0.3,0.25,0.05}'::real[] @@ -565,8 +637,9 @@ AND attname = 'id'; -- warn: NULL in histogram array, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.24::real, 'histogram_bounds', '{1,NULL,3,4}'::text @@ -590,8 +663,9 @@ AND attname = 'id'; -- ok: histogram_bounds SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'histogram_bounds', '{1,2,3,4}'::text ); @@ -613,8 +687,9 @@ AND attname = 'id'; -- warn: elem_count_histogram null element, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'tags'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.25::real, 'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[] @@ -638,8 +713,9 @@ AND attname = 'tags'; -- ok: elem_count_histogram SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'tags'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.26::real, 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] @@ -662,8 +738,9 @@ AND attname = 'tags'; -- warn: range stats on a scalar type, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.27::real, 'range_empty_frac', 0.5::real, @@ -689,8 +766,9 @@ AND attname = 'id'; -- warn: range_empty_frac range_length_hist null mismatch, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', 'inherited', false::boolean, 'null_frac', 0.28::real, 'range_length_histogram', '{399,499,Infinity}'::text @@ -714,8 +792,9 @@ AND attname = 'arange'; -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', 'inherited', false::boolean, 'null_frac', 0.29::real, 'range_empty_frac', 0.5::real @@ -739,8 +818,9 @@ AND attname = 'arange'; -- ok: range_empty_frac + range_length_hist SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', 'inherited', false::boolean, 'range_empty_frac', 0.5::real, 'range_length_histogram', '{399,499,Infinity}'::text @@ -763,8 +843,9 @@ AND attname = 'arange'; -- warn: range bounds histogram on scalar, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.31::real, 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text @@ -789,8 +870,9 @@ AND attname = 'id'; -- ok: range_bounds_histogram SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', 'inherited', false::boolean, 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text ); @@ -812,8 +894,9 @@ AND attname = 'arange'; -- warn: cannot set most_common_elems for range type, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', 'inherited', false::boolean, 'null_frac', 0.32::real, 'most_common_elems', '{3,1}'::text, @@ -839,8 +922,9 @@ AND attname = 'arange'; -- warn: scalars can't have mcelem, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.33::real, 'most_common_elems', '{1,3}'::text, @@ -866,8 +950,9 @@ AND attname = 'id'; -- warn: mcelem / mcelem mismatch, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'tags'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.34::real, 'most_common_elems', '{one,two}'::text @@ -891,8 +976,9 @@ AND attname = 'tags'; -- warn: mcelem / mcelem null mismatch part 2, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'tags'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.35::real, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[] @@ -916,8 +1002,9 @@ AND attname = 'tags'; -- ok: mcelem SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'tags'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', 'inherited', false::boolean, 'most_common_elems', '{one,three}'::text, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] @@ -940,8 +1027,9 @@ AND attname = 'tags'; -- warn: scalars can't have elem_count_histogram, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.36::real, 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[] @@ -993,8 +1081,9 @@ SELECT s.schemaname, s.tablename, s.attname, s.inherited, r.* FROM pg_catalog.pg_stats AS s CROSS JOIN LATERAL pg_catalog.pg_restore_attribute_stats( - 'relation', ('stats_import.' || s.tablename || '_clone')::regclass, - 'attname', s.attname, + 'schemaname', 'stats_import', + 'relname', s.tablename::text || '_clone', + 'attname', s.attname::text, 'inherited', s.inherited, 'version', 150000, 'null_frac', s.null_frac, @@ -1171,9 +1260,10 @@ AND attname = 'arange'; (1 row) SELECT pg_catalog.pg_clear_attribute_stats( - relation => 'stats_import.test'::regclass, - attname => 'arange'::name, - inherited => false::boolean); + schemaname => 'stats_import', + relname => 'test', + attname => 'arange', + inherited => false); pg_clear_attribute_stats -------------------------- diff --git a/src/test/regress/sql/stats_import.sql b/src/test/regress/sql/stats_import.sql index 8d04ff4f378..3c330387243 100644 --- a/src/test/regress/sql/stats_import.sql +++ b/src/test/regress/sql/stats_import.sql @@ -21,31 +21,46 @@ CREATE INDEX test_i ON stats_import.test(id); -- relstats tests -- ---- error: relation is wrong type +-- error: schemaname missing SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 0::oid, + 'relname', 'test', + 'relpages', 17::integer); + +-- error: relname missing +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relpages', 17::integer); + +--- error: schemaname is wrong type +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 3.6::float, + 'relname', 'test', + 'relpages', 17::integer); + +--- error: relname is wrong type +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 0::oid, 'relpages', 17::integer); -- error: relation not found SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 0::oid::regclass, + 'schemaname', 'stats_import', + 'relname', 'nope', 'relpages', 17::integer); -- error: odd number of variadic arguments cannot be pairs SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'relallvisible'); -- error: argument name is NULL SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', NULL, '17'::integer); --- error: argument name is not a text type -SELECT pg_restore_relation_stats( - 'relation', '0'::oid::regclass, - 17, '17'::integer); - -- starting stats SELECT relpages, reltuples, relallvisible, relallfrozen FROM pg_class @@ -54,7 +69,8 @@ WHERE oid = 'stats_import.test_i'::regclass; -- regular indexes have special case locking rules BEGIN; SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.test_i'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test_i', 'relpages', 18::integer); SELECT mode FROM pg_locks @@ -91,7 +107,8 @@ WHERE oid = 'stats_import.part_parent'::regclass; BEGIN; SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.part_parent_i'::regclass, + 'schemaname', 'stats_import', + 'relname', 'part_parent_i', 'relpages', 2::integer); SELECT mode FROM pg_locks @@ -110,7 +127,8 @@ WHERE oid = 'stats_import.part_parent_i'::regclass; -- ok: set all relstats, with version, no bounds checking SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'version', 150000::integer, 'relpages', '-17'::integer, 'reltuples', 400::real, @@ -123,7 +141,8 @@ WHERE oid = 'stats_import.test'::regclass; -- ok: set just relpages, rest stay same SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'relpages', '16'::integer); SELECT relpages, reltuples, relallvisible, relallfrozen @@ -132,7 +151,8 @@ WHERE oid = 'stats_import.test'::regclass; -- ok: set just reltuples, rest stay same SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'reltuples', '500'::real); SELECT relpages, reltuples, relallvisible, relallfrozen @@ -141,7 +161,8 @@ WHERE oid = 'stats_import.test'::regclass; -- ok: set just relallvisible, rest stay same SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'relallvisible', 5::integer); SELECT relpages, reltuples, relallvisible, relallfrozen @@ -150,7 +171,8 @@ WHERE oid = 'stats_import.test'::regclass; -- ok: just relallfrozen SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'version', 150000::integer, 'relallfrozen', 3::integer); @@ -160,7 +182,8 @@ WHERE oid = 'stats_import.test'::regclass; -- warn: bad relpages type, rest updated SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'relpages', 'nope'::text, 'reltuples', 400.0::real, 'relallvisible', 4::integer, @@ -172,7 +195,8 @@ WHERE oid = 'stats_import.test'::regclass; -- unrecognized argument name, rest ok SELECT pg_restore_relation_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'relpages', '171'::integer, 'nope', 10::integer); @@ -181,8 +205,7 @@ FROM pg_class WHERE oid = 'stats_import.test'::regclass; -- ok: clear stats -SELECT pg_catalog.pg_clear_relation_stats( - relation => 'stats_import.test'::regclass); +SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'test'); SELECT relpages, reltuples, relallvisible FROM pg_class @@ -192,48 +215,70 @@ WHERE oid = 'stats_import.test'::regclass; CREATE SEQUENCE stats_import.testseq; SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.testseq'::regclass); + 'schemaname', 'stats_import', + 'relname', 'testseq'); -SELECT pg_catalog.pg_clear_relation_stats( - 'stats_import.testseq'::regclass); +SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testseq'); CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test; -SELECT pg_catalog.pg_restore_relation_stats( - 'relation', 'stats_import.testview'::regclass); - -SELECT pg_catalog.pg_clear_relation_stats( - 'stats_import.testview'::regclass); +SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testview'); -- -- attribute stats -- --- error: object does not exist +-- error: schemaname missing SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', '0'::oid::regclass, - 'attname', 'id'::name, + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.1::real); --- error: relation null +-- error: schema does not exist SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', NULL::oid::regclass, - 'attname', 'id'::name, + 'schemaname', 'nope', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +-- error: relname missing +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +-- error: relname does not exist +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'nope', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +-- error: relname null +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', NULL, + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.1::real); -- error: NULL attname SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', NULL::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', NULL, 'inherited', false::boolean, 'null_frac', 0.1::real); -- error: attname doesn't exist SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'nope'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'nope', 'inherited', false::boolean, 'null_frac', 0.1::real, 'avg_width', 2::integer, @@ -241,36 +286,41 @@ SELECT pg_catalog.pg_restore_attribute_stats( -- error: both attname and attnum SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'attnum', 1::smallint, 'inherited', false::boolean, 'null_frac', 0.1::real); -- error: neither attname nor attnum SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'inherited', false::boolean, 'null_frac', 0.1::real); -- error: attribute is system column SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'xmin'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'xmin', 'inherited', false::boolean, 'null_frac', 0.1::real); -- error: inherited null SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', NULL::boolean, 'null_frac', 0.1::real); -- ok: just the fixed values, with version, no stakinds SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'version', 150000::integer, 'null_frac', 0.2::real, @@ -290,7 +340,8 @@ AND attname = 'id'; -- for any stat-having relation. -- SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, + 'schemaname', 'stats_import', + 'relname', 'test', 'attnum', 1::smallint, 'inherited', false::boolean, 'null_frac', 0.4::real); @@ -304,8 +355,9 @@ AND attname = 'id'; -- warn: unrecognized argument name, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.2::real, 'nope', 0.5::real); @@ -319,8 +371,9 @@ AND attname = 'id'; -- warn: mcv / mcf null mismatch part 1, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.21::real, 'most_common_freqs', '{0.1,0.2,0.3}'::real[] @@ -335,8 +388,9 @@ AND attname = 'id'; -- warn: mcv / mcf null mismatch part 2, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.21::real, 'most_common_vals', '{1,2,3}'::text @@ -351,8 +405,9 @@ AND attname = 'id'; -- warn: mcf type mismatch, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.22::real, 'most_common_vals', '{2,1,3}'::text, @@ -368,8 +423,9 @@ AND attname = 'id'; -- warn: mcv cast failure, mcv-pair fails, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.23::real, 'most_common_vals', '{2,four,3}'::text, @@ -385,8 +441,9 @@ AND attname = 'id'; -- ok: mcv+mcf SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'most_common_vals', '{2,1,3}'::text, 'most_common_freqs', '{0.3,0.25,0.05}'::real[] @@ -401,8 +458,9 @@ AND attname = 'id'; -- warn: NULL in histogram array, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.24::real, 'histogram_bounds', '{1,NULL,3,4}'::text @@ -417,8 +475,9 @@ AND attname = 'id'; -- ok: histogram_bounds SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'histogram_bounds', '{1,2,3,4}'::text ); @@ -432,8 +491,9 @@ AND attname = 'id'; -- warn: elem_count_histogram null element, rest get set SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'tags'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.25::real, 'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[] @@ -448,8 +508,9 @@ AND attname = 'tags'; -- ok: elem_count_histogram SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'tags'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.26::real, 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] @@ -464,8 +525,9 @@ AND attname = 'tags'; -- warn: range stats on a scalar type, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.27::real, 'range_empty_frac', 0.5::real, @@ -481,8 +543,9 @@ AND attname = 'id'; -- warn: range_empty_frac range_length_hist null mismatch, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', 'inherited', false::boolean, 'null_frac', 0.28::real, 'range_length_histogram', '{399,499,Infinity}'::text @@ -497,8 +560,9 @@ AND attname = 'arange'; -- warn: range_empty_frac range_length_hist null mismatch part 2, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', 'inherited', false::boolean, 'null_frac', 0.29::real, 'range_empty_frac', 0.5::real @@ -513,8 +577,9 @@ AND attname = 'arange'; -- ok: range_empty_frac + range_length_hist SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', 'inherited', false::boolean, 'range_empty_frac', 0.5::real, 'range_length_histogram', '{399,499,Infinity}'::text @@ -529,8 +594,9 @@ AND attname = 'arange'; -- warn: range bounds histogram on scalar, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.31::real, 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text @@ -545,8 +611,9 @@ AND attname = 'id'; -- ok: range_bounds_histogram SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', 'inherited', false::boolean, 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text ); @@ -560,8 +627,9 @@ AND attname = 'arange'; -- warn: cannot set most_common_elems for range type, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'arange'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', 'inherited', false::boolean, 'null_frac', 0.32::real, 'most_common_elems', '{3,1}'::text, @@ -577,8 +645,9 @@ AND attname = 'arange'; -- warn: scalars can't have mcelem, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.33::real, 'most_common_elems', '{1,3}'::text, @@ -594,8 +663,9 @@ AND attname = 'id'; -- warn: mcelem / mcelem mismatch, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'tags'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.34::real, 'most_common_elems', '{one,two}'::text @@ -610,8 +680,9 @@ AND attname = 'tags'; -- warn: mcelem / mcelem null mismatch part 2, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'tags'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', 'inherited', false::boolean, 'null_frac', 0.35::real, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[] @@ -626,8 +697,9 @@ AND attname = 'tags'; -- ok: mcelem SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'tags'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', 'inherited', false::boolean, 'most_common_elems', '{one,three}'::text, 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] @@ -642,8 +714,9 @@ AND attname = 'tags'; -- warn: scalars can't have elem_count_histogram, rest ok SELECT pg_catalog.pg_restore_attribute_stats( - 'relation', 'stats_import.test'::regclass, - 'attname', 'id'::name, + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', 'inherited', false::boolean, 'null_frac', 0.36::real, 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[] @@ -690,8 +763,9 @@ SELECT s.schemaname, s.tablename, s.attname, s.inherited, r.* FROM pg_catalog.pg_stats AS s CROSS JOIN LATERAL pg_catalog.pg_restore_attribute_stats( - 'relation', ('stats_import.' || s.tablename || '_clone')::regclass, - 'attname', s.attname, + 'schemaname', 'stats_import', + 'relname', s.tablename::text || '_clone', + 'attname', s.attname::text, 'inherited', s.inherited, 'version', 150000, 'null_frac', s.null_frac, @@ -836,9 +910,10 @@ AND inherited = false AND attname = 'arange'; SELECT pg_catalog.pg_clear_attribute_stats( - relation => 'stats_import.test'::regclass, - attname => 'arange'::name, - inherited => false::boolean); + schemaname => 'stats_import', + relname => 'test', + attname => 'arange', + inherited => false); SELECT COUNT(*) FROM pg_stats diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index f97f0ce570a..4c5ef0604de 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -30331,22 +30331,24 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset mytable: SELECT pg_restore_relation_stats( - 'relation', 'mytable'::regclass, - 'relpages', 173::integer, - 'reltuples', 10000::real); + 'schemaname', 'myschema', + 'relname', 'mytable', + 'relpages', 173::integer, + 'reltuples', 10000::real); - The argument relation with a value of type - regclass is required, and specifies the table. Other - arguments are the names and values of statistics corresponding to - certain columns in schemaname with a value of type + regclass and relname are required, + and specifies the table. Other arguments are the names and values + of statistics corresponding to certain columns in pg_class. The currently-supported relation statistics are relpages with a value of type integer, reltuples with a value of - type real, and relallvisible with a - value of type integer. + type real, relallvisible with a + value of type integer, and relallfrozen + with a value of type integer. Additionally, this function accepts argument name @@ -30374,7 +30376,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset pg_clear_relation_stats - pg_clear_relation_stats ( relation regclass ) + pg_clear_relation_stats ( schemaname text, relname text ) void @@ -30423,16 +30425,18 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset mytable: SELECT pg_restore_attribute_stats( - 'relation', 'mytable'::regclass, - 'attname', 'col1'::name, - 'inherited', false, - 'avg_width', 125::integer, - 'null_frac', 0.5::real); + 'schemaname', 'myschema', + 'relname', 'mytable', + 'attname', 'col1', + 'inherited', false, + 'avg_width', 125::integer, + 'null_frac', 0.5::real); - The required arguments are relation with a value - of type regclass, which specifies the table; either + The required arguments are schemaname with a value + of type regclass and relname with a value + of type text which specify the table; either attname with a value of type name or attnum with a value of type smallint, which specifies the column; and inherited, which @@ -30468,7 +30472,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset pg_clear_attribute_stats pg_clear_attribute_stats ( - relation regclass, + schemaname text, + relname text, attname name, inherited boolean ) void -- 2.48.1