aboutsummaryrefslogtreecommitdiffstats
path: root/sql/serenitas.c
diff options
context:
space:
mode:
Diffstat (limited to 'sql/serenitas.c')
-rw-r--r--sql/serenitas.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/sql/serenitas.c b/sql/serenitas.c
index 22e7f855..34511722 100644
--- a/sql/serenitas.c
+++ b/sql/serenitas.c
@@ -251,3 +251,100 @@ Datum upfront_from_level(PG_FUNCTION_ARGS) {
upfront = calc(TDate_from_DateADT(trade_date), issue_date, TDate_from_DateADT(maturity), recovery, coupon / 10000.0, cal_from_currency(currency), curve, traded_level, true);
PG_RETURN_FLOAT8(upfront);
}
+
+
+PG_FUNCTION_INFO_V1(update_attach);
+
+Datum
+update_attach(PG_FUNCTION_ARGS)
+{
+ TriggerData *trigdata = (TriggerData *) fcinfo->context;
+ Trigger *trigger; /* to get trigger name */
+ int nargs; /* # of arguments */
+ char *relname; /* triggered relation name */
+ Relation rel; /* triggered relation */
+ HeapTuple rettuple = NULL;
+ TupleDesc tupdesc; /* tuple description */
+ bool isnull;
+ if (!CALLED_AS_TRIGGER(fcinfo))
+ /* internal error */
+ elog(ERROR, "not fired by trigger manager");
+ if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
+ /* internal error */
+ elog(ERROR, "must be fired for row");
+ if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
+ /* internal error */
+ elog(ERROR, "must be fired before event");
+
+ if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
+ rettuple = trigdata->tg_trigtuple;
+ else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
+ rettuple = trigdata->tg_newtuple;
+ else
+ /* internal error */
+ elog(ERROR, "cannot process DELETE events");
+
+ rel = trigdata->tg_relation;
+
+ if (rettuple)
+ relname = SPI_getrelname(rel);
+
+ trigger = trigdata->tg_trigger;
+ tupdesc = rel->rd_att;
+ /* int attname = SPI_fnumer(tupdesc, "traded_level"); */
+ /* Oid traded_level = DatumGetObjectId(SPI_getbinval(rettuple, tupdesc, SPI_fnumber(tupdesc, "traded_level"), &isnull)); */
+ int16 orig_attach, orig_detach;
+ orig_attach = DatumGetInt16(SPI_getbinval(rettuple, tupdesc, SPI_fnumber(tupdesc, "orig_attach"), &isnull));
+
+ if (isnull)
+ return PointerGetDatum(rettuple);
+ else
+ orig_detach = DatumGetInt16(SPI_getbinval(rettuple, tupdesc, SPI_fnumber(tupdesc, "orig_detach"), &isnull));
+ char* sql_query = "SELECT indexfactor/100, cumulativeloss "
+ "FROM index_factors "
+ "WHERE redindexcode=$1";
+ uint64 proc;
+ Oid argtypes[1] = {TEXTOID};
+ char nulls[1] = " ";
+ Datum values[1];
+ int ret;
+ values[0] = SPI_getbinval(rettuple, tupdesc, SPI_fnumber(tupdesc, "security_desc"), &isnull);
+
+ if (SPI_connect() == SPI_ERROR_CONNECT) {
+ elog(ERROR, "something wrong happened");
+ }
+ ret = SPI_execute_with_args(sql_query, nargs, argtypes, values, nulls, true, 1);
+ proc = SPI_processed;
+ double factor, cumloss;
+ if (ret == SPI_OK_SELECT && SPI_tuptable != NULL) {
+ SPITupleTable *tuptable = SPI_tuptable;
+ TupleDesc tupdesc = tuptable->tupdesc;
+ bool isnull;
+ HeapTuple tuple = tuptable->vals[0];
+ factor = DatumGetFloat8(SPI_getbinval(tuple, tupdesc, 4, &isnull));
+ cumloss = DatumGetFloat8(SPI_getbinval(tuple, tupdesc, 5, &isnull));
+ elog(INFO, "%f %f", factor, cumloss);
+ } else {
+ elog(ERROR, "something wrong happened");
+ }
+ SPI_finish();
+ double detach, attach;
+ detach = factor * Min(Max((orig_detach - cumloss) / factor, 0.0), 1.0);
+ if (isnull)
+ attach = 0;
+ else
+ attach = factor * Min(Max((orig_attach - cumloss) / factor, 0.0), 1.0);
+ int chnattrs = 2;
+ int chattrs[2];
+ Datum newvals[2];
+ bool newnulls[2] = {false, false};
+ chattrs[0] = SPI_fnumber(tupdesc, "attach");
+ chattrs[1] = SPI_fnumber(tupdesc, "detach");
+ newvals[0] = Float8GetDatum(attach);
+ newvals[1] = Float8GetDatum(detach);
+
+ rettuple = heap_modify_tuple_by_cols(rettuple, tupdesc,
+ chnattrs, chattrs,
+ newvals, newnulls);
+ return PointerGetDatum(rettuple);
+}