~ubuntu-branches/ubuntu/karmic/firebird2.1/karmic

« back to all changes in this revision

Viewing changes to src/dbs/grant.gdl

  • Committer: Bazaar Package Importer
  • Author(s): Damyan Ivanov
  • Date: 2008-05-26 23:59:25 UTC
  • Revision ID: james.westby@ubuntu.com-20080526235925-2pnqj6nxpppoeaer
Tags: upstream-2.1.0.17798-0.ds2
ImportĀ upstreamĀ versionĀ 2.1.0.17798-0.ds2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * The contents of this file are subject to the Interbase Public
 
3
 * License Version 1.0 (the "License"); you may not use this file
 
4
 * except in compliance with the License. You may obtain a copy
 
5
 * of the License at http://www.Inprise.com/IPL.html
 
6
 *
 
7
 * Software distributed under the License is distributed on an
 
8
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 
9
 * or implied. See the License for the specific language governing
 
10
 * rights and limitations under the License.
 
11
 *
 
12
 * The Original Code was created by Inprise Corporation
 
13
 * and its predecessors. Portions created by Inprise Corporation are
 
14
 * Copyright (C) Inprise Corporation.
 
15
 *
 
16
 * All Rights Reserved.
 
17
 * Contributor(s): ______________________________________.
 
18
 */
 
19
define database "bar.fdb";
 
20
 
 
21
/*
 
22
define generator RDB$SECURITY_CLASS;
 
23
define generator SQL$DEFAULT;
 
24
define generator RDB$PROCEDURES;
 
25
define generator RDB$EXCEPTIONS;
 
26
*/
 
27
 
 
28
/*
 
29
 * The SYSDBA_USER_NAME name is assumed to be "SYSDBA" in the
 
30
 * below trigger
 
31
 */
 
32
define trigger grant_trigger for rdb$user_privileges pre store 0
 
33
    begin
 
34
        if new.rdb$object_type = 0
 
35
            begin
 
36
            if not any rel in rdb$relations
 
37
                with rel.rdb$relation_name eq new.rdb$relation_name
 
38
                abort 0;
 
39
            if new.rdb$field_name not missing
 
40
                if not any rlf in rdb$relation_fields
 
41
                    with rlf.rdb$relation_name eq new.rdb$relation_name and
 
42
                    rlf.rdb$field_name eq new.rdb$field_name
 
43
                    abort 1;
 
44
            end;
 
45
        if new.rdb$object_type = 5 and
 
46
           not any prc in rdb$procedures
 
47
             with prc.rdb$procedure_name eq new.rdb$relation_name
 
48
            abort 0;
 
49
 
 
50
        if new.rdb$user_type = 0  or new.rdb$user_type = 3  or
 
51
           new.rdb$user_type = 4  or new.rdb$user_type = 6  or
 
52
           new.rdb$user_type = 7  or new.rdb$user_type = 8  or
 
53
           new.rdb$user_type = 9  or new.rdb$user_type = 10 or
 
54
           new.rdb$user_type = 11 or new.rdb$user_type = 12
 
55
            new.rdb$user = UPPERCASE (new.rdb$user);
 
56
 
 
57
        if new.rdb$grantor missing
 
58
            new.rdb$grantor = UPPERCASE (rdb$user_name);
 
59
        if new.rdb$object_type = 0
 
60
            begin
 
61
            /* Verify that the grantor has the 'grant option'. */
 
62
            for rel in rdb$relations
 
63
                with rel.rdb$relation_name eq new.rdb$relation_name
 
64
                /* As part of the creation of a table/view, the creator gets
 
65
                   records that gives him/her all privileges. */
 
66
                if rel.rdb$owner_name eq UPPERCASE (rdb$user_name) and
 
67
                   rel.rdb$owner_name eq new.rdb$grantor and
 
68
                   rel.rdb$owner_name eq new.rdb$user or
 
69
                   UPPERCASE (rdb$user_name) eq "SYSDBA"
 
70
                    begin
 
71
                    end
 
72
                else
 
73
                /* The owner always has the grant option.  
 
74
                   A non-owner should have the grant option explicitely granted. */
 
75
                if rel.rdb$owner_name ne UPPERCASE (rdb$user_name)
 
76
                    begin
 
77
                    if not any priv in rdb$user_privileges 
 
78
                        with priv.rdb$relation_name eq new.rdb$relation_name and
 
