48#include "utils/fmgroids.h"
85 const char *indexname);
123 if (
strcmp(opt->defname,
"verbose") == 0)
125 else if (
strcmp(opt->defname,
"analyze") == 0 ||
126 strcmp(opt->defname,
"analyse") == 0)
131 errmsg(
"unrecognized %s option \"%s\"",
155 errmsg(
"cannot execute %s on multiple tables",
156 "REPACK (ANALYZE)"));
196 if (
stmt->usingindex)
202 if (!
stmt->indexname)
207 errmsg(
"there is no previously clustered index for table \"%s\"",
213 errmsg(
"cannot execute %s on partitioned table \"%s\" USING INDEX with no index name",
221 elog(
ERROR,
"unable to determine index to cluster on");
305 int save_sec_context;
353 errmsg(
"cannot execute %s on a shared catalog",
364 errmsg(
"cannot execute %s on temporary tables of other sessions",
397 errmsg(
"permission denied: \"%s\" is a system catalog",
399 errdetail(
"System catalogs can only be clustered by the index they're already clustered on, if any, unless \"%s\" is enabled.",
400 "allow_system_table_mods"));
521 errmsg(
"\"%s\" is not an index for table \"%s\"",
526 if (!
OldIndex->rd_indam->amclusterable)
529 errmsg(
"cannot cluster on index \"%s\" because access method does not support clustering",
541 errmsg(
"cannot cluster on partial index \"%s\"",
552 if (!
OldIndex->rd_index->indisvalid)
555 errmsg(
"cannot cluster on invalid index \"%s\"",
614 elog(
ERROR,
"cannot cluster on invalid index %u", indexOid);
643 Oid tableSpace =
OldHeap->rd_rel->reltablespace;
660 relpersistence =
OldHeap->rd_rel->relpersistence;
716 char relpersistence,
LOCKMODE lockmode)
747 reloptions = (
Datum) 0;
820 reloptions = (
Datum) 0;
853 double num_tuples = 0,
887 if (
OldHeap->rd_rel->reltoastrelid)
897 if (
OldHeap->rd_rel->reltoastrelid &&
NewHeap->rd_rel->reltoastrelid)
971 errmsg(
"repacking \"%s.%s\" using index scan on \"%s\"",
977 errmsg(
"repacking \"%s.%s\" using sequential scan and sort",
982 errmsg(
"repacking \"%s.%s\" in physical order",
1009 (
errmsg(
"\"%s.%s\": found %.0f removable, %.0f nonremovable row versions in %u pages",
1014 errdetail(
"%.0f dead row versions cannot be removed yet.\n"
1025 elog(
ERROR,
"cache lookup failed for relation %u",
1029 relform->relpages = num_pages;
1030 relform->reltuples = num_tuples;
1097 elog(
ERROR,
"cache lookup failed for relation %u",
r1);
1102 elog(
ERROR,
"cache lookup failed for relation %u",
r2);
1151 elog(
ERROR,
"cannot swap mapped relation \"%s\" with non-mapped relation",
1162 elog(
ERROR,
"cannot change tablespace of mapped relation \"%s\"",
1165 elog(
ERROR,
"cannot change persistence of mapped relation \"%s\"",
1168 elog(
ERROR,
"cannot change access method of mapped relation \"%s\"",
1172 elog(
ERROR,
"cannot swap toast by links for mapped relation \"%s\"",
1180 elog(
ERROR,
"could not find relation mapping for relation \"%s\", OID %u",
1184 elog(
ERROR,
"could not find relation mapping for relation \"%s\", OID %u",
1209 rel2->rd_createSubid =
rel1->rd_createSubid;
1210 rel2->rd_newRelfilelocatorSubid =
rel1->rd_newRelfilelocatorSubid;
1211 rel2->rd_firstRelfilelocatorSubid =
rel1->rd_firstRelfilelocatorSubid;
1297 elog(
ERROR,
"could not change access method dependency for relation \"%s.%s\"",
1305 elog(
ERROR,
"could not change access method dependency for relation \"%s.%s\"",
1342 elog(
ERROR,
"cannot swap toast files by content when there's only one");
1369 elog(
ERROR,
"cannot swap toast files by links for system catalogs");
1378 elog(
ERROR,
"expected one dependency record for TOAST table, found %ld",
1387 elog(
ERROR,
"expected one dependency record for TOAST table, found %ld",
1462 char newrelpersistence)
1567 object.objectSubId = 0;
1767 rtc->tableOid =
class->oid;
1859 errmsg(
"permission denied to execute %s on \"%s\", skipping it",
1894 errmsg(
"ANALYZE option must be specified when a column list is provided"));
1916 errmsg(
"cannot execute %s on temporary tables of other sessions",
1954 stmt->relation->va_cols,
true,
NULL);
1976 if (indexname ==
NULL && usingindex)
1995 errmsg(
"there is no previously clustered index for table \"%s\"",
1998 else if (indexname !=
NULL)
2005 errmsg(
"index \"%s\" for table \"%s\" does not exist",
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
void pgstat_progress_update_param(int index, int64 val)
void pgstat_progress_end_command(void)
@ PROGRESS_COMMAND_REPACK
#define RelationGetNumberOfBlocks(reln)
#define PG_USED_FOR_ASSERTS_ONLY
#define Assert(condition)
TransactionId MultiXactId
#define OidIsValid(objectId)
bool IsSystemRelation(Relation relation)
bool IsCatalogRelation(Relation relation)
bool IsSystemClass(Oid relid, Form_pg_class reltuple)
static Relation process_single_relation(RepackStmt *stmt, ClusterParams *params)
static List * get_tables_to_repack_partitioned(RepackCommand cmd, Oid relid, bool rel_is_index, MemoryContext permcxt)
static void copy_table_data(Relation NewHeap, Relation OldHeap, Relation OldIndex, bool verbose, bool *pSwapToastByContent, TransactionId *pFreezeXid, MultiXactId *pCutoffMulti)
void check_index_is_clusterable(Relation OldHeap, Oid indexOid, LOCKMODE lockmode)
void finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, bool is_system_catalog, bool swap_toast_by_content, bool check_constraints, bool is_internal, TransactionId frozenXid, MultiXactId cutoffMulti, char newrelpersistence)
static bool repack_is_permitted_for_relation(RepackCommand cmd, Oid relid, Oid userid)
void ExecRepack(ParseState *pstate, RepackStmt *stmt, bool isTopLevel)
static List * get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt)
static const char * RepackCommandAsString(RepackCommand cmd)
static bool cluster_rel_recheck(RepackCommand cmd, Relation OldHeap, Oid indexOid, Oid userid, int options)
Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod, char relpersistence, LOCKMODE lockmode)
static void rebuild_relation(Relation OldHeap, Relation index, bool verbose)
void cluster_rel(RepackCommand cmd, Relation OldHeap, Oid indexOid, ClusterParams *params)
void mark_index_clustered(Relation rel, Oid indexOid, bool is_internal)
static void swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, bool swap_toast_by_content, bool is_internal, TransactionId frozenXid, MultiXactId cutoffMulti, Oid *mapped_tables)
static Oid determine_clustered_index(Relation rel, bool usingindex, const char *indexname)
#define CLUOPT_RECHECK_ISCLUSTERED
void analyze_rel(Oid relid, RangeVar *relation, const VacuumParams params, List *va_cols, bool in_outer_xact, BufferAccessStrategy bstrategy)
bool defGetBoolean(DefElem *def)
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
#define PERFORM_DELETION_INTERNAL
int errcode(int sqlerrcode)
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
#define palloc_object(type)
bool allowSystemTableMods
int NewGUCNestLevel(void)
void RestrictSearchPath(void)
void AtEOXact_GUC(bool isCommit, int nestLevel)
void RelationClearMissing(Relation rel)
Oid heap_create_with_catalog(const char *relname, Oid relnamespace, Oid reltablespace, Oid relid, Oid reltypeid, Oid reloftypeid, Oid ownerid, Oid accessmtd, TupleDesc tupdesc, List *cooked_constraints, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, OnCommitAction oncommit, Datum reloptions, bool use_user_acl, bool allow_system_table_mods, bool is_internal, Oid relrewrite, ObjectAddress *typaddress)
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
Oid IndexGetRelation(Oid indexId, bool missing_ok)
bool reindex_relation(const ReindexStmt *stmt, Oid relid, int flags, const ReindexParams *params)
#define REINDEX_REL_FORCE_INDEXES_UNLOGGED
#define REINDEX_REL_SUPPRESS_INDEX_USE
#define REINDEX_REL_FORCE_INDEXES_PERMANENT
#define REINDEX_REL_CHECK_CONSTRAINTS
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void CatalogTupleUpdateWithInfo(Relation heapRel, const ItemPointerData *otid, HeapTuple tup, CatalogIndexState indstate)
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
void CatalogCloseIndexes(CatalogIndexState indstate)
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
void CacheInvalidateCatalog(Oid catalogId)
void CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
List * lappend(List *list, void *datum)
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger)
bool CheckRelationOidLockedByMe(Oid relid, LOCKMODE lockmode, bool orstronger)
#define AccessExclusiveLock
char * get_rel_name(Oid relid)
char get_rel_relkind(Oid relid)
Oid get_rel_namespace(Oid relid)
bool get_index_isclustered(Oid index_oid)
char * get_namespace_name(Oid nspid)
Oid get_relname_relid(const char *relname, Oid relnamespace)
void MemoryContextDelete(MemoryContext context)
MemoryContext PortalContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define SECURITY_RESTRICTED_OPERATION
#define CHECK_FOR_INTERRUPTS()
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
void SetUserIdAndSecContext(Oid userid, int sec_context)
bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2)
#define MultiXactIdIsValid(multi)
#define InvalidMultiXactId
Oid LookupCreationNamespace(const char *nspname)
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
#define InvokeObjectPostAlterHookArg(classId, objectId, subId, auxiliaryId, is_internal)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
int parser_errposition(ParseState *pstate, int location)
@ REPACK_COMMAND_VACUUMFULL
FormData_pg_class * Form_pg_class
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
END_CATALOG_STRUCT typedef FormData_pg_index * Form_pg_index
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
#define foreach_ptr(type, var, lst)
#define foreach_node(type, var, lst)
#define foreach_oid(var, lst)
const char * pg_rusage_show(const PGRUsage *ru0)
void pg_rusage_init(PGRUsage *ru0)
bool plan_cluster_use_sort(Oid tableOid, Oid indexOid)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
void TransferPredicateLocksToHeapRelation(Relation relation)
#define PROGRESS_REPACK_PHASE
#define PROGRESS_REPACK_COMMAND
#define PROGRESS_REPACK_PHASE_SWAP_REL_FILES
#define PROGRESS_REPACK_PHASE_FINAL_CLEANUP
#define PROGRESS_REPACK_PHASE_REBUILD_INDEX
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationIsMapped(relation)
#define RelationGetRelationName(relation)
#define RelationIsPopulated(relation)
#define RELATION_IS_OTHER_TEMP(relation)
#define RelationGetNamespace(relation)
List * RelationGetIndexList(Relation relation)
void RelationAssumeNewRelfilelocator(Relation relation)
void RelationMapRemoveMapping(Oid relationId)
RelFileNumber RelationMapOidToFilenumber(Oid relationId, bool shared)
void RelationMapUpdateMap(Oid relationId, RelFileNumber fileNumber, bool shared, bool immediate)
#define RelFileNumberIsValid(relnumber)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Snapshot GetTransactionSnapshot(void)
void PushActiveSnapshot(Snapshot snapshot)
void PopActiveSnapshot(void)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation relation_open(Oid relationId, LOCKMODE lockmode)
#define BTEqualStrategyNumber
TransactionId FreezeLimit
TransactionId relfrozenxid
MultiXactId MultiXactCutoff
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
#define SearchSysCacheCopy1(cacheId, key1)
#define SearchSysCacheExists1(cacheId, key1)
Relation try_table_open(Oid relationId, LOCKMODE lockmode)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, ScanKeyData *key)
static void table_endscan(TableScanDesc scan)
static void table_relation_copy_for_cluster(Relation OldTable, Relation NewTable, Relation OldIndex, bool use_sort, TransactionId OldestXmin, TransactionId *xid_cutoff, MultiXactId *multi_cutoff, double *num_tuples, double *tups_vacuumed, double *tups_recently_dead)
void ResetRelRewrite(Oid myrelid)
void CheckTableNotInUse(Relation rel, const char *stmt)
void RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal, bool is_index)
void RangeVarCallbackMaintainsTable(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock)
void NewHeapCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, Oid OIDOldToast)
#define InvalidTransactionId
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
bool vacuum_get_cutoffs(Relation rel, const VacuumParams params, struct VacuumCutoffs *cutoffs)
void CommandCounterIncrement(void)
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
void StartTransactionCommand(void)
void CommitTransactionCommand(void)