#include "catalog/dependency.h"
#include "catalog/heap.h"
#include "catalog/index.h"
+#include "catalog/namespace.h"
#include "catalog/toasting.h"
#include "commands/cluster.h"
#include "commands/tablecmds.h"
indexOid = InvalidOid;
Relation rel;
- /* Find and lock the table */
- rel = heap_openrv(stmt->relation, AccessExclusiveLock);
-
- tableOid = RelationGetRelid(rel);
-
- /* Check permissions */
- if (!pg_class_ownercheck(tableOid, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
- RelationGetRelationName(rel));
+ /* Find, lock, and check permissions on the table */
+ tableOid = RangeVarGetRelidExtended(stmt->relation,
+ AccessExclusiveLock,
+ false, false,
+ RangeVarCallbackOwnsTable, NULL);
+ rel = heap_open(tableOid, NoLock);
/*
* Reject clustering a remote temp table ... their local buffer
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
+#include "commands/tablecmds.h"
#include "commands/tablespace.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
static Oid GetIndexOpClass(List *opclass, Oid attrType,
char *accessMethodName, Oid accessMethodId);
static char *ChooseIndexNameAddition(List *colnames);
-static void RangeVarCallbackForReindexTable(const RangeVar *relation,
- Oid relId, Oid oldRelId, void *arg);
static void RangeVarCallbackForReindexIndex(const RangeVar *relation,
Oid relId, Oid oldRelId, void *arg);
/* The lock level used here should match reindex_relation(). */
heapOid = RangeVarGetRelidExtended(relation, ShareLock, false, false,
- RangeVarCallbackForReindexTable, NULL);
+ RangeVarCallbackOwnsTable, NULL);
if (!reindex_relation(heapOid, REINDEX_REL_PROCESS_TOAST))
ereport(NOTICE,
relation->relname)));
}
-/*
- * Check permissions on table before acquiring relation lock.
- */
-static void
-RangeVarCallbackForReindexTable(const RangeVar *relation,
- Oid relId, Oid oldRelId, void *arg)
-{
- char relkind;
-
- /* Nothing to do if the relation was not found. */
- if (!OidIsValid(relId))
- return;
-
- /*
- * If the relation does exist, check whether it's an index. But note
- * that the relation might have been dropped between the time we did the
- * name lookup and now. In that case, there's nothing to do.
- */
- relkind = get_rel_relkind(relId);
- if (!relkind)
- return;
- if (relkind != RELKIND_RELATION && relkind != RELKIND_TOASTVALUE)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not a table", relation->relname)));
-
- /* Check permissions */
- if (!pg_class_ownercheck(relId, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, relation->relname);
-}
-
/*
* ReindexDatabase
* Recreate indexes of a database.
}
}
}
+
+/*
+ * This is intended as a callback for RangeVarGetRelidExtended(). It allows
+ * the table to be locked only if (1) it's a plain table or TOAST table and
+ * (2) the current user is the owner (or the superuser). This meets the
+ * permission-checking needs of both CLUTER and REINDEX TABLE; we expose it
+ * here so that it can be used by both.
+ */
+void
+RangeVarCallbackOwnsTable(const RangeVar *relation,
+ Oid relId, Oid oldRelId, void *arg)
+{
+ char relkind;
+
+ /* Nothing to do if the relation was not found. */
+ if (!OidIsValid(relId))
+ return;
+
+ /*
+ * If the relation does exist, check whether it's an index. But note
+ * that the relation might have been dropped between the time we did the
+ * name lookup and now. In that case, there's nothing to do.
+ */
+ relkind = get_rel_relkind(relId);
+ if (!relkind)
+ return;
+ if (relkind != RELKIND_RELATION && relkind != RELKIND_TOASTVALUE)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a table", relation->relname)));
+
+ /* Check permissions */
+ if (!pg_class_ownercheck(relId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, relation->relname);
+}
SubTransactionId mySubid,
SubTransactionId parentSubid);
+extern void RangeVarCallbackOwnsTable(const RangeVar *relation,
+ Oid relId, Oid oldRelId, void *arg);
+
#endif /* TABLECMDS_H */