79
                             priv.rdb$object_type   eq 0 and
 
80
                             priv.rdb$privilege     eq new.rdb$privilege and
 
81
                             priv.rdb$user          eq new.rdb$grantor and
 
82
                             priv.rdb$user_type     eq 8 and
 
83
                             priv.rdb$grant_option ne 0 and
 
84
                             (priv.rdb$field_name missing or 
 
85
                              priv.rdb$field_name eq new.rdb$field_name)
 
86
                        abort 2;
 
87
                    end
 
88
                else
 
89
                /* If a view-owner is granting privileges on his/her view, then
 
90
                   verify that the view owner has the grant option on the base table/view. */
 
91
                if new.rdb$field_name not missing
 
92
                    begin
 
93
                    for fld in rdb$relation_fields cross
 
94
                        view in rdb$view_relations cross
 
95
                        rel2 in rdb$relations
 
96
                        with fld.rdb$field_name eq new.rdb$field_name and
 
97
                             fld.rdb$relation_name eq new.rdb$relation_name and
 
98
                             fld.rdb$base_field not missing and
 
99
                             view.rdb$view_name eq fld.rdb$relation_name and
 
100
                             view.rdb$view_context eq fld.rdb$view_context and
 
101
                             view.rdb$relation_name eq rel2.rdb$relation_name
 
102
                        if rel2.rdb$owner_name ne rel.rdb$owner_name
 
103
                           and UPPERCASE (rdb$user_name) ne "SYSDBA"
 
104
                            begin
 
105
                            if not any priv in rdb$user_privileges
 
106
                                with priv.rdb$relation_name eq rel2.rdb$relation_name and
 
107
                                     priv.rdb$object_type   eq 0 and
 
108
                                     priv.rdb$privilege     eq new.rdb$privilege and
 
109
                                     priv.rdb$user          eq rel.rdb$owner_name and
 
110
                                     priv.rdb$user_type     eq 8 and
 
111
                                     priv.rdb$grant_option ne 0 and
 
112
                                     (priv.rdb$field_name missing or
 
113
                                      priv.rdb$field_name eq fld.rdb$base_field)
 
114
                                abort 5;
 
115
                            end;
 
116
                    end_for;
 
117
                    end
 
118
                else
 
119
                    begin
 
120
                    for view in rdb$view_relations cross
 
121
                        rel2 in rdb$relations
 
122
                        with view.rdb$view_name eq new.rdb$relation_name and
 
123
                             view.rdb$relation_name eq rel2.rdb$relation_name
 
124
                        if rel2.rdb$owner_name ne rel.rdb$owner_name
 
125
                           and UPPERCASE (rdb$user_name) ne "SYSDBA"
 
126
                            begin
 
127
                            if not any priv in rdb$user_privileges
 
128
                                with priv.rdb$relation_name eq rel2.rdb$relation_name and
 
129
                                     priv.rdb$object_type   eq 0 and
 
130
                                     priv.rdb$privilege     eq new.rdb$privilege and
 
131
                                     priv.rdb$user          eq rel.rdb$owner_name and
 
132
                                     priv.rdb$user_type     eq 8 and
 
133
                                     priv.rdb$grant_option ne 0 and
 
134
                                     priv.rdb$field_name missing
 
135
                                abort 5;
 
136
                            end;
 
137
                    end_for;
 
138
                    end
 
139
                if rel.rdb$security_class missing
 
140
                    modify rel
 
141
                        rel.rdb$security_class = "SQL$" | rel.rdb$relation_name;
 
142
                    end_modify
 
143
                else if rel.rdb$security_class != "SQL$" | rel.rdb$relation_name
 
144
                    abort 3;
 
145
            end_for;
 
146
            if new.rdb$field_name not missing
 
147
                for rfl in rdb$relation_fields
 
148
                    with rfl.rdb$relation_name eq new.rdb$relation_name and
 
149
                    rfl.rdb$field_name eq new.rdb$field_name
 
150
                    if rfl.rdb$security_class missing
 
151
                        modify rfl
 
152
                            rfl.rdb$security_class = "SQL$GRANT" | gen_id (RDB$SECURITY_CLASS, 1);
 
153
                        end_modify;
 
154
                    else if rfl.rdb$security_class not starting "SQL$GRANT"
 
155
                        abort 4;
 
156
                end_for;
 
157
            end
 
158
        else if new.rdb$object_type = 5
 
