diff --git a/src/backend/access/common/relation.c b/src/backend/access/common/relation.c index 22c4cd5a256..60a9106d6fa 100644 --- a/src/backend/access/common/relation.c +++ b/src/backend/access/common/relation.c @@ -23,6 +23,7 @@ #include "access/relation.h" #include "access/xact.h" #include "catalog/namespace.h" +#include "commands/tablecmds.h" #include "pgstat.h" #include "storage/lmgr.h" #include "utils/inval.h" @@ -70,8 +71,13 @@ relation_open(Oid relationId, LOCKMODE lockmode) /* Make note that we've accessed a temporary relation */ if (RelationUsesLocalBuffers(r)) + { MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE; + /* ... and mark the temporary relation accessed */ + MarkTemporaryRelAccessed(RelationGetRelid(r)); + } + pgstat_init_relation(r); return r; @@ -120,8 +126,13 @@ try_relation_open(Oid relationId, LOCKMODE lockmode) /* Make note that we've accessed a temporary relation */ if (RelationUsesLocalBuffers(r)) + { MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE; + /* ... and mark the temporary relation accessed */ + MarkTemporaryRelAccessed(RelationGetRelid(r)); + } + pgstat_init_relation(r); return r; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index c6dd2e020da..0bfe9efa40c 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -129,6 +129,7 @@ typedef struct OnCommitItem } OnCommitItem; static List *on_commits = NIL; +static List *in_use = NIL; /* record accessed temporary relations */ /* @@ -739,6 +740,7 @@ static List *GetParentedForeignKeyRefs(Relation partition); static void ATDetachCheckNoForeignKeyRefs(Relation partition); static char GetAttributeCompression(Oid atttypid, const char *compression); static char GetAttributeStorage(Oid atttypid, const char *storagemode); +static bool CheckTemporaryRelAccessed(Oid relid); /* ---------------------------------------------------------------- @@ -19302,11 +19304,11 @@ PreCommit_on_commit_actions(void) case ONCOMMIT_DELETE_ROWS: /* - * If this transaction hasn't accessed any temporary + * If this transaction hasn't accessed this temporary * relations, we can skip truncating ON COMMIT DELETE ROWS * tables, as they must still be empty. */ - if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPNAMESPACE)) + if (CheckTemporaryRelAccessed(oc->relid)) oids_to_truncate = lappend_oid(oids_to_truncate, oc->relid); break; case ONCOMMIT_DROP: @@ -19375,6 +19377,10 @@ PreCommit_on_commit_actions(void) } #endif } + + /* free accessed list */ + list_free(in_use); + in_use = NIL; } /* @@ -19485,6 +19491,21 @@ RangeVarCallbackMaintainsTable(const RangeVar *relation, relation->relname); } +/* + * Mark one temporary relation accessed + */ +void +MarkTemporaryRelAccessed(Oid relid) +{ + MemoryContext oldctx; + + oldctx = MemoryContextSwitchTo(CacheMemoryContext); + + in_use = list_append_unique_oid(in_use, relid); + + MemoryContextSwitchTo(oldctx); +} + /* * Callback to RangeVarGetRelidExtended() for TRUNCATE processing. */ @@ -22057,3 +22078,27 @@ GetAttributeStorage(Oid atttypid, const char *storagemode) return cstorage; } + + +/* + * Check temporary relation accessed + */ +static bool +CheckTemporaryRelAccessed(Oid relid) +{ + ListCell *lc; + + /* quick check if temporary relation accessed in this transaction */ + if (!(MyXactFlags & XACT_FLAGS_ACCESSEDTEMPNAMESPACE)) + return false; + + foreach(lc, in_use) + { + Oid tid = lfirst_oid(lc); + + if (tid == relid) + return true; + } + + return false; +} \ No newline at end of file diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index 6832470d387..a7a27945864 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -106,5 +106,6 @@ extern void RangeVarCallbackOwnsRelation(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg); extern bool PartConstraintImpliedByRelConstraint(Relation scanrel, List *partConstraint); +extern void MarkTemporaryRelAccessed(Oid relid); #endif /* TABLECMDS_H */