CUBRID Engine  latest
trigger_manager.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef _TRIGGER_MANAGER_H_
20 #define _TRIGGER_MANAGER_H_
21 
22 #ident "$Id$"
23 
24 #if defined (SERVER_MODE)
25 #error Does not belong to server module
26 #endif /* defined (SERVER_MODE) */
27 
28 #include "memory_alloc.h"
29 #include "dbtype_def.h"
30 #include "class_object.h"
31 
32 /*
33  * TR_LOWEST_PRIORITY
34  *
35  * Note:
36  * This defines the default lowest priority for a trigger.
37  *
38  */
39 
40 #define TR_LOWEST_PRIORITY 0.0
41 
42 /*
43  * TR_INFINITE_RECURSION_LEVEL
44  *
45  * Note:
46  * This number is used to indicate an infinite recursion level.
47  *
48  */
49 
50 #define TR_MAX_RECURSION_LEVEL 32
51 
52 /*
53  * TR_MAX_PRINT_STRING
54  *
55  * Note:
56  * Maximum length of string available for use in the PRINT action.
57  *
58  */
59 
60 #define TR_MAX_PRINT_STRING 2048
61 
62 /* free_and_init routine */
63 #define tr_free_schema_cache_and_init(cache) \
64  do \
65  { \
66  tr_free_schema_cache ((cache)); \
67  (cache) = NULL; \
68  } \
69  while (0)
70 
71 typedef struct tr_trigger
72 {
75  char *name;
76  double priority;
80  char *attribute;
81 
84 
86  char *temp_refname;
88 
89  /*
90  * copy of the "cache coherency number" from the instance, used
91  * to detect when the object gets modified and the trigger cache
92  * needs to be re-evaluated
93  */
94  int chn;
95  const char *comment;
96 } TR_TRIGGER;
97 
98 
99 
100 typedef struct tr_triglist
101 {
102  struct tr_triglist *next;
103  struct tr_triglist *prev;
104 
106  DB_OBJECT *target; /* associated target instance */
107 } TR_TRIGLIST;
108 
109 typedef struct tr_deferred_context
110 {
113 
116 
119 
120 /*
121  * TR_ACTIVITY
122  *
123  * Note:
124  * This is a substructure of the TR_TRIGGER structure and is used
125  * to hold the state of the condition and action activities.
126  *
127  */
128 
129 typedef struct tr_activity TR_ACTIVITY;
131 {
134  char *source; /* source text (or string for PRINT) */
135  void *parser; /* parser for statement */
136  void *statement; /* PT_NODE* of statement */
137  int exec_cnt; /* number of executions */
138 };
139 
140 /*
141  * TR_STATE
142  *
143  * Note:
144  * This structure is used to pass trigger execution state between
145  * tr_before, tr_after, and tr_abort.
146  *
147  */
148 
149 typedef struct tr_state
150 {
152 } TR_STATE;
153 
154 
155 
156 typedef struct tr_schema_cache
157 {
158  struct tr_schema_cache *next; /* all caches maintained on a global list */
159  DB_OBJLIST *objects; /* flattened object list */
160  short compiled; /* flag set when object list is compiled */
161  unsigned short array_length; /* number of elements in array */
162 
163  TR_TRIGLIST *triggers[1]; /* will actually allocate of variable length */
165 
166 /*
167  * TR_CACHE_TYPE
168  *
169  * Note:
170  * This is used by the functions that allocate class caches. Rather
171  * than passing in the length, just specify the type of cache and the
172  * tr_ module will allocate it of the appropriate length.
173  *
174  */
175 
176 typedef enum
177 {
180 } TR_CACHE_TYPE;
181 
182 /* TR_RECURSION_DECISION */
183 /* When analyzing the stack searching for recursion (which is forbidden),
184  * there are three scenarios:
185  * 1. no recursive activity found: continue
186  * 2. we found a recursive trigger and we must return an error
187  * 3. we found a recursive STATEMENT trigger. This is supposed to happen, and
188  * we should not continue the trigger firing chain, but we should allow
189  * the transaction to go on.
190  */
191 typedef enum
192 {
197 
198 /* TRIGGER OBJECT ATTRIBUTES */
199 /*
200  * Names of the trigger class and its attributes.
201  */
202 
203 extern const char *TR_CLASS_NAME;
204 extern const char *TR_ATT_NAME;
205 extern const char *TR_ATT_OWNER;
206 extern const char *TR_ATT_EVENT;
207 extern const char *TR_ATT_STATUS;
208 extern const char *TR_ATT_PRIORITY;
209 extern const char *TR_ATT_CLASS;
210 extern const char *TR_ATT_ATTRIBUTE;
211 extern const char *TR_ATT_CLASS_ATTRIBUTE;
212 extern const char *TR_ATT_CONDITION_TYPE;
213 extern const char *TR_ATT_CONDITION_TIME;
214 extern const char *TR_ATT_CONDITION;
215 extern const char *TR_ATT_ACTION_TYPE;
216 extern const char *TR_ATT_ACTION_TIME;
217 extern const char *TR_ATT_ACTION;
218 extern const char *TR_ATT_ACTION_OLD;
219 extern const char *TR_ATT_PROPERTIES;
220 extern const char *TR_ATT_COMMENT;
221 
222 extern int tr_Current_depth;
223 extern int tr_Maximum_depth;
224 extern bool tr_Invalid_transaction;
226 
227 extern bool tr_Trace;
228 
231 
232 extern int tr_Recursion_level;
233 extern int tr_Recursion_level_max;
234 
237 
238 /* INTERFACE FUNCTIONS */
239 
240 /* Module control */
241 
242 extern void tr_init (void);
243 extern void tr_final (void);
244 extern void tr_dump (FILE * fpp); /* debug status */
245 extern int tr_install (void);
246 
247 /* Global trigger firing state : enable/disable functions */
248 
249 extern bool tr_get_execution_state (void);
250 extern bool tr_set_execution_state (bool new_state);
251 
252 /* Trigger creation */
253 
254 extern DB_OBJECT *tr_create_trigger (const char *name, DB_TRIGGER_STATUS status, double priority,
255  DB_TRIGGER_EVENT event, DB_OBJECT * class_, const char *attribute,
256  DB_TRIGGER_TIME cond_time, const char *cond_source, DB_TRIGGER_TIME action_time,
257  DB_TRIGGER_ACTION action_type, const char *action_source, const char *comment);
258 
259 /* Trigger location */
260 
261 extern int tr_find_all_triggers (DB_OBJLIST ** list);
262 extern DB_OBJECT *tr_find_trigger (const char *name);
263 extern int tr_find_event_triggers (DB_TRIGGER_EVENT event, DB_OBJECT * class_, const char *attribute, bool active,
264  DB_OBJLIST ** list);
265 
266 /* Check access rights */
267 extern int tr_check_authorization (DB_OBJECT * trigger_object, int alter_flag);
268 
269 /* Trigger modification */
270 
271 extern int tr_drop_trigger (DB_OBJECT * obj, bool call_from_api);
272 extern int tr_rename_trigger (DB_OBJECT * trigger_object, const char *name, bool call_from_api);
273 
274 extern int tr_set_status (DB_OBJECT * trigger_object, DB_TRIGGER_STATUS status, bool call_from_api);
275 extern int tr_set_priority (DB_OBJECT * trigger_object, double priority, bool call_from_api);
276 extern int tr_set_comment (DB_OBJECT * trigger_object, const char *comment, bool call_from_api);
277 
278 /* Parameters */
279 extern int tr_get_depth (void);
280 extern int tr_set_depth (int depth);
281 extern int tr_get_trace (void);
282 extern int tr_set_trace (bool trace);
283 
284 /* Signaling */
285 
286 extern int tr_prepare_statement (TR_STATE ** state_p, DB_TRIGGER_EVENT event, DB_OBJECT * class_, int attcount,
287  const char **attnames);
288 #if defined(ENABLE_UNUSED_FUNCTION)
289 extern int tr_prepare (TR_STATE ** state_p, TR_TRIGLIST * triggers);
290 #endif
291 extern int tr_prepare_class (TR_STATE ** state_p, TR_SCHEMA_CACHE * cache, MOP class_Mop, DB_TRIGGER_EVENT event);
292 
293 extern int tr_before_object (TR_STATE * state, DB_OBJECT * current, DB_OBJECT * temp);
294 extern int tr_before (TR_STATE * state);
295 extern int tr_after_object (TR_STATE * state, DB_OBJECT * current, DB_OBJECT * temp);
296 extern int tr_after (TR_STATE * state);
297 
298 extern void tr_abort (TR_STATE * state);
299 
300 /* Transaction manager trigger hooks */
301 
302 extern int tr_has_user_trigger (bool * has_user_trigger);
303 extern int tr_check_commit_triggers (DB_TRIGGER_TIME time);
305 #if defined(ENABLE_UNUSED_FUNCTION)
306 extern void tr_check_timeout_triggers (void);
307 #endif
308 extern void tr_check_abort_triggers (void);
309 
310 #if defined(ENABLE_UNUSED_FUNCTION)
311 extern int tr_set_savepoint (void *savepoint_id);
312 extern int tr_abort_to_savepoint (void *savepoint_id);
313 #endif
314 
315 /* Deferred activity control */
316 
317 extern int tr_execute_deferred_activities (DB_OBJECT * trigger_object, DB_OBJECT * target);
318 extern int tr_drop_deferred_activities (DB_OBJECT * trigger_object, DB_OBJECT * target);
319 
320 /* Trigger object accessors */
321 
322 extern int tr_trigger_name (DB_OBJECT * trigger_object, char **name);
323 extern int tr_trigger_status (DB_OBJECT * trigger_object, DB_TRIGGER_STATUS * status);
324 extern int tr_trigger_priority (DB_OBJECT * trigger_object, double *priority);
325 extern int tr_trigger_event (DB_OBJECT * trigger_object, DB_TRIGGER_EVENT * event);
326 extern int tr_trigger_class (DB_OBJECT * trigger_object, DB_OBJECT ** class_);
327 extern int tr_trigger_attribute (DB_OBJECT * trigger_object, char **attribute);
328 extern int tr_trigger_condition (DB_OBJECT * trigger_object, char **condition);
329 extern int tr_trigger_condition_time (DB_OBJECT * trigger_object, DB_TRIGGER_TIME * tr_time);
330 extern int tr_trigger_action (DB_OBJECT * trigger_object, char **action);
331 extern int tr_trigger_action_time (DB_OBJECT * trigger_object, DB_TRIGGER_TIME * tr_time);
332 extern int tr_trigger_action_type (DB_OBJECT * trigger_object, DB_TRIGGER_ACTION * type);
333 extern int tr_trigger_comment (DB_OBJECT * trigger_objet, char **comment);
334 extern int tr_is_trigger (DB_OBJECT * trigger_object, int *status);
335 
336 /* Special schema functions */
337 
339 extern TR_SCHEMA_CACHE *tr_copy_schema_cache (TR_SCHEMA_CACHE * cache, MOP filter_class);
340 extern int tr_merge_schema_cache (TR_SCHEMA_CACHE * destination, TR_SCHEMA_CACHE * source);
341 extern int tr_empty_schema_cache (TR_SCHEMA_CACHE * cache);
342 extern void tr_free_schema_cache (TR_SCHEMA_CACHE * cache);
343 
344 extern int tr_get_cache_objects (TR_SCHEMA_CACHE * cache, DB_OBJLIST ** list);
346 
347 extern int tr_active_schema_cache (MOP class_mop, TR_SCHEMA_CACHE * cache, DB_TRIGGER_EVENT event_type,
348  bool * has_event_type_triggers);
349 extern int tr_delete_schema_cache (TR_SCHEMA_CACHE * cache, DB_OBJECT * class_object);
350 
351 extern int tr_add_cache_trigger (TR_SCHEMA_CACHE * cache, DB_OBJECT * trigger_object);
352 extern int tr_drop_cache_trigger (TR_SCHEMA_CACHE * cache, DB_OBJECT * trigger_object);
353 
354 extern int tr_delete_triggers_for_class (TR_SCHEMA_CACHE ** cache, DB_OBJECT * class_object);
355 
356 
357 /* Shouldn't be external any more ? */
358 
359 extern TR_TRIGGER *tr_map_trigger (DB_OBJECT * object, int fetch);
360 extern int tr_unmap_trigger (TR_TRIGGER * trigger);
361 
362 /* Cache control */
363 
364 extern int tr_update_user_cache (void);
365 extern void tr_invalidate_user_cache (void);
366 
367 /* Migration and information functions */
368 
369 extern const char *tr_time_as_string (DB_TRIGGER_TIME time);
370 extern const char *tr_event_as_string (DB_TRIGGER_EVENT event);
371 extern const char *tr_status_as_string (DB_TRIGGER_STATUS status);
372 #if defined(ENABLE_UNUSED_FUNCTION)
373 extern int tr_dump_all_triggers (FILE * fp, bool quoted_id_flag);
374 #endif
375 extern void tr_free_trigger_list (TR_TRIGLIST * list);
376 extern const char *tr_get_class_name (void);
377 
378 #if defined(ENABLE_UNUSED_FUNCTION)
379 extern int tr_reset_schema_cache (TR_SCHEMA_CACHE * cache);
380 extern int tr_downcase_all_trigger_info (void);
381 #endif
382 
383 #endif /* _TRIGGER_MANAGER_H_ */
int tr_update_user_cache(void)
const char * TR_ATT_ACTION
double priority
DB_TRIGGER_TIME time
TR_TRIGGER * trigger
int tr_merge_schema_cache(TR_SCHEMA_CACHE *destination, TR_SCHEMA_CACHE *source)
char * current_refname
int tr_Maximum_depth
char tr_Invalid_transaction_trigger[SM_MAX_IDENTIFIER_LENGTH+2]
const char * TR_ATT_COMMENT
int tr_drop_deferred_activities(DB_OBJECT *trigger_object, DB_OBJECT *target)
int tr_rename_trigger(DB_OBJECT *trigger_object, const char *name, bool call_from_api)
int tr_get_depth(void)
const char * TR_ATT_ACTION_OLD
void tr_final(void)
int tr_trigger_event(DB_OBJECT *trigger_object, DB_TRIGGER_EVENT *event)
TR_DEFERRED_CONTEXT * tr_Deferred_activities
const char * TR_ATT_EVENT
struct tr_activity * condition
const char * tr_time_as_string(DB_TRIGGER_TIME time)
DB_OBJECT * object
int tr_prepare_statement(TR_STATE **state_p, DB_TRIGGER_EVENT event, DB_OBJECT *class_, int attcount, const char **attnames)
int tr_delete_triggers_for_class(TR_SCHEMA_CACHE **cache, DB_OBJECT *class_object)
const char * TR_ATT_CONDITION_TIME
bool tr_Trace
const char * TR_ATT_PRIORITY
int tr_trigger_action_type(DB_OBJECT *trigger_object, DB_TRIGGER_ACTION *type)
int tr_trigger_attribute(DB_OBJECT *trigger_object, char **attribute)
bool tr_Invalid_transaction
#define SM_MAX_IDENTIFIER_LENGTH
const char * tr_event_as_string(DB_TRIGGER_EVENT event)
DB_TRIGGER_EVENT event
int tr_has_user_trigger(bool *has_user_trigger)
void tr_init(void)
void tr_abort(TR_STATE *state)
void tr_check_abort_triggers(void)
TR_TRIGLIST * triggers[1]
int tr_drop_trigger(DB_OBJECT *obj, bool call_from_api)
int tr_find_event_triggers(DB_TRIGGER_EVENT event, DB_OBJECT *class_, const char *attribute, bool active, DB_OBJLIST **list)
const char * TR_ATT_CONDITION_TYPE
const char * tr_get_class_name(void)
bool tr_set_execution_state(bool new_state)
int tr_set_trace(bool trace)
int tr_install(void)
TR_TRIGLIST * triggers
int tr_active_schema_cache(MOP class_mop, TR_SCHEMA_CACHE *cache, DB_TRIGGER_EVENT event_type, bool *has_event_type_triggers)
int tr_Recursion_level_max
struct tr_triglist * prev
int tr_set_status(DB_OBJECT *trigger_object, DB_TRIGGER_STATUS status, bool call_from_api)
struct tr_schema_cache * next
const char * TR_ATT_ACTION_TYPE
int tr_empty_schema_cache(TR_SCHEMA_CACHE *cache)
int tr_get_trace(void)
int tr_unmap_trigger(TR_TRIGGER *trigger)
char * temp_refname
const char * TR_ATT_NAME
int tr_prepare_class(TR_STATE **state_p, TR_SCHEMA_CACHE *cache, MOP class_Mop, DB_TRIGGER_EVENT event)
const char * TR_CLASS_NAME
TR_TRIGLIST * tr_Deferred_triggers_tail
const char * TR_ATT_ACTION_TIME
const char * TR_ATT_OWNER
DB_OBJECT * owner
struct tr_activity * action
int tr_check_authorization(DB_OBJECT *trigger_object, int alter_flag)
const char * comment
struct tr_schema_cache TR_SCHEMA_CACHE
const char * TR_ATT_PROPERTIES
const char * TR_ATT_ATTRIBUTE
DB_OBJLIST * objects
DB_TRIGGER_STATUS status
DB_TRIGGER_ACTION type
int tr_find_all_triggers(DB_OBJLIST **list)
void tr_dump(FILE *fpp)
const char * tr_status_as_string(DB_TRIGGER_STATUS status)
DB_OBJECT * tr_create_trigger(const char *name, DB_TRIGGER_STATUS status, double priority, DB_TRIGGER_EVENT event, DB_OBJECT *class_, const char *attribute, DB_TRIGGER_TIME cond_time, const char *cond_source, DB_TRIGGER_TIME action_time, DB_TRIGGER_ACTION action_type, const char *action_source, const char *comment)
int tr_trigger_action_time(DB_OBJECT *trigger_object, DB_TRIGGER_TIME *tr_time)
TR_CACHE_TYPE
int tr_drop_cache_trigger(TR_SCHEMA_CACHE *cache, DB_OBJECT *trigger_object)
int tr_delete_schema_cache(TR_SCHEMA_CACHE *cache, DB_OBJECT *class_object)
struct tr_trigger TR_TRIGGER
int tr_after(TR_STATE *state)
int tr_trigger_condition(DB_OBJECT *trigger_object, char **condition)
int tr_add_cache_trigger(TR_SCHEMA_CACHE *cache, DB_OBJECT *trigger_object)
TR_RECURSION_DECISION
int tr_before(TR_STATE *state)
const char * TR_ATT_CONDITION
unsigned short array_length
DB_TRIGGER_TIME
Definition: dbtype_def.h:388
void tr_check_rollback_triggers(DB_TRIGGER_TIME time)
int tr_trigger_status(DB_OBJECT *trigger_object, DB_TRIGGER_STATUS *status)
const char * TR_ATT_CLASS_ATTRIBUTE
TR_SCHEMA_CACHE * tr_make_schema_cache(TR_CACHE_TYPE type, DB_OBJLIST *objects)
DB_OBJECT * tr_find_trigger(const char *name)
TR_SCHEMA_CACHE * tr_copy_schema_cache(TR_SCHEMA_CACHE *cache, MOP filter_class)
int tr_Current_depth
struct tr_deferred_context TR_DEFERRED_CONTEXT
int tr_set_depth(int depth)
int tr_trigger_name(DB_OBJECT *trigger_object, char **name)
int tr_trigger_priority(DB_OBJECT *trigger_object, double *priority)
int tr_trigger_class(DB_OBJECT *trigger_object, DB_OBJECT **class_)
int tr_is_trigger(DB_OBJECT *trigger_object, int *status)
void tr_free_trigger_list(TR_TRIGLIST *list)
void tr_free_schema_cache(TR_SCHEMA_CACHE *cache)
int tr_get_cache_objects(TR_SCHEMA_CACHE *cache, DB_OBJLIST **list)
int tr_before_object(TR_STATE *state, DB_OBJECT *current, DB_OBJECT *temp)
DB_TRIGGER_EVENT
Definition: dbtype_def.h:356
int tr_after_object(TR_STATE *state, DB_OBJECT *current, DB_OBJECT *temp)
struct tr_triglist TR_TRIGLIST
struct tr_deferred_context * prev
int tr_set_comment(DB_OBJECT *trigger_object, const char *comment, bool call_from_api)
bool tr_get_execution_state(void)
struct tr_triglist * next
int tr_trigger_comment(DB_OBJECT *trigger_objet, char **comment)
struct tr_deferred_context * next
DB_OBJECT * class_mop
struct tr_state TR_STATE
int tr_Recursion_level
int tr_check_commit_triggers(DB_TRIGGER_TIME time)
char * attribute
DB_TRIGGER_STATUS
Definition: dbtype_def.h:344
TR_DEFERRED_CONTEXT * tr_Deferred_activities_tail
DB_TRIGGER_ACTION
Definition: dbtype_def.h:397
const char * TR_ATT_CLASS
void tr_invalidate_user_cache(void)
int tr_execute_deferred_activities(DB_OBJECT *trigger_object, DB_OBJECT *target)
int tr_trigger_condition_time(DB_OBJECT *trigger_object, DB_TRIGGER_TIME *tr_time)
TR_TRIGGER * tr_map_trigger(DB_OBJECT *object, int fetch)
int tr_validate_schema_cache(TR_SCHEMA_CACHE *cache, MOP class_mop)
int tr_trigger_action(DB_OBJECT *trigger_object, char **action)
DB_OBJECT * target
TR_TRIGLIST * tr_Deferred_triggers
int tr_set_priority(DB_OBJECT *trigger_object, double priority, bool call_from_api)
const char * TR_ATT_STATUS