22
22
#include "catalog/heap.h"
23
23
#include "catalog/pg_authid.h"
24
24
#include "catalog/pg_proc.h"
25
+ #include "catalog/pg_trigger.h"
25
26
#include "catalog/pg_type.h"
26
27
#include "catalog/toasting.h"
27
28
#include "commands/event_trigger.h"
28
29
#include "commands/sequence.h"
29
30
#include "commands/tablecmds.h"
30
31
#include "commands/tablespace.h"
32
+ #include "commands/trigger.h"
31
33
#include "miscadmin.h"
32
34
#include "parser/parse_func.h"
33
35
#include "parser/parse_relation.h"
@@ -52,9 +54,11 @@ static Oid spawn_partitions_val(Oid parent_relid,
52
54
Datum value ,
53
55
Oid value_type );
54
56
55
- static void create_single_partition_common (Oid partition_relid ,
57
+ static void create_single_partition_common (Oid parent_relid ,
58
+ Oid partition_relid ,
56
59
Constraint * check_constraint ,
57
- init_callback_params * callback_params );
60
+ init_callback_params * callback_params ,
61
+ const char * attname );
58
62
59
63
static Oid create_single_partition_internal (Oid parent_relid ,
60
64
RangeVar * partition_rv ,
@@ -77,6 +81,8 @@ static Constraint *make_constraint_common(char *name, Node *raw_expr);
77
81
static Value make_string_value_struct (char * str );
78
82
static Value make_int_value_struct (int int_val );
79
83
84
+ static bool update_trigger_exists (Oid relid , char * trigname );
85
+
80
86
81
87
/*
82
88
* ---------------------------------------
@@ -130,9 +136,11 @@ create_single_range_partition_internal(Oid parent_relid,
130
136
* start_value , * end_value , value_type );
131
137
132
138
/* Add constraint & execute init_callback */
133
- create_single_partition_common (partition_relid ,
139
+ create_single_partition_common (parent_relid ,
140
+ partition_relid ,
134
141
check_constr ,
135
- & callback_params );
142
+ & callback_params ,
143
+ partitioned_column );
136
144
137
145
/* Return the Oid */
138
146
return partition_relid ;
@@ -183,21 +191,25 @@ create_single_hash_partition_internal(Oid parent_relid,
183
191
parent_relid , partition_relid );
184
192
185
193
/* Add constraint & execute init_callback */
186
- create_single_partition_common (partition_relid ,
194
+ create_single_partition_common (parent_relid ,
195
+ partition_relid ,
187
196
check_constr ,
188
- & callback_params );
197
+ & callback_params ,
198
+ partitioned_column );
189
199
190
200
/* Return the Oid */
191
201
return partition_relid ;
192
202
}
193
203
194
204
/* Add constraint & execute init_callback */
195
205
void
196
- create_single_partition_common (Oid partition_relid ,
206
+ create_single_partition_common (Oid parent_relid ,
207
+ Oid partition_relid ,
197
208
Constraint * check_constraint ,
198
- init_callback_params * callback_params )
209
+ init_callback_params * callback_params ,
210
+ const char * attname )
199
211
{
200
- Relation child_relation ;
212
+ Relation child_relation ;
201
213
202
214
/* Open the relation and add new check constraint & fkeys */
203
215
child_relation = heap_open (partition_relid , AccessExclusiveLock );
@@ -209,6 +221,20 @@ create_single_partition_common(Oid partition_relid,
209
221
/* Make constraint visible */
210
222
CommandCounterIncrement ();
211
223
224
+ /* Create trigger */
225
+ if (is_update_trigger_enabled_internal (parent_relid ))
226
+ {
227
+ char * trigname ;
228
+
229
+ trigname = build_update_trigger_name_internal (parent_relid );
230
+ create_single_update_trigger_internal (partition_relid ,
231
+ trigname ,
232
+ attname );
233
+ }
234
+
235
+ /* Make trigger visible */
236
+ CommandCounterIncrement ();
237
+
212
238
/* Finally invoke 'init_callback' */
213
239
invoke_part_callback (callback_params );
214
240
@@ -1649,3 +1675,82 @@ text_to_regprocedure(text *proc_signature)
1649
1675
1650
1676
return DatumGetObjectId (result );
1651
1677
}
1678
+
1679
+ /*
1680
+ * Create trigger for partition
1681
+ */
1682
+ void
1683
+ create_single_update_trigger_internal (Oid relid ,
1684
+ const char * trigname ,
1685
+ const char * attname )
1686
+ {
1687
+ CreateTrigStmt * stmt ;
1688
+ List * func ;
1689
+
1690
+ func = list_make2 (makeString (get_namespace_name (get_pathman_schema ())),
1691
+ makeString ("update_trigger_func" ));
1692
+
1693
+ stmt = makeNode (CreateTrigStmt );
1694
+ stmt -> trigname = (char * ) trigname ;
1695
+ stmt -> relation = makeRangeVarFromRelid (relid );
1696
+ stmt -> funcname = func ;
1697
+ stmt -> args = NIL ;
1698
+ stmt -> row = true;
1699
+ stmt -> timing = TRIGGER_TYPE_BEFORE ;
1700
+ stmt -> events = TRIGGER_TYPE_UPDATE ;
1701
+ stmt -> columns = list_make1 (makeString ((char * ) attname ));
1702
+ stmt -> whenClause = NULL ;
1703
+ stmt -> isconstraint = false;
1704
+ stmt -> deferrable = false;
1705
+ stmt -> initdeferred = false;
1706
+ stmt -> constrrel = NULL ;
1707
+
1708
+ (void ) CreateTrigger (stmt , NULL , InvalidOid , InvalidOid ,
1709
+ InvalidOid , InvalidOid , false);
1710
+ }
1711
+
1712
+ /*
1713
+ * Check if update trigger is enabled. Basicly it returns true if update
1714
+ * trigger exists for parent table
1715
+ */
1716
+ bool
1717
+ is_update_trigger_enabled_internal (Oid parent )
1718
+ {
1719
+ char * trigname ;
1720
+
1721
+ trigname = build_update_trigger_name_internal (parent );
1722
+ return update_trigger_exists (parent , trigname );
1723
+ }
1724
+
1725
+ static bool
1726
+ update_trigger_exists (Oid relid , char * trigname )
1727
+ {
1728
+ bool res = false;
1729
+ Relation tgrel ;
1730
+ SysScanDesc tgscan ;
1731
+ ScanKeyData key ;
1732
+ HeapTuple tuple ;
1733
+
1734
+ tgrel = heap_open (TriggerRelationId , RowExclusiveLock );
1735
+
1736
+ ScanKeyInit (& key ,
1737
+ Anum_pg_trigger_tgrelid ,
1738
+ BTEqualStrategyNumber , F_OIDEQ ,
1739
+ ObjectIdGetDatum (relid ));
1740
+ tgscan = systable_beginscan (tgrel , TriggerRelidNameIndexId , true,
1741
+ NULL , 1 , & key );
1742
+ while (HeapTupleIsValid (tuple = systable_getnext (tgscan )))
1743
+ {
1744
+ Form_pg_trigger pg_trigger = (Form_pg_trigger ) GETSTRUCT (tuple );
1745
+
1746
+ if (namestrcmp (& (pg_trigger -> tgname ), trigname ) == 0 )
1747
+ {
1748
+ res = true;
1749
+ break ;
1750
+ }
1751
+ }
1752
+ systable_endscan (tgscan );
1753
+ heap_close (tgrel , RowExclusiveLock );
1754
+
1755
+ return res ;
1756
+ }
0 commit comments