mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
Fix problems with dropped columns in pltcl triggers, per report from Patrick Samson.
This commit is contained in:
parent
0152f14812
commit
c8bcd5ca92
@ -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">
|
<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
|
element. So looking up a column name in the list with <application>Tcl</>'s
|
||||||
<function>lsearch</> command returns the element's number starting
|
<function>lsearch</> command returns the element's number starting
|
||||||
with 1 for the first column, the same way the columns are customarily
|
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>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
* ENHANCEMENTS, OR MODIFICATIONS.
|
* ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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);
|
pfree(stroid);
|
||||||
|
|
||||||
/* A list of attribute names for argument TG_relatts */
|
/* A list of attribute names for argument TG_relatts */
|
||||||
/* note: we deliberately include dropped atts here */
|
|
||||||
Tcl_DStringAppendElement(&tcl_trigtup, "");
|
Tcl_DStringAppendElement(&tcl_trigtup, "");
|
||||||
for (i = 0; i < tupdesc->natts; i++)
|
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_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup));
|
||||||
Tcl_DStringFree(&tcl_trigtup);
|
Tcl_DStringFree(&tcl_trigtup);
|
||||||
Tcl_DStringInit(&tcl_trigtup);
|
Tcl_DStringInit(&tcl_trigtup);
|
||||||
@ -881,9 +885,10 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
|
|||||||
siglongjmp(Warn_restart, 1);
|
siglongjmp(Warn_restart, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
for (i = 0; i < ret_numvals; i += 2)
|
||||||
while (i < ret_numvals)
|
|
||||||
{
|
{
|
||||||
|
CONST84 char *ret_name = ret_values[i];
|
||||||
|
CONST84 char *ret_value = ret_values[i + 1];
|
||||||
int attnum;
|
int attnum;
|
||||||
HeapTuple typeTup;
|
HeapTuple typeTup;
|
||||||
Oid typinput;
|
Oid typinput;
|
||||||
@ -891,24 +896,25 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
|
|||||||
FmgrInfo finfo;
|
FmgrInfo finfo;
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Ignore pseudo elements with a dot name
|
* Ignore ".tupno" pseudo elements (see pltcl_set_tuple_values)
|
||||||
************************************************************/
|
************************************************************/
|
||||||
if (*(ret_values[i]) == '.')
|
if (strcmp(ret_name, ".tupno") == 0)
|
||||||
{
|
|
||||||
i += 2;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Get the attribute number
|
* Get the attribute number
|
||||||
************************************************************/
|
************************************************************/
|
||||||
attnum = SPI_fnumber(tupdesc, ret_values[i++]);
|
attnum = SPI_fnumber(tupdesc, ret_name);
|
||||||
if (attnum == SPI_ERROR_NOATTRIBUTE)
|
if (attnum == SPI_ERROR_NOATTRIBUTE)
|
||||||
elog(ERROR, "invalid attribute \"%s\"",
|
elog(ERROR, "invalid attribute \"%s\"", ret_name);
|
||||||
ret_values[--i]);
|
|
||||||
if (attnum <= 0)
|
if (attnum <= 0)
|
||||||
elog(ERROR, "cannot set system attribute \"%s\"",
|
elog(ERROR, "cannot set system attribute \"%s\"", ret_name);
|
||||||
ret_values[--i]);
|
|
||||||
|
/************************************************************
|
||||||
|
* Ignore dropped columns
|
||||||
|
************************************************************/
|
||||||
|
if (tupdesc->attrs[attnum - 1]->attisdropped)
|
||||||
|
continue;
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Lookup the attribute type in the syscache
|
* Lookup the attribute type in the syscache
|
||||||
@ -932,7 +938,7 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
|
|||||||
UTF_BEGIN;
|
UTF_BEGIN;
|
||||||
modvalues[attnum - 1] =
|
modvalues[attnum - 1] =
|
||||||
FunctionCall3(&finfo,
|
FunctionCall3(&finfo,
|
||||||
CStringGetDatum(UTF_U2E(ret_values[i++])),
|
CStringGetDatum(UTF_U2E(ret_value)),
|
||||||
ObjectIdGetDatum(typelem),
|
ObjectIdGetDatum(typelem),
|
||||||
Int32GetDatum(tupdesc->attrs[attnum - 1]->atttypmod));
|
Int32GetDatum(tupdesc->attrs[attnum - 1]->atttypmod));
|
||||||
UTF_END;
|
UTF_END;
|
||||||
|
Loading…
Reference in New Issue
Block a user