1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-23 03:21:12 +03:00

Repair problems with the result of lookup_rowtype_tupdesc() possibly being

discarded by cache flush while still in use.  This is a minimal patch that
just copies the tupdesc anywhere it could be needed across a flush.  Applied
to back branches only; Neil Conway is working on a better long-term solution
for HEAD.
This commit is contained in:
Tom Lane
2006-01-17 17:33:23 +00:00
parent afe91cae6c
commit 7b3d9367b4
11 changed files with 49 additions and 17 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.53.2.2 2005/11/22 18:23:04 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.53.2.3 2006/01/17 17:33:20 tgl Exp $
*
*
* INTERFACE ROUTINES
@ -847,6 +847,7 @@ toast_flatten_tuple_attribute(Datum value,
if (tupleDesc == NULL)
return value; /* not a composite type */
tupleDesc = CreateTupleDescCopy(tupleDesc);
att = tupleDesc->attrs;
numAttrs = tupleDesc->natts;
@ -893,7 +894,10 @@ toast_flatten_tuple_attribute(Datum value,
* If nothing to untoast, just return the original tuple.
*/
if (!need_change)
{
FreeTupleDesc(tupleDesc);
return value;
}
/*
* Calculate the new size of the tuple. Header size should not change,
@ -930,6 +934,7 @@ toast_flatten_tuple_attribute(Datum value,
for (i = 0; i < numAttrs; i++)
if (toast_free[i])
pfree(DatumGetPointer(toast_values[i]));
FreeTupleDesc(tupleDesc);
return PointerGetDatum(new_data);
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.132.2.2 2006/01/12 22:29:11 neilc Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.132.2.3 2006/01/17 17:33:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -705,7 +705,7 @@ coerce_record_to_complex(ParseState *pstate, Node *node,
format_type_be(RECORDOID),
format_type_be(targetTypeId))));
tupdesc = lookup_rowtype_tupdesc(targetTypeId, -1);
tupdesc = CreateTupleDescCopy(lookup_rowtype_tupdesc(targetTypeId, -1));
newargs = NIL;
ucolno = 1;
arg = list_head(args);
@ -763,6 +763,8 @@ coerce_record_to_complex(ParseState *pstate, Node *node,
format_type_be(targetTypeId)),
errdetail("Input has too many columns.")));
FreeTupleDesc(tupdesc);
rowexpr = makeNode(RowExpr);
rowexpr->args = newargs;
rowexpr->row_typeid = targetTypeId;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.138.2.1 2005/11/22 18:23:14 momjian Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.138.2.2 2006/01/17 17:33:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -816,7 +816,8 @@ ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
((Var *) expr)->vartype == RECORDOID)
tupleDesc = expandRecordVariable(pstate, (Var *) expr, 0);
else if (get_expr_result_type(expr, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
tupleDesc = lookup_rowtype_tupdesc(exprType(expr), exprTypmod(expr));
tupleDesc = CreateTupleDescCopy(lookup_rowtype_tupdesc(exprType(expr),
exprTypmod(expr)));
Assert(tupleDesc);
/* Generate a list of references to the individual fields */
@ -993,7 +994,8 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
* appropriate error message while failing.
*/
if (get_expr_result_type(expr, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
tupleDesc = lookup_rowtype_tupdesc(exprType(expr), exprTypmod(expr));
tupleDesc = CreateTupleDescCopy(lookup_rowtype_tupdesc(exprType(expr),
exprTypmod(expr)));
return tupleDesc;
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/rowtypes.c,v 1.13 2005/10/15 02:49:29 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/rowtypes.c,v 1.13.2.1 2006/01/17 17:33:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -83,6 +83,7 @@ record_in(PG_FUNCTION_ARGS)
errmsg("input of anonymous composite types is not implemented")));
tupTypmod = -1; /* for all non-anonymous types */
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
tupdesc = CreateTupleDescCopy(tupdesc);
ncolumns = tupdesc->natts;
/*
@ -261,6 +262,7 @@ record_in(PG_FUNCTION_ARGS)
pfree(buf.data);
pfree(values);
pfree(nulls);
FreeTupleDesc(tupdesc);
PG_RETURN_HEAPTUPLEHEADER(result);
}
@ -288,6 +290,7 @@ record_out(PG_FUNCTION_ARGS)
tupType = HeapTupleHeaderGetTypeId(rec);
tupTypmod = HeapTupleHeaderGetTypMod(rec);
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
tupdesc = CreateTupleDescCopy(tupdesc);
ncolumns = tupdesc->natts;
/* Build a temporary HeapTuple control structure */
@ -409,6 +412,7 @@ record_out(PG_FUNCTION_ARGS)
pfree(values);
pfree(nulls);
FreeTupleDesc(tupdesc);
PG_RETURN_CSTRING(buf.data);
}
@ -449,6 +453,7 @@ record_recv(PG_FUNCTION_ARGS)
errmsg("input of anonymous composite types is not implemented")));
tupTypmod = -1; /* for all non-anonymous types */
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
tupdesc = CreateTupleDescCopy(tupdesc);
ncolumns = tupdesc->natts;
/*
@ -597,6 +602,7 @@ record_recv(PG_FUNCTION_ARGS)
heap_freetuple(tuple);
pfree(values);
pfree(nulls);
FreeTupleDesc(tupdesc);
PG_RETURN_HEAPTUPLEHEADER(result);
}
@ -624,6 +630,7 @@ record_send(PG_FUNCTION_ARGS)
tupType = HeapTupleHeaderGetTypeId(rec);
tupTypmod = HeapTupleHeaderGetTypMod(rec);
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
tupdesc = CreateTupleDescCopy(tupdesc);
ncolumns = tupdesc->natts;
/* Build a temporary HeapTuple control structure */
@ -724,6 +731,7 @@ record_send(PG_FUNCTION_ARGS)
pfree(values);
pfree(nulls);
FreeTupleDesc(tupdesc);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

