From 84a89e24ee42fb332f114c6e2e4483985aa35f17 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 8 Mar 2000 23:41:00 +0000 Subject: [PATCH] Repair access-to-already-freed-memory error recently introduced into VACUUM. --- src/backend/commands/vacuum.c | 37 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index dc8ebf4635..3cd9b02651 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.141 2000/02/24 04:34:38 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.142 2000/03/08 23:41:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -144,6 +144,7 @@ PortalVariableMemory CommonSpecialPortalGetMemory(void) { return PortalGetVariableMemory(vc_portal); } + bool CommonSpecialPortalIsOpen(void) { return CommonSpecialPortalInUse; @@ -153,6 +154,7 @@ void vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec) { NameData VacRel; + Name VacRelName; PortalVariableMemory pmem; MemoryContext old; List *le; @@ -173,17 +175,22 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec) if (IsTransactionBlock()) elog(ERROR, "VACUUM cannot run inside a BEGIN/END block"); - /* initialize vacuum cleaner, particularly vc_portal */ - vc_init(); - if (verbose) MESSAGE_LEVEL = NOTICE; else MESSAGE_LEVEL = DEBUG; - /* vacrel gets de-allocated on transaction commit, so copy it */ + /* Create special portal for cross-transaction storage */ + CommonSpecialPortalOpen(); + + /* vacrel gets de-allocated on xact commit, so copy it to safe storage */ if (vacrel) - strcpy(NameStr(VacRel), vacrel); + { + namestrcpy(&VacRel, vacrel); + VacRelName = &VacRel; + } + else + VacRelName = NULL; /* must also copy the column list, if any, to safe storage */ pmem = CommonSpecialPortalGetMemory(); @@ -196,11 +203,18 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec) } MemoryContextSwitchTo(old); + /* + * Start up the vacuum cleaner. + * + * NOTE: since this commits the current transaction, the memory holding + * any passed-in parameters gets freed here. We must have already copied + * pass-by-reference parameters to safe storage. Don't make me fix this + * again! + */ + vc_init(); + /* vacuum the database */ - if (vacrel) - vc_vacuum(&VacRel, analyze, va_cols); - else - vc_vacuum(NULL, analyze, NIL); + vc_vacuum(VacRelName, analyze, va_cols); /* clean up */ vc_shutdown(); @@ -229,8 +243,6 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec) static void vc_init() { - CommonSpecialPortalOpen(); - /* matches the StartTransaction in PostgresMain() */ CommitTransactionCommand(); } @@ -252,6 +264,7 @@ vc_shutdown() */ unlink(RELCACHE_INIT_FILENAME); + /* Clean up working storage */ CommonSpecialPortalClose(); /* matches the CommitTransaction in PostgresMain() */ -- 2.40.0