Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit40e27d0

Browse files
committed
Use attnum to identify index columns in pg_restore_attribute_stats().
Previously we used attname for both table and index columns, butthat is problematic for indexes because their attnames are assignedby internal rules that don't guarantee to preserve the names acrossdump and reload. (This is what's causing the remaining buildfarmfailures in cross-version-upgrade tests.) Fortunately we can useattnum instead, since there's no such thing as adding or droppingcolumns in an existing index. We met this same problem previouslywith ALTER INDEX ... SET STATISTICS, and solved it the same way,cf commit5b6d13e.In pg_restore_attribute_stats() itself, we accept either attnum orattname, but the policy used by pg_dump is to always use attnamefor tables and attnum for indexes.Author: Tom Lane <tgl@sss.pgh.pa.us>Author: Corey Huinker <corey.huinker@gmail.com>Discussion:https://postgr.es/m/1457469.1740419458@sss.pgh.pa.us
1 parentf734c9f commit40e27d0

File tree

8 files changed

+391
-157
lines changed

8 files changed

+391
-157
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30209,8 +30209,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
3020930209
</programlisting>
3021030210
</para>
3021130211
<para>
30212-
For example, to set the <structname>relpages</structname> and
30213-
<structname>reltuples</structname> of the table
30212+
For example, to set the <structfield>relpages</structfield> and
30213+
<structfield>reltuples</structfield> values for the table
3021430214
<structname>mytable</structname>:
3021530215
<programlisting>
3021630216
SELECT pg_restore_relation_stats(
@@ -30222,8 +30222,8 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
3022230222
<para>
3022330223
The argument <literal>relation</literal> with a value of type
3022430224
<type>regclass</type> is required, and specifies the table. Other
30225-
arguments are the names of statistics corresponding to certain
30226-
columns in <link
30225+
arguments are the namesand valuesof statistics corresponding to
30226+
certaincolumns in <link
3022730227
linkend="catalog-pg-class"><structname>pg_class</structname></link>.
3022830228
The currently-supported relation statistics are
3022930229
<literal>relpages</literal> with a value of type
@@ -30232,16 +30232,16 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
3023230232
value of type <type>integer</type>.
3023330233
</para>
3023430234
<para>
30235-
Additionally, this functionsupports argument name
30235+
Additionally, this functionaccepts argument name
3023630236
<literal>version</literal> of type <type>integer</type>, which
30237-
specifies the version from which the statistics originated, improving
30238-
interpretation ofstatistics from older versions of
30239-
<productname>PostgreSQL</productname>.
30237+
specifies theserverversion from which the statistics originated.
30238+
This is anticipated to be helpful in portingstatistics from older
30239+
versions of<productname>PostgreSQL</productname>.
3024030240
</para>
3024130241
<para>
3024230242
Minor errors are reported as a <literal>WARNING</literal> and
3024330243
ignored, and remaining statistics will still be restored. If all
30244-
specified statistics are successfully restored,return
30244+
specified statistics are successfully restored,returns
3024530245
<literal>true</literal>, otherwise <literal>false</literal>.
3024630246
</para>
3024730247
<para>
@@ -30281,7 +30281,7 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
3028130281
<returnvalue>boolean</returnvalue>
3028230282
</para>
3028330283
<para>
30284-
Create orupdate column-level statistics. Ordinarily, these
30284+
Creates orupdates column-level statistics. Ordinarily, these
3028530285
statistics are collected automatically or updated as a part of <xref
3028630286
linkend="sql-vacuum"/> or <xref linkend="sql-analyze"/>, so it's not
3028730287
necessary to call this function. However, it is useful after a
@@ -30300,9 +30300,9 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
3030030300
</programlisting>
3030130301
</para>
3030230302
<para>
30303-
For example, to set the <structname>avg_width</structname> and
30304-
<structname>null_frac</structname> for the attribute
30305-
<structname>col1</structname> of the table
30303+
For example, to set the <structfield>avg_width</structfield> and
30304+
<structfield>null_frac</structfield> values for the attribute
30305+
<structfield>col1</structfield> of the table
3030630306
<structname>mytable</structname>:
3030730307
<programlisting>
3030830308
SELECT pg_restore_attribute_stats(
@@ -30315,25 +30315,26 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
3031530315
</para>
3031630316
<para>
3031730317
The required arguments are <literal>relation</literal> with a value
30318-
of type <type>regclass</type>, which specifies the table;
30319-
<literal>attname</literal> with a value of type <type>name</type>,
30318+
of type <type>regclass</type>, which specifies the table; either
30319+
<literal>attname</literal> with a value of type <type>name</type> or
30320+
<literal>attnum</literal> with a value of type <type>smallint</type>,
3032030321
which specifies the column; and <literal>inherited</literal>, which
30321-
specifies whether the statisticsincludes values from child tables.
30322-
Other arguments are the names of statistics corresponding to columns
30323-
in <link
30322+
specifies whether the statisticsinclude values from child tables.
30323+
Other arguments are the namesand valuesof statistics corresponding
30324+
to columnsin <link
3032430325
linkend="view-pg-stats"><structname>pg_stats</structname></link>.
3032530326
</para>
3032630327
<para>
30327-
Additionally, this functionsupports argument name
30328+
Additionally, this functionaccepts argument name
3032830329
<literal>version</literal> of type <type>integer</type>, which
30329-
specifies the version from which the statistics originated, improving
30330-
interpretation ofstatistics from older versions of
30331-
<productname>PostgreSQL</productname>.
30330+
specifies theserverversion from which the statistics originated.
30331+
This is anticipated to be helpful in portingstatistics from older
30332+
versions of<productname>PostgreSQL</productname>.
3033230333
</para>
3033330334
<para>
3033430335
Minor errors are reported as a <literal>WARNING</literal> and
3033530336
ignored, and remaining statistics will still be restored. If all
30336-
specified statistics are successfully restored,return
30337+
specified statistics are successfully restored,returns
3033730338
<literal>true</literal>, otherwise <literal>false</literal>.
3033830339
</para>
3033930340
<para>

‎src/backend/statistics/attribute_stats.c

Lines changed: 95 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ enum attribute_stats_argnum
3838
{
3939
ATTRELATION_ARG=0,
4040
ATTNAME_ARG,
41+
ATTNUM_ARG,
4142
INHERITED_ARG,
4243
NULL_FRAC_ARG,
4344
AVG_WIDTH_ARG,
@@ -59,6 +60,7 @@ static struct StatsArgInfo attarginfo[] =
5960
{
6061
[ATTRELATION_ARG]= {"relation",REGCLASSOID},
6162
[ATTNAME_ARG]= {"attname",NAMEOID},
63+
[ATTNUM_ARG]= {"attnum",INT2OID},
6264
[INHERITED_ARG]= {"inherited",BOOLOID},
6365
[NULL_FRAC_ARG]= {"null_frac",FLOAT4OID},
6466
[AVG_WIDTH_ARG]= {"avg_width",INT4OID},
@@ -76,6 +78,22 @@ static struct StatsArgInfo attarginfo[] =
7678
[NUM_ATTRIBUTE_STATS_ARGS]= {0}
7779
};
7880

81+
enumclear_attribute_stats_argnum
82+
{
83+
C_ATTRELATION_ARG=0,
84+
C_ATTNAME_ARG,
85+
C_INHERITED_ARG,
86+
C_NUM_ATTRIBUTE_STATS_ARGS
87+
};
88+
89+
staticstructStatsArgInfocleararginfo[]=
90+
{
91+
[C_ATTRELATION_ARG]= {"relation",REGCLASSOID},
92+
[C_ATTNAME_ARG]= {"attname",NAMEOID},
93+
[C_INHERITED_ARG]= {"inherited",BOOLOID},
94+
[C_NUM_ATTRIBUTE_STATS_ARGS]= {0}
95+
};
96+
7997
staticboolattribute_statistics_update(FunctionCallInfofcinfo);
8098
staticNode*get_attr_expr(Relationrel,intattnum);
8199
staticvoidget_attr_stat_type(Oidreloid,AttrNumberattnum,
@@ -116,9 +134,9 @@ static bool
116134
attribute_statistics_update(FunctionCallInfofcinfo)
117135
{
118136
Oidreloid;
119-
Nameattname;
120-
boolinherited;
137+
char*attname;
121138
AttrNumberattnum;
139+
boolinherited;
122140

123141
Relationstarel;
124142
HeapTuplestatup;
@@ -164,21 +182,51 @@ attribute_statistics_update(FunctionCallInfo fcinfo)
164182
/* lock before looking up attribute */
165183
stats_lock_check_privileges(reloid);
166184

167-
stats_check_required_arg(fcinfo,attarginfo,ATTNAME_ARG);
168-
attname=PG_GETARG_NAME(ATTNAME_ARG);
169-
attnum=get_attnum(reloid,NameStr(*attname));
185+
/* user can specify either attname or attnum, but not both */
186+
if (!PG_ARGISNULL(ATTNAME_ARG))
187+
{
188+
Nameattnamename;
189+
190+
if (!PG_ARGISNULL(ATTNUM_ARG))
191+
ereport(ERROR,
192+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
193+
errmsg("cannot specify both attname and attnum")));
194+
attnamename=PG_GETARG_NAME(ATTNAME_ARG);
195+
attname=NameStr(*attnamename);
196+
attnum=get_attnum(reloid,attname);
197+
/* note that this test covers attisdropped cases too: */
198+
if (attnum==InvalidAttrNumber)
199+
ereport(ERROR,
200+
(errcode(ERRCODE_UNDEFINED_COLUMN),
201+
errmsg("column \"%s\" of relation \"%s\" does not exist",
202+
attname,get_rel_name(reloid))));
203+
}
204+
elseif (!PG_ARGISNULL(ATTNUM_ARG))
205+
{
206+
attnum=PG_GETARG_INT16(ATTNUM_ARG);
207+
attname=get_attname(reloid,attnum, true);
208+
/* annoyingly, get_attname doesn't check attisdropped */
209+
if (attname==NULL||
210+
!SearchSysCacheExistsAttName(reloid,attname))
211+
ereport(ERROR,
212+
(errcode(ERRCODE_UNDEFINED_COLUMN),
213+
errmsg("column %d of relation \"%s\" does not exist",
214+
attnum,get_rel_name(reloid))));
215+
}
216+
else
217+
{
218+
ereport(ERROR,
219+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
220+
errmsg("must specify either attname or attnum")));
221+
attname=NULL;/* keep compiler quiet */
222+
attnum=0;
223+
}
170224

171225
if (attnum<0)
172226
ereport(ERROR,
173227
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
174228
errmsg("cannot modify statistics on system column \"%s\"",
175-
NameStr(*attname))));
176-
177-
if (attnum==InvalidAttrNumber)
178-
ereport(ERROR,
179-
(errcode(ERRCODE_UNDEFINED_COLUMN),
180-
errmsg("column \"%s\" of relation \"%s\" does not exist",
181-
NameStr(*attname),get_rel_name(reloid))));
229+
attname)));
182230

