summaryrefslogtreecommitdiff
path: root/src/backend/commands/statscmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/statscmds.c')
-rw-r--r--src/backend/commands/statscmds.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index 662b4fa15d2..db5f4278d55 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -50,11 +50,11 @@ CreateStatistics(CreateStatsStmt *stmt)
{
int16 attnums[STATS_MAX_DIMENSIONS];
int numcols = 0;
- ObjectAddress address = InvalidObjectAddress;
char *namestr;
NameData stxname;
Oid statoid;
Oid namespaceId;
+ Oid stxowner = GetUserId();
HeapTuple htup;
Datum values[Natts_pg_statistic_ext];
bool nulls[Natts_pg_statistic_ext];
@@ -63,7 +63,7 @@ CreateStatistics(CreateStatsStmt *stmt)
Relation rel = NULL;
Oid relid;
ObjectAddress parentobject,
- childobject;
+ myself;
Datum types[2]; /* one for each possible type of statistics */
int ntypes;
ArrayType *stxkind;
@@ -140,7 +140,7 @@ CreateStatistics(CreateStatsStmt *stmt)
RelationGetRelationName(rel))));
/* You must own the relation to create stats on it */
- if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
+ if (!pg_class_ownercheck(RelationGetRelid(rel), stxowner))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
RelationGetRelationName(rel));
}
@@ -185,7 +185,7 @@ CreateStatistics(CreateStatsStmt *stmt)
attForm = (Form_pg_attribute) GETSTRUCT(atttuple);
/* Disallow use of system attributes in extended stats */
- if (attForm->attnum < 0)
+ if (attForm->attnum <= 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("statistics creation on system columns is not supported")));
@@ -205,7 +205,7 @@ CreateStatistics(CreateStatsStmt *stmt)
errmsg("cannot have more than %d columns in statistics",
STATS_MAX_DIMENSIONS)));
- attnums[numcols] = ((Form_pg_attribute) GETSTRUCT(atttuple))->attnum;
+ attnums[numcols] = attForm->attnum;
numcols++;
ReleaseSysCache(atttuple);
}
@@ -231,10 +231,12 @@ CreateStatistics(CreateStatsStmt *stmt)
* just check consecutive elements.
*/
for (i = 1; i < numcols; i++)
+ {
if (attnums[i] == attnums[i - 1])
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_COLUMN),
errmsg("duplicate column name in statistics definition")));
+ }
/* Form an int2vector representation of the sorted column list */
stxkeys = buildint2vector(attnums, numcols);
@@ -288,7 +290,7 @@ CreateStatistics(CreateStatsStmt *stmt)
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_stxowner - 1] = ObjectIdGetDatum(GetUserId());
+ values[Anum_pg_statistic_ext_stxowner - 1] = ObjectIdGetDatum(stxowner);
values[Anum_pg_statistic_ext_stxkeys - 1] = PointerGetDatum(stxkeys);
values[Anum_pg_statistic_ext_stxkind - 1] = PointerGetDatum(stxkind);
@@ -312,29 +314,35 @@ CreateStatistics(CreateStatsStmt *stmt)
relation_close(rel, NoLock);
/*
- * Add a dependency on the table, so that stats get dropped on DROP TABLE.
- *
- * XXX don't we need dependencies on the specific columns, instead?
+ * Add an AUTO dependency on each column used in the stats, so that the
+ * stats object goes away if any or all of them get dropped.
*/
- ObjectAddressSet(parentobject, RelationRelationId, relid);
- ObjectAddressSet(childobject, StatisticExtRelationId, statoid);
- recordDependencyOn(&childobject, &parentobject, DEPENDENCY_AUTO);
+ ObjectAddressSet(myself, StatisticExtRelationId, statoid);
+
+ for (i = 0; i < numcols; i++)
+ {
+ ObjectAddressSubSet(parentobject, RelationRelationId, relid, attnums[i]);
+ recordDependencyOn(&myself, &parentobject, DEPENDENCY_AUTO);
+ }
/*
- * Also add dependency on the schema. This is required to ensure that we
- * drop the statistics on DROP SCHEMA. This is not handled automatically
- * by DROP TABLE because the statistics might be in a different schema
- * from the table itself. (This definition is a bit bizarre for the
- * single-table case, but it will make more sense if/when we support
- * extended stats across multiple tables.)
+ * Also add dependencies on namespace and owner. These are required
+ * because the stats object might have a different namespace and/or owner
+ * than the underlying table(s).
*/
ObjectAddressSet(parentobject, NamespaceRelationId, namespaceId);
- recordDependencyOn(&childobject, &parentobject, DEPENDENCY_AUTO);
+ recordDependencyOn(&myself, &parentobject, DEPENDENCY_NORMAL);
- /* Return stats object's address */
- ObjectAddressSet(address, StatisticExtRelationId, statoid);
+ recordDependencyOnOwner(StatisticExtRelationId, statoid, stxowner);
- return address;
+ /*
+ * XXX probably there should be a recordDependencyOnCurrentExtension call
+ * here too, but we'd have to add support for ALTER EXTENSION ADD/DROP
+ * STATISTICS, which is more work than it seems worth.
+ */
+
+ /* Return stats object's address */
+ return myself;
}
/*