]> granicus.if.org Git - postgresql/commitdiff
Repair problems with the result of lookup_rowtype_tupdesc() possibly being
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 17 Jan 2006 17:33:23 +0000 (17:33 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 17 Jan 2006 17:33:23 +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/backend/utils/fmgr/funcapi.c
src/pl/plperl/plperl.c
src/pl/plpgsql/src/pl_exec.c
src/pl/plpython/plpython.c
src/pl/tcl/pltcl.c

index 2292f6965122fcc42f3735861ac504441e96a193..bdd9bc100ac06e6e320c623663d61013f0871bcb 100644 (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);
 }
index 407744005fe648ebc9c4e2d504de511fcb77f016..56229fd8c920b9bca550931b509aff348d7cb406 100644 (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;
index 4290045baab4ac58455503bbf7d956547495cb88..e32ad225514dc29d757d4fd300c181b50352e2fe 100644 (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;
 }
index 1a12185b048289e07d95b745292b17001afeb354..04756db10c855d48062edda562c567d13bbf7bc2 100644 (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));
 }
index 3e6e2ffac47452dbf4c2828df440aaa0ed7e2085..82830223999dde31a504bb5d03348c74758fa5b9 100644 (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);
                                }
 
index b681892ca9e711c280a9e77f4c52e443c9b47f5e..16025e2c6ff000dd4ca30ad9cc0926ff92c9cf38 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.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)
index 0a51f7ae0f2b0d2ef7cdd9d7fcb6430892c72e59..565eb111027406ab18c0db7a0aa01b1b4491725f 100644 (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:
index 6a5d1546ff52bb6e33bd347963a650d3854d9ce2..57343fe21dbaf8459698c7d771cbc48806676147 100644 (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
                {
index 39e7ae510c772aca15f5b61fe60b68779e63c89e..7fc4f8e0be3a0d131e147474dc2733e0554c5f94 100644 (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;
                        }
index 329387b428b1e650b2c3061229d6f96b9c9707e6..e9b9c5958d74fa86299a60a64aa4021e2701cbc3 100644 (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
index 3f3d6acd45ad2b1542b1cf7f721dc67b37476e67..a84e5d438ad5a77c46330a5f987524171bda397c 100644 (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