diff options
Diffstat (limited to 'sql/serenitas.c')
| -rw-r--r-- | sql/serenitas.c | 97 |
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); +} |
