]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
pltcl's spi_execp didn't handle NULL arguments quite correctly.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 24 Jan 2002 19:31:36 +0000 (19:31 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 24 Jan 2002 19:31:36 +0000 (19:31 +0000)
It would try to call the input conversion routines for them anyway.
So, a valid input string for the datatype had to be supplied.

src/pl/tcl/pltcl.c

index 47f92d1e383a07dfaa96bdbe961e750d98ca2cb5..336b837c961f708cc295c742a09493c53ade603b 100644 (file)
@@ -31,7 +31,7 @@
  *       ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.48 2001/11/05 17:46:39 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.49 2002/01/24 19:31:36 tgl Exp $
  *
  **********************************************************************/
 
@@ -124,8 +124,6 @@ typedef struct pltcl_query_desc
        Oid                *argtypes;
        FmgrInfo   *arginfuncs;
        Oid                *argtypelems;
-       bool       *argbyvals;
-       Datum      *argvalues;
 }      pltcl_query_desc;
 
 
@@ -819,9 +817,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
        if (strcmp(interp->result, "OK") == 0)
                return rettup;
        if (strcmp(interp->result, "SKIP") == 0)
-       {
-               return (HeapTuple) NULL;;
-       }
+               return (HeapTuple) NULL;
 
        /************************************************************
         * Convert the result value from the Tcl interpreter
@@ -889,6 +885,8 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
                attnum = SPI_fnumber(tupdesc, ret_values[i++]);
                if (attnum == SPI_ERROR_NOATTRIBUTE)
                        elog(ERROR, "pltcl: invalid attribute '%s'", ret_values[--i]);
+               if (attnum <= 0)
+                       elog(ERROR, "pltcl: cannot set system attribute '%s'", ret_values[--i]);
 
                /************************************************************
                 * Lookup the attribute type in the syscache
@@ -1724,8 +1722,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
        qdesc->argtypes = (Oid *) malloc(nargs * sizeof(Oid));
        qdesc->arginfuncs = (FmgrInfo *) malloc(nargs * sizeof(FmgrInfo));
        qdesc->argtypelems = (Oid *) malloc(nargs * sizeof(Oid));
-       qdesc->argbyvals = (bool *) malloc(nargs * sizeof(bool));
-       qdesc->argvalues = (Datum *) malloc(nargs * sizeof(Datum));
 
        /************************************************************
         * Prepare to start a controlled return through all
@@ -1739,8 +1735,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
                free(qdesc->argtypes);
                free(qdesc->arginfuncs);
                free(qdesc->argtypelems);
-               free(qdesc->argbyvals);
-               free(qdesc->argvalues);
                free(qdesc);
                ckfree((char *) args);
                return TCL_ERROR;
@@ -1761,8 +1755,6 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
                perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput,
                                           &(qdesc->arginfuncs[i]));
                qdesc->argtypelems[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
-               qdesc->argbyvals[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typbyval;
-               qdesc->argvalues[i] = (Datum) NULL;
                ReleaseSysCache(typeTup);
        }
 
@@ -1879,6 +1871,7 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
        int                     loop_body;
        Tcl_HashEntry *hashent;
        pltcl_query_desc *qdesc;
+       Datum      *argvalues = NULL;
        char       *volatile nulls = NULL;
        char       *volatile arrayname = NULL;
        int                     count = 0;
@@ -2033,15 +2026,6 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
                if (sigsetjmp(Warn_restart, 1) != 0)
                {
                        memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
-                       for (j = 0; j < callnargs; j++)
-                       {
-                               if (!qdesc->argbyvals[j] &&
-                                       qdesc->argvalues[j] != (Datum) NULL)
-                               {
-                                       pfree(DatumGetPointer(qdesc->argvalues[j]));
-                                       qdesc->argvalues[j] = (Datum) NULL;
-                               }
-                       }
                        ckfree((char *) callargs);
                        callargs = NULL;
                        pltcl_restart_in_progress = 1;
@@ -2053,15 +2037,25 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
                 * Setup the value array for the SPI_execp() using
                 * the type specific input functions
                 ************************************************************/
+               argvalues = (Datum *) palloc(callnargs * sizeof(Datum));
+
                for (j = 0; j < callnargs; j++)
                {
-                       UTF_BEGIN;
-                       qdesc->argvalues[j] =
-                               FunctionCall3(&qdesc->arginfuncs[j],
-                                                         CStringGetDatum(UTF_U2E(callargs[j])),
-                                                         ObjectIdGetDatum(qdesc->argtypelems[j]),
-                                                         Int32GetDatum(-1));
-                       UTF_END;
+                       if (nulls && nulls[j] == 'n')
+                       {
+                               /* don't try to convert the input for a null */
+                               argvalues[j] = (Datum) 0;
+                       }
+                       else
+                       {
+                               UTF_BEGIN;
+                               argvalues[j] =
+                                       FunctionCall3(&qdesc->arginfuncs[j],
+                                                                 CStringGetDatum(UTF_U2E(callargs[j])),
+                                                                 ObjectIdGetDatum(qdesc->argtypelems[j]),
+                                                                 Int32GetDatum(-1));
+                               UTF_END;
+                       }
                }
 
                /************************************************************
@@ -2088,14 +2082,6 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
        if (sigsetjmp(Warn_restart, 1) != 0)
        {
                memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
-               for (j = 0; j < callnargs; j++)
-               {
-                       if (!qdesc->argbyvals[j] && qdesc->argvalues[j] != (Datum) NULL)
-                       {
-                               pfree(DatumGetPointer(qdesc->argvalues[j]));
-                               qdesc->argvalues[j] = (Datum) NULL;
-                       }
-               }
                pltcl_restart_in_progress = 1;
                Tcl_SetResult(interp, "Transaction abort", TCL_VOLATILE);
                return TCL_ERROR;
@@ -2104,21 +2090,9 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
        /************************************************************
         * Execute the plan
         ************************************************************/
-       spi_rc = SPI_execp(qdesc->plan, qdesc->argvalues, nulls, count);
+       spi_rc = SPI_execp(qdesc->plan, argvalues, nulls, count);
        memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
 
-       /************************************************************
-        * For varlena data types, free the argument values
-        ************************************************************/
-       for (j = 0; j < callnargs; j++)
-       {
-               if (!qdesc->argbyvals[j] && qdesc->argvalues[j] != (Datum) NULL)
-               {
-                       pfree(DatumGetPointer(qdesc->argvalues[j]));
-                       qdesc->argvalues[j] = (Datum) NULL;
-               }
-       }
-
        /************************************************************
         * Check the return code from SPI_execp()
         ************************************************************/