8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-30 18:43:03 +01:00
firebird-mirror/src/jrd/grant.gdl

713 lines
22 KiB
Plaintext

/*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
define database "bar.gdb";
/*
define generator RDB$SECURITY_CLASS;
define generator SQL$DEFAULT;
define generator RDB$PROCEDURES;
define generator RDB$EXCEPTIONS;
*/
/*
* The SYSDBA_USER_NAME name is assumed to be "SYSDBA" in the
* below trigger
*/
define trigger grant_trigger for rdb$user_privileges pre store 0
begin
if new.rdb$object_type = 0
begin
if not any rel in rdb$relations
with rel.rdb$relation_name eq new.rdb$relation_name
abort 0;
if new.rdb$field_name not missing
if not any rlf in rdb$relation_fields
with rlf.rdb$relation_name eq new.rdb$relation_name and
rlf.rdb$field_name eq new.rdb$field_name
abort 1;
end;
if new.rdb$object_type = 5 and
not any prc in rdb$procedures
with prc.rdb$procedure_name eq new.rdb$relation_name
abort 0;
if new.rdb$user_type = 0 or new.rdb$user_type = 3 or
new.rdb$user_type = 4 or new.rdb$user_type = 6 or
new.rdb$user_type = 7 or new.rdb$user_type = 8 or
new.rdb$user_type = 9 or new.rdb$user_type = 10 or
new.rdb$user_type = 11 or new.rdb$user_type = 12
new.rdb$user = UPPERCASE (new.rdb$user);
if new.rdb$grantor missing
new.rdb$grantor = UPPERCASE (rdb$user_name);
if new.rdb$object_type = 0
begin
/* Verify that the grantor has the 'grant option'. */
for rel in rdb$relations
with rel.rdb$relation_name eq new.rdb$relation_name
/* As part of the creation of a table/view, the creator gets
records that gives him/her all privileges. */
if rel.rdb$owner_name eq UPPERCASE (rdb$user_name) and
rel.rdb$owner_name eq new.rdb$grantor and
rel.rdb$owner_name eq new.rdb$user or
UPPERCASE (rdb$user_name) eq "SYSDBA"
begin
end
else
/* The owner always has the grant option.
A non-owner should have the grant option explicitely granted. */
if rel.rdb$owner_name ne UPPERCASE (rdb$user_name)
begin
if not any priv in rdb$user_privileges
with priv.rdb$relation_name eq new.rdb$relation_name and
priv.rdb$object_type eq 0 and
priv.rdb$privilege eq new.rdb$privilege and
priv.rdb$user eq new.rdb$grantor and
priv.rdb$user_type eq 8 and
priv.rdb$grant_option ne 0 and
(priv.rdb$field_name missing or
priv.rdb$field_name eq new.rdb$field_name)
abort 2;
end
else
/* If a view-owner is granting privileges on his/her view, then
verify that the view owner has the grant option on the base table/view. */
if new.rdb$field_name not missing
begin
for fld in rdb$relation_fields cross
view in rdb$view_relations cross
rel2 in rdb$relations
with fld.rdb$field_name eq new.rdb$field_name and
fld.rdb$relation_name eq new.rdb$relation_name and
fld.rdb$base_field not missing and
view.rdb$view_name eq fld.rdb$relation_name and
view.rdb$view_context eq fld.rdb$view_context and
view.rdb$relation_name eq rel2.rdb$relation_name
if rel2.rdb$owner_name ne rel.rdb$owner_name
and UPPERCASE (rdb$user_name) ne "SYSDBA"
begin
if not any priv in rdb$user_privileges
with priv.rdb$relation_name eq rel2.rdb$relation_name and
priv.rdb$object_type eq 0 and
priv.rdb$privilege eq new.rdb$privilege and
priv.rdb$user eq rel.rdb$owner_name and
priv.rdb$user_type eq 8 and
priv.rdb$grant_option ne 0 and
(priv.rdb$field_name missing or
priv.rdb$field_name eq fld.rdb$base_field)
abort 5;
end;
end_for;
end
else
begin
for view in rdb$view_relations cross
rel2 in rdb$relations
with view.rdb$view_name eq new.rdb$relation_name and
view.rdb$relation_name eq rel2.rdb$relation_name
if rel2.rdb$owner_name ne rel.rdb$owner_name
and UPPERCASE (rdb$user_name) ne "SYSDBA"
begin
if not any priv in rdb$user_privileges
with priv.rdb$relation_name eq rel2.rdb$relation_name and
priv.rdb$object_type eq 0 and
priv.rdb$privilege eq new.rdb$privilege and
priv.rdb$user eq rel.rdb$owner_name and
priv.rdb$user_type eq 8 and
priv.rdb$grant_option ne 0 and
priv.rdb$field_name missing
abort 5;
end;
end_for;
end
if rel.rdb$security_class missing
modify rel
rel.rdb$security_class = "SQL$" | rel.rdb$relation_name;
end_modify
else if rel.rdb$security_class != "SQL$" | rel.rdb$relation_name
abort 3;
end_for;
if new.rdb$field_name not missing
for rfl in rdb$relation_fields
with rfl.rdb$relation_name eq new.rdb$relation_name and
rfl.rdb$field_name eq new.rdb$field_name
if rfl.rdb$security_class missing
modify rfl
rfl.rdb$security_class = "SQL$GRANT" | gen_id (RDB$SECURITY_CLASS, 1);
end_modify;
else if rfl.rdb$security_class not starting "SQL$GRANT"
abort 4;
end_for;
end
else if new.rdb$object_type = 5
for prc in rdb$procedures
with prc.rdb$procedure_name eq new.rdb$relation_name
if prc.rdb$owner_name ne UPPERCASE (rdb$user_name)
and UPPERCASE (rdb$user_name) ne "SYSDBA"
if not any priv in rdb$user_privileges
with priv.rdb$relation_name eq new.rdb$relation_name and
priv.rdb$object_type eq 5 and
priv.rdb$privilege eq new.rdb$privilege and
priv.rdb$user eq new.rdb$grantor and
priv.rdb$user_type eq 8 and
priv.rdb$grant_option ne 0 and
(priv.rdb$field_name missing or
priv.rdb$field_name eq new.rdb$field_name)
abort 2;
if prc.rdb$security_class missing
modify prc
prc.rdb$security_class = "SQL$" | prc.rdb$procedure_name;
end_modify
else if prc.rdb$security_class != "SQL$" | prc.rdb$procedure_name
abort 3;
end_for;
end;
end_trigger;
/***
define trigger revoke_trigger for rdb$user_privileges pre erase 0
if old.rdb$grantor ne UPPERCASE (rdb$user_name)
abort 0;
end_trigger;
***/
define trigger revoke_trigger for rdb$user_privileges pre erase 0
if old.rdb$field_name not missing
for rf in rdb$relation_fields
with rf.rdb$relation_name eq old.rdb$relation_name and
rf.rdb$field_name eq old.rdb$field_name
if rf.rdb$security_class starting "SQL$GRANT"
begin
for sec in rdb$security_classes
with sec.rdb$security_class eq rf.rdb$security_class
erase sec;
end_for;
modify rf
rf.rdb$security_class = null;
end_modify;
end;
end_for;
end_trigger;
define trigger grant_revoke for rdb$user_privileges pre modify 0
abort 0;
end_trigger;
define trigger system_protection_1 for rdb$triggers pre modify 0
if old.rdb$system_flag = 1
abort 0;
end_trigger;
define trigger system_protection_2 for rdb$triggers pre erase 0
if old.rdb$system_flag = 1
abort 0;
end_trigger;
define trigger system_protection_3 for rdb$relations pre store 0
if new.rdb$owner_name missing
new.rdb$owner_name = UPPERCASE (rdb$user_name);
end_trigger;
define trigger system_protection_4 for rdb$relations pre modify 0
if old.rdb$owner_name ne new.rdb$owner_name and
old.rdb$owner_name ne UPPERCASE (rdb$user_name)
abort 0;
end_trigger;
/* triggers for integrity constraints */
define trigger add_constraint for rdb$relation_constraints
pre store:
begin
if any r in rdb$relations with
r.rdb$relation_name = new.rdb$relation_name
and r.rdb$view_source not missing
abort 1;
if NOT (new.RDB$CONSTRAINT_TYPE = 'UNIQUE' OR
new.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' OR
new.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' OR
new.RDB$CONSTRAINT_TYPE = 'NOT NULL' OR
new.RDB$CONSTRAINT_TYPE = 'CHECK')
abort 2;
if (new.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY')
begin
if ANY r in rdb$relation_constraints with
r.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY'
and r.rdb$relation_name = new.rdb$relation_name
abort 3;
end;
end;
end_trigger
message 1: "Cannot define constraints on VIEWS",
message 2: "internal gds software consistency check (Invalid RDB$CONSTRAINT_TYPE)",
message 3: "Attempt to define a second primary key for the same relation";
define trigger update_constraint for rdb$relation_constraints
pre modify:
begin
abort 1;
end;
end_trigger
message 1: "Can't update constraints (RDB$RELATION_CONSTRAINTS).";
define trigger pre_delete_constraint for rdb$relation_constraints
pre erase:
begin
if old.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' OR
old.RDB$CONSTRAINT_TYPE = 'UNIQUE'
begin
if ANY r in rdb$ref_constraints with
r.rdb$CONST_NAME_UQ = old.rdb$constraint_name
abort 1;
end;
if old.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'
begin
for c in RDB$REF_CONSTRAINTS
with old.RDB$CONSTRAINT_NAME = c.RDB$CONSTRAINT_NAME
erase c;
end_for;
end;
if old.RDB$CONSTRAINT_TYPE = 'NOT NULL'
begin
for chk in RDB$CHECK_CONSTRAINTS cross
fld in RDB$RELATION_FIELDS cross
idx in RDB$INDICES cross
ids in RDB$INDEX_SEGMENTS with
old.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME AND
fld.RDB$FIELD_NAME = chk.RDB$TRIGGER_NAME AND
fld.RDB$RELATION_NAME = old.RDB$RELATION_NAME AND
fld.RDB$FIELD_NAME = ids.RDB$FIELD_NAME AND
idx.RDB$RELATION_NAME = old.RDB$RELATION_NAME AND
idx.RDB$INDEX_NAME = ids.RDB$INDEX_NAME
if any const in RDB$RELATION_CONSTRAINTS with
const.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
(const.RDB$CONSTRAINT_TYPE = 'UNIQUE' OR
const.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY')
abort 2;
end_for;
end;
end;
end_trigger
message 1: "Cannot delete PRIMARY KEY being used in FOREIGN KEY definition.",
message 2: "Cannot drop NOT NULL constraint for fields in PRIMARY/UNIQUE constraints.";
define trigger post_delete_constraint for rdb$relation_constraints
post erase:
begin
if old.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' OR
old.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' OR
old.RDB$CONSTRAINT_TYPE = 'UNIQUE'
begin
for i in RDB$INDICES with old.RDB$INDEX_NAME = i.RDB$INDEX_NAME
erase i;
for is in RDB$INDEX_SEGMENTS
with is.RDB$INDEX_NAME = i.RDB$INDEX_NAME erase is;
end_for;
end_for;
end;
if old.RDB$CONSTRAINT_TYPE = 'NOT NULL'
begin
for c in RDB$CHECK_CONSTRAINTS cross
f in rdb$relation_fields with
old.RDB$CONSTRAINT_NAME = c.RDB$CONSTRAINT_NAME and
f.RDB$RELATION_NAME = old.RDB$RELATION_NAME and
f.RDB$FIELD_NAME = c.RDB$TRIGGER_NAME
erase c;
modify f using
f.RDB$NULL_FLAG = 0;
end_modify;
end_for;
end;
if old.RDB$CONSTRAINT_TYPE = 'CHECK'
begin
for chk in RDB$CHECK_CONSTRAINTS
with old.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME
erase chk;
for t in RDB$TRIGGERS
with t.RDB$TRIGGER_NAME = chk.RDB$TRIGGER_NAME and
t.RDB$RELATION_NAME = old.RDB$RELATION_NAME
erase t;
end_for;
end_for;
end;
end;
end_trigger;
define trigger add_ref_constraint for rdb$ref_constraints
pre store:
begin
if NOT ANY r in rdb$relation_constraints with
r.RDB$CONSTRAINT_NAME = new.RDB$CONSTRAINT_NAME and
r.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'
abort 1;
if NOT ANY r in rdb$relation_constraints with
r. RDB$CONSTRAINT_NAME = new.RDB$CONST_NAME_UQ and
(r.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' OR
r.RDB$CONSTRAINT_TYPE = 'UNIQUE')
abort 2;
end;
end_trigger
message 1: "Name of Referential Constraint not defined in constraints relation.",
message 2: "Non-existent Primary or Unique key specifed for Foreign Key.";
define trigger update_ref_constraint for rdb$ref_constraints
pre modify:
begin
abort 1;
end;
end_trigger
message 1: "Can't update constraints (RDB$REF_CONSTRAINTS).";
define trigger update_check_constraint for rdb$check_constraints
pre modify:
begin
abort 1;
end;
end_trigger
message 1: "Can't update constraints (RDB$CHECK_CONSTRAINTS).";
define trigger pre_delete_check_constraint for rdb$check_constraints
pre erase:
begin
if any c in RDB$RELATION_CONSTRAINTS with
c.RDB$CONSTRAINT_NAME = old.RDB$CONSTRAINT_NAME
abort 2;
end;
end_trigger
message 1: "Can't delete CHECK constraint entry (RDB$CHECK_CONSTRAINTS)";
define trigger post_delete_check_constraint for rdb$check_constraints
post erase:
begin
for f in rdb$relation_fields cross
cnst in RDB$RELATION_CONSTRAINTS with
f.RDB$RELATION_NAME = cnst.RDB$RELATION_NAME and
cnst.RDB$CONSTRAINT_NAME = old.RDB$CONSTRAINT_NAME and
cnst.RDB$CONSTRAINT_TYPE = 'NOT NULL' and
f.RDB$FIELD_NAME = old.RDB$TRIGGER_NAME
modify f using
f.RDB$NULL_FLAG = 0;
end_modify;
end_for;
for t in RDB$TRIGGERS cross
cnst in RDB$RELATION_CONSTRAINTS with
cnst.RDB$CONSTRAINT_NAME = old.RDB$CONSTRAINT_NAME and
cnst.RDB$CONSTRAINT_TYPE = 'CHECK' and
t.RDB$RELATION_NAME = cnst.RDB$RELATION_NAME and
t.RDB$TRIGGER_NAME = old.RDB$TRIGGER_NAME
erase t;
end_for;
end;
end_trigger;
define trigger delete_constraint_segs for rdb$index_segments
pre erase:
begin
if any c in RDB$RELATION_CONSTRAINTS with
c.RDB$INDEX_NAME = old.RDB$INDEX_NAME
abort 1;
end;
end_trigger
message 1: "Can't delete index segment used by an Integrity Constraint";
define trigger update_constraint_segs for rdb$index_segments
pre modify:
begin
if any c in RDB$RELATION_CONSTRAINTS with
c.RDB$INDEX_NAME = old.RDB$INDEX_NAME
abort 1;
end;
end_trigger
message 1: "Can't update index segment used by an Integrity Constraint";
define trigger delete_constraint_idx for rdb$indices
pre erase:
begin
if any c in RDB$RELATION_CONSTRAINTS with
c.RDB$INDEX_NAME = old.RDB$INDEX_NAME
abort 1;
end;
end_trigger
message 1: "Can't delete index used by an Integrity Constraint";
define trigger update_constraint_idx for rdb$indices
pre modify :
begin
if any c in RDB$RELATION_CONSTRAINTS with
c.RDB$INDEX_NAME = old.RDB$INDEX_NAME
begin
if NOT (old.RDB$INDEX_NAME = new.RDB$INDEX_NAME AND
old.RDB$RELATION_NAME = new.RDB$RELATION_NAME AND
old.RDB$INDEX_ID = new.RDB$INDEX_ID AND
old.RDB$SEGMENT_COUNT = new.RDB$SEGMENT_COUNT AND
old.RDB$FOREIGN_KEY = new.RDB$FOREIGN_KEY)
abort 1;
end;
for cnst in RDB$RELATION_CONSTRAINTS cross
idx1 in RDB$INDICES cross
idx2 in RDB$INDICES
with
cnst.RDB$INDEX_NAME = old.RDB$INDEX_NAME and
idx1.RDB$INDEX_NAME = old.RDB$INDEX_NAME and
idx2.RDB$FOREIGN_KEY = old.RDB$INDEX_NAME and
new.RDB$INDEX_INACTIVE = 1 and
( old.RDB$INDEX_INACTIVE = 0 or
old.RDB$INDEX_INACTIVE = null)
abort 2;
end_for;
if any c in RDB$RELATION_CONSTRAINTS with
c.RDB$INDEX_NAME = old.RDB$INDEX_NAME and
( c.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' or
c.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY')
begin
if new.RDB$INDEX_INACTIVE = 1 and
( old.RDB$INDEX_INACTIVE = 0 or
old.RDB$INDEX_INACTIVE = null)
abort 3;
end;
end;
end_trigger
message 1: "Can't modify index used by an Integrity Constraint",
message 2: "Can't deactivate index used by an Integrity Constraint",
message 3: "Can't deactivate a primary index";
define trigger delete_constraint_trigger for rdb$triggers
pre erase:
begin
for chk in RDB$CHECK_CONSTRAINTS cross
cnst in RDB$RELATION_CONSTRAINTS with
chk.RDB$TRIGGER_NAME = old.RDB$TRIGGER_NAME and
cnst.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME and
cnst.RDB$CONSTRAINT_TYPE = 'CHECK'
abort 1;
end_for;
end;
end_trigger
message 1: "Can't delete trigger used by an Integrity Constraint";
define trigger update_constraint_trigger for rdb$triggers
pre modify:
begin
for chk in RDB$CHECK_CONSTRAINTS cross
cnst in RDB$RELATION_CONSTRAINTS with
chk.RDB$TRIGGER_NAME = old.RDB$TRIGGER_NAME and
cnst.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME and
cnst.RDB$CONSTRAINT_TYPE = 'CHECK'
abort 1;
end_for;
end;
end_trigger
message 1: "Can't update trigger used by a CHECK Constraint";
define trigger pre_delete_field for rdb$relation_fields
pre erase:
begin
for idx in RDB$INDICES cross
cnst in RDB$RELATION_CONSTRAINTS cross
ids in RDB$INDEX_SEGMENTS with
idx.RDB$RELATION_NAME = old.RDB$RELATION_NAME AND
idx.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
cnst.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
ids.RDB$FIELD_NAME = old.RDB$FIELD_NAME AND
(cnst.RDB$CONSTRAINT_TYPE = 'UNIQUE' OR
cnst.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' OR
cnst.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY')
if any ids1 in RDB$INDEX_SEGMENTS with
ids1.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
ids1.RDB$FIELD_NAME NE old.RDB$FIELD_NAME
abort 1
else
erase cnst;
end_for;
for cnst in RDB$RELATION_CONSTRAINTS cross
chk in RDB$CHECK_CONSTRAINTS over RDB$CONSTRAINT_NAME cross
dep in RDB$DEPENDENCIES with
cnst.RDB$RELATION_NAME = old.RDB$RELATION_NAME and
cnst.RDB$CONSTRAINT_TYPE = 'CHECK' and
chk.RDB$TRIGGER_NAME = dep.RDB$DEPENDENT_NAME and
dep.RDB$DEPENDENT_TYPE = 2 and
dep.RDB$DEPENDED_ON_TYPE = 0 and
dep.RDB$DEPENDED_ON_NAME = old.RDB$RELATION_NAME and
dep.RDB$FIELD_NAME = old.RDB$FIELD_NAME
if any dep1 in RDB$DEPENDENCIES with
dep1.RDB$DEPENDENT_NAME = chk.RDB$TRIGGER_NAME and
dep1.RDB$DEPENDENT_TYPE = 2 and
dep1.RDB$DEPENDED_ON_TYPE = 0 and
dep1.RDB$DEPENDED_ON_NAME = old.RDB$RELATION_NAME and
dep1.RDB$FIELD_NAME NE old.RDB$FIELD_NAME
abort 1
else
erase cnst;
end_for;
end;
end_trigger
message 1: "Cannot delete field being used in an integrity constraint.";
define trigger pre_modify_field for rdb$relation_fields
pre modify:
begin
if old.rdb$field_name != new.rdb$field_name
for idx in RDB$INDICES cross
cnst in RDB$RELATION_CONSTRAINTS cross
ids in RDB$INDEX_SEGMENTS with
idx.RDB$RELATION_NAME = old.RDB$RELATION_NAME AND
idx.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
cnst.RDB$INDEX_NAME = ids.RDB$INDEX_NAME AND
ids.RDB$FIELD_NAME = old.RDB$FIELD_NAME AND
(cnst.RDB$CONSTRAINT_TYPE = 'UNIQUE' OR
cnst.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' OR
cnst.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY')
abort 1;
end_for;
end;
end_trigger
message 1: "Cannot rename field being used in an integrity constraint.";
define trigger post_delete_field for rdb$relation_fields
post erase:
begin
for chk in RDB$CHECK_CONSTRAINTS cross
const in RDB$RELATION_CONSTRAINTS with
old.RDB$FIELD_NAME = chk.RDB$TRIGGER_NAME AND
const.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME AND
old.RDB$RELATION_NAME = const.RDB$RELATION_NAME AND
const.RDB$CONSTRAINT_TYPE = 'NOT NULL'
erase const;
erase chk;
end_for;
end;
end_trigger;
define trigger system_protection_5 for rdb$procedures pre store 0
begin
if new.rdb$owner_name missing
new.rdb$owner_name = UPPERCASE (rdb$user_name);
new.rdb$procedure_id = gen_id (RDB$PROCEDURES, 1);
end;
end_trigger;
define trigger system_protection_6 for rdb$procedures pre modify 0
if old.rdb$owner_name ne new.rdb$owner_name and
old.rdb$owner_name ne UPPERCASE (rdb$user_name)
abort 0;
end_trigger;
define trigger new_exception for rdb$exceptions pre store 0
begin
new.rdb$exception_number = gen_id (RDB$EXCEPTIONS, 1);
end;
end_trigger;
define trigger post_del_for_constraint for rdb$relation_constraints
post erase:
begin
/* To be able to drop foreign key constriants with
referential action. When this trigger fires, it
runs without checking for any privileges. This is an ODS
8.1 trigger */
if old.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'
begin
for chk in RDB$CHECK_CONSTRAINTS
with old.RDB$CONSTRAINT_NAME = chk.RDB$CONSTRAINT_NAME
erase chk;
for t in RDB$TRIGGERS
with t.RDB$TRIGGER_NAME = chk.RDB$TRIGGER_NAME
erase t;
end_for;
end_for;
end;
end;
end_trigger;
define trigger post_del_check_for_constraint for rdb$check_constraints
post erase:
begin
/* To be able to drop foreign key constriants with
referential action. When this trigger fires, it
runs without checking for any privileges. This is an ODS
8.1 trigger */
for t in RDB$TRIGGERS cross
cnst in RDB$RELATION_CONSTRAINTS with
cnst.RDB$CONSTRAINT_NAME = old.RDB$CONSTRAINT_NAME and
cnst.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' and
t.RDB$TRIGGER_NAME = old.RDB$TRIGGER_NAME
erase t;
end_for;
end;
end_trigger;
/* this trigger (grantor_check_trigger) was added as a fix to bug 8071.
the same trigger is defined for ON UPDATE and ON DELETE, in
addition to the ON INSERT (below). This is an ODS 8.1 trigger.
*/
define trigger grantor_check_trigger for rdb$user_privileges pre store 0
begin
/* If grantor is missing, trigger grant_trigger will assign it to
rdb$user_name.
If the grantor is not the current user or SYSDBA, make sure
the grantor is the owner of the table.
*/
if ( (new.rdb$grantor not missing) and
(new.rdb$grantor ne UPPERCASE (rdb$user_name)) and
(UPPERCASE (rdb$user_name) ne "SYSDBA")
)
begin
for rel in rdb$relations with
rel.rdb$relation_name = "RDB$DATABASE"
if ( (rel.rdb$owner_name missing) or
(rel.rdb$owner_name ne UPPERCASE(rdb$user_name)) )
abort 0;
end_for
end
end;
end_trigger;