diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/common/tupdesc.c | 4 | ||||
-rw-r--r-- | src/backend/bootstrap/bootstrap.c | 1 | ||||
-rw-r--r-- | src/backend/catalog/genbki.pl | 1 | ||||
-rw-r--r-- | src/backend/catalog/heap.c | 18 | ||||
-rw-r--r-- | src/backend/catalog/index.c | 21 | ||||
-rw-r--r-- | src/backend/commands/analyze.c | 21 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 43 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 18 | ||||
-rw-r--r-- | src/backend/utils/cache/lsyscache.c | 27 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 7 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/pg_attribute.h | 20 | ||||
-rw-r--r-- | src/include/commands/vacuum.h | 2 | ||||
-rw-r--r-- | src/include/utils/lsyscache.h | 1 | ||||
-rw-r--r-- | src/test/regress/expected/create_index.out | 4 |
15 files changed, 107 insertions, 83 deletions
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index 6e7ad79834f..bc80caee117 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -453,8 +453,6 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) return false; if (attr1->atttypid != attr2->atttypid) return false; - if (attr1->attstattarget != attr2->attstattarget) - return false; if (attr1->attlen != attr2->attlen) return false; if (attr1->attndims != attr2->attndims) @@ -639,7 +637,6 @@ TupleDescInitEntry(TupleDesc desc, else if (attributeName != NameStr(att->attname)) namestrcpy(&(att->attname), attributeName); - att->attstattarget = -1; att->attcacheoff = -1; att->atttypmod = typmod; @@ -702,7 +699,6 @@ TupleDescInitBuiltinEntry(TupleDesc desc, Assert(attributeName != NULL); namestrcpy(&(att->attname), attributeName); - att->attstattarget = -1; att->attcacheoff = -1; att->atttypmod = typmod; diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 55c53d01f87..141b25ddd7a 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -552,7 +552,6 @@ DefineAttr(char *name, char *type, int attnum, int nullness) if (OidIsValid(attrtypes[attnum]->attcollation)) attrtypes[attnum]->attcollation = C_COLLATION_OID; - attrtypes[attnum]->attstattarget = -1; attrtypes[attnum]->attcacheoff = -1; attrtypes[attnum]->atttypmod = -1; attrtypes[attnum]->attislocal = true; diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl index 531d7cd0d52..93553e8c3c4 100644 --- a/src/backend/catalog/genbki.pl +++ b/src/backend/catalog/genbki.pl @@ -840,7 +840,6 @@ sub gen_pg_attribute my %row; $row{attnum} = $attnum; $row{attrelid} = $table->{relation_oid}; - $row{attstattarget} = '0'; morph_row_for_pgattr(\%row, $schema, $attr, 1); print_bki_insert(\%row, $schema); diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index e80a90ef4c0..45a71081d42 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -749,14 +749,16 @@ InsertPgAttributeTuples(Relation pg_attribute_rel, slot[slotCount]->tts_values[Anum_pg_attribute_attisdropped - 1] = BoolGetDatum(attrs->attisdropped); slot[slotCount]->tts_values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(attrs->attislocal); slot[slotCount]->tts_values[Anum_pg_attribute_attinhcount - 1] = Int16GetDatum(attrs->attinhcount); - slot[slotCount]->tts_values[Anum_pg_attribute_attstattarget - 1] = Int16GetDatum(attrs->attstattarget); slot[slotCount]->tts_values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attrs->attcollation); if (attoptions && attoptions[natts] != (Datum) 0) slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attoptions[natts]; else slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = true; - /* start out with empty permissions and empty options */ + /* + * The remaining fields are not set for new columns. + */ + slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = true; slot[slotCount]->tts_isnull[Anum_pg_attribute_attacl - 1] = true; slot[slotCount]->tts_isnull[Anum_pg_attribute_attfdwoptions - 1] = true; slot[slotCount]->tts_isnull[Anum_pg_attribute_attmissingval - 1] = true; @@ -818,9 +820,6 @@ AddNewAttributeTuples(Oid new_rel_oid, indstate = CatalogOpenIndexes(rel); - /* set stats detail level to a sane default */ - for (int i = 0; i < natts; i++) - tupdesc->attrs[i].attstattarget = -1; InsertPgAttributeTuples(rel, tupdesc, new_rel_oid, NULL, indstate); /* add dependencies on their datatypes and collations */ @@ -1685,9 +1684,6 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) /* Remove any not-null constraint the column may have */ attStruct->attnotnull = false; - /* We don't want to keep stats for it anymore */ - attStruct->attstattarget = 0; - /* Unset this so no one tries to look up the generation expression */ attStruct->attgenerated = '\0'; @@ -1704,9 +1700,11 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) replacesAtt[Anum_pg_attribute_attmissingval - 1] = true; /* - * Clear the other variable-length fields. This saves some space in - * pg_attribute and removes no longer useful information. + * Clear the other nullable fields. This saves some space in pg_attribute + * and removes no longer useful information. */ + nullsAtt[Anum_pg_attribute_attstattarget - 1] = true; + replacesAtt[Anum_pg_attribute_attstattarget - 1] = true; nullsAtt[Anum_pg_attribute_attacl - 1] = true; replacesAtt[Anum_pg_attribute_attacl - 1] = true; nullsAtt[Anum_pg_attribute_attoptions - 1] = true; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 88f7994b5a6..fbef3d5382d 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -325,7 +325,6 @@ ConstructTupleDescriptor(Relation heapRelation, MemSet(to, 0, ATTRIBUTE_FIXED_PART_SIZE); to->attnum = i + 1; - to->attstattarget = -1; to->attcacheoff = -1; to->attislocal = true; to->attcollation = (i < numkeyatts) ? collationIds[i] : InvalidOid; @@ -1780,10 +1779,12 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName) while (HeapTupleIsValid((attrTuple = systable_getnext(scan)))) { Form_pg_attribute att = (Form_pg_attribute) GETSTRUCT(attrTuple); + HeapTuple tp; + Datum dat; + bool isnull; Datum repl_val[Natts_pg_attribute]; bool repl_null[Natts_pg_attribute]; bool repl_repl[Natts_pg_attribute]; - int attstattarget; HeapTuple newTuple; /* Ignore dropped columns */ @@ -1793,10 +1794,18 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName) /* * Get attstattarget from the old index and refresh the new value. */ - attstattarget = get_attstattarget(oldIndexId, att->attnum); + tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(oldIndexId), Int16GetDatum(att->attnum)); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for attribute %d of relation %u", + att->attnum, oldIndexId); + dat = SysCacheGetAttr(ATTNUM, tp, Anum_pg_attribute_attstattarget, &isnull); + ReleaseSysCache(tp); - /* no need for a refresh if both match */ - if (attstattarget == att->attstattarget) + /* + * No need for a refresh if old index value is null. (All new + * index values are null at this point.) + */ + if (isnull) continue; memset(repl_val, 0, sizeof(repl_val)); @@ -1804,7 +1813,7 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName) memset(repl_repl, false, sizeof(repl_repl)); repl_repl[Anum_pg_attribute_attstattarget - 1] = true; - repl_val[Anum_pg_attribute_attstattarget - 1] = Int16GetDatum(attstattarget); + repl_val[Anum_pg_attribute_attstattarget - 1] = dat; newTuple = heap_modify_tuple(attrTuple, RelationGetDescr(pg_attribute), diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index deef865ce6d..a03495d6c95 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -1004,6 +1004,10 @@ static VacAttrStats * examine_attribute(Relation onerel, int attnum, Node *index_expr) { Form_pg_attribute attr = TupleDescAttr(onerel->rd_att, attnum - 1); + int attstattarget; + HeapTuple atttuple; + Datum dat; + bool isnull; HeapTuple typtuple; VacAttrStats *stats; int i; @@ -1013,15 +1017,28 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr) if (attr->attisdropped) return NULL; + /* + * Get attstattarget value. Set to -1 if null. (Analyze functions expect + * -1 to mean use default_statistics_target; see for example + * std_typanalyze.) + */ + atttuple = SearchSysCache2(ATTNUM, ObjectIdGetDatum(RelationGetRelid(onerel)), Int16GetDatum(attnum)); + if (!HeapTupleIsValid(atttuple)) + elog(ERROR, "cache lookup failed for attribute %d of relation %u", + attnum, RelationGetRelid(onerel)); + dat = SysCacheGetAttr(ATTNUM, atttuple, Anum_pg_attribute_attstattarget, &isnull); + attstattarget = isnull ? -1 : DatumGetInt16(dat); + ReleaseSysCache(atttuple); + /* Don't analyze column if user has specified not to */ - if (attr->attstattarget == 0) + if (attstattarget == 0) return NULL; /* * Create the VacAttrStats struct. */ stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats)); - stats->attstattarget = attr->attstattarget; + stats->attstattarget = attstattarget; /* * When analyzing an expression index, believe the expression tree's type diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 5e558fabf65..5496f126826 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8543,10 +8543,14 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa { int newtarget; Relation attrelation; - HeapTuple tuple; + HeapTuple tuple, + newtuple; Form_pg_attribute attrtuple; AttrNumber attnum; ObjectAddress address; + Datum repl_val[Natts_pg_attribute]; + bool repl_null[Natts_pg_attribute]; + bool repl_repl[Natts_pg_attribute]; /* * We allow referencing columns by numbers only for indexes, since table @@ -8559,8 +8563,18 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot refer to non-index column by number"))); - Assert(IsA(newValue, Integer)); - newtarget = intVal(newValue); + if (newValue) + { + Assert(IsA(newValue, Integer)); + newtarget = intVal(newValue); + } + else + { + /* + * -1 was used in previous versions to represent the default setting + */ + newtarget = -1; + } /* * Limit target to a sane range @@ -8585,7 +8599,7 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa if (colName) { - tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName); + tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName); if (!HeapTupleIsValid(tuple)) ereport(ERROR, @@ -8595,7 +8609,7 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa } else { - tuple = SearchSysCacheCopyAttNum(RelationGetRelid(rel), colNum); + tuple = SearchSysCacheAttNum(RelationGetRelid(rel), colNum); if (!HeapTupleIsValid(tuple)) ereport(ERROR, @@ -8629,16 +8643,27 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa errhint("Alter statistics on table column instead."))); } - attrtuple->attstattarget = newtarget; - - CatalogTupleUpdate(attrelation, &tuple->t_self, tuple); + /* Build new tuple. */ + memset(repl_null, false, sizeof(repl_null)); + memset(repl_repl, false, sizeof(repl_repl)); + if (newtarget != -1) + repl_val[Anum_pg_attribute_attstattarget - 1] = newtarget; + else + repl_null[Anum_pg_attribute_attstattarget - 1] = true; + repl_repl[Anum_pg_attribute_attstattarget - 1] = true; + newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrelation), + repl_val, repl_null, repl_repl); + CatalogTupleUpdate(attrelation, &tuple->t_self, newtuple); InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), attrtuple->attnum); ObjectAddressSubSet(address, RelationRelationId, RelationGetRelid(rel), attnum); - heap_freetuple(tuple); + + heap_freetuple(newtuple); + + ReleaseSysCache(tuple); table_close(attrelation, RowExclusiveLock); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 6b88096e8e1..3460fea56ba 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -337,6 +337,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <list> alter_table_cmds alter_type_cmds %type <list> alter_identity_column_option_list %type <defelt> alter_identity_column_option +%type <node> set_statistics_value %type <list> createdb_opt_list createdb_opt_items copy_opt_list transaction_mode_list @@ -2446,18 +2447,18 @@ alter_table_cmd: n->missing_ok = true; $$ = (Node *) n; } - /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STATISTICS <SignedIconst> */ - | ALTER opt_column ColId SET STATISTICS SignedIconst + /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STATISTICS */ + | ALTER opt_column ColId SET STATISTICS set_statistics_value { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_SetStatistics; n->name = $3; - n->def = (Node *) makeInteger($6); + n->def = $6; $$ = (Node *) n; } - /* ALTER TABLE <name> ALTER [COLUMN] <colnum> SET STATISTICS <SignedIconst> */ - | ALTER opt_column Iconst SET STATISTICS SignedIconst + /* ALTER TABLE <name> ALTER [COLUMN] <colnum> SET STATISTICS */ + | ALTER opt_column Iconst SET STATISTICS set_statistics_value { AlterTableCmd *n = makeNode(AlterTableCmd); @@ -2469,7 +2470,7 @@ alter_table_cmd: n->subtype = AT_SetStatistics; n->num = (int16) $3; - n->def = (Node *) makeInteger($6); + n->def = $6; $$ = (Node *) n; } /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET ( column_parameter = value [, ... ] ) */ @@ -3070,6 +3071,11 @@ alter_identity_column_option: } ; +set_statistics_value: + SignedIconst { $$ = (Node *) makeInteger($1); } + | DEFAULT { $$ = NULL; } + ; + PartitionBoundSpec: /* a HASH partition */ FOR VALUES WITH '(' hash_partbound ')' diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 8ec83561bfa..f730aa26c47 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -873,33 +873,6 @@ get_attnum(Oid relid, const char *attname) } /* - * get_attstattarget - * - * Given the relation id and the attribute number, - * return the "attstattarget" field from the attribute relation. - * - * Errors if not found. - */ -int -get_attstattarget(Oid relid, AttrNumber attnum) -{ - HeapTuple tp; - Form_pg_attribute att_tup; - int result; - - tp = SearchSysCache2(ATTNUM, - ObjectIdGetDatum(relid), - Int16GetDatum(attnum)); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for attribute %d of relation %u", - attnum, relid); - att_tup = (Form_pg_attribute) GETSTRUCT(tp); - result = att_tup->attstattarget; - ReleaseSysCache(tp); - return result; -} - -/* * get_attgenerated * * Given the relation id and the attribute number, diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 22d1e6cf922..d4a888f5f13 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -8925,7 +8925,10 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) tbinfo->dobj.name); tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname)); tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname)); - tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget)); + if (PQgetisnull(res, r, i_attstattarget)) + tbinfo->attstattarget[j] = -1; + else + tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget)); tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage)); tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage)); tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity)); @@ -16507,7 +16510,7 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo) /* * Dump per-column statistics information. We only issue an ALTER * TABLE statement if the attstattarget entry for this column is - * non-negative (i.e. it's not the default value) + * not the default value. */ if (tbinfo->attstattarget[j] >= 0) appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STATISTICS %d;\n", diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index a94dcdc2713..460d80ac97e 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202401111 +#define CATALOG_VERSION_NO 202401131 #endif diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index 7f4d308e8dd..e2aadb94141 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -158,22 +158,22 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75, /* Number of times inherited from direct parent relation(s) */ int16 attinhcount BKI_DEFAULT(0); + /* attribute's collation, if any */ + Oid attcollation BKI_LOOKUP_OPT(pg_collation); + +#ifdef CATALOG_VARLEN /* variable-length/nullable fields start here */ + /* NOTE: The following fields are not present in tuple descriptors. */ + /* * attstattarget is the target number of statistics datapoints to collect * during VACUUM ANALYZE of this column. A zero here indicates that we do - * not wish to collect any stats about this column. A "-1" here indicates - * that no value has been explicitly set for this column, so ANALYZE - * should use the default setting. + * not wish to collect any stats about this column. A null value here + * indicates that no value has been explicitly set for this column, so + * ANALYZE should use the default setting. * * int16 is sufficient for the current max value (MAX_STATISTICS_TARGET). */ - int16 attstattarget BKI_DEFAULT(-1); - - /* attribute's collation, if any */ - Oid attcollation BKI_LOOKUP_OPT(pg_collation); - -#ifdef CATALOG_VARLEN /* variable-length fields start here */ - /* NOTE: The following fields are not present in tuple descriptors. */ + int16 attstattarget BKI_DEFAULT(_null_) BKI_FORCE_NULL; /* Column-level access permissions */ aclitem attacl[1] BKI_DEFAULT(_null_); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 5cacefc7670..7f623b37fdc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -121,7 +121,7 @@ typedef struct VacAttrStats * than the underlying column/expression. Therefore, use these fields for * information about the datatype being fed to the typanalyze function. */ - int attstattarget; + int attstattarget; /* -1 to use default */ Oid attrtypid; /* type of data being analyzed */ int32 attrtypmod; /* typmod of data being analyzed */ Form_pg_type attrtype; /* copy of pg_type row for attrtypid */ diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index be9ed70e841..e4a200b00ec 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -90,7 +90,6 @@ extern Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum); extern char *get_attname(Oid relid, AttrNumber attnum, bool missing_ok); extern AttrNumber get_attnum(Oid relid, const char *attname); -extern int get_attstattarget(Oid relid, AttrNumber attnum); extern char get_attgenerated(Oid relid, AttrNumber attnum); extern Oid get_atttype(Oid relid, AttrNumber attnum); extern void get_atttypetypmodcoll(Oid relid, AttrNumber attnum, diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out index 446cfa678b7..79fa117cb54 100644 --- a/src/test/regress/expected/create_index.out +++ b/src/test/regress/expected/create_index.out @@ -2707,8 +2707,8 @@ SELECT attrelid::regclass, attnum, attstattarget attrelid | attnum | attstattarget ---------------------------+--------+--------------- concur_exprs_index_expr | 1 | 100 - concur_exprs_index_pred | 1 | -1 - concur_exprs_index_pred_2 | 1 | -1 + concur_exprs_index_pred | 1 | + concur_exprs_index_pred_2 | 1 | (3 rows) DROP TABLE concur_exprs_tab; |