50 #include "utils/fmgroids.h"
71 const char *expected_name);
73 Oid parentTriggerOid,
const char *newname,
74 const char *expected_name);
97 int event,
bool row_trigger,
101 bool is_crosspart_update);
159 Oid relOid,
Oid refRelOid,
Oid constraintOid,
Oid indexOid,
160 Oid funcoid,
Oid parentTriggerOid,
Node *whenClause,
161 bool isInternal,
bool in_partition)
165 constraintOid, indexOid, funcoid,
166 parentTriggerOid, whenClause, isInternal,
176 Oid relOid,
Oid refRelOid,
Oid constraintOid,
177 Oid indexOid,
Oid funcoid,
Oid parentTriggerOid,
178 Node *whenClause,
bool isInternal,
bool in_partition,
179 char trigger_fires_when)
188 bool nulls[Natts_pg_trigger];
201 char *oldtablename = NULL;
202 char *newtablename = NULL;
203 bool partition_recurse;
204 bool trigger_exists =
false;
206 bool existing_isInternal =
false;
207 bool existing_isClone =
false;
218 if (rel->
rd_rel->relkind == RELKIND_RELATION)
221 if (
stmt->timing != TRIGGER_TYPE_BEFORE &&
222 stmt->timing != TRIGGER_TYPE_AFTER)
224 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
225 errmsg(
"\"%s\" is a table",
227 errdetail(
"Tables cannot have INSTEAD OF triggers.")));
229 else if (rel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
232 if (
stmt->timing != TRIGGER_TYPE_BEFORE &&
233 stmt->timing != TRIGGER_TYPE_AFTER)
235 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
236 errmsg(
"\"%s\" is a table",
238 errdetail(
"Tables cannot have INSTEAD OF triggers.")));
256 if (
stmt->transitionRels !=
NIL)
258 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
259 errmsg(
"\"%s\" is a partitioned table",
261 errdetail(
"ROW triggers with transition tables are not supported on partitioned tables.")));
264 else if (rel->
rd_rel->relkind == RELKIND_VIEW)
270 if (
stmt->timing != TRIGGER_TYPE_INSTEAD &&
stmt->row)
272 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
273 errmsg(
"\"%s\" is a view",
275 errdetail(
"Views cannot have row-level BEFORE or AFTER triggers.")));
277 if (TRIGGER_FOR_TRUNCATE(
stmt->events))
279 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
280 errmsg(
"\"%s\" is a view",
282 errdetail(
"Views cannot have TRUNCATE triggers.")));
284 else if (rel->
rd_rel->relkind == RELKIND_FOREIGN_TABLE)
286 if (
stmt->timing != TRIGGER_TYPE_BEFORE &&
287 stmt->timing != TRIGGER_TYPE_AFTER)
289 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
290 errmsg(
"\"%s\" is a foreign table",
292 errdetail(
"Foreign tables cannot have INSTEAD OF triggers.")));
299 if (
stmt->isconstraint)
301 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
302 errmsg(
"\"%s\" is a foreign table",
304 errdetail(
"Foreign tables cannot have constraint triggers.")));
308 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
309 errmsg(
"relation \"%s\" cannot have triggers",
315 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
316 errmsg(
"permission denied: \"%s\" is a system catalog",
319 if (
stmt->isconstraint)
331 constrrelid = refRelOid;
333 else if (
stmt->constrrel != NULL)
363 partition_recurse = !isInternal &&
stmt->row &&
364 rel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE;
365 if (partition_recurse)
370 TRIGGER_CLEAR_TYPE(tgtype);
372 TRIGGER_SETT_ROW(tgtype);
373 tgtype |=
stmt->timing;
374 tgtype |=
stmt->events;
377 if (TRIGGER_FOR_ROW(tgtype) && TRIGGER_FOR_TRUNCATE(tgtype))
379 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
380 errmsg(
"TRUNCATE FOR EACH ROW triggers are not supported")));
383 if (TRIGGER_FOR_INSTEAD(tgtype))
385 if (!TRIGGER_FOR_ROW(tgtype))
387 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
388 errmsg(
"INSTEAD OF triggers must be FOR EACH ROW")));
389 if (
stmt->whenClause)
391 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
392 errmsg(
"INSTEAD OF triggers cannot have WHEN conditions")));
395 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
396 errmsg(
"INSTEAD OF triggers cannot have column lists")));
413 if (
stmt->transitionRels !=
NIL)
415 List *varList =
stmt->transitionRels;
424 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
425 errmsg(
"ROW variable naming in the REFERENCING clause is not supported"),
426 errhint(
"Use OLD TABLE or NEW TABLE for naming transition tables.")));
434 if (rel->
rd_rel->relkind == RELKIND_FOREIGN_TABLE)
436 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
437 errmsg(
"\"%s\" is a foreign table",
439 errdetail(
"Triggers on foreign tables cannot have transition tables.")));
441 if (rel->
rd_rel->relkind == RELKIND_VIEW)
443 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
444 errmsg(
"\"%s\" is a view",
446 errdetail(
"Triggers on views cannot have transition tables.")));
459 if (rel->
rd_rel->relispartition)
461 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
462 errmsg(
"ROW triggers with transition tables are not supported on partitions")));
465 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
466 errmsg(
"ROW triggers with transition tables are not supported on inheritance children")));
469 if (
stmt->timing != TRIGGER_TYPE_AFTER)
471 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
472 errmsg(
"transition table name can only be specified for an AFTER trigger")));
474 if (TRIGGER_FOR_TRUNCATE(tgtype))
476 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
477 errmsg(
"TRUNCATE triggers with transition tables are not supported")));
489 if (((TRIGGER_FOR_INSERT(tgtype) ? 1 : 0) +
490 (TRIGGER_FOR_UPDATE(tgtype) ? 1 : 0) +
491 (TRIGGER_FOR_DELETE(tgtype) ? 1 : 0)) != 1)
493 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
494 errmsg(
"transition tables cannot be specified for triggers with more than one event")));
504 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
505 errmsg(
"transition tables cannot be specified for triggers with column lists")));
518 if (!(TRIGGER_FOR_INSERT(tgtype) ||
519 TRIGGER_FOR_UPDATE(tgtype)))
521 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
522 errmsg(
"NEW TABLE can only be specified for an INSERT or UPDATE trigger")));
524 if (newtablename != NULL)
526 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
527 errmsg(
"NEW TABLE cannot be specified multiple times")));
529 newtablename = tt->
name;
533 if (!(TRIGGER_FOR_DELETE(tgtype) ||
534 TRIGGER_FOR_UPDATE(tgtype)))
536 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
537 errmsg(
"OLD TABLE can only be specified for a DELETE or UPDATE trigger")));
539 if (oldtablename != NULL)
541 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
542 errmsg(
"OLD TABLE cannot be specified multiple times")));
544 oldtablename = tt->
name;
548 if (newtablename != NULL && oldtablename != NULL &&
549 strcmp(newtablename, oldtablename) == 0)
551 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
552 errmsg(
"OLD TABLE name and NEW TABLE name cannot be the same")));
563 if (!whenClause &&
stmt->whenClause)
613 if (!TRIGGER_FOR_ROW(tgtype))
615 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
616 errmsg(
"statement trigger's WHEN condition cannot reference column values"),
618 if (TRIGGER_FOR_INSERT(tgtype))
620 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
621 errmsg(
"INSERT trigger's WHEN condition cannot reference OLD values"),
626 if (!TRIGGER_FOR_ROW(tgtype))
628 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
629 errmsg(
"statement trigger's WHEN condition cannot reference column values"),
631 if (TRIGGER_FOR_DELETE(tgtype))
633 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
634 errmsg(
"DELETE trigger's WHEN condition cannot reference NEW values"),
636 if (var->
varattno < 0 && TRIGGER_FOR_BEFORE(tgtype))
638 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
639 errmsg(
"BEFORE trigger's WHEN condition cannot reference NEW system columns"),
641 if (TRIGGER_FOR_BEFORE(tgtype) &&
646 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
647 errmsg(
"BEFORE trigger's WHEN condition cannot reference NEW generated columns"),
648 errdetail(
"A whole-row reference is used and the table contains generated columns."),
650 if (TRIGGER_FOR_BEFORE(tgtype) &&
654 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
655 errmsg(
"BEFORE trigger's WHEN condition cannot reference NEW generated columns"),
656 errdetail(
"Column \"%s\" is a generated column.",
662 elog(
ERROR,
"trigger WHEN condition cannot contain references to other relations");
674 else if (!whenClause)
699 if (funcrettype != TRIGGEROID)
701 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
702 errmsg(
"function %s must return type %s",
720 Anum_pg_trigger_tgrelid,
725 Anum_pg_trigger_tgname,
737 trigoid = oldtrigger->oid;
738 existing_constraint_oid = oldtrigger->tgconstraint;
739 existing_isInternal = oldtrigger->tgisinternal;
740 existing_isClone =
OidIsValid(oldtrigger->tgparentid);
741 trigger_exists =
true;
752 Anum_pg_trigger_oid);
763 errmsg(
"trigger \"%s\" for relation \"%s\" already exists",
772 if ((existing_isInternal || existing_isClone) &&
773 !isInternal && !in_partition)
776 errmsg(
"trigger \"%s\" for relation \"%s\" is an internal or a child trigger",
795 errmsg(
"trigger \"%s\" for relation \"%s\" is a constraint trigger",
848 snprintf(internaltrigname,
sizeof(internaltrigname),
849 "%s_%u",
stmt->trigname, trigoid);
850 trigname = internaltrigname;
855 trigname =
stmt->trigname;
861 memset(nulls,
false,
sizeof(nulls));
870 values[Anum_pg_trigger_tgenabled - 1] = trigger_fires_when;
885 foreach(le,
stmt->args)
889 len += strlen(ar) + 4;
898 foreach(le,
stmt->args)
932 foreach(cell,
stmt->columns)
942 (
errcode(ERRCODE_UNDEFINED_COLUMN),
943 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
947 for (
j =
i - 1;
j >= 0;
j--)
951 (
errcode(ERRCODE_DUPLICATE_COLUMN),
952 errmsg(
"column \"%s\" specified more than once",
966 nulls[Anum_pg_trigger_tgqual - 1] =
true;
972 nulls[Anum_pg_trigger_tgoldtable - 1] =
true;
977 nulls[Anum_pg_trigger_tgnewtable - 1] =
true;
1015 elog(
ERROR,
"cache lookup failed for relation %u",
1042 myself.
classId = TriggerRelationId;
1046 referenced.
classId = ProcedureRelationId;
1059 referenced.
classId = ConstraintRelationId;
1060 referenced.
objectId = constraintOid;
1071 referenced.
classId = RelationRelationId;
1078 referenced.
classId = RelationRelationId;
1092 referenced.
classId = ConstraintRelationId;
1093 referenced.
objectId = constraintOid;
1111 if (columns != NULL)
1115 referenced.
classId = RelationRelationId;
1117 for (
i = 0;
i < ncolumns;
i++)
1128 if (whenRtable !=
NIL)
1139 if (partition_recurse)
1186 partdesc->
oids[
i], refRelOid,
1188 funcoid, trigoid, qual,
1189 isInternal,
true, trigger_fires_when);
1233 Anum_pg_trigger_oid,
1242 elog(
ERROR,
"could not find tuple for trigger %u", childTrigId);
1249 elog(
ERROR,
"trigger %u already has a parent trigger",
1252 trigForm->tgparentid = parentTrigId;
1302 Anum_pg_trigger_oid,
1311 elog(
ERROR,
"could not find tuple for trigger %u", trigOid);
1320 if (rel->
rd_rel->relkind != RELKIND_RELATION &&
1321 rel->
rd_rel->relkind != RELKIND_VIEW &&
1322 rel->
rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
1323 rel->
rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1325 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1326 errmsg(
"relation \"%s\" cannot have triggers",
1332 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1333 errmsg(
"permission denied: \"%s\" is a system catalog",
1380 Anum_pg_trigger_tgrelid,
1384 Anum_pg_trigger_tgname,
1397 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1398 errmsg(
"trigger \"%s\" for table \"%s\" does not exist",
1428 if (form->relkind != RELKIND_RELATION && form->relkind != RELKIND_VIEW &&
1429 form->relkind != RELKIND_FOREIGN_TABLE &&
1430 form->relkind != RELKIND_PARTITIONED_TABLE)
1432 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
1433 errmsg(
"relation \"%s\" cannot have triggers",
1442 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1443 errmsg(
"permission denied: \"%s\" is a system catalog",
1490 if (targetrel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1499 Anum_pg_trigger_tgrelid,
1503 Anum_pg_trigger_tgname,
1513 tgoid = trigform->oid;
1523 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1524 errmsg(
"cannot rename trigger \"%s\" on table \"%s\"",
1526 errhint(
"Rename the trigger on the partitioned table \"%s\" instead.",
1535 if (targetrel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1539 for (
int i = 0;
i < partdesc->
nparts;
i++)
1541 Oid partitionId = partdesc->
oids[
i];
1551 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1552 errmsg(
"trigger \"%s\" for table \"%s\" does not exist",
1579 const char *newname,
const char *expected_name)
1588 if (strcmp(
NameStr(tgform->tgname), newname) == 0)
1597 Anum_pg_trigger_tgrelid,
1601 Anum_pg_trigger_tgname,
1609 errmsg(
"trigger \"%s\" for relation \"%s\" already exists",
1624 if (strcmp(
NameStr(tgform->tgname), expected_name) != 0)
1626 errmsg(
"renamed trigger \"%s\" on relation \"%s\"",
1650 const char *newname,
const char *expected_name)
1662 Anum_pg_trigger_tgrelid,
1672 if (tgform->tgparentid != parentTriggerOid)
1681 if (partitionRel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1686 for (
int i = 0;
i < partdesc->
nparts;
i++)
1723 char fires_when,
bool skip_system,
bool recurse,
1738 Anum_pg_trigger_tgrelid,
1744 Anum_pg_trigger_tgname,
1755 found = changed =
false;
1761 if (
OidIsValid(tgparent) && tgparent != oldtrig->tgparentid)
1764 if (oldtrig->tgisinternal)
1771 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1772 errmsg(
"permission denied: \"%s\" is a system trigger",
1778 if (oldtrig->tgenabled != fires_when)
1784 newtrig->tgenabled = fires_when;
1803 rel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE &&
1804 (TRIGGER_FOR_ROW(oldtrig->tgtype)))
1816 fires_when, skip_system, recurse,
1830 if (tgname && !found)
1832 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1833 errmsg(
"trigger \"%s\" for table \"%s\" does not exist",
1885 Anum_pg_trigger_tgrelid,
1900 if (numtrigs >= maxtrigs)
1905 build = &(triggers[numtrigs]);
1907 build->
tgoid = pg_trigger->oid;
1910 build->
tgfoid = pg_trigger->tgfoid;
1911 build->
tgtype = pg_trigger->tgtype;
1912 build->
tgenabled = pg_trigger->tgenabled;
1920 build->
tgnargs = pg_trigger->tgnargs;
1922 build->
tgnattr = pg_trigger->tgattr.dim1;
1926 memcpy(build->
tgattr, &(pg_trigger->tgattr.values),
1937 Anum_pg_trigger_tgargs,
1938 tgrel->
rd_att, &isnull));
1940 elog(
ERROR,
"tgargs is null in trigger for relation \"%s\"",
1953 datum =
fastgetattr(htup, Anum_pg_trigger_tgoldtable,
1961 datum =
fastgetattr(htup, Anum_pg_trigger_tgnewtable,
1993 for (
i = 0;
i < numtrigs;
i++)
2014 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2015 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSERT);
2017 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2018 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_INSERT);
2020 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2021 TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_INSERT);
2023 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2024 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_INSERT);
2026 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2027 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_INSERT);
2029 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2030 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_UPDATE);
2032 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2033 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_UPDATE);
2035 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2036 TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_UPDATE);
2038 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2039 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_UPDATE);
2041 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2042 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_UPDATE);
2044 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2045 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_DELETE);
2047 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2048 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_DELETE);
2050 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_ROW,
2051 TRIGGER_TYPE_INSTEAD, TRIGGER_TYPE_DELETE);
2053 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2054 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_DELETE);
2056 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2057 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_DELETE);
2060 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2061 TRIGGER_TYPE_BEFORE, TRIGGER_TYPE_TRUNCATE);
2063 TRIGGER_TYPE_MATCHES(tgtype, TRIGGER_TYPE_STATEMENT,
2064 TRIGGER_TYPE_AFTER, TRIGGER_TYPE_TRUNCATE);
2067 (TRIGGER_FOR_INSERT(tgtype) &&
2068 TRIGGER_USES_TRANSITION_TABLE(trigger->
tgnewtable));
2070 (TRIGGER_FOR_UPDATE(tgtype) &&
2071 TRIGGER_USES_TRANSITION_TABLE(trigger->
tgoldtable));
2073 (TRIGGER_FOR_UPDATE(tgtype) &&
2074 TRIGGER_USES_TRANSITION_TABLE(trigger->
tgnewtable));
2076 (TRIGGER_FOR_DELETE(tgtype) &&
2077 TRIGGER_USES_TRANSITION_TABLE(trigger->
tgoldtable));
2092 if (trigdesc == NULL || trigdesc->
numtriggers <= 0)
2099 memcpy(trigger, trigdesc->
triggers,
2111 memcpy(newattr, trigger->
tgattr,
2113 trigger->
tgattr = newattr;
2120 newargs = (
char **)
palloc(trigger->
tgnargs *
sizeof(
char *));
2123 trigger->
tgargs = newargs;
2146 if (trigdesc == NULL)
2157 while (--(trigger->
tgnargs) >= 0)
2195 if (trigdesc1 != NULL)
2197 if (trigdesc2 == NULL)
2243 else if (trig1->
tgqual == NULL || trig2->
tgqual == NULL)
2261 else if (trigdesc2 != NULL)
2275 if (trigdesc != NULL)
2380 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2381 errmsg(
"trigger function %u returned null value",
2382 fcinfo->flinfo->fn_oid)));
2403 if (trigdesc == NULL)
2413 LocTriggerData.
type = T_TriggerData;
2422 if (!TRIGGER_TYPE_MATCHES(trigger->
tgtype,
2423 TRIGGER_TYPE_STATEMENT,
2424 TRIGGER_TYPE_BEFORE,
2425 TRIGGER_TYPE_INSERT))
2440 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2441 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
2454 false, NULL, NULL,
NIL, NULL, transition_capture,
2468 LocTriggerData.
type = T_TriggerData;
2478 if (!TRIGGER_TYPE_MATCHES(trigger->
tgtype,
2480 TRIGGER_TYPE_BEFORE,
2481 TRIGGER_TYPE_INSERT))
2498 if (newtuple == NULL)
2504 else if (newtuple != oldtuple)
2516 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2517 errmsg(
"moving row to another partition during a BEFORE FOR EACH ROW trigger is not supported"),
2518 errdetail(
"Before executing trigger \"%s\", the row was to be in partition \"%s.%s\".",
2546 recheckIndexes, NULL,
2561 LocTriggerData.
type = T_TriggerData;
2571 if (!TRIGGER_TYPE_MATCHES(trigger->
tgtype,
2573 TRIGGER_TYPE_INSTEAD,
2574 TRIGGER_TYPE_INSERT))
2591 if (newtuple == NULL)
2597 else if (newtuple != oldtuple)
2621 if (trigdesc == NULL)
2631 LocTriggerData.
type = T_TriggerData;
2640 if (!TRIGGER_TYPE_MATCHES(trigger->
tgtype,
2641 TRIGGER_TYPE_STATEMENT,
2642 TRIGGER_TYPE_BEFORE,
2643 TRIGGER_TYPE_DELETE))
2658 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2659 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
2672 false, NULL, NULL,
NIL, NULL, transition_capture,
2697 bool should_free =
false;
2701 if (fdw_trigtuple == NULL)
2715 if (epqslot_candidate != NULL && epqslot != NULL)
2717 *epqslot = epqslot_candidate;
2725 trigtuple = fdw_trigtuple;
2729 LocTriggerData.
type = T_TriggerData;
2739 if (!TRIGGER_TYPE_MATCHES(trigger->
tgtype,
2741 TRIGGER_TYPE_BEFORE,
2742 TRIGGER_TYPE_DELETE))
2756 if (newtuple == NULL)
2761 if (newtuple != trigtuple)
2780 bool is_crosspart_update)
2790 if (fdw_trigtuple == NULL)
2805 true, slot, NULL,
NIL, NULL,
2807 is_crosspart_update);
2820 LocTriggerData.
type = T_TriggerData;
2833 if (!TRIGGER_TYPE_MATCHES(trigger->
tgtype,
2835 TRIGGER_TYPE_INSTEAD,
2836 TRIGGER_TYPE_DELETE))
2850 if (rettuple == NULL)
2852 if (rettuple != trigtuple)
2868 if (trigdesc == NULL)
2883 LocTriggerData.
type = T_TriggerData;
2893 if (!TRIGGER_TYPE_MATCHES(trigger->
tgtype,
2894 TRIGGER_TYPE_STATEMENT,
2895 TRIGGER_TYPE_BEFORE,
2896 TRIGGER_TYPE_UPDATE))
2899 updatedCols, NULL, NULL))
2911 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2912 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
2928 false, NULL, NULL,
NIL,
2947 bool should_free_trig =
false;
2948 bool should_free_new =
false;
2958 if (fdw_trigtuple == NULL)
2964 lockmode, oldslot, &epqslot_candidate,
2977 if (epqslot_candidate != NULL)
2990 if (
unlikely(newslot != epqslot_clean))
3015 trigtuple = fdw_trigtuple;
3018 LocTriggerData.
type = T_TriggerData;
3030 if (!TRIGGER_TYPE_MATCHES(trigger->
tgtype,
3032 TRIGGER_TYPE_BEFORE,
3033 TRIGGER_TYPE_UPDATE))
3036 updatedCols, oldslot, newslot))
3053 if (newtuple == NULL)
3055 if (should_free_trig)
3057 if (should_free_new)
3061 else if (newtuple != oldtuple)
3071 if (should_free_trig && newtuple == trigtuple)
3074 if (should_free_new)
3081 if (should_free_trig)
3104 List *recheckIndexes,
3106 bool is_crosspart_update)
3111 (transition_capture &&
3124 Assert((src_partinfo != NULL && dst_partinfo != NULL) ||
3125 !is_crosspart_update);
3127 tupsrc = src_partinfo ? src_partinfo : relinfo;
3140 else if (fdw_trigtuple != NULL)
3146 src_partinfo, dst_partinfo,
3149 oldslot, newslot, recheckIndexes,
3152 is_crosspart_update);
3167 LocTriggerData.
type = T_TriggerData;
3180 if (!TRIGGER_TYPE_MATCHES(trigger->
tgtype,
3182 TRIGGER_TYPE_INSTEAD,
3183 TRIGGER_TYPE_UPDATE))
3186 NULL, oldslot, newslot))
3203 if (newtuple == NULL)
3207 else if (newtuple != oldtuple)
3231 if (trigdesc == NULL)
3236 LocTriggerData.
type = T_TriggerData;
3246 if (!TRIGGER_TYPE_MATCHES(trigger->
tgtype,
3247 TRIGGER_TYPE_STATEMENT,
3248 TRIGGER_TYPE_BEFORE,
3249 TRIGGER_TYPE_TRUNCATE))
3264 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
3265 errmsg(
"BEFORE STATEMENT trigger cannot return a value")));
3278 false, NULL, NULL,
NIL, NULL, NULL,
3299 if (epqslot != NULL)
3308 Assert(epqstate != NULL);
3341 (
errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION),
3342 errmsg(
"tuple to be updated was already modified by an operation triggered by the current command"),
3343 errhint(
"Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows.")));
3384 errmsg(
"could not serialize access due to concurrent update")));
3385 elog(
ERROR,
"unexpected table_tuple_lock status: %u",
test);
3392 errmsg(
"could not serialize access due to concurrent delete")));
3397 elog(
ERROR,
"attempted to lock invisible tuple");
3401 elog(
ERROR,
"unrecognized table_tuple_lock status: %u",
test);
3413 elog(
ERROR,
"failed to fetch tuple for trigger");
3487 if (*predicate == NULL)
3514 if (!
ExecQual(*predicate, econtext))
3620 #define AFTER_TRIGGER_OFFSET 0x07FFFFFF
3621 #define AFTER_TRIGGER_DONE 0x80000000
3622 #define AFTER_TRIGGER_IN_PROGRESS 0x40000000
3624 #define AFTER_TRIGGER_FDW_REUSE 0x00000000
3625 #define AFTER_TRIGGER_FDW_FETCH 0x20000000
3626 #define AFTER_TRIGGER_1CTID 0x10000000
3627 #define AFTER_TRIGGER_2CTID 0x30000000
3628 #define AFTER_TRIGGER_CP_UPDATE 0x08000000
3629 #define AFTER_TRIGGER_TUP_BITS 0x38000000
3680 #define SizeofTriggerEvent(evt) \
3681 (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_CP_UPDATE ? \
3682 sizeof(AfterTriggerEventData) : \
3683 (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_2CTID ? \
3684 sizeof(AfterTriggerEventDataNoOids) : \
3685 (((evt)->ate_flags & AFTER_TRIGGER_TUP_BITS) == AFTER_TRIGGER_1CTID ? \
3686 sizeof(AfterTriggerEventDataOneCtid) : \
3687 sizeof(AfterTriggerEventDataZeroCtids))))
3689 #define GetTriggerSharedData(evt) \
3690 ((AfterTriggerShared) ((char *) (evt) + ((evt)->ate_flags & AFTER_TRIGGER_OFFSET)))
3708 #define CHUNK_DATA_START(cptr) ((char *) (cptr) + MAXALIGN(sizeof(AfterTriggerEventChunk)))
3719 #define for_each_chunk(cptr, evtlist) \
3720 for (cptr = (evtlist).head; cptr != NULL; cptr = cptr->next)
3721 #define for_each_event(eptr, cptr) \
3722 for (eptr = (AfterTriggerEvent) CHUNK_DATA_START(cptr); \
3723 (char *) eptr < (cptr)->freeptr; \
3724 eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3726 #define for_each_event_chunk(eptr, cptr, evtlist) \
3727 for_each_chunk(cptr, evtlist) for_each_event(eptr, cptr)
3730 #define for_each_chunk_from(cptr) \
3731 for (; cptr != NULL; cptr = cptr->next)
3732 #define for_each_event_from(eptr, cptr) \
3734 (char *) eptr < (cptr)->freeptr; \
3735 eptr = (AfterTriggerEvent) (((char *) eptr) + SizeofTriggerEvent(eptr)))
3910 Oid tgoid,
bool tgisdeferred);
3975 for (
i = 0;
i <
state->numstates;
i++)
3977 if (
state->trigstates[
i].sct_tgoid == tgoid)
3978 return state->trigstates[
i].sct_tgisdeferred;
3982 if (
state->all_isset)
3983 return state->all_isdeferred;
4012 "AfterTriggerEvents",
4046 if (
chunk == NULL ||
4055 "AfterTriggerEvents",
4073 #define MIN_CHUNK_SIZE 1024
4074 #define MAX_CHUNK_SIZE (1024*1024)
4076 #if MAX_CHUNK_SIZE > (AFTER_TRIGGER_OFFSET+1)
4077 #error MAX_CHUNK_SIZE must not exceed AFTER_TRIGGER_OFFSET
4100 if (events->
head == NULL)
4113 (
char *) newshared >=
chunk->endfree;
4123 if ((
char *) newshared < chunk->endfree)
4125 *newshared = *evtshared;
4127 chunk->endfree = (
char *) newshared;
4132 memcpy(newevent, event, eventsize);
4135 newevent->
ate_flags |= (
char *) newshared - (
char *) newevent;
4137 chunk->freeptr += eventsize;
4157 events->
tail = NULL;
4175 if (old_events->
tail == NULL)
4182 *events = *old_events;
4186 next_chunk =
chunk->next;
4290 bool should_free_trig =
false;
4291 bool should_free_new =
false;
4298 if (trigdesc == NULL)
4300 for (tgindx = 0; tgindx < trigdesc->
numtriggers; tgindx++)
4329 elog(
ERROR,
"failed to fetch tuple1 for AFTER trigger");
4335 elog(
ERROR,
"failed to fetch tuple2 for AFTER trigger");
4356 LocTriggerData.
tg_newslot = trig_tuple_slot2;
4376 elog(
ERROR,
"failed to fetch tuple1 for AFTER trigger");
4382 if (src_relInfo != relInfo)
4418 elog(
ERROR,
"failed to fetch tuple2 for AFTER trigger");
4425 if (dst_relInfo != relInfo)
4482 LocTriggerData.
type = T_TriggerData;
4500 if (rettuple != NULL &&
4508 if (should_free_trig)
4510 if (should_free_new)
4514 if (trig_tuple_slot1 == NULL)
4548 bool immediate_only)
4551 bool deferred_found =
false;
4558 bool defer_it =
false;
4585 if (defer_it && move_list != NULL)
4587 deferred_found =
true;
4602 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4603 errmsg(
"cannot fire deferred trigger within security-restricted operation")));
4635 bool all_fired =
true;
4638 bool local_estate =
false;
4651 local_estate =
true;
4657 "AfterTriggerTupleContext",
4663 bool all_fired_in_chunk =
true;
4697 slot1 = slot2 = NULL;
4699 if (rel->
rd_rel->relkind == RELKIND_FOREIGN_TABLE)
4725 src_rInfo = dst_rInfo = rInfo;
4733 src_rInfo, dst_rInfo,
4734 trigdesc, finfo, instr,
4735 per_tuple_context, slot1, slot2);
4746 all_fired = all_fired_in_chunk =
false;
4751 if (delete_ok && all_fired_in_chunk)
4814 if (table->
relid == relid && table->
cmdType == cmdType &&
4822 table->
relid = relid;
4896 if (trigdesc == NULL)
4903 need_old_upd = need_old_del = need_new_upd =
false;
4909 need_old_del = need_new_ins =
false;
4913 need_old_upd = need_new_upd = need_new_ins =
false;
4922 elog(
ERROR,
"unexpected CmdType: %d", (
int) cmdType);
4924 need_old_upd = need_new_upd = need_old_del = need_new_ins =
false;
4927 if (!need_old_upd && !need_new_upd && !need_new_ins && !need_old_del)
4932 elog(
ERROR,
"MakeTransitionCaptureState() called outside of query");
4975 state->tcs_private = table;
5203 bool snap_pushed =
false;
5214 if (events->
head != NULL)
5512 if (tuplestore == NULL)
5515 if (original_insert_tuple)