1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-28 05:21:27 +03:00

Give a better error for duplicate entries in VACUUM/ANALYZE column list.

Previously, the code didn't think about this case and would just try to
analyze such a column twice.  That would fail at the point of inserting
the second version of the pg_statistic row, with obscure error messsages
like "duplicate key value violates unique constraint" or "tuple already
updated by self", depending on context and PG version.  We could allow
the case by ignoring duplicate column specifications, but it seems better
to reject it explicitly.

The bogus error messages seem like arguably a bug, so back-patch to
all supported versions.

Nathan Bossart, per a report from Michael Paquier, and whacked
around a bit by me.

Discussion: https://postgr.es/m/E061A8E3-5E3D-494D-94F0-E8A9B312BBFC@amazon.com
This commit is contained in:
Tom Lane 2017-09-21 18:13:11 -04:00
parent 149cfdb3a2
commit a09d8be7dd
3 changed files with 21 additions and 1 deletions

View File

@ -369,10 +369,14 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
/*
* Determine which columns to analyze
*
* Note that system attributes are never analyzed.
* Note that system attributes are never analyzed, so we just reject them
* at the lookup stage. We also reject duplicate column mentions. (We
* could alternatively ignore duplicates, but analyzing a column twice
* won't work; we'd end up making a conflicting update in pg_statistic.)
*/
if (vacstmt->va_cols != NIL)
{
Bitmapset *unique_cols = NULL;
ListCell *le;
vacattrstats = (VacAttrStats **) palloc(list_length(vacstmt->va_cols) *
@ -388,6 +392,13 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
col, RelationGetRelationName(onerel))));
if (bms_is_member(i, unique_cols))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_COLUMN),
errmsg("column \"%s\" of relation \"%s\" is specified twice",
col, RelationGetRelationName(onerel))));
unique_cols = bms_add_member(unique_cols, i);
vacattrstats[tcnt] = examine_attribute(onerel, i, NULL);
if (vacattrstats[tcnt] != NULL)
tcnt++;

View File

@ -79,5 +79,10 @@ ERROR: ANALYZE cannot be executed from VACUUM or ANALYZE
CONTEXT: SQL function "do_analyze" statement 1
SQL function "wrap_do_analyze" statement 1
VACUUM FULL vactst;
-- check behavior with duplicate column mentions
VACUUM ANALYZE vaccluster(i,i);
ERROR: column "i" of relation "vaccluster" is specified twice
ANALYZE vaccluster(i,i);
ERROR: column "i" of relation "vaccluster" is specified twice
DROP TABLE vaccluster;
DROP TABLE vactst;

View File

@ -60,5 +60,9 @@ VACUUM FULL pg_database;
VACUUM FULL vaccluster;
VACUUM FULL vactst;
-- check behavior with duplicate column mentions
VACUUM ANALYZE vaccluster(i,i);
ANALYZE vaccluster(i,i);
DROP TABLE vaccluster;
DROP TABLE vactst;