Skip to content

Commit 012460e

Browse files
committed
Make stxstattarget nullable
To match attstattarget change (commit 4f62250). The logic inside CreateStatistics() is clarified a bit compared to that previous patch, and so here we also update ATExecSetStatistics() to match. Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com> Discussion: https://www.postgresql.org/message-id/flat/4da8d211-d54d-44b9-9847-f2a9f1184c76@eisentraut.org
1 parent 33e729c commit 012460e

File tree

11 files changed

+93
-70
lines changed

11 files changed

+93
-70
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7657,6 +7657,19 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
76577657
</para></entry>
76587658
</row>
76597659

7660+
<row>
7661+
<entry role="catalog_table_entry"><para role="column_definition">
7662+
<structfield>stxkeys</structfield> <type>int2vector</type>
7663+
(references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
7664+
</para>
7665+
<para>
7666+
An array of attribute numbers, indicating which table columns are
7667+
covered by this statistics object;
7668+
for example a value of <literal>1 3</literal> would
7669+
mean that the first and the third table columns are covered
7670+
</para></entry>
7671+
</row>
7672+
76607673
<row>
76617674
<entry role="catalog_table_entry"><para role="column_definition">
76627675
<structfield>stxstattarget</structfield> <type>int2</type>
@@ -7666,27 +7679,14 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
76667679
of statistics accumulated for this statistics object by
76677680
<link linkend="sql-analyze"><command>ANALYZE</command></link>.
76687681
A zero value indicates that no statistics should be collected.
7669-
A negative value says to use the maximum of the statistics targets of
7682+
A null value says to use the maximum of the statistics targets of
76707683
the referenced columns, if set, or the system default statistics target.
76717684
Positive values of <structfield>stxstattarget</structfield>
76727685
determine the target number of <quote>most common values</quote>
76737686
to collect.
76747687
</para></entry>
76757688
</row>
76767689

7677-
<row>
7678-
<entry role="catalog_table_entry"><para role="column_definition">
7679-
<structfield>stxkeys</structfield> <type>int2vector</type>
7680-
(references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
7681-
</para>
7682-
<para>
7683-
An array of attribute numbers, indicating which table columns are
7684-
covered by this statistics object;
7685-
for example a value of <literal>1 3</literal> would
7686-
mean that the first and the third table columns are covered
7687-
</para></entry>
7688-
</row>
7689-
76907690
<row>
76917691
<entry role="catalog_table_entry"><para role="column_definition">
76927692
<structfield>stxkind</structfield> <type>char[]</type>

doc/src/sgml/ref/alter_statistics.sgml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ PostgreSQL documentation
2626
ALTER STATISTICS <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
2727
ALTER STATISTICS <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
2828
ALTER STATISTICS <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
29-
ALTER STATISTICS <replaceable class="parameter">name</replaceable> SET STATISTICS <replaceable class="parameter">new_target</replaceable>
29+
ALTER STATISTICS <replaceable class="parameter">name</replaceable> SET STATISTICS { <replaceable class="parameter">new_target</replaceable> | DEFAULT }
3030
</synopsis>
3131
</refsynopsisdiv>
3232

@@ -101,10 +101,11 @@ ALTER STATISTICS <replaceable class="parameter">name</replaceable> SET STATISTIC
101101
<para>
102102
The statistic-gathering target for this statistics object for subsequent
103103
<link linkend="sql-analyze"><command>ANALYZE</command></link> operations.
104-
The target can be set in the range 0 to 10000; alternatively, set it
105-
to -1 to revert to using the maximum of the statistics target of the
106-
referenced columns, if set, or the system default statistics
107-
target (<xref linkend="guc-default-statistics-target"/>).
104+
The target can be set in the range 0 to 10000. Set it to
105+
<literal>DEFAULT</literal> to revert to using the system default
106+
statistics target (<xref linkend="guc-default-statistics-target"/>).
107+
(Setting to a value of -1 is an obsolete way spelling to get the same
108+
outcome.)
108109
For more information on the use of statistics by the
109110
<productname>PostgreSQL</productname> query planner, refer to
110111
<xref linkend="planner-stats"/>.

src/backend/commands/statscmds.c

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -495,9 +495,9 @@ CreateStatistics(CreateStatsStmt *stmt)
495495
values[Anum_pg_statistic_ext_stxrelid - 1] = ObjectIdGetDatum(relid);
496496
values[Anum_pg_statistic_ext_stxname - 1] = NameGetDatum(&stxname);
497497
values[Anum_pg_statistic_ext_stxnamespace - 1] = ObjectIdGetDatum(namespaceId);
498-
values[Anum_pg_statistic_ext_stxstattarget - 1] = Int16GetDatum(-1);
499498
values[Anum_pg_statistic_ext_stxowner - 1] = ObjectIdGetDatum(stxowner);
500499
values[Anum_pg_statistic_ext_stxkeys - 1] = PointerGetDatum(stxkeys);
500+
nulls[Anum_pg_statistic_ext_stxstattarget - 1] = true;
501501
values[Anum_pg_statistic_ext_stxkind - 1] = PointerGetDatum(stxkind);
502502

503503
values[Anum_pg_statistic_ext_stxexprs - 1] = exprsDatum;
@@ -606,23 +606,36 @@ AlterStatistics(AlterStatsStmt *stmt)
606606
bool repl_null[Natts_pg_statistic_ext];
607607
bool repl_repl[Natts_pg_statistic_ext];
608608
ObjectAddress address;
609-
int newtarget = stmt->stxstattarget;
609+
int newtarget;
610+
bool newtarget_default;
610611

611-
/* Limit statistics target to a sane range */
612-
if (newtarget < -1)
612+
/* -1 was used in previous versions for the default setting */
613+
if (stmt->stxstattarget && intVal(stmt->stxstattarget) != -1)
613614
{
614-
ereport(ERROR,
615-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
616-
errmsg("statistics target %d is too low",
617-
newtarget)));
615+
newtarget = intVal(stmt->stxstattarget);
616+
newtarget_default = false;
618617
}
619-
else if (newtarget > MAX_STATISTICS_TARGET)
618+
else
619+
newtarget_default = true;
620+
621+
if (!newtarget_default)
620622
{
621-
newtarget = MAX_STATISTICS_TARGET;
622-
ereport(WARNING,
623-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
624-
errmsg("lowering statistics target to %d",
625-
newtarget)));
623+
/* Limit statistics target to a sane range */
624+
if (newtarget < 0)
625+
{
626+
ereport(ERROR,
627+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
628+
errmsg("statistics target %d is too low",
629+
newtarget)));
630+
}
631+
else if (newtarget > MAX_STATISTICS_TARGET)
632+
{
633+
newtarget = MAX_STATISTICS_TARGET;
634+
ereport(WARNING,
635+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
636+
errmsg("lowering statistics target to %d",
637+
newtarget)));
638+
}
626639
}
627640

