Repair access-to-already-freed-memory error recently introduced into

VACUUM.
This commit is contained in:
Tom Lane 2000-03-08 23:41:00 +00:00
parent d261adf6db
commit 84a89e24ee

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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); return PortalGetVariableMemory(vc_portal);
} }
bool CommonSpecialPortalIsOpen(void) bool CommonSpecialPortalIsOpen(void)
{ {
return CommonSpecialPortalInUse; return CommonSpecialPortalInUse;
@ -153,6 +154,7 @@ void
vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec) vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
{ {
NameData VacRel; NameData VacRel;
Name VacRelName;
PortalVariableMemory pmem; PortalVariableMemory pmem;
MemoryContext old; MemoryContext old;
List *le; List *le;
@ -173,17 +175,22 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
if (IsTransactionBlock()) if (IsTransactionBlock())
elog(ERROR, "VACUUM cannot run inside a BEGIN/END block"); elog(ERROR, "VACUUM cannot run inside a BEGIN/END block");
/* initialize vacuum cleaner, particularly vc_portal */
vc_init();
if (verbose) if (verbose)
MESSAGE_LEVEL = NOTICE; MESSAGE_LEVEL = NOTICE;
else else
MESSAGE_LEVEL = DEBUG; 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) 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 */ /* must also copy the column list, if any, to safe storage */
pmem = CommonSpecialPortalGetMemory(); pmem = CommonSpecialPortalGetMemory();
@ -196,11 +203,18 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
} }
MemoryContextSwitchTo(old); 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 */ /* vacuum the database */
if (vacrel) vc_vacuum(VacRelName, analyze, va_cols);
vc_vacuum(&VacRel, analyze, va_cols);
else
vc_vacuum(NULL, analyze, NIL);
/* clean up */ /* clean up */
vc_shutdown(); vc_shutdown();
@ -229,8 +243,6 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
static void static void
vc_init() vc_init()
{ {
CommonSpecialPortalOpen();
/* matches the StartTransaction in PostgresMain() */ /* matches the StartTransaction in PostgresMain() */
CommitTransactionCommand(); CommitTransactionCommand();
} }
@ -252,6 +264,7 @@ vc_shutdown()
*/ */
unlink(RELCACHE_INIT_FILENAME); unlink(RELCACHE_INIT_FILENAME);
/* Clean up working storage */
CommonSpecialPortalClose(); CommonSpecialPortalClose();
/* matches the CommitTransaction in PostgresMain() */ /* matches the CommitTransaction in PostgresMain() */