Repair problems with the result of lookup_rowtype_tupdesc() possibly being
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 17 Jan 2006 17:33:37 +0000 (17:33 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 17 Jan 2006 17:33:37 +0000 (17:33 +0000)
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.

src/backend/access/heap/tuptoaster.c
src/backend/parser/parse_coerce.c
src/backend/parser/parse_target.c
src/backend/utils/adt/rowtypes.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/cache/typcache.c
src/pl/plperl/plperl.c
src/pl/plpgsql/src/pl_exec.c
src/pl/plpython/plpython.c
src/pl/tcl/pltcl.c

index c06b3b8d36ae9c312321d0134902c08225ef484d..02af9d8e4555abbeee56844ae764a796c7ec0b15 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.47 2005/01/01 05:43:06 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.47.4.1 2006/01/17 17:33:34 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -820,6 +820,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;
 
@@ -866,7 +867,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
@@ -903,6 +907,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);
 }
index 125c218bb5563739c407962d477fa0f6f474e407..869e870b66c76ec4da480f3c332b0a88a80702be 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.126.4.1 2006/01/12 22:29:22 neilc Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.126.4.2 2006/01/17 17:33:34 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -700,7 +700,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);
@@ -758,6 +758,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;
index a6b1edbe48dd7e3bcf7f272442661d708ae97b2c..fc1ddc3dadb7ee41b97cdf8b32c16d82f5291690 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.129.4.1 2005/12/14 16:30:20 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.129.4.2 2006/01/17 17:33:34 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -839,6 +839,7 @@ ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
 
    /* Verify it's a composite type, and get the tupdesc */
    tupleDesc = lookup_rowtype_tupdesc(exprType(expr), exprTypmod(expr));
+   tupleDesc = CreateTupleDescCopy(tupleDesc);
 
    /* Generate a list of references to the individual fields */
    numAttrs = tupleDesc->natts;
@@ -889,6 +890,8 @@ ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
        te_list = lappend(te_list, te);
    }
 
+   FreeTupleDesc(tupleDesc);
+
    return te_list;
 }
 
index 603072886e23b84595d3f7b7d684b7549db69dcc..6f9c8aca0ce0395cae6982c9dfd871c62c1ec11a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/rowtypes.c,v 1.8.4.2 2005/04/30 20:04:46 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/rowtypes.c,v 1.8.4.3 2006/01/17 17:33:34 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -79,6 +79,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;
 
    /*
@@ -257,6 +258,7 @@ record_in(PG_FUNCTION_ARGS)
    pfree(buf.data);
    pfree(values);
    pfree(nulls);
+   FreeTupleDesc(tupdesc);
 
    PG_RETURN_HEAPTUPLEHEADER(result);
 }
@@ -284,6 +286,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 */
@@ -408,6 +411,7 @@ record_out(PG_FUNCTION_ARGS)
 
    pfree(values);
    pfree(nulls);
+   FreeTupleDesc(tupdesc);
 
    PG_RETURN_CSTRING(buf.data);
 }
@@ -444,6 +448,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;
 
    /*
@@ -593,6 +598,7 @@ record_recv(PG_FUNCTION_ARGS)
    heap_freetuple(tuple);
    pfree(values);
    pfree(nulls);
+   FreeTupleDesc(tupdesc);
 
    PG_RETURN_HEAPTUPLEHEADER(result);
 }
@@ -620,6 +626,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 */
@@ -722,6 +729,7 @@ record_send(PG_FUNCTION_ARGS)
 
    pfree(values);
    pfree(nulls);
+   FreeTupleDesc(tupdesc);
 
    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
 }
index 63ec591edfb0fb9bb56b079cae120f6289c3757e..a2552f4722af913c3beca4c280c59add8a819ad3 100644 (file)
@@ -3,7 +3,7 @@
  *             back to source text
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.188.4.2 2005/07/15 18:40:20 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.188.4.3 2006/01/17 17:33:34 tgl Exp $
  *
  *   This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -3245,6 +3245,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);
                }
 
index 7e15f884f61fcf74af73b7c72cda25d4f267a9af..b719f99d82dffd659be244311ac23b1bd7605ed5 100644 (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.11 2004/12/31 22:01:25 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.11.4.1 2006/01/17 17:33:35 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -383,6 +383,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)
index c14e6eb60f937a9d842fe7ef8db2c01ec78f6283..96c8705e225a65ea5ff1adfb560e8e50efda1541 100644 (file)
@@ -33,7 +33,7 @@
  *   ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.67.4.4 2006/01/08 15:51:18 adunstan Exp $
+ *   $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.67.4.5 2006/01/17 17:33:35 tgl Exp $
  *
  **********************************************************************/
 
@@ -705,12 +705,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
        {
@@ -1009,7 +1011,7 @@ plperl_func_handler(PG_FUNCTION_ARGS)
         */
        td = get_function_tupdesc(prodesc->result_oid,
                                  (ReturnSetInfo *) fcinfo->resultinfo);
-       /* td = CreateTupleDescCopy(td); */
+       td = CreateTupleDescCopy(td);
        attinmeta = TupleDescGetAttInMetadata(td);
 
        tup = plperl_build_tuple_result(perlhash, attinmeta);
index 9d17ead258fb32d6233dd370526b539e01ba6ccb..d1a3a098dc208af4d5b21888be773b03157360f1 100644 (file)
@@ -3,7 +3,7 @@
  *           procedural language
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.127.4.4 2006/01/03 22:48:28 tgl Exp $
+ *   $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.127.4.5 2006/01/17 17:33:36 tgl Exp $
  *
  *   This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -273,12 +273,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
                    {
@@ -2948,12 +2950,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;
            }
@@ -2990,12 +2994,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;
            }
index b93a94c8826634f29fbcee566a6a82f2896df95c..851a89ae2abcfc67a49d46c7b0ca88faa42a8e7f 100644 (file)
@@ -29,7 +29,7 @@
  * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.58.4.4 2006/01/10 00:33:48 neilc Exp $
+ * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.58.4.5 2006/01/17 17:33:37 tgl Exp $
  *
  *********************************************************************
  */
@@ -861,6 +861,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)
@@ -871,6 +872,7 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure * proc)
                    tmptup.t_data = td;
 
                    arg = PLyDict_FromTuple(&(proc->args[i]), &tmptup, tupdesc);
+                   FreeTupleDesc(tupdesc);
                }
            }
            else
index a95344759a313653e974de1de5172a34f5a75e5a..7928f3eb761f189498e8b6af6fd09373256b4a70 100644 (file)
@@ -31,7 +31,7 @@
  *   ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.94 2004/11/21 21:17:05 tgl Exp $
+ *   $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.94.4.1 2006/01/17 17:33:37 tgl Exp $
  *
  **********************************************************************/
 
@@ -533,6 +533,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;
@@ -541,6 +542,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