159
            for prc in rdb$procedures
 
160
                with prc.rdb$procedure_name eq new.rdb$relation_name
 
161
                if prc.rdb$owner_name ne UPPERCASE (rdb$user_name)
 
162
                           and UPPERCASE (rdb$user_name) ne "SYSDBA"
 
163
                    if not any priv in rdb$user_privileges 
 
164
                        with priv.rdb$relation_name eq new.rdb$relation_name and
 
165
                             priv.rdb$object_type   eq 5 and
 
166
                             priv.rdb$privilege     eq new.rdb$privilege and
 
167
                             priv.rdb$user          eq new.rdb$grantor and
 
168
                             priv.rdb$user_type     eq 8 and
 
169
                             priv.rdb$grant_option ne 0 and
 
170
                             (priv.rdb$field_name missing or 
 
171
                              priv.rdb$field_name eq new.rdb$field_name)
 
172
                        abort 2;
 
173
                if prc.rdb$security_class missing
 
174
                    modify prc
 
175
                        prc.rdb$security_class = "SQL$" | prc.rdb$procedure_name;
 
176
                    end_modify
 
177
                else if prc.rdb$security_class != "SQL$" | prc.rdb$procedure_name
 
178
                    abort 3;
 
179
            end_for;
 
180
    end;
 
181
end_trigger;
 
182
 
 
183
/***
 
184
define trigger revoke_trigger for rdb$user_privileges pre erase 0
 
185
    if old.rdb$grantor ne UPPERCASE (rdb$user_name)
 
186
        abort 0;
 
187
end_trigger;
 
188
***/
 
189
 
 
190
define trigger revoke_trigger for rdb$user_privileges pre erase 0
 
191
    if old.rdb$field_name not missing
 
192
        for rf in rdb$relation_fields
 
193
            with rf.rdb$relation_name eq old.rdb$relation_name and
 
194
                 rf.rdb$field_name eq old.rdb$field_name
 
195
            if rf.rdb$security_class starting "SQL$GRANT"
 
196
                begin
 
197
                    for sec in rdb$security_classes
 
198
                          with sec.rdb$security_class eq rf.rdb$security_class
 
199
                        erase sec;
 
200
                    end_for;
 
201
                    modify rf
 
202
                        rf.rdb$security_class = null;
 
203
                    end_modify;
 
204
                end;
 
205
        end_for;
 
206
end_trigger;
 
207
 
 
208
define trigger grant_revoke for rdb$user_privileges pre modify 0
 
209
    abort 0;
 
210
end_trigger;
 
211
 
 
212
define trigger system_protection_1 for rdb$triggers pre modify 0
 
213
    if old.rdb$system_flag = 1
 
214
        abort 0;
 
215
end_trigger;
 
216
 
 
217
define trigger system_protection_2 for rdb$triggers pre erase 0
 
218
    if old.rdb$system_flag = 1
 
219
        abort 0;
 
220
end_trigger;
 
221
 
 
222
define trigger system_protection_3 for rdb$relations pre store 0
 
223
    if new.rdb$owner_name missing
 
224
        new.rdb$owner_name = UPPERCASE (rdb$user_name);
 
225
end_trigger;
 
226
 
 
227
define trigger system_protection_4 for rdb$relations pre modify 0
 
228
    if old.rdb$owner_name ne new.rdb$owner_name and
 
229
       old.rdb$owner_name ne UPPERCASE (rdb$user_name)
 
230
        abort 0;
 
231
end_trigger;
 
232
 
 
233
/* triggers for integrity constraints           */
 
234
 
 
235
define trigger add_constraint for rdb$relation_constraints
 
236
pre store:
 
237
begin
 
238
        if any r in rdb$relations with 
 
239
           r.rdb$relation_name = new.rdb$relation_name
 
240
           and r.rdb$view_source not missing 
 
241
              abort 1;
 
242
 
 
243
        if NOT (new.RDB$CONSTRAINT_TYPE = 'UNIQUE' OR  
 
244
           new.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' OR
 
245
           new.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' OR
 
246
           new.RDB$CONSTRAINT_TYPE = 'NOT NULL' OR
 
247
           new.RDB$CONSTRAINT_TYPE = 'CHECK')
 
248
        abort 2;
 
