From 71d60e2aa05157efec28393b15c0b0b9fc1b210c Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 9 Mar 2020 09:22:22 +0100 Subject: Add tg_updatedcols to TriggerData This allows a trigger function to determine for an UPDATE trigger which columns were actually updated. This allows some optimizations in generic trigger functions such as lo_manage and tsvector_update_trigger. Reviewed-by: Daniel Gustafsson Discussion: https://www.postgresql.org/message-id/flat/11c5f156-67a9-0fb5-8200-2a8018eb2e0c@2ndquadrant.com --- src/backend/utils/adt/tsvector_op.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'src/backend/utils/adt/tsvector_op.c') diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c index 790355082d9..108dd998c7a 100644 --- a/src/backend/utils/adt/tsvector_op.c +++ b/src/backend/utils/adt/tsvector_op.c @@ -2416,6 +2416,7 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column) bool isnull; text *txt; Oid cfgId; + bool update_needed; /* Check call context */ if (!CALLED_AS_TRIGGER(fcinfo)) /* internal error */ @@ -2428,9 +2429,15 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column) elog(ERROR, "tsvector_update_trigger: must be fired BEFORE event"); if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) + { rettuple = trigdata->tg_trigtuple; + update_needed = true; + } else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + { rettuple = trigdata->tg_newtuple; + update_needed = false; /* computed below */ + } else elog(ERROR, "tsvector_update_trigger: must be fired for INSERT or UPDATE"); @@ -2518,6 +2525,9 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column) errmsg("column \"%s\" is not of a character type", trigger->tgargs[i]))); + if (bms_is_member(numattr - FirstLowInvalidHeapAttributeNumber, trigdata->tg_updatedcols)) + update_needed = true; + datum = SPI_getbinval(rettuple, rel->rd_att, numattr, &isnull); if (isnull) continue; @@ -2530,16 +2540,19 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column) pfree(txt); } - /* make tsvector value */ - datum = TSVectorGetDatum(make_tsvector(&prs)); - isnull = false; + if (update_needed) + { + /* make tsvector value */ + datum = TSVectorGetDatum(make_tsvector(&prs)); + isnull = false; - /* and insert it into tuple */ - rettuple = heap_modify_tuple_by_cols(rettuple, rel->rd_att, - 1, &tsvector_attr_num, - &datum, &isnull); + /* and insert it into tuple */ + rettuple = heap_modify_tuple_by_cols(rettuple, rel->rd_att, + 1, &tsvector_attr_num, + &datum, &isnull); - pfree(DatumGetPointer(datum)); + pfree(DatumGetPointer(datum)); + } return PointerGetDatum(rettuple); } -- cgit v1.2.3