]> granicus.if.org Git - postgresql/commitdiff
Fix problems with dropped columns in pltcl triggers, per report from Patrick Samson.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 24 Jan 2004 23:06:29 +0000 (23:06 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 24 Jan 2004 23:06:29 +0000 (23:06 +0000)
doc/src/sgml/pltcl.sgml
src/pl/tcl/pltcl.c

index 22121c2b2979ac1ff61a6c370f8ea62d047b17dd..2e7b9f88e188f0f39e102defbb2f86ddb7897154 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.28 2003/11/29 19:51:37 pgsql Exp $
+$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.29 2004/01/24 23:06:29 tgl Exp $
 -->
 
  <chapter id="pltcl">
@@ -516,7 +516,10 @@ SELECT 'doesn''t' AS ret
          element. So looking up a column name in the list with <application>Tcl</>'s
          <function>lsearch</> command returns the element's number starting
         with 1 for the first column, the same way the columns are customarily
-        numbered in <productname>PostgreSQL</productname>.
+        numbered in <productname>PostgreSQL</productname>.  (Empty list
+        elements also appear in the positions of columns that have been
+        dropped, so that the attribute numbering is correct for columns
+        to their right.)
        </para>
        </listitem>
       </varlistentry>
index f813841f2d86a6a9c66d23e1eb5f3dba71a0c35a..37e515ff66b590e42891d19a7689a354302c9058 100644 (file)
@@ -31,7 +31,7 @@
  *       ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.81 2004/01/06 23:55:19 tgl Exp $
+ *       $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.82 2004/01/24 23:06:29 tgl Exp $
  *
  **********************************************************************/
 
@@ -695,11 +695,15 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
        pfree(stroid);
 
        /* A list of attribute names for argument TG_relatts */
-       /* note: we deliberately include dropped atts here */
        Tcl_DStringAppendElement(&tcl_trigtup, "");
        for (i = 0; i < tupdesc->natts; i++)
-               Tcl_DStringAppendElement(&tcl_trigtup,
-                                                                NameStr(tupdesc->attrs[i]->attname));
+       {
+               if (tupdesc->attrs[i]->attisdropped)
+                       Tcl_DStringAppendElement(&tcl_trigtup, "");
+               else
+                       Tcl_DStringAppendElement(&tcl_trigtup,
+                                                                        NameStr(tupdesc->attrs[i]->attname));
+       }
        Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup));
        Tcl_DStringFree(&tcl_trigtup);
        Tcl_DStringInit(&tcl_trigtup);
@@ -881,9 +885,10 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
                siglongjmp(Warn_restart, 1);
        }
 
-       i = 0;
-       while (i < ret_numvals)
+       for (i = 0; i < ret_numvals; i += 2)
        {
+               CONST84 char *ret_name = ret_values[i];
+               CONST84 char *ret_value = ret_values[i + 1];
                int                     attnum;
                HeapTuple       typeTup;
                Oid                     typinput;
@@ -891,24 +896,25 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
                FmgrInfo        finfo;
 
                /************************************************************
-                * Ignore pseudo elements with a dot name
+                * Ignore ".tupno" pseudo elements (see pltcl_set_tuple_values)
                 ************************************************************/
-               if (*(ret_values[i]) == '.')
-               {
-                       i += 2;
+               if (strcmp(ret_name, ".tupno") == 0)
                        continue;
-               }
 
                /************************************************************
                 * Get the attribute number
                 ************************************************************/
-               attnum = SPI_fnumber(tupdesc, ret_values[i++]);
+               attnum = SPI_fnumber(tupdesc, ret_name);
                if (attnum == SPI_ERROR_NOATTRIBUTE)
-                       elog(ERROR, "invalid attribute \"%s\"",
-                                ret_values[--i]);
+                       elog(ERROR, "invalid attribute \"%s\"", ret_name);
                if (attnum <= 0)
-                       elog(ERROR, "cannot set system attribute \"%s\"",
-                                ret_values[--i]);
+                       elog(ERROR, "cannot set system attribute \"%s\"", ret_name);
+
+               /************************************************************
+                * Ignore dropped columns
+                ************************************************************/
+               if (tupdesc->attrs[attnum - 1]->attisdropped)
+                       continue;
 
                /************************************************************
                 * Lookup the attribute type in the syscache
@@ -932,7 +938,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
                UTF_BEGIN;
                modvalues[attnum - 1] =
                        FunctionCall3(&finfo,
-                                                 CStringGetDatum(UTF_U2E(ret_values[i++])),
+                                                 CStringGetDatum(UTF_U2E(ret_value)),
                                                  ObjectIdGetDatum(typelem),
                                   Int32GetDatum(tupdesc->attrs[attnum - 1]->atttypmod));
                UTF_END;