249
 
 
250
        if (new.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY')
 
251
        begin
 
252
         if ANY r in rdb$relation_constraints with 
 
253
                 r.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY'
 
254
                 and r.rdb$relation_name = new.rdb$relation_name
 
255
         abort 3;
 
256
        end;
 
257
        
 
258
end;
 
259
end_trigger
 
260
message 1: "Cannot define constraints on VIEWS", 
 
261
message 2: "internal gds software consistency check (Invalid RDB$CONSTRAINT_TYPE)",
 
262
message 3: "Attempt to define a second primary key for the same relation";
 
263
 
 
264
define trigger update_constraint for rdb$relation_constraints
 
265
pre modify:
 
266
begin
 
267
    abort 1;
 
268
end;
 
269
end_trigger
 
270
message 1: "Can't update constraints (RDB$RELATION_CONSTRAINTS).";
 
271
 
 
272
define trigger pre_delete_constraint for rdb$relation_constraints
 
273
pre erase:
 
274
begin
 
275
        if old.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' OR
 
276
           old.RDB$CONSTRAINT_TYPE = 'UNIQUE'
 
277
        begin
 
278
         if ANY r in rdb$ref_constraints with 
 
279
                r.rdb$CONST_NAME_UQ = old.rdb$constraint_name
 
280
         abort 1;
 
281
        end;
 
282
     
 
283
        if old.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'
 
284
        begin
 
285
          for c in RDB$REF_CONSTRAINTS
 
286
                with old.RDB$CONSTRAINT_NAME = c.RDB$CONSTRAINT_NAME
 
287
                erase c;
 
288
          end_for;
 
289
        end;
 
290
 
 
291
        if old.RDB$CONSTRAINT_TYPE = 'NOT NULL'
 
292
        begin
 
293
          for chk in RDB$CHECK_CONSTRAINTS cross
 
294
              fld in RDB$RELATION_FIELDS cross
 
295
              idx in RDB$INDICES cross
 
296
              ids in RDB$INDEX_SEGMENTS with
 
297
              old.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME AND
 
298
              fld.RDB$FIELD_NAME = chk.RDB$TRIGGER_NAME AND
 
299
              fld.RDB$RELATION_NAME = old.RDB$RELATION_NAME AND
 
300
              fld.RDB$FIELD_NAME = ids.RDB$FIELD_NAME AND
 
301
              idx.RDB$RELATION_NAME = old.RDB$RELATION_NAME AND
 
302
              idx.RDB$INDEX_NAME = ids.RDB$INDEX_NAME
 
303
              if any const in RDB$RELATION_CONSTRAINTS with
 
304
                 const.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
 
305
                 (const.RDB$CONSTRAINT_TYPE = 'UNIQUE' OR
 
306
                  const.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY')
 
307
           abort 2;
 
308
           end_for;
 
309
         end;
 
310
end;
 
311
end_trigger
 
312
message 1: "Cannot delete PRIMARY KEY being used in FOREIGN KEY definition.",
 
313
message 2: "Cannot drop NOT NULL constraint for fields in PRIMARY/UNIQUE constraints.";
 
314
 
 
315
 
 
316
define trigger post_delete_constraint for rdb$relation_constraints
 
317
post erase:
 
318
begin
 
319
        if old.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' OR
 
320
           old.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' OR
 
321
           old.RDB$CONSTRAINT_TYPE = 'UNIQUE'     
 
322
        begin
 
323
          for i in RDB$INDICES with old.RDB$INDEX_NAME = i.RDB$INDEX_NAME 
 
324
                erase i;
 
325
                for is in RDB$INDEX_SEGMENTS 
 
326
                   with is.RDB$INDEX_NAME = i.RDB$INDEX_NAME erase is;
 
327
                end_for;
 
328
          end_for;
 
329
        end;
 
330
     
 
331
        if old.RDB$CONSTRAINT_TYPE = 'NOT NULL'
 
332
        begin
 
333
          for c in  RDB$CHECK_CONSTRAINTS cross
 
334
              f in rdb$relation_fields with
 
335
                 old.RDB$CONSTRAINT_NAME = c.RDB$CONSTRAINT_NAME and
 
336
                    f.RDB$RELATION_NAME = old.RDB$RELATION_NAME and
 
337
                    f.RDB$FIELD_NAME = c.RDB$TRIGGER_NAME
 
338
                    erase c;
 
339
                    modify f using
 
340
                      f.RDB$NULL_FLAG = 0;
 
341
                    end_modify;
 
342
          end_for;
 
343
        end;
 
344
 
 
345
        if old.RDB$CONSTRAINT_TYPE = 'CHECK'
 
346
        begin
 
347
            for chk in  RDB$CHECK_CONSTRAINTS
 
348
                with old.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME
 
349
              erase chk;
 
350
              for t in RDB$TRIGGERS
 
351
               with t.RDB$TRIGGER_NAME = chk.RDB$TRIGGER_NAME and
 
352
                    t.RDB$RELATION_NAME = old.RDB$RELATION_NAME
 
353
               erase t;
 
354
              end_for;
 
355
          end_for;
 
356
        end;
 
357
 
 
358
 
 
359
end;
 
360
end_trigger;
 
361
 
 
362
define trigger add_ref_constraint for rdb$ref_constraints
 
363
pre store:
 
364
begin
 
365
        if NOT ANY r in rdb$relation_constraints with 
 
366
                    r.RDB$CONSTRAINT_NAME = new.RDB$CONSTRAINT_NAME and
 
367
                 r.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'
 
368
           abort 1;
 
369
 
 
370
        if NOT ANY r in rdb$relation_constraints with
 
371
                    r. RDB$CONSTRAINT_NAME = new.RDB$CONST_NAME_UQ and
 
372
                    (r.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' OR 
 
373
                     r.RDB$CONSTRAINT_TYPE = 'UNIQUE')
 
374
           abort 2;
 
375
end;
 
376
end_trigger
 
377
message 1: "Name of Referential Constraint not defined in constraints relation.",
 
378
message 2: "Non-existent Primary or Unique key specifed for Foreign Key.";
 
379
 
 
380
define trigger update_ref_constraint for rdb$ref_constraints
 
381
pre modify:
 
382
begin
 
383
    abort 1;
 
384
end;
 
385
end_trigger
 
386
message 1: "Can't update constraints (RDB$REF_CONSTRAINTS).";
 
387
 
 
388
define trigger update_check_constraint for rdb$check_constraints
 
389
pre modify:
 
390
begin
 
391
    abort 1;
 
392
end;
 
393
end_trigger
 
394
message 1: "Can't update constraints (RDB$CHECK_CONSTRAINTS).";
 
395
 
 
396
define trigger pre_delete_check_constraint for rdb$check_constraints
 
397
pre erase:
 
398
begin
 
399
 
 
400
        if any c in RDB$RELATION_CONSTRAINTS with
 
401
           c.RDB$CONSTRAINT_NAME = old.RDB$CONSTRAINT_NAME 
 
402
           abort 2;
 
403
end;
 
404
end_trigger
 
405
message 1: "Can't delete CHECK constraint entry (RDB$CHECK_CONSTRAINTS)";
 
406
 
 
407
define trigger post_delete_check_constraint for rdb$check_constraints
 
408
post erase:
 
409
begin
 
410
       for f in rdb$relation_fields cross
 
411
            cnst in RDB$RELATION_CONSTRAINTS with
 
412
            f.RDB$RELATION_NAME = cnst.RDB$RELATION_NAME and
 
413
            cnst.RDB$CONSTRAINT_NAME = old.RDB$CONSTRAINT_NAME and
 
414
            cnst.RDB$CONSTRAINT_TYPE = 'NOT NULL' and
 
415
            f.RDB$FIELD_NAME = old.RDB$TRIGGER_NAME
 
416
           modify f using
 
417
              f.RDB$NULL_FLAG = 0;
 
418
           end_modify;
 
419
        end_for;
 
420
 
 
421
        for t in RDB$TRIGGERS cross
 
422
            cnst in RDB$RELATION_CONSTRAINTS with
 
423
            cnst.RDB$CONSTRAINT_NAME = old.RDB$CONSTRAINT_NAME and
 
424
            cnst.RDB$CONSTRAINT_TYPE = 'CHECK' and
 
425
            t.RDB$RELATION_NAME = cnst.RDB$RELATION_NAME and
 
426
            t.RDB$TRIGGER_NAME = old.RDB$TRIGGER_NAME
 
427
            erase t;
 
428
        end_for;
 
429
 
 
430
end;
 
431
end_trigger;
 
432
 
 
433
define trigger delete_constraint_segs for rdb$index_segments
 
434
pre erase:
 
435
begin
 
436
        if any c in RDB$RELATION_CONSTRAINTS with 
 
437
           c.RDB$INDEX_NAME = old.RDB$INDEX_NAME
 
438
        abort 1;
 
439
end;
 
440
end_trigger
 
441
message 1: "Can't delete index segment used by an Integrity Constraint";
 
442
 
 
443
 
 
444
define trigger update_constraint_segs for rdb$index_segments
 
445
pre modify:
 
446
begin
 
447
        if any c in RDB$RELATION_CONSTRAINTS with 
 
448
           c.RDB$INDEX_NAME = old.RDB$INDEX_NAME
 
449
        abort 1;
 
450
end;
 
451
end_trigger
 
452
message 1: "Can't update index segment used by an Integrity Constraint";
 
453
 
 
454
define trigger delete_constraint_idx for rdb$indices
 
455
pre erase:
 
456
begin
 
457
        if any c in RDB$RELATION_CONSTRAINTS with 
 
458
           c.RDB$INDEX_NAME = old.RDB$INDEX_NAME
 
459
        abort 1;
 
460
end;
 
461
end_trigger
 
462
message 1: "Can't delete index used by an Integrity Constraint";
 
463
 
 
464
define trigger update_constraint_idx for rdb$indices
 
465
pre modify :
 
466
begin
 
467
        if any c in RDB$RELATION_CONSTRAINTS with 
 
468
           c.RDB$INDEX_NAME = old.RDB$INDEX_NAME
 
469
        begin
 
470
            if NOT (old.RDB$INDEX_NAME = new.RDB$INDEX_NAME AND
 
471
                old.RDB$RELATION_NAME = new.RDB$RELATION_NAME AND
 
472
                old.RDB$INDEX_ID = new.RDB$INDEX_ID AND
 
473
                old.RDB$SEGMENT_COUNT = new.RDB$SEGMENT_COUNT AND
 
474
                old.RDB$FOREIGN_KEY = new.RDB$FOREIGN_KEY) 
 
475
            abort 1;
 
476
        end;
 
477
        for cnst in RDB$RELATION_CONSTRAINTS cross
 
478
            idx1 in RDB$INDICES cross
 
479
            idx2 in RDB$INDICES
 
480
            with
 
481
                cnst.RDB$INDEX_NAME = old.RDB$INDEX_NAME and
 
482
                idx1.RDB$INDEX_NAME = old.RDB$INDEX_NAME and
 
483
                idx2.RDB$FOREIGN_KEY = old.RDB$INDEX_NAME and
 
484
                new.RDB$INDEX_INACTIVE = 1 and
 
485
                ( old.RDB$INDEX_INACTIVE = 0 or
 
486
                  old.RDB$INDEX_INACTIVE = null)
 
487
                    abort 2;
 
488
        end_for;
 
489
        if any c in RDB$RELATION_CONSTRAINTS with 
 
490
           c.RDB$INDEX_NAME = old.RDB$INDEX_NAME and
 
491
           ( c.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' or
 
492
             c.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY')
 
493
        begin
 
494
           if new.RDB$INDEX_INACTIVE = 1 and
 
495
              ( old.RDB$INDEX_INACTIVE = 0 or
 
496
                old.RDB$INDEX_INACTIVE = null)
 
497
              abort 3;
 
498
        end;
 
499
end;
 
500
end_trigger
 
501
message 1: "Can't modify index used by an Integrity Constraint",
 
502
message 2: "Can't deactivate index used by an Integrity Constraint",
 
503
message 3: "Can't deactivate a primary index";
 
504
 
 
505
define trigger delete_constraint_trigger for rdb$triggers
 
506
pre erase:
 
507
begin
 
508
        for chk in RDB$CHECK_CONSTRAINTS cross
 
509
            cnst in RDB$RELATION_CONSTRAINTS with
 
510
            chk.RDB$TRIGGER_NAME = old.RDB$TRIGGER_NAME and
 
511
            cnst.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME and
 
512
            cnst.RDB$CONSTRAINT_TYPE = 'CHECK'
 
513
               abort 1;
 
514
        end_for;
 
515
 
 
516
end;
 
517
end_trigger
 
518
message 1: "Can't delete trigger used by an Integrity Constraint";
 
519
 
 
520
define trigger update_constraint_trigger for rdb$triggers
 
521
pre modify:
 
522
begin
 
523
        for chk in RDB$CHECK_CONSTRAINTS cross
 
524
            cnst in RDB$RELATION_CONSTRAINTS with
 
525
            chk.RDB$TRIGGER_NAME = old.RDB$TRIGGER_NAME and
 
526
            cnst.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME and
 
527
            cnst.RDB$CONSTRAINT_TYPE = 'CHECK'
 
528
               abort 1;
 
529
        end_for;
 
530
 
 
531
end;
 
532
end_trigger
 
533
message 1: "Can't update trigger used by a CHECK Constraint";
 
534
 
 
535
define trigger pre_delete_field for rdb$relation_fields
 
536
pre erase:
 
537
begin
 
538
 
 
539
for idx in RDB$INDICES cross
 
540
    cnst in RDB$RELATION_CONSTRAINTS cross
 
541
    ids in RDB$INDEX_SEGMENTS with
 
542
    idx.RDB$RELATION_NAME = old.RDB$RELATION_NAME AND
 
543
    idx.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
 
544
    cnst.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
 
545
    ids.RDB$FIELD_NAME = old.RDB$FIELD_NAME AND
 
546
    (cnst.RDB$CONSTRAINT_TYPE = 'UNIQUE' OR
 
547
     cnst.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' OR
 
548
     cnst.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY')
 
549
     if any ids1 in RDB$INDEX_SEGMENTS with
 
550
        ids1.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
 
551
        ids1.RDB$FIELD_NAME NE old.RDB$FIELD_NAME
 
552
           abort 1
 
553
     else
 
554
        erase cnst;
 
555
end_for;
 
556
 
 
557
for cnst in RDB$RELATION_CONSTRAINTS cross
 
558
        chk in RDB$CHECK_CONSTRAINTS over RDB$CONSTRAINT_NAME cross
 
559
        dep in RDB$DEPENDENCIES with
 
560
        cnst.RDB$RELATION_NAME = old.RDB$RELATION_NAME and 
 
561
        cnst.RDB$CONSTRAINT_TYPE = 'CHECK' and
 
562
        chk.RDB$TRIGGER_NAME = dep.RDB$DEPENDENT_NAME and 
 
563
        dep.RDB$DEPENDENT_TYPE = 2 and
 
564
        dep.RDB$DEPENDED_ON_TYPE = 0 and
 
565
        dep.RDB$DEPENDED_ON_NAME = old.RDB$RELATION_NAME and
 
566
        dep.RDB$FIELD_NAME = old.RDB$FIELD_NAME
 
567
        
 
568
        if any dep1 in RDB$DEPENDENCIES with
 
569
                dep1.RDB$DEPENDENT_NAME = chk.RDB$TRIGGER_NAME and
 
570
                dep1.RDB$DEPENDENT_TYPE = 2 and
 
571
                dep1.RDB$DEPENDED_ON_TYPE = 0 and
 
572
                dep1.RDB$DEPENDED_ON_NAME = old.RDB$RELATION_NAME and
 
573
                dep1.RDB$FIELD_NAME NE old.RDB$FIELD_NAME
 
574
                        abort 1
 
575
        else
 
576
                erase cnst;
 
577
end_for;
 
578
 
 
579
end;
 
580
end_trigger
 
581
message 1: "Cannot delete field being used in an integrity constraint.";
 
582
 
 
583
define trigger pre_modify_field for rdb$relation_fields
 
584
pre modify:
 
585
begin
 
586
 
 
587
if old.rdb$field_name != new.rdb$field_name
 
588
for idx in RDB$INDICES cross
 
589
    cnst in RDB$RELATION_CONSTRAINTS cross
 
590
    ids in RDB$INDEX_SEGMENTS with
 
591
    idx.RDB$RELATION_NAME = old.RDB$RELATION_NAME AND
 
592
    idx.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
 
593
    cnst.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
 
594
    ids.RDB$FIELD_NAME = old.RDB$FIELD_NAME AND
 
595
    (cnst.RDB$CONSTRAINT_TYPE = 'UNIQUE' OR
 
596
     cnst.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' OR
 
597
     cnst.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY')
 
598
           abort 1;
 
599
end_for;
 
600
 
 
601
end;
 
602
end_trigger
 
603
message 1: "Cannot rename field being used in an integrity constraint.";
 
604
 
 
605
define trigger post_delete_field for rdb$relation_fields
 
606
post erase:
 
607
begin
 
608
 
 
609
for chk in RDB$CHECK_CONSTRAINTS cross
 
610
    const in RDB$RELATION_CONSTRAINTS with
 
611
    old.RDB$FIELD_NAME = chk.RDB$TRIGGER_NAME AND
 
612
    const.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME AND
 
613
    old.RDB$RELATION_NAME = const.RDB$RELATION_NAME AND
 
614
    const.RDB$CONSTRAINT_TYPE = 'NOT NULL'
 
615
 
 
616
    erase const;
 
617
    erase chk;
 
618
 
 
619
end_for;
 
620
end;
 
621
end_trigger;
 
622
 
 
623
define trigger system_protection_5 for rdb$procedures pre store 0
 
624
    begin
 
625
    if new.rdb$owner_name missing
 
626
        new.rdb$owner_name = UPPERCASE (rdb$user_name);
 
627
    new.rdb$procedure_id = gen_id (RDB$PROCEDURES, 1);
 
628
    end;
 
629
end_trigger;
 
630
 
 
631
define trigger system_protection_6 for rdb$procedures pre modify 0
 
632
    if old.rdb$owner_name ne new.rdb$owner_name and
 
633
       old.rdb$owner_name ne UPPERCASE (rdb$user_name)
 
634
        abort 0;
 
635
end_trigger;
 
636
 
 
637
define trigger new_exception for rdb$exceptions pre store 0
 
638
    begin
 
639
    new.rdb$exception_number = gen_id (RDB$EXCEPTIONS, 1);
 
640
    end;
 
641
end_trigger;
 
642
 
 
643
define trigger post_del_for_constraint for rdb$relation_constraints
 
644
post erase:
 
645
begin
 
646
        /* To be able to drop foreign key constriants with 
 
647
           referential action. When this trigger fires, it
 
648
           runs without checking for any privileges. This is an ODS
 
649
           8.1 trigger */
 
650
 
 
651
        if old.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'
 
652
        begin
 
653
            for chk in  RDB$CHECK_CONSTRAINTS
 
654
                with old.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME
 
655
              erase chk;
 
656
 
 
657
              for t in RDB$TRIGGERS
 
658
               with t.RDB$TRIGGER_NAME = chk.RDB$TRIGGER_NAME 
 
659
               erase t;
 
660
              end_for;
 
661
          end_for;
 
662
        end;
 
663
 
 
664
end;
 
665
end_trigger;
 
666
 
 
667
define trigger post_del_check_for_constraint for rdb$check_constraints
 
668
post erase:
 
669
begin
 
670
        /* To be able to drop foreign key constriants with 
 
671
           referential action.  When this trigger fires, it
 
672
           runs without checking for any privileges.  This is an ODS
 
673
           8.1 trigger */
 
674
 
 
675
        for t in RDB$TRIGGERS cross
 
676
            cnst in RDB$RELATION_CONSTRAINTS with
 
677
            cnst.RDB$CONSTRAINT_NAME = old.RDB$CONSTRAINT_NAME and
 
678
            cnst.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' and
 
679
            t.RDB$TRIGGER_NAME = old.RDB$TRIGGER_NAME
 
680
            erase t;
 
681
        end_for;
 
682
 
 
683
end;
 
684
end_trigger;
 
685
 
 
686
 
 
687
/* this trigger (grantor_check_trigger) was added as a fix to bug 8071.
 
688
   the same trigger is defined for ON UPDATE and ON DELETE, in
 
689
   addition to the ON INSERT (below). This is an ODS 8.1 trigger. 
 
690
*/
 
691
define trigger grantor_check_trigger for rdb$user_privileges pre store 0
 
692
    begin
 
693
        /* If grantor is missing, trigger grant_trigger will assign it to
 
694
           rdb$user_name.
 
695
           If the grantor is not the current user or SYSDBA, make sure
 
696
           the grantor is the owner of the table.
 
697
         */
 
698
        if ( (new.rdb$grantor not missing) and
 
699
             (new.rdb$grantor ne UPPERCASE (rdb$user_name)) and
 
700
             (UPPERCASE (rdb$user_name) ne "SYSDBA")
 
701
           )
 
702
           begin
 
703
           for rel in rdb$relations with
 
704
               rel.rdb$relation_name = "RDB$DATABASE"
 
705
               if ( (rel.rdb$owner_name missing) or
 
706
                    (rel.rdb$owner_name ne UPPERCASE(rdb$user_name)) )
 
707
                   abort 0;
 
708
           end_for
 
709
           end
 
710
    end;
 
711
end_trigger;
 
712