</para></entry>
</row>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxkeys</structfield> <type>int2vector</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ An array of attribute numbers, indicating which table columns are
+ covered by this statistics object;
+ for example a value of <literal>1 3</literal> would
+ mean that the first and the third table columns are covered
+ </para></entry>
+ </row>
+
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>stxstattarget</structfield> <type>int2</type>
of statistics accumulated for this statistics object by
<link linkend="sql-analyze"><command>ANALYZE</command></link>.
A zero value indicates that no statistics should be collected.
- A negative value says to use the maximum of the statistics targets of
+ A null value says to use the maximum of the statistics targets of
the referenced columns, if set, or the system default statistics target.
Positive values of <structfield>stxstattarget</structfield>
determine the target number of <quote>most common values</quote>
</para></entry>
</row>
- <row>
- <entry role="catalog_table_entry"><para role="column_definition">
- <structfield>stxkeys</structfield> <type>int2vector</type>
- (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
- </para>
- <para>
- An array of attribute numbers, indicating which table columns are
- covered by this statistics object;
- for example a value of <literal>1 3</literal> would
- mean that the first and the third table columns are covered
- </para></entry>
- </row>
-
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>stxkind</structfield> <type>char[]</type>
ALTER STATISTICS <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
ALTER STATISTICS <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
ALTER STATISTICS <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
-ALTER STATISTICS <replaceable class="parameter">name</replaceable> SET STATISTICS <replaceable class="parameter">new_target</replaceable>
+ALTER STATISTICS <replaceable class="parameter">name</replaceable> SET STATISTICS { <replaceable class="parameter">new_target</replaceable> | DEFAULT }
</synopsis>
</refsynopsisdiv>
<para>
The statistic-gathering target for this statistics object for subsequent
<link linkend="sql-analyze"><command>ANALYZE</command></link> operations.
- The target can be set in the range 0 to 10000; alternatively, set it
- to -1 to revert to using the maximum of the statistics target of the
- referenced columns, if set, or the system default statistics
- target (<xref linkend="guc-default-statistics-target"/>).
+ The target can be set in the range 0 to 10000. Set it to
+ <literal>DEFAULT</literal> to revert to using the system default
+ statistics target (<xref linkend="guc-default-statistics-target"/>).
+ (Setting to a value of -1 is an obsolete way spelling to get the same
+ outcome.)
For more information on the use of statistics by the
<productname>PostgreSQL</productname> query planner, refer to
<xref linkend="planner-stats"/>.
values[Anum_pg_statistic_ext_stxrelid - 1] = ObjectIdGetDatum(relid);
values[Anum_pg_statistic_ext_stxname - 1] = NameGetDatum(&stxname);
values[Anum_pg_statistic_ext_stxnamespace - 1] = ObjectIdGetDatum(namespaceId);
- values[Anum_pg_statistic_ext_stxstattarget - 1] = Int16GetDatum(-1);
values[Anum_pg_statistic_ext_stxowner - 1] = ObjectIdGetDatum(stxowner);
values[Anum_pg_statistic_ext_stxkeys - 1] = PointerGetDatum(stxkeys);
+ nulls[Anum_pg_statistic_ext_stxstattarget - 1] = true;
values[Anum_pg_statistic_ext_stxkind - 1] = PointerGetDatum(stxkind);
values[Anum_pg_statistic_ext_stxexprs - 1] = exprsDatum;
bool repl_null[Natts_pg_statistic_ext];
bool repl_repl[Natts_pg_statistic_ext];
ObjectAddress address;
- int newtarget = stmt->stxstattarget;
+ int newtarget;
+ bool newtarget_default;
- /* Limit statistics target to a sane range */
- if (newtarget < -1)
+ /* -1 was used in previous versions for the default setting */
+ if (stmt->stxstattarget && intVal(stmt->stxstattarget) != -1)
{
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("statistics target %d is too low",
- newtarget)));
+ newtarget = intVal(stmt->stxstattarget);
+ newtarget_default = false;
}
- else if (newtarget > MAX_STATISTICS_TARGET)
+ else
+ newtarget_default = true;
+
+ if (!newtarget_default)
{
- newtarget = MAX_STATISTICS_TARGET;
- ereport(WARNING,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("lowering statistics target to %d",
- newtarget)));
+ /* Limit statistics target to a sane range */
+ if (newtarget < 0)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("statistics target %d is too low",
+ newtarget)));
+ }
+ else if (newtarget > MAX_STATISTICS_TARGET)
+ {
+ newtarget = MAX_STATISTICS_TARGET;
+ ereport(WARNING,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("lowering statistics target to %d",
+ newtarget)));
+ }
}
/* lookup OID of the statistics object */
/* replace the stxstattarget column */
repl_repl[Anum_pg_statistic_ext_stxstattarget - 1] = true;
- repl_val[Anum_pg_statistic_ext_stxstattarget - 1] = Int16GetDatum(newtarget);
+ if (!newtarget_default)
+ repl_val[Anum_pg_statistic_ext_stxstattarget - 1] = Int16GetDatum(newtarget);
+ else
+ repl_null[Anum_pg_statistic_ext_stxstattarget - 1] = true;
newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
repl_val, repl_null, repl_repl);
ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newValue, LOCKMODE lockmode)
{
int newtarget;
+ bool newtarget_default;
Relation attrelation;
HeapTuple tuple,
newtuple;
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot refer to non-index column by number")));
- if (newValue)
+ /* -1 was used in previous versions for the default setting */
+ if (newValue && intVal(newValue) != -1)
{
newtarget = intVal(newValue);
+ newtarget_default = false;
}
else
+ newtarget_default = true;
+
+ if (!newtarget_default)
{
/*
- * -1 was used in previous versions to represent the default setting
+ * Limit target to a sane range
*/
- newtarget = -1;
- }
-
- /*
- * Limit target to a sane range
- */
- if (newtarget < -1)
- {
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("statistics target %d is too low",
- newtarget)));
- }
- else if (newtarget > MAX_STATISTICS_TARGET)
- {
- newtarget = MAX_STATISTICS_TARGET;
- ereport(WARNING,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("lowering statistics target to %d",
- newtarget)));
+ if (newtarget < 0)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("statistics target %d is too low",
+ newtarget)));
+ }
+ else if (newtarget > MAX_STATISTICS_TARGET)
+ {
+ newtarget = MAX_STATISTICS_TARGET;
+ ereport(WARNING,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("lowering statistics target to %d",
+ newtarget)));
+ }
}
attrelation = table_open(AttributeRelationId, RowExclusiveLock);
/* Build new tuple. */
memset(repl_null, false, sizeof(repl_null));
memset(repl_repl, false, sizeof(repl_repl));
- if (newtarget != -1)
+ if (!newtarget_default)
repl_val[Anum_pg_attribute_attstattarget - 1] = newtarget;
else
repl_null[Anum_pg_attribute_attstattarget - 1] = true;
*****************************************************************************/
AlterStatsStmt:
- ALTER STATISTICS any_name SET STATISTICS SignedIconst
+ ALTER STATISTICS any_name SET STATISTICS set_statistics_value
{
AlterStatsStmt *n = makeNode(AlterStatsStmt);
n->stxstattarget = $6;
$$ = (Node *) n;
}
- | ALTER STATISTICS IF_P EXISTS any_name SET STATISTICS SignedIconst
+ | ALTER STATISTICS IF_P EXISTS any_name SET STATISTICS set_statistics_value
{
AlterStatsStmt *n = makeNode(AlterStatsStmt);
entry->statOid = staForm->oid;
entry->schema = get_namespace_name(staForm->stxnamespace);
entry->name = pstrdup(NameStr(staForm->stxname));
- entry->stattarget = staForm->stxstattarget;
for (i = 0; i < staForm->stxkeys.dim1; i++)
{
entry->columns = bms_add_member(entry->columns,
staForm->stxkeys.values[i]);
}
+ datum = SysCacheGetAttr(STATEXTOID, htup, Anum_pg_statistic_ext_stxstattarget, &isnull);
+ entry->stattarget = isnull ? -1 : DatumGetInt16(datum);
+
/* decode the stxkind char array into a list of chars */
datum = SysCacheGetAttrNotNull(STATEXTOID, htup,
Anum_pg_statistic_ext_stxkind);
if (fout->remoteVersion < 130000)
appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
- "stxnamespace, stxowner, stxrelid, (-1) AS stxstattarget "
+ "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
"FROM pg_catalog.pg_statistic_ext");
else
appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
statsextinfo[i].stattable =
findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
- statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
+ if (PQgetisnull(res, i, i_stattarget))
+ statsextinfo[i].stattarget = -1;
+ else
+ statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
/* Decide whether we want to dump it */
selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
/*
* We only issue an ALTER STATISTICS statement if the stxstattarget entry
- * for this statistics object is non-negative (i.e. it's not the default
- * value).
+ * for this statistics object is not the default value.
*/
if (statsextinfo->stattarget >= 0)
{
PQgetvalue(result, i, 1));
/* Show the stats target if it's not default */
- if (strcmp(PQgetvalue(result, i, 8), "-1") != 0)
+ if (!PQgetisnull(result, i, 8) &&
+ strcmp(PQgetvalue(result, i, 8), "-1") != 0)
appendPQExpBuffer(&buf, "; STATISTICS %s",
PQgetvalue(result, i, 8));
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202403141
+#define CATALOG_VERSION_NO 202403171
#endif
* object's namespace */
Oid stxowner BKI_LOOKUP(pg_authid); /* statistics object's owner */
- int16 stxstattarget BKI_DEFAULT(-1); /* statistics target */
/*
- * variable-length fields start here, but we allow direct access to
- * stxkeys
+ * variable-length/nullable fields start here, but we allow direct access
+ * to stxkeys
*/
int2vector stxkeys BKI_FORCE_NOT_NULL; /* array of column keys */
#ifdef CATALOG_VARLEN
+ int16 stxstattarget BKI_DEFAULT(_null_) BKI_FORCE_NULL; /* statistics target */
char stxkind[1] BKI_FORCE_NOT_NULL; /* statistics kinds requested
* to build */
pg_node_tree stxexprs; /* A list of expression trees for stats
{
NodeTag type;
List *defnames; /* qualified name (list of String) */
- int stxstattarget; /* statistics target */
+ Node *stxstattarget; /* statistics target */
bool missing_ok; /* skip error if statistics object is missing */
} AlterStatsStmt;