From a933ee38bbb8dffbc48a3363a94ff6f2a9f7964d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 16 Nov 2000 22:30:52 +0000 Subject: Change SearchSysCache coding conventions so that a reference count is maintained for each cache entry. A cache entry will not be freed until the matching ReleaseSysCache call has been executed. This eliminates worries about cache entries getting dropped while still in use. See my posting to pg-hackers of even date for more info. --- src/pl/plpgsql/src/pl_comp.c | 92 ++++++++++++++++++++++++++++---------------- src/pl/plpgsql/src/pl_exec.c | 53 ++++++++++++++++--------- 2 files changed, 94 insertions(+), 51 deletions(-) (limited to 'src/pl/plpgsql') diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index bed95890968..c0fe5968970 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.23 2000/08/31 13:26:16 wieck Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.24 2000/11/16 22:30:50 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -53,7 +53,6 @@ #include "access/heapam.h" #include "utils/syscache.h" -#include "utils/catcache.h" #include "catalog/catname.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" @@ -131,9 +130,9 @@ plpgsql_compile(Oid fn_oid, int functype) * Lookup the pg_proc tuple by Oid * ---------- */ - procTup = SearchSysCacheTuple(PROCOID, - ObjectIdGetDatum(fn_oid), - 0, 0, 0); + procTup = SearchSysCache(PROCOID, + ObjectIdGetDatum(fn_oid), + 0, 0, 0); if (!HeapTupleIsValid(procTup)) elog(ERROR, "plpgsql: cache lookup for proc %u failed", fn_oid); @@ -176,9 +175,9 @@ plpgsql_compile(Oid fn_oid, int functype) * Lookup the functions return type * ---------- */ - typeTup = SearchSysCacheTuple(TYPEOID, - ObjectIdGetDatum(procStruct->prorettype), 0, 0, 0); - + typeTup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(procStruct->prorettype), + 0, 0, 0); if (!HeapTupleIsValid(typeTup)) { plpgsql_comperrinfo(); @@ -195,6 +194,7 @@ plpgsql_compile(Oid fn_oid, int functype) function->fn_rettypelem = typeStruct->typelem; fmgr_info(typeStruct->typinput, &(function->fn_retinput)); } + ReleaseSysCache(typeTup); /* ---------- * Create the variables for the procedures parameters @@ -208,9 +208,9 @@ plpgsql_compile(Oid fn_oid, int functype) * Get the parameters type * ---------- */ - typeTup = SearchSysCacheTuple(TYPEOID, - ObjectIdGetDatum(procStruct->proargtypes[i]), 0, 0, 0); - + typeTup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(procStruct->proargtypes[i]), + 0, 0, 0); if (!HeapTupleIsValid(typeTup)) { plpgsql_comperrinfo(); @@ -276,6 +276,7 @@ plpgsql_compile(Oid fn_oid, int functype) arg_varnos[i] = var->varno; } + ReleaseSysCache(typeTup); } break; @@ -512,6 +513,7 @@ plpgsql_compile(Oid fn_oid, int functype) function->datums[i] = plpgsql_Datums[i]; function->action = plpgsql_yylval.program; + ReleaseSysCache(procTup); /* ---------- * Finally return the compiled function @@ -608,8 +610,9 @@ plpgsql_parse_word(char *word) * ---------- */ typeXlated = xlateSqlType(cp); - typeTup = SearchSysCacheTuple(TYPENAME, - PointerGetDatum(typeXlated), 0, 0, 0); + typeTup = SearchSysCache(TYPENAME, + PointerGetDatum(typeXlated), + 0, 0, 0); if (HeapTupleIsValid(typeTup)) { PLpgSQL_type *typ; @@ -618,6 +621,7 @@ plpgsql_parse_word(char *word) if (typeStruct->typrelid != InvalidOid) { + ReleaseSysCache(typeTup); pfree(cp); return T_WORD; } @@ -634,6 +638,7 @@ plpgsql_parse_word(char *word) plpgsql_yylval.dtype = typ; + ReleaseSysCache(typeTup); pfree(cp); return T_DTYPE; } @@ -933,8 +938,9 @@ plpgsql_parse_wordtype(char *word) * ---------- */ typeXlated = xlateSqlType(cp); - typeTup = SearchSysCacheTuple(TYPENAME, - PointerGetDatum(typeXlated), 0, 0, 0); + typeTup = SearchSysCache(TYPENAME, + PointerGetDatum(typeXlated), + 0, 0, 0); if (HeapTupleIsValid(typeTup)) { PLpgSQL_type *typ; @@ -943,6 +949,7 @@ plpgsql_parse_wordtype(char *word) if (typeStruct->typrelid != InvalidOid) { + ReleaseSysCache(typeTup); pfree(cp); return T_ERROR; } @@ -959,6 +966,7 @@ plpgsql_parse_wordtype(char *word) plpgsql_yylval.dtype = typ; + ReleaseSysCache(typeTup); pfree(cp); return T_DTYPE; } @@ -1045,8 +1053,9 @@ plpgsql_parse_dblwordtype(char *string) * First word could also be a table name * ---------- */ - classtup = SearchSysCacheTuple(RELNAME, - PointerGetDatum(word1), 0, 0, 0); + classtup = SearchSysCache(RELNAME, + PointerGetDatum(word1), + 0, 0, 0); if (!HeapTupleIsValid(classtup)) { pfree(word1); @@ -1060,6 +1069,7 @@ plpgsql_parse_dblwordtype(char *string) classStruct = (Form_pg_class) GETSTRUCT(classtup); if (classStruct->relkind != 'r' && classStruct->relkind != 's') { + ReleaseSysCache(classtup); pfree(word1); return T_ERROR; } @@ -1068,31 +1078,33 @@ plpgsql_parse_dblwordtype(char *string) * Fetch the named table field and it's type * ---------- */ - attrtup = SearchSysCacheTuple(ATTNAME, - ObjectIdGetDatum(classtup->t_data->t_oid), - PointerGetDatum(word2), 0, 0); + attrtup = SearchSysCache(ATTNAME, + ObjectIdGetDatum(classtup->t_data->t_oid), + PointerGetDatum(word2), + 0, 0); if (!HeapTupleIsValid(attrtup)) { + ReleaseSysCache(classtup); pfree(word1); return T_ERROR; } attrStruct = (Form_pg_attribute) GETSTRUCT(attrtup); - typetup = SearchSysCacheTuple(TYPEOID, - ObjectIdGetDatum(attrStruct->atttypid), 0, 0, 0); + typetup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(attrStruct->atttypid), + 0, 0, 0); if (!HeapTupleIsValid(typetup)) { plpgsql_comperrinfo(); elog(ERROR, "cache lookup for type %u of %s.%s failed", attrStruct->atttypid, word1, word2); } + typeStruct = (Form_pg_type) GETSTRUCT(typetup); /* ---------- * Found that - build a compiler type struct and return it * ---------- */ - typeStruct = (Form_pg_type) GETSTRUCT(typetup); - typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type)); typ->typname = DatumGetCString(DirectFunctionCall1(nameout, @@ -1105,6 +1117,9 @@ plpgsql_parse_dblwordtype(char *string) plpgsql_yylval.dtype = typ; + ReleaseSysCache(classtup); + ReleaseSysCache(attrtup); + ReleaseSysCache(typetup); pfree(word1); return T_DTYPE; } @@ -1138,8 +1153,9 @@ plpgsql_parse_wordrowtype(char *string) cp = strchr(word1, '%'); *cp = '\0'; - classtup = SearchSysCacheTuple(RELNAME, - PointerGetDatum(word1), 0, 0, 0); + classtup = SearchSysCache(RELNAME, + PointerGetDatum(word1), + 0, 0, 0); if (!HeapTupleIsValid(classtup)) { plpgsql_comperrinfo(); @@ -1156,8 +1172,9 @@ plpgsql_parse_wordrowtype(char *string) * Fetch the tables pg_type tuple too * ---------- */ - typetup = SearchSysCacheTuple(TYPENAME, - PointerGetDatum(word1), 0, 0, 0); + typetup = SearchSysCache(TYPENAME, + PointerGetDatum(word1), + 0, 0, 0); if (!HeapTupleIsValid(typetup)) { plpgsql_comperrinfo(); @@ -1178,15 +1195,18 @@ plpgsql_parse_wordrowtype(char *string) row->fieldnames = malloc(sizeof(char *) * row->nfields); row->varnos = malloc(sizeof(int) * row->nfields); + ReleaseSysCache(typetup); + for (i = 0; i < row->nfields; i++) { /* ---------- * Get the attribute and it's type * ---------- */ - attrtup = SearchSysCacheTuple(ATTNUM, - ObjectIdGetDatum(classtup->t_data->t_oid), - (Datum) (i + 1), 0, 0); + attrtup = SearchSysCache(ATTNUM, + ObjectIdGetDatum(classtup->t_data->t_oid), + Int16GetDatum(i + 1), + 0, 0); if (!HeapTupleIsValid(attrtup)) { plpgsql_comperrinfo(); @@ -1198,8 +1218,9 @@ plpgsql_parse_wordrowtype(char *string) cp = DatumGetCString(DirectFunctionCall1(nameout, NameGetDatum(&(attrStruct->attname)))); - typetup = SearchSysCacheTuple(TYPEOID, - ObjectIdGetDatum(attrStruct->atttypid), 0, 0, 0); + typetup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(attrStruct->atttypid), + 0, 0, 0); if (!HeapTupleIsValid(typetup)) { plpgsql_comperrinfo(); @@ -1238,6 +1259,9 @@ plpgsql_parse_wordrowtype(char *string) var->isnull = true; var->shouldfree = false; + ReleaseSysCache(typetup); + ReleaseSysCache(attrtup); + plpgsql_adddatum((PLpgSQL_datum *) var); /* ---------- @@ -1248,6 +1272,8 @@ plpgsql_parse_wordrowtype(char *string) row->varnos[i] = var->varno; } + ReleaseSysCache(classtup); + /* ---------- * Return the complete row definition * ---------- diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 9c094a0739a..565e304f649 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.31 2000/09/12 19:41:40 tgl Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.32 2000/11/16 22:30:50 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -1641,10 +1641,12 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt) extval = ""; else { - typetup = SearchSysCacheTuple(TYPEOID, - ObjectIdGetDatum(var->datatype->typoid), 0, 0, 0); + typetup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(var->datatype->typoid), + 0, 0, 0); if (!HeapTupleIsValid(typetup)) - elog(ERROR, "cache lookup for type %u failed (1)", var->datatype->typoid); + elog(ERROR, "cache lookup for type %u failed (1)", + var->datatype->typoid); typeStruct = (Form_pg_type) GETSTRUCT(typetup); fmgr_info(typeStruct->typoutput, &finfo_output); @@ -1652,6 +1654,7 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt) var->value, ObjectIdGetDatum(typeStruct->typelem), Int32GetDatum(var->datatype->atttypmod))); + ReleaseSysCache(typetup); } plpgsql_dstring_append(&ds, extval); break; @@ -1961,21 +1964,24 @@ exec_stmt_dynexecute(PLpgSQL_execstate * estate, * Get the C-String representation. * ---------- */ - typetup = SearchSysCacheTuple(TYPEOID, - ObjectIdGetDatum(restype), 0, 0, 0); + typetup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(restype), + 0, 0, 0); if (!HeapTupleIsValid(typetup)) elog(ERROR, "cache lookup for type %u failed (1)", restype); typeStruct = (Form_pg_type) GETSTRUCT(typetup); fmgr_info(typeStruct->typoutput, &finfo_output); querystr = DatumGetCString(FunctionCall3(&finfo_output, - query, - ObjectIdGetDatum(typeStruct->typelem), - Int32GetDatum(-1))); + query, + ObjectIdGetDatum(typeStruct->typelem), + Int32GetDatum(-1))); if(!typeStruct->typbyval) pfree((void *)query); + ReleaseSysCache(typetup); + /* ---------- * Call SPI_exec() without preparing a saved plan. * The returncode can be any OK except for OK_SELECT. @@ -2064,8 +2070,9 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt) * Get the C-String representation. * ---------- */ - typetup = SearchSysCacheTuple(TYPEOID, - ObjectIdGetDatum(restype), 0, 0, 0); + typetup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(restype), + 0, 0, 0); if (!HeapTupleIsValid(typetup)) elog(ERROR, "cache lookup for type %u failed (1)", restype); typeStruct = (Form_pg_type) GETSTRUCT(typetup); @@ -2079,6 +2086,8 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt) if(!typeStruct->typbyval) pfree((void *)query); + ReleaseSysCache(typetup); + /* ---------- * Run the query * ---------- @@ -2283,8 +2292,9 @@ exec_assign_value(PLpgSQL_execstate * estate, */ atttype = SPI_gettypeid(rec->tupdesc, i + 1); atttypmod = rec->tupdesc->attrs[i]->atttypmod; - typetup = SearchSysCacheTuple(TYPEOID, - ObjectIdGetDatum(atttype), 0, 0, 0); + typetup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(atttype), + 0, 0, 0); if (!HeapTupleIsValid(typetup)) elog(ERROR, "cache lookup for type %u failed", atttype); typeStruct = (Form_pg_type) GETSTRUCT(typetup); @@ -2299,6 +2309,7 @@ exec_assign_value(PLpgSQL_execstate * estate, nulls[i] = 'n'; else nulls[i] = ' '; + ReleaseSysCache(typetup); } /* ---------- @@ -2603,9 +2614,13 @@ exec_eval_simple_expr(PLpgSQL_execstate * estate, * so that we can free the expression context. */ if (! *isNull) - retval = datumCopy(retval, - get_typbyval(*rettype), - get_typlen(*rettype)); + { + int16 typeLength; + bool byValue; + + get_typlenbyval(*rettype, &typeLength, &byValue); + retval = datumCopy(retval, byValue, typeLength); + } FreeExprContext(econtext); @@ -2726,8 +2741,9 @@ exec_cast_value(Datum value, Oid valtype, FmgrInfo finfo_output; char *extval; - typetup = SearchSysCacheTuple(TYPEOID, - ObjectIdGetDatum(valtype), 0, 0, 0); + typetup = SearchSysCache(TYPEOID, + ObjectIdGetDatum(valtype), + 0, 0, 0); if (!HeapTupleIsValid(typetup)) elog(ERROR, "cache lookup for type %u failed", valtype); typeStruct = (Form_pg_type) GETSTRUCT(typetup); @@ -2742,6 +2758,7 @@ exec_cast_value(Datum value, Oid valtype, ObjectIdGetDatum(reqtypelem), Int32GetDatum(reqtypmod)); pfree(extval); + ReleaseSysCache(typetup); } } -- cgit v1.2.3