summaryrefslogtreecommitdiff
path: root/src/pl/plpgsql
diff options
context:
space:
mode:
authorTom Lane2000-11-16 22:30:52 +0000
committerTom Lane2000-11-16 22:30:52 +0000
commita933ee38bbb8dffbc48a3363a94ff6f2a9f7964d (patch)
tree1c32737389b2530e7152dc2287161b36d9001e8c /src/pl/plpgsql
parentcff23842a4c68301ddf34559c7af383bb5557054 (diff)
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.
Diffstat (limited to 'src/pl/plpgsql')
-rw-r--r--src/pl/plpgsql/src/pl_comp.c92
-rw-r--r--src/pl/plpgsql/src/pl_exec.c53
2 files changed, 94 insertions, 51 deletions
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 = "<NULL>";
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);
}
}