View File

@ -3,7 +3,7 @@
* back to source text
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.207.2.3 2005/12/30 18:34:27 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.207.2.4 2006/01/17 17:33:21 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@ -2699,7 +2699,7 @@ get_name_for_var_field(Var *var, int fieldno,
/* Got the tupdesc, so we can extract the field name */
Assert(fieldno >= 1 && fieldno <= tupleDesc->natts);
return NameStr(tupleDesc->attrs[fieldno - 1]->attname);
return pstrdup(NameStr(tupleDesc->attrs[fieldno - 1]->attname));
}
@ -3493,6 +3493,7 @@ get_rule_expr(Node *node, deparse_context *context,
if (rowexpr->row_typeid != RECORDOID)
{
tupdesc = lookup_rowtype_tupdesc(rowexpr->row_typeid, -1);
tupdesc = CreateTupleDescCopy(tupdesc);
Assert(list_length(rowexpr->args) <= tupdesc->natts);
}

View File

@ -36,7 +36,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.15.2.1 2005/11/22 18:23:23 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.15.2.2 2006/01/17 17:33:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -377,6 +377,8 @@ lookup_default_opclass(Oid type_id, Oid am_id)
*
* Note: returned TupleDesc points to cached copy; caller must copy it
* if intending to scribble on it or keep a reference for a long time.
* ("A long time" basically means "across any possible cache flush",
* which typically could occur at any relation open or catalog lookup.)
*/
TupleDesc
lookup_rowtype_tupdesc(Oid type_id, int32 typmod)

View File

@ -7,7 +7,7 @@
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.26 2005/10/15 02:49:32 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.26.2.1 2006/01/17 17:33:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -246,7 +246,7 @@ get_expr_result_type(Node *expr,
*resultTupleDesc = NULL;
result = get_type_func_class(typid);
if (result == TYPEFUNC_COMPOSITE && resultTupleDesc)
*resultTupleDesc = lookup_rowtype_tupdesc(typid, -1);
*resultTupleDesc = CreateTupleDescCopy(lookup_rowtype_tupdesc(typid, -1));
}
return result;
@ -363,7 +363,7 @@ internal_get_result_type(Oid funcid,
{
case TYPEFUNC_COMPOSITE:
if (resultTupleDesc)
*resultTupleDesc = lookup_rowtype_tupdesc(rettype, -1);
*resultTupleDesc = CreateTupleDescCopy(lookup_rowtype_tupdesc(rettype, -1));
/* Named composite types can't have any polymorphic columns */
break;
case TYPEFUNC_SCALAR:

View File

@ -33,7 +33,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.94.2.2 2006/01/08 15:50:00 adunstan Exp $
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.94.2.3 2006/01/17 17:33:22 tgl Exp $
*
**********************************************************************/
@ -796,12 +796,14 @@ plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
tupType = HeapTupleHeaderGetTypeId(td);
tupTypmod = HeapTupleHeaderGetTypMod(td);
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
tupdesc = CreateTupleDescCopy(tupdesc);
/* Build a temporary HeapTuple control structure */
tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
tmptup.t_data = td;
hashref = plperl_hash_from_tuple(&tmptup, tupdesc);
XPUSHs(sv_2mortal(hashref));
FreeTupleDesc(tupdesc);
}
else
{

View File

@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.154.2.2 2006/01/03 22:48:21 tgl Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.154.2.3 2006/01/17 17:33:22 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@ -253,12 +253,14 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo)
tupType = HeapTupleHeaderGetTypeId(td);
tupTypmod = HeapTupleHeaderGetTypMod(td);
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
tupdesc = CreateTupleDescCopy(tupdesc);
/* Build a temporary HeapTuple control structure */
tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
ItemPointerSetInvalid(&(tmptup.t_self));
tmptup.t_tableOid = InvalidOid;
tmptup.t_data = td;
exec_move_row(&estate, NULL, row, &tmptup, tupdesc);
FreeTupleDesc(tupdesc);
}
else
{
@ -3110,12 +3112,14 @@ exec_assign_value(PLpgSQL_execstate *estate,
tupType = HeapTupleHeaderGetTypeId(td);
tupTypmod = HeapTupleHeaderGetTypMod(td);
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
tupdesc = CreateTupleDescCopy(tupdesc);
/* Build a temporary HeapTuple control structure */
tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
ItemPointerSetInvalid(&(tmptup.t_self));
tmptup.t_tableOid = InvalidOid;
tmptup.t_data = td;
exec_move_row(estate, NULL, row, &tmptup, tupdesc);
FreeTupleDesc(tupdesc);
}
break;
}
@ -3152,12 +3156,14 @@ exec_assign_value(PLpgSQL_execstate *estate,
tupType = HeapTupleHeaderGetTypeId(td);
tupTypmod = HeapTupleHeaderGetTypMod(td);
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
tupdesc = CreateTupleDescCopy(tupdesc);
/* Build a temporary HeapTuple control structure */
tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
ItemPointerSetInvalid(&(tmptup.t_self));
tmptup.t_tableOid = InvalidOid;
tmptup.t_data = td;
exec_move_row(estate, rec, NULL, &tmptup, tupdesc);
FreeTupleDesc(tupdesc);
}
break;
}