183231
stats_check_required_arg(fcinfo,attarginfo,INHERITED_ARG);
184232
inherited=PG_GETARG_BOOL(INHERITED_ARG);
@@ -241,7 +289,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo)
241289
&elemtypid,&elem_eq_opr))
242290
{
243291
ereport(WARNING,
244-
(errmsg("unable to determine element type of attribute \"%s\"",NameStr(*attname)),
292+
(errmsg("unable to determine element type of attribute \"%s\"",attname),
245293
errdetail("Cannot set STATISTIC_KIND_MCELEM or STATISTIC_KIND_DECHIST.")));
246294
elemtypid=InvalidOid;
247295
elem_eq_opr=InvalidOid;
@@ -257,7 +305,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo)
257305
{
258306
ereport(WARNING,
259307
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
260-
errmsg("could not determine less-than operator for attribute \"%s\"",NameStr(*attname)),
308+
errmsg("could not determine less-than operator for attribute \"%s\"",attname),
261309
errdetail("Cannot set STATISTIC_KIND_HISTOGRAM or STATISTIC_KIND_CORRELATION.")));
262310

263311
do_histogram= false;
@@ -271,7 +319,7 @@ attribute_statistics_update(FunctionCallInfo fcinfo)
271319
{
272320
ereport(WARNING,
273321
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
274-
errmsg("attribute \"%s\" is not a range type",NameStr(*attname)),
322+
errmsg("attribute \"%s\" is not a range type",attname),
275323
errdetail("Cannot set STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM or STATISTIC_KIND_BOUNDS_HISTOGRAM.")));
276324

277325
do_bounds_histogram= false;
@@ -857,8 +905,8 @@ pg_clear_attribute_stats(PG_FUNCTION_ARGS)
857905
AttrNumberattnum;
858906
boolinherited;
859907

860-
stats_check_required_arg(fcinfo,attarginfo,ATTRELATION_ARG);
861-
reloid=PG_GETARG_OID(ATTRELATION_ARG);
908+
stats_check_required_arg(fcinfo,cleararginfo,C_ATTRELATION_ARG);
909+
reloid=PG_GETARG_OID(C_ATTRELATION_ARG);
862910

863911
if (RecoveryInProgress())
864912
ereport(ERROR,
@@ -868,8 +916,8 @@ pg_clear_attribute_stats(PG_FUNCTION_ARGS)
868916

869917
stats_lock_check_privileges(reloid);
870918

871-
stats_check_required_arg(fcinfo,attarginfo,ATTNAME_ARG);
872-
attname=PG_GETARG_NAME(ATTNAME_ARG);
919+
stats_check_required_arg(fcinfo,cleararginfo,C_ATTNAME_ARG);
920+
attname=PG_GETARG_NAME(C_ATTNAME_ARG);
873921
attnum=get_attnum(reloid,NameStr(*attname));
874922

875923
if (attnum<0)
@@ -884,13 +932,39 @@ pg_clear_attribute_stats(PG_FUNCTION_ARGS)
884932
errmsg("column \"%s\" of relation \"%s\" does not exist",
885933
NameStr(*attname),get_rel_name(reloid))));
886934

