summaryrefslogtreecommitdiff
path: root/src/pl/tcl/pltcl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl/tcl/pltcl.c')
-rw-r--r--src/pl/tcl/pltcl.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 76c9afc339..1362ca51d1 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -324,7 +324,7 @@ static void pltcl_subtrans_abort(Tcl_Interp *interp,
static void pltcl_set_tuple_values(Tcl_Interp *interp, const char *arrayname,
uint64 tupno, HeapTuple tuple, TupleDesc tupdesc);
-static Tcl_Obj *pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc);
+static Tcl_Obj *pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, bool include_generated);
static HeapTuple pltcl_build_tuple_result(Tcl_Interp *interp,
Tcl_Obj **kvObjv, int kvObjc,
pltcl_call_state *call_state);
@@ -889,7 +889,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state,
tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
tmptup.t_data = td;
- list_tmp = pltcl_build_tuple_argument(&tmptup, tupdesc);
+ list_tmp = pltcl_build_tuple_argument(&tmptup, tupdesc, true);
Tcl_ListObjAppendElement(NULL, tcl_cmd, list_tmp);
ReleaseTupleDesc(tupdesc);
@@ -1060,7 +1060,6 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state,
volatile HeapTuple rettup;
Tcl_Obj *tcl_cmd;
Tcl_Obj *tcl_trigtup;
- Tcl_Obj *tcl_newtup;
int tcl_rc;
int i;
const char *result;
@@ -1162,20 +1161,22 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state,
Tcl_ListObjAppendElement(NULL, tcl_cmd,
Tcl_NewStringObj("ROW", -1));
- /* Build the data list for the trigtuple */
- tcl_trigtup = pltcl_build_tuple_argument(trigdata->tg_trigtuple,
- tupdesc);
-
/*
* Now the command part of the event for TG_op and data for NEW
* and OLD
+ *
+ * Note: In BEFORE trigger, stored generated columns are not computed yet,
+ * so don't make them accessible in NEW row.
*/
if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
{
Tcl_ListObjAppendElement(NULL, tcl_cmd,
Tcl_NewStringObj("INSERT", -1));
- Tcl_ListObjAppendElement(NULL, tcl_cmd, tcl_trigtup);
+ Tcl_ListObjAppendElement(NULL, tcl_cmd,
+ pltcl_build_tuple_argument(trigdata->tg_trigtuple,
+ tupdesc,
+ !TRIGGER_FIRED_BEFORE(trigdata->tg_event)));
Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewObj());
rettup = trigdata->tg_trigtuple;
@@ -1186,7 +1187,10 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state,
Tcl_NewStringObj("DELETE", -1));
Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewObj());
- Tcl_ListObjAppendElement(NULL, tcl_cmd, tcl_trigtup);
+ Tcl_ListObjAppendElement(NULL, tcl_cmd,
+ pltcl_build_tuple_argument(trigdata->tg_trigtuple,
+ tupdesc,
+ true));
rettup = trigdata->tg_trigtuple;
}
@@ -1195,11 +1199,14 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state,
Tcl_ListObjAppendElement(NULL, tcl_cmd,
Tcl_NewStringObj("UPDATE", -1));
- tcl_newtup = pltcl_build_tuple_argument(trigdata->tg_newtuple,
- tupdesc);
-
- Tcl_ListObjAppendElement(NULL, tcl_cmd, tcl_newtup);
- Tcl_ListObjAppendElement(NULL, tcl_cmd, tcl_trigtup);
+ Tcl_ListObjAppendElement(NULL, tcl_cmd,
+ pltcl_build_tuple_argument(trigdata->tg_newtuple,
+ tupdesc,
+ !TRIGGER_FIRED_BEFORE(trigdata->tg_event)));
+ Tcl_ListObjAppendElement(NULL, tcl_cmd,
+ pltcl_build_tuple_argument(trigdata->tg_trigtuple,
+ tupdesc,
+ true));
rettup = trigdata->tg_newtuple;
}
@@ -3091,7 +3098,7 @@ pltcl_set_tuple_values(Tcl_Interp *interp, const char *arrayname,
* from all attributes of a given tuple
**********************************************************************/
static Tcl_Obj *
-pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
+pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, bool include_generated)
{
Tcl_Obj *retobj = Tcl_NewObj();
int i;
@@ -3110,6 +3117,13 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
if (att->attisdropped)
continue;
+ if (att->attgenerated)
+ {
+ /* don't include unless requested */
+ if (!include_generated)
+ continue;
+ }
+
/************************************************************
* Get the attribute name
************************************************************/
@@ -3219,6 +3233,12 @@ pltcl_build_tuple_result(Tcl_Interp *interp, Tcl_Obj **kvObjv, int kvObjc,
errmsg("cannot set system attribute \"%s\"",
fieldName)));
+ if (TupleDescAttr(tupdesc, attn - 1)->attgenerated)
+ ereport(ERROR,
+ (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
+ errmsg("cannot set generated column \"%s\"",
+ fieldName)));
+
values[attn - 1] = utf_u2e(Tcl_GetString(kvObjv[i + 1]));
}