View File

@ -29,7 +29,7 @@
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.66.2.2 2006/01/10 00:33:30 neilc Exp $
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.66.2.3 2006/01/17 17:33:23 tgl Exp $
*
*********************************************************************
*/
@ -862,6 +862,7 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
tupType = HeapTupleHeaderGetTypeId(td);
tupTypmod = HeapTupleHeaderGetTypMod(td);
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
tupdesc = CreateTupleDescCopy(tupdesc);
/* Set up I/O funcs if not done yet */
if (proc->args[i].is_rowtype != 1)
@ -872,6 +873,7 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
tmptup.t_data = td;
arg = PLyDict_FromTuple(&(proc->args[i]), &tmptup, tupdesc);
FreeTupleDesc(tupdesc);
}
}
else

View File

@ -31,7 +31,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.98.2.1 2005/11/22 18:23:31 momjian Exp $
* $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.98.2.2 2006/01/17 17:33:23 tgl Exp $
*
**********************************************************************/
@ -531,6 +531,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
tupType = HeapTupleHeaderGetTypeId(td);
tupTypmod = HeapTupleHeaderGetTypMod(td);
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
tupdesc = CreateTupleDescCopy(tupdesc);
/* Build a temporary HeapTuple control structure */
tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
tmptup.t_data = td;
@ -539,6 +540,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
pltcl_build_tuple_argument(&tmptup, tupdesc, &list_tmp);
Tcl_DStringAppendElement(&tcl_cmd,
Tcl_DStringValue(&list_tmp));
FreeTupleDesc(tupdesc);
}
}
else