887-
stats_check_required_arg(fcinfo,attarginfo,INHERITED_ARG);
888-
inherited=PG_GETARG_BOOL(INHERITED_ARG);
935+
stats_check_required_arg(fcinfo,cleararginfo,C_INHERITED_ARG);
936+
inherited=PG_GETARG_BOOL(C_INHERITED_ARG);
889937

890938
delete_pg_statistic(reloid,attnum,inherited);
891939
PG_RETURN_VOID();
892940
}
893941

942+
/*
943+
* Import statistics for a given relation attribute.
944+
*
945+
* Inserts or replaces a row in pg_statistic for the given relation and
946+
* attribute name or number. It takes input parameters that correspond to
947+
* columns in the view pg_stats.
948+
*
949+
* Parameters are given in a pseudo named-attribute style: they must be
950+
* pairs of parameter names (as text) and values (of appropriate types).
951+
* We do that, rather than using regular named-parameter notation, so
952+
* that we can add or change parameters without fear of breaking
953+
* carelessly-written calls.
954+
*
955+
* Parameters null_frac, avg_width, and n_distinct all correspond to NOT NULL
956+
* columns in pg_statistic. The remaining parameters all belong to a specific
957+
* stakind. Some stakinds require multiple parameters, which must be specified
958+
* together (or neither specified).
959+
*
960+
* Parameters are only superficially validated. Omitting a parameter or
961+
* passing NULL leaves the statistic unchanged.
962+
*
963+
* Parameters corresponding to ANYARRAY columns are instead passed in as text
964+
* values, which is a valid input string for an array of the type or element
965+
* type of the attribute. Any error generated by the array_in() function will
966+
* in turn fail the function.
967+
*/
894968
Datum
895969
pg_restore_attribute_stats(PG_FUNCTION_ARGS)
896970
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp