Joe Conway <[EMAIL PROTECTED]> writes:
Note that I also changed behavior in that when trigdata->tg_event doesn't match anything known -- instead of pressing on with a value of "UNKNOWN" it now throws an "elog(ERROR...". The previous behavior made no sense to me, but you may not want to change existing behavior in this way (even though it seems to me that it is a "should not happen" kind of error).
Seems reasonable to me. As a matter of style, the "unrecognized" elogs should print the offending tg_event value; otherwise the patch looks fine.
If this patch is acceptable, I'll make similar changes to plpython.
Please do.
This patch includes pltcl and plpython, with the mentioned style issue fixed. Both PLs pass their scripted tests and my simple statement level trigger test.
Joe
Index: src/pl/plpython/plpython.c =================================================================== RCS file: /opt/src/cvs/pgsql-server/src/pl/plpython/plpython.c,v retrieving revision 1.38 diff -c -r1.38 plpython.c *** src/pl/plpython/plpython.c 4 Aug 2003 01:57:58 -0000 1.38 --- src/pl/plpython/plpython.c 4 Aug 2003 17:32:55 -0000 *************** *** 612,618 **** DECLARE_EXC(); TriggerData *tdata; PyObject *pltname, ! *pltevent, *pltwhen, *pltlevel, *pltrelid; --- 612,618 ---- DECLARE_EXC(); TriggerData *tdata; PyObject *pltname, ! *pltevent = NULL, *pltwhen, *pltlevel, *pltrelid; *************** *** 651,718 **** Py_DECREF(pltrelid); pfree(stroid); - - if (TRIGGER_FIRED_BEFORE(tdata->tg_event)) pltwhen = PyString_FromString("BEFORE"); else if (TRIGGER_FIRED_AFTER(tdata->tg_event)) pltwhen = PyString_FromString("AFTER"); else ! pltwhen = PyString_FromString("UNKNOWN"); PyDict_SetItemString(pltdata, "when", pltwhen); Py_DECREF(pltwhen); if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event)) pltlevel = PyString_FromString("ROW"); else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event)) pltlevel = PyString_FromString("STATEMENT"); ! else ! pltlevel = PyString_FromString("UNKNOWN"); ! PyDict_SetItemString(pltdata, "level", pltlevel); ! Py_DECREF(pltlevel); - if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) - { - pltevent = PyString_FromString("INSERT"); PyDict_SetItemString(pltdata, "old", Py_None); - pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, - tdata->tg_relation->rd_att); - PyDict_SetItemString(pltdata, "new", pytnew); - Py_DECREF(pytnew); - *rv = tdata->tg_trigtuple; - } - else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) - { - pltevent = PyString_FromString("DELETE"); PyDict_SetItemString(pltdata, "new", Py_None); ! pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, ! tdata->tg_relation->rd_att); ! PyDict_SetItemString(pltdata, "old", pytold); ! Py_DECREF(pytold); ! *rv = tdata->tg_trigtuple; ! } ! else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) ! { ! pltevent = PyString_FromString("UPDATE"); ! pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_newtuple, ! tdata->tg_relation->rd_att); ! PyDict_SetItemString(pltdata, "new", pytnew); ! Py_DECREF(pytnew); ! pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, ! tdata->tg_relation->rd_att); ! PyDict_SetItemString(pltdata, "old", pytold); ! Py_DECREF(pytold); ! *rv = tdata->tg_newtuple; } else ! { ! pltevent = PyString_FromString("UNKNOWN"); ! PyDict_SetItemString(pltdata, "old", Py_None); ! PyDict_SetItemString(pltdata, "new", Py_None); ! *rv = tdata->tg_trigtuple; ! } ! PyDict_SetItemString(pltdata, "event", pltevent); ! Py_DECREF(pltevent); if (tdata->tg_trigger->tgnargs) { --- 651,741 ---- Py_DECREF(pltrelid); pfree(stroid); if (TRIGGER_FIRED_BEFORE(tdata->tg_event)) pltwhen = PyString_FromString("BEFORE"); else if (TRIGGER_FIRED_AFTER(tdata->tg_event)) pltwhen = PyString_FromString("AFTER"); else ! /* internal error */ ! elog(ERROR, "unrecognized WHEN tg_event: %u", tdata->tg_event); PyDict_SetItemString(pltdata, "when", pltwhen); Py_DECREF(pltwhen); if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event)) + { pltlevel = PyString_FromString("ROW"); + PyDict_SetItemString(pltdata, "level", pltlevel); + Py_DECREF(pltlevel); + + if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) + { + pltevent = PyString_FromString("INSERT"); + + PyDict_SetItemString(pltdata, "old", Py_None); + pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, + tdata->tg_relation->rd_att); + PyDict_SetItemString(pltdata, "new", pytnew); + Py_DECREF(pytnew); + *rv = tdata->tg_trigtuple; + } + else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) + { + pltevent = PyString_FromString("DELETE"); + + PyDict_SetItemString(pltdata, "new", Py_None); + pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, + tdata->tg_relation->rd_att); + PyDict_SetItemString(pltdata, "old", pytold); + Py_DECREF(pytold); + *rv = tdata->tg_trigtuple; + } + else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) + { + pltevent = PyString_FromString("UPDATE"); + + pytnew = PLyDict_FromTuple(&(proc->result), tdata->tg_newtuple, + tdata->tg_relation->rd_att); + PyDict_SetItemString(pltdata, "new", pytnew); + Py_DECREF(pytnew); + pytold = PLyDict_FromTuple(&(proc->result), tdata->tg_trigtuple, + tdata->tg_relation->rd_att); + PyDict_SetItemString(pltdata, "old", pytold); + Py_DECREF(pytold); + *rv = tdata->tg_newtuple; + } + else + /* internal error */ + elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event); + + PyDict_SetItemString(pltdata, "event", pltevent); + Py_DECREF(pltevent); + } else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event)) + { pltlevel = PyString_FromString("STATEMENT"); ! PyDict_SetItemString(pltdata, "level", pltlevel); ! Py_DECREF(pltlevel); PyDict_SetItemString(pltdata, "old", Py_None); PyDict_SetItemString(pltdata, "new", Py_None); ! *rv = (HeapTuple) NULL; ! ! if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) ! pltevent = PyString_FromString("INSERT"); ! else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) ! pltevent = PyString_FromString("DELETE"); ! else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) ! pltevent = PyString_FromString("UPDATE"); ! else ! /* internal error */ ! elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event); ! ! PyDict_SetItemString(pltdata, "event", pltevent); ! Py_DECREF(pltevent); } else ! /* internal error */ ! elog(ERROR, "unrecognized LEVEL tg_event: %u", tdata->tg_event); if (tdata->tg_trigger->tgnargs) { Index: src/pl/tcl/pltcl.c =================================================================== RCS file: /opt/src/cvs/pgsql-server/src/pl/tcl/pltcl.c,v retrieving revision 1.74 diff -c -r1.74 pltcl.c *** src/pl/tcl/pltcl.c 4 Aug 2003 00:43:33 -0000 1.74 --- src/pl/tcl/pltcl.c 4 Aug 2003 17:07:24 -0000 *************** *** 708,770 **** else if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) Tcl_DStringAppendElement(&tcl_cmd, "AFTER"); else ! Tcl_DStringAppendElement(&tcl_cmd, "UNKNOWN"); /* The level part of the event for TG_level */ if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)) Tcl_DStringAppendElement(&tcl_cmd, "ROW"); else if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) Tcl_DStringAppendElement(&tcl_cmd, "STATEMENT"); - else - Tcl_DStringAppendElement(&tcl_cmd, "UNKNOWN"); ! /* Build the data list for the trigtuple */ ! pltcl_build_tuple_argument(trigdata->tg_trigtuple, ! tupdesc, &tcl_trigtup); ! ! /* ! * Now the command part of the event for TG_op and data for NEW and ! * OLD ! */ ! if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) ! { ! Tcl_DStringAppendElement(&tcl_cmd, "INSERT"); - Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); Tcl_DStringAppendElement(&tcl_cmd, ""); - - rettup = trigdata->tg_trigtuple; - } - else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) - { - Tcl_DStringAppendElement(&tcl_cmd, "DELETE"); - Tcl_DStringAppendElement(&tcl_cmd, ""); - Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); ! rettup = trigdata->tg_trigtuple; ! } ! else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) ! { ! Tcl_DStringAppendElement(&tcl_cmd, "UPDATE"); ! ! pltcl_build_tuple_argument(trigdata->tg_newtuple, ! tupdesc, &tcl_newtup); ! ! Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_newtup)); ! Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); ! ! rettup = trigdata->tg_newtuple; } else ! { ! Tcl_DStringAppendElement(&tcl_cmd, "UNKNOWN"); ! ! Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); ! Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); ! ! rettup = trigdata->tg_trigtuple; ! } memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart)); Tcl_DStringFree(&tcl_trigtup); --- 708,785 ---- else if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) Tcl_DStringAppendElement(&tcl_cmd, "AFTER"); else ! /* internal error */ ! elog(ERROR, "unrecognized WHEN tg_event: %u", trigdata->tg_event); /* The level part of the event for TG_level */ if (TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)) + { Tcl_DStringAppendElement(&tcl_cmd, "ROW"); + + /* Build the data list for the trigtuple */ + pltcl_build_tuple_argument(trigdata->tg_trigtuple, + tupdesc, &tcl_trigtup); + + /* + * Now the command part of the event for TG_op and data for NEW and + * OLD + */ + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) + { + Tcl_DStringAppendElement(&tcl_cmd, "INSERT"); + + Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); + Tcl_DStringAppendElement(&tcl_cmd, ""); + + rettup = trigdata->tg_trigtuple; + } + else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) + { + Tcl_DStringAppendElement(&tcl_cmd, "DELETE"); + + Tcl_DStringAppendElement(&tcl_cmd, ""); + Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); + + rettup = trigdata->tg_trigtuple; + } + else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + { + Tcl_DStringAppendElement(&tcl_cmd, "UPDATE"); + + pltcl_build_tuple_argument(trigdata->tg_newtuple, + tupdesc, &tcl_newtup); + + Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_newtup)); + Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup)); + + rettup = trigdata->tg_newtuple; + } + else + /* internal error */ + elog(ERROR, "unrecognized OP tg_event: %u", trigdata->tg_event); + } else if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) + { Tcl_DStringAppendElement(&tcl_cmd, "STATEMENT"); ! if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) ! Tcl_DStringAppendElement(&tcl_cmd, "INSERT"); ! else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) ! Tcl_DStringAppendElement(&tcl_cmd, "DELETE"); ! else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) ! Tcl_DStringAppendElement(&tcl_cmd, "UPDATE"); ! else ! /* internal error */ ! elog(ERROR, "unrecognized OP tg_event: %u", trigdata->tg_event); Tcl_DStringAppendElement(&tcl_cmd, ""); Tcl_DStringAppendElement(&tcl_cmd, ""); ! rettup = (HeapTuple) NULL; } else ! /* internal error */ ! elog(ERROR, "unrecognized LEVEL tg_event: %u", trigdata->tg_event); memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart)); Tcl_DStringFree(&tcl_trigtup);
---------------------------(end of broadcast)--------------------------- TIP 9: the planner will ignore your desire to choose an index scan if your joining column's datatypes do not match