628641
/* lookup OID of the statistics object */
@@ -673,7 +686,10 @@ AlterStatistics(AlterStatsStmt *stmt)
673686

674687
/* replace the stxstattarget column */
675688
repl_repl[Anum_pg_statistic_ext_stxstattarget - 1] = true;
676-
repl_val[Anum_pg_statistic_ext_stxstattarget - 1] = Int16GetDatum(newtarget);
689+
if (!newtarget_default)
690+
repl_val[Anum_pg_statistic_ext_stxstattarget - 1] = Int16GetDatum(newtarget);
691+
else
692+
repl_null[Anum_pg_statistic_ext_stxstattarget - 1] = true;
677693

678694
newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
679695
repl_val, repl_null, repl_repl);

src/backend/commands/tablecmds.c

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8712,6 +8712,7 @@ static ObjectAddress
87128712
ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newValue, LOCKMODE lockmode)
87138713
{
87148714
int newtarget;
8715+
bool newtarget_default;
87158716
Relation attrelation;
87168717
HeapTuple tuple,
87178718
newtuple;
@@ -8733,35 +8734,35 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa
87338734
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
87348735
errmsg("cannot refer to non-index column by number")));
87358736

8736-
if (newValue)
8737+
/* -1 was used in previous versions for the default setting */
8738+
if (newValue && intVal(newValue) != -1)
87378739
{
87388740
newtarget = intVal(newValue);
8741+
newtarget_default = false;
87398742
}
87408743
else
8744+
newtarget_default = true;
8745+
8746+
if (!newtarget_default)
87418747
{
87428748
/*
8743-
* -1 was used in previous versions to represent the default setting
8749+
* Limit target to a sane range
87448750
*/
8745-
newtarget = -1;
8746-
}
8747-
8748-
/*
8749-
* Limit target to a sane range
8750-
*/
8751-
if (newtarget < -1)
8752-
{
8753-
ereport(ERROR,
8754-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8755-
errmsg("statistics target %d is too low",
8756-
newtarget)));
8757-
}
8758-
else if (newtarget > MAX_STATISTICS_TARGET)
8759-
{
8760-
newtarget = MAX_STATISTICS_TARGET;
8761-
ereport(WARNING,
8762-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8763-
errmsg("lowering statistics target to %d",
8764-
newtarget)));
8751+
if (newtarget < 0)
8752+
{
8753+
ereport(ERROR,
8754+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8755+
errmsg("statistics target %d is too low",
8756+
newtarget)));
8757+
}
8758+
else if (newtarget > MAX_STATISTICS_TARGET)
8759+
{
8760+
newtarget = MAX_STATISTICS_TARGET;
8761+
ereport(WARNING,
8762+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8763+
errmsg("lowering statistics target to %d",
8764+
newtarget)));
8765+
}
87658766
}
87668767

87678768
attrelation = table_open(AttributeRelationId, RowExclusiveLock);
@@ -8815,7 +8816,7 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa
88158816
/* Build new tuple. */
88168817
memset(repl_null, false, sizeof(repl_null));
88178818
memset(repl_repl, false, sizeof(repl_repl));
8818-
if (newtarget != -1)
8819+
if (!newtarget_default)
88198820
repl_val[Anum_pg_attribute_attstattarget - 1] = newtarget;
88208821
else
88218822
repl_null[Anum_pg_attribute_attstattarget - 1] = true;

src/backend/parser/gram.y

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4610,7 +4610,7 @@ stats_param: ColId
46104610
*****************************************************************************/
46114611

46124612
AlterStatsStmt:
4613-
ALTER STATISTICS any_name SET STATISTICS SignedIconst
4613+
ALTER STATISTICS any_name SET STATISTICS set_statistics_value
46144614
{
46154615
AlterStatsStmt *n = makeNode(AlterStatsStmt);
46164616

@@ -4619,7 +4619,7 @@ AlterStatsStmt:
46194619
n->stxstattarget = $6;
46204620
$$ = (Node *) n;
46214621
}
4622-
| ALTER STATISTICS IF_P EXISTS any_name SET STATISTICS SignedIconst
4622+
| ALTER STATISTICS IF_P EXISTS any_name SET STATISTICS set_statistics_value
46234623
{
46244624
AlterStatsStmt *n = makeNode(AlterStatsStmt);
46254625

src/backend/statistics/extended_stats.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,13 +454,15 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid)
454454
entry->statOid = staForm->oid;
455455
entry->schema = get_namespace_name(staForm->stxnamespace);
456456
entry->name = pstrdup(NameStr(staForm->stxname));
457-
entry->stattarget = staForm->stxstattarget;
458457
for (i = 0; i < staForm->stxkeys.dim1; i++)
459458
{
460459
entry->columns = bms_add_member(entry->columns,
461460
staForm->stxkeys.values[i]);
462461
}
463462

463+
datum = SysCacheGetAttr(STATEXTOID, htup, Anum_pg_statistic_ext_stxstattarget, &isnull);
464+
entry->stattarget = isnull ? -1 : DatumGetInt16(datum);
465+
464466
/* decode the stxkind char array into a list of chars */
465467
datum = SysCacheGetAttrNotNull(STATEXTOID, htup,
466468
Anum_pg_statistic_ext_stxkind);

src/bin/pg_dump/pg_dump.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7580,7 +7580,7 @@ getExtendedStatistics(Archive *fout)
75807580

75817581
if (fout->remoteVersion < 130000)
75827582
appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
7583-
"stxnamespace, stxowner, stxrelid, (-1) AS stxstattarget "
7583+
"stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
75847584
"FROM pg_catalog.pg_statistic_ext");
75857585
else
75867586
appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
@@ -7613,7 +7613,10 @@ getExtendedStatistics(Archive *fout)
76137613
statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
76147614
statsextinfo[i].stattable =
76157615
findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
7616-
statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
7616+
if (PQgetisnull(res, i, i_stattarget))
7617+
statsextinfo[i].stattarget = -1;
7618+
else
7619+
statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
76177620

76187621
/* Decide whether we want to dump it */
76197622
selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
@@ -17062,8 +17065,7 @@ dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
1706217065

1706317066
/*
1706417067
* We only issue an ALTER STATISTICS statement if the stxstattarget entry
17065-
* for this statistics object is non-negative (i.e. it's not the default
17066-
* value).
17068+
* for this statistics object is not the default value.
1706717069
*/
1706817070
if (statsextinfo->stattarget >= 0)
1706917071
{

src/bin/psql/describe.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2804,7 +2804,8 @@ describeOneTableDetails(const char *schemaname,
28042804
PQgetvalue(result, i, 1));
28052805

28062806
/* Show the stats target if it's not default */
2807-
if (strcmp(PQgetvalue(result, i, 8), "-1") != 0)
2807+
if (!PQgetisnull(result, i, 8) &&
2808+
strcmp(PQgetvalue(result, i, 8), "-1") != 0)
28082809
appendPQExpBuffer(&buf, "; STATISTICS %s",
28092810
PQgetvalue(result, i, 8));
28102811

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/* yyyymmddN */
60-
#define CATALOG_VERSION_NO 202403141
60+
#define CATALOG_VERSION_NO 202403171
6161

6262
#endif

src/include/catalog/pg_statistic_ext.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ CATALOG(pg_statistic_ext,3381,StatisticExtRelationId)
4343
* object's namespace */
4444

4545
Oid stxowner BKI_LOOKUP(pg_authid); /* statistics object's owner */
46-
int16 stxstattarget BKI_DEFAULT(-1); /* statistics target */
4746

4847
/*
49-
* variable-length fields start here, but we allow direct access to
50-
* stxkeys
48+
* variable-length/nullable fields start here, but we allow direct access
49+
* to stxkeys
5150
*/
5251
int2vector stxkeys BKI_FORCE_NOT_NULL; /* array of column keys */
5352

5453
#ifdef CATALOG_VARLEN
54+
int16 stxstattarget BKI_DEFAULT(_null_) BKI_FORCE_NULL; /* statistics target */
5555
char stxkind[1] BKI_FORCE_NOT_NULL; /* statistics kinds requested
5656
* to build */
5757
pg_node_tree stxexprs; /* A list of expression trees for stats

src/include/nodes/parsenodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3269,7 +3269,7 @@ typedef struct AlterStatsStmt
32693269
{
32703270
NodeTag type;
32713271
List *defnames; /* qualified name (list of String) */
3272-
int stxstattarget; /* statistics target */
3272+
Node *stxstattarget; /* statistics target */
32733273
bool missing_ok; /* skip error if statistics object is missing */
32743274
} AlterStatsStmt;
32753275

0 commit comments

Comments
 (0)