summaryrefslogtreecommitdiff
path: root/src/pl
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-06-16 18:42:24 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-06-16 18:42:24 +0000
commit06e10abc0bb4297a0754313b4f158bdd5622ca24 (patch)
tree6d413dfdfab3fea4a6d96b07b7fdb8ba81498860 /src/pl
parentb49ce32da1975b2fdab26e463b7189b95e770809 (diff)
downloadpostgresql-06e10abc0bb4297a0754313b4f158bdd5622ca24.tar.gz
Fix problems with cached tuple descriptors disappearing while still in use
by creating a reference-count mechanism, similar to what we did a long time ago for catcache entries. The back branches have an ugly solution involving lots of extra copies, but this way is more efficient. Reference counting is only applied to tupdescs that are actually in caches --- there seems no need to use it for tupdescs that are generated in the executor, since they'll go away during plan shutdown by virtue of being in the per-query memory context. Neil Conway and Tom Lane
Diffstat (limited to 'src/pl')
-rw-r--r--src/pl/plperl/plperl.c3
-rw-r--r--src/pl/plpgsql/src/pl_exec.c35
-rw-r--r--src/pl/plpython/plpython.c3
-rw-r--r--src/pl/tcl/pltcl.c3
4 files changed, 25 insertions, 19 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 612d4261f6..2ed16b12cb 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -1,7 +1,7 @@
/**********************************************************************
* plperl.c - perl as a procedural language for PostgreSQL
*
- * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.111 2006/05/30 22:12:15 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.112 2006/06/16 18:42:23 tgl Exp $
*
**********************************************************************/
@@ -904,6 +904,7 @@ plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
hashref = plperl_hash_from_tuple(&tmptup, tupdesc);
XPUSHs(sv_2mortal(hashref));
+ ReleaseTupleDesc(tupdesc);
}
else
{
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 893ad1dfdc..e74dcac231 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.171 2006/06/15 18:02:22 momjian Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.172 2006/06/16 18:42:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -233,6 +233,7 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo)
tmptup.t_tableOid = InvalidOid;
tmptup.t_data = td;
exec_move_row(&estate, NULL, row, &tmptup, tupdesc);
+ ReleaseTupleDesc(tupdesc);
}
else
{
@@ -1701,10 +1702,11 @@ exec_stmt_select(PLpgSQL_execstate *estate, PLpgSQL_stmt_select *stmt)
/*
* Run the query
+ *
* Retrieving two rows can be slower than a single row, e.g.
* a sequential scan where the scan has to be completed to
- * check for a second row. For this reason, we only do the
- * second-line check for STRICT.
+ * check for a second row. For this reason, we only retrieve
+ * the second row if checking STRICT.
*/
exec_run_select(estate, stmt->query, stmt->strict ? 2 : 1, NULL);
tuptab = estate->eval_tuptable;
@@ -1717,22 +1719,21 @@ exec_stmt_select(PLpgSQL_execstate *estate, PLpgSQL_stmt_select *stmt)
*/
if (n == 0)
{
- if (!stmt->strict)
- {
- /* null the target */
- exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
- exec_eval_cleanup(estate);
- return PLPGSQL_RC_OK;
- }
- else
+ if (stmt->strict)
ereport(ERROR,
- (errcode(ERRCODE_NO_DATA),
- errmsg("query returned no rows")));
+ (errcode(ERRCODE_NO_DATA),
+ errmsg("query returned no rows")));
+
+ /* set the target to NULL(s) */
+ exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);
+ exec_eval_cleanup(estate);
+ return PLPGSQL_RC_OK;
}
- else if (n > 1 && stmt->strict)
+
+ if (n > 1 && stmt->strict)
ereport(ERROR,
- (errcode(ERRCODE_CARDINALITY_VIOLATION),
- errmsg("query more than one row")));
+ (errcode(ERRCODE_CARDINALITY_VIOLATION),
+ errmsg("query returned more than one row")));
/*
* Put the first result into the target and set found to true
@@ -3138,6 +3139,7 @@ exec_assign_value(PLpgSQL_execstate *estate,
tmptup.t_tableOid = InvalidOid;
tmptup.t_data = td;
exec_move_row(estate, NULL, row, &tmptup, tupdesc);
+ ReleaseTupleDesc(tupdesc);
}
break;
}
@@ -3180,6 +3182,7 @@ exec_assign_value(PLpgSQL_execstate *estate,
tmptup.t_tableOid = InvalidOid;
tmptup.t_data = td;
exec_move_row(estate, rec, NULL, &tmptup, tupdesc);
+ ReleaseTupleDesc(tupdesc);
}
break;
}
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 1aedc0c762..bc8310a045 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -1,7 +1,7 @@
/**********************************************************************
* plpython.c - python as a procedural language for PostgreSQL
*
- * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.81 2006/05/30 22:12:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.82 2006/06/16 18:42:23 tgl Exp $
*
*********************************************************************
*/
@@ -883,6 +883,7 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
tmptup.t_data = td;
arg = PLyDict_FromTuple(&(proc->args[i]), &tmptup, tupdesc);
+ ReleaseTupleDesc(tupdesc);
}
}
else
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 198b11c77e..75964b2568 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -2,7 +2,7 @@
* pltcl.c - PostgreSQL support for Tcl as
* procedural language (PL)
*
- * $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.104 2006/05/30 22:12:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.105 2006/06/16 18:42:24 tgl Exp $
*
**********************************************************************/
@@ -511,6 +511,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
pltcl_build_tuple_argument(&tmptup, tupdesc, &list_tmp);
Tcl_DStringAppendElement(&tcl_cmd,
Tcl_DStringValue(&list_tmp));
+ ReleaseTupleDesc(tupdesc);
}
}
else