Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit71d60e2

Browse files
committed
Add tg_updatedcols to TriggerData
This allows a trigger function to determine for an UPDATE triggerwhich columns were actually updated. This allows some optimizationsin generic trigger functions such as lo_manage andtsvector_update_trigger.Reviewed-by: Daniel Gustafsson <daniel@yesql.se>Discussion:https://www.postgresql.org/message-id/flat/11c5f156-67a9-0fb5-8200-2a8018eb2e0c@2ndquadrant.com
1 parent8f152b6 commit71d60e2

File tree

7 files changed

+68
-9
lines changed

7 files changed

+68
-9
lines changed

‎contrib/lo/expected/lo.out

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ SELECT lo_get(43214);
3636
\x
3737
(1 row)
3838

39+
-- test updating of unrelated column
40+
UPDATE image SET title = 'beautiful picture' WHERE title = 'beautiful image';
41+
SELECT lo_get(43214);
42+
lo_get
43+
--------
44+
\x
45+
(1 row)
46+
3947
DELETE FROM image;
4048
SELECT lo_get(43214);
4149
ERROR: large object 43214 does not exist

‎contrib/lo/lo.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ lo_manage(PG_FUNCTION_ARGS)
7474
* Here, if the value of the monitored attribute changes, then the large
7575
* object associated with the original value is unlinked.
7676
*/
77-
if (newtuple!=NULL)
77+
if (newtuple!=NULL&&
78+
bms_is_member(attnum-FirstLowInvalidHeapAttributeNumber,trigdata->tg_updatedcols))
7879
{
7980
char*orig=SPI_getvalue(trigtuple,tupdesc,attnum);
8081
char*newv=SPI_getvalue(newtuple,tupdesc,attnum);

‎contrib/lo/sql/lo.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ UPDATE image SET raster = 43214 WHERE title = 'beautiful image';
1818
SELECT lo_get(43213);
1919
SELECT lo_get(43214);
2020

21+
-- test updating of unrelated column
22+
UPDATE imageSET title='beautiful picture'WHERE title='beautiful image';
23+
24+
SELECT lo_get(43214);
25+
2126
DELETEFROM image;
2227

2328
SELECT lo_get(43214);

‎doc/src/sgml/trigger.sgml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ typedef struct TriggerData
517517
TupleTableSlot *tg_newslot;
518518
Tuplestorestate *tg_oldtable;
519519
Tuplestorestate *tg_newtable;
520+
const Bitmapset *tg_updatedcols;
520521
} TriggerData;
521522
</programlisting>
522523

@@ -759,6 +760,30 @@ typedef struct Trigger
759760
</listitem>
760761
</varlistentry>
761762

763+
<varlistentry>
764+
<term><structfield>tg_updatedcols</structfield></term>
765+
<listitem>
766+
<para>
767+
For <literal>UPDATE</literal> triggers, a bitmap set indicating the
768+
columns that were updated by the triggering command. Generic trigger
769+
functions can use this to optimize actions by not having to deal with
770+
columns that were not changed.
771+
</para>
772+
773+
<para>
774+
As an example, to determine whether a column with attribute number
775+
<varname>attnum</varname> (1-based) is a member of this bitmap set,
776+
call <literal>bms_is_member(attnum -
777+
FirstLowInvalidHeapAttributeNumber,
778+
trigdata->tg_updatedcols))</literal>.
779+
</para>
780+
781+
<para>
782+
For triggers other than <literal>UPDATE</literal> triggers, this will
783+
be <symbol>NULL</symbol>.
784+
</para>
785+
</listitem>
786+
</varlistentry>
762787
</variablelist>
763788
</para>
764789

‎src/backend/commands/trigger.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2591,6 +2591,7 @@ ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
25912591
LocTriggerData.tg_event=TRIGGER_EVENT_UPDATE |
25922592
TRIGGER_EVENT_BEFORE;
25932593
LocTriggerData.tg_relation=relinfo->ri_RelationDesc;
2594+
LocTriggerData.tg_updatedcols=updatedCols;
25942595
for (i=0;i<trigdesc->numtriggers;i++)
25952596
{
25962597
Trigger*trigger=&trigdesc->triggers[i];
@@ -2699,6 +2700,7 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
26992700
TRIGGER_EVENT_BEFORE;
27002701
LocTriggerData.tg_relation=relinfo->ri_RelationDesc;
27012702
updatedCols=GetAllUpdatedColumns(relinfo,estate);
2703+
LocTriggerData.tg_updatedcols=updatedCols;
27022704
for (i=0;i<trigdesc->numtriggers;i++)
27032705
{
27042706
Trigger*trigger=&trigdesc->triggers[i];
@@ -3255,6 +3257,7 @@ typedef struct AfterTriggerSharedData
32553257
Oidats_relid;/* the relation it's on */
32563258
CommandIdats_firing_id;/* ID for firing cycle */
32573259
structAfterTriggersTableData*ats_table;/* transition table access */
3260+
Bitmapset*ats_modifiedcols;/* modified columns */
32583261
}AfterTriggerSharedData;
32593262

32603263
typedefstructAfterTriggerEventData*AfterTriggerEvent;
@@ -3954,6 +3957,8 @@ AfterTriggerExecute(EState *estate,
39543957
LocTriggerData.tg_event=
39553958
evtshared->ats_event& (TRIGGER_EVENT_OPMASK |TRIGGER_EVENT_ROW);
39563959
LocTriggerData.tg_relation=rel;
3960+
if (TRIGGER_FOR_UPDATE(LocTriggerData.tg_trigger->tgtype))
3961+
LocTriggerData.tg_updatedcols=evtshared->ats_modifiedcols;
39573962

39583963
MemoryContextReset(per_tuple_context);
39593964

@@ -5641,6 +5646,7 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
56415646
new_shared.ats_table=transition_capture->tcs_private;
56425647
else
56435648
new_shared.ats_table=NULL;
5649+
new_shared.ats_modifiedcols=modifiedCols;
56445650

56455651
afterTriggerAddEvent(&afterTriggers.query_stack[afterTriggers.query_depth].events,
56465652
&new_event,&new_shared);

‎src/backend/utils/adt/tsvector_op.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,6 +2416,7 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column)
24162416
boolisnull;
24172417
text*txt;
24182418
OidcfgId;
2419+
boolupdate_needed;
24192420

24202421
/* Check call context */
24212422
if (!CALLED_AS_TRIGGER(fcinfo))/* internal error */
@@ -2428,9 +2429,15 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column)
24282429
elog(ERROR,"tsvector_update_trigger: must be fired BEFORE event");
24292430

24302431
if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
2432+
{
24312433
rettuple=trigdata->tg_trigtuple;
2434+
update_needed= true;
2435+
}
24322436
elseif (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
2437+
{
24332438
rettuple=trigdata->tg_newtuple;
2439+
update_needed= false;/* computed below */
2440+
}
24342441
else
24352442
elog(ERROR,"tsvector_update_trigger: must be fired for INSERT or UPDATE");
24362443

@@ -2518,6 +2525,9 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column)
25182525
errmsg("column \"%s\" is not of a character type",
25192526
trigger->tgargs[i])));
25202527

2528+
if (bms_is_member(numattr-FirstLowInvalidHeapAttributeNumber,trigdata->tg_updatedcols))
2529+
update_needed= true;
2530+
25212531
datum=SPI_getbinval(rettuple,rel->rd_att,numattr,&isnull);
25222532
if (isnull)
25232533
continue;
@@ -2530,16 +2540,19 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column)
25302540
pfree(txt);
25312541
}
25322542

2533-
/* make tsvector value */
2534-
datum=TSVectorGetDatum(make_tsvector(&prs));
2535-
isnull= false;
2543+
if (update_needed)
2544+
{
2545+
/* make tsvector value */
2546+
datum=TSVectorGetDatum(make_tsvector(&prs));
2547+
isnull= false;
25362548

2537-
/* and insert it into tuple */
2538-
rettuple=heap_modify_tuple_by_cols(rettuple,rel->rd_att,
2539-
1,&tsvector_attr_num,
2540-
&datum,&isnull);
2549+
/* and insert it into tuple */
2550+
rettuple=heap_modify_tuple_by_cols(rettuple,rel->rd_att,
2551+
1,&tsvector_attr_num,
2552+
&datum,&isnull);
25412553

2542-
pfree(DatumGetPointer(datum));
2554+
pfree(DatumGetPointer(datum));
2555+
}
25432556

25442557
returnPointerGetDatum(rettuple);
25452558
}

‎src/include/commands/trigger.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ typedef struct TriggerData
3939
TupleTableSlot*tg_newslot;
4040
Tuplestorestate*tg_oldtable;
4141
Tuplestorestate*tg_newtable;
42+
constBitmapset*tg_updatedcols;
4243
}TriggerData;
4344

4445
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp