Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
b7b6d4bf
Commit
b7b6d4bf
authored
Jan 06, 2000
by
Jan Wieck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changed "triggered data change violation" detection code
in trigger manager. Jan
parent
88016a56
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
427 additions
and
294 deletions
+427
-294
src/backend/commands/trigger.c
src/backend/commands/trigger.c
+161
-165
src/backend/parser/analyze.c
src/backend/parser/analyze.c
+125
-125
src/backend/utils/adt/ri_triggers.c
src/backend/utils/adt/ri_triggers.c
+124
-1
src/include/catalog/pg_proc.h
src/include/catalog/pg_proc.h
+5
-1
src/include/commands/trigger.h
src/include/commands/trigger.h
+9
-1
src/include/utils/builtins.h
src/include/utils/builtins.h
+3
-1
No files found.
src/backend/commands/trigger.c
View file @
b7b6d4bf
This diff is collapsed.
Click to expand it.
src/backend/parser/analyze.c
View file @
b7b6d4bf
...
...
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: analyze.c,v 1.12
6 1999/12/10 07:37:35 tgl
Exp $
* $Id: analyze.c,v 1.12
7 2000/01/06 20:46:49 wieck
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1015,141 +1015,141 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
extras_after
=
lappend
(
extras_after
,
(
Node
*
)
fk_trigger
);
if
((
fkconstraint
->
actions
&
FKCONSTR_ON_DELETE_MASK
)
!=
0
)
/*
* Build a CREATE CONSTRAINT TRIGGER statement for the
* ON DELETE action fired on the PK table !!!
*
*/
fk_trigger
=
(
CreateTrigStmt
*
)
makeNode
(
CreateTrigStmt
);
fk_trigger
->
trigname
=
fkconstraint
->
constr_name
;
fk_trigger
->
relname
=
fkconstraint
->
pktable_name
;
switch
((
fkconstraint
->
actions
&
FKCONSTR_ON_DELETE_MASK
)
>>
FKCONSTR_ON_DELETE_SHIFT
)
{
/*
* Build a CREATE CONSTRAINT TRIGGER statement for the
* ON DELETE action fired on the PK table !!!
*
*/
fk_trigger
=
(
CreateTrigStmt
*
)
makeNode
(
CreateTrigStmt
);
fk_trigger
->
trigname
=
fkconstraint
->
constr_name
;
fk_trigger
->
relname
=
fkconstraint
->
pktable_name
;
switch
((
fkconstraint
->
actions
&
FKCONSTR_ON_DELETE_MASK
)
>>
FKCONSTR_ON_DELETE_SHIFT
)
{
case
FKCONSTR_ON_KEY_RESTRICT
:
fk_trigger
->
funcname
=
"RI_FKey_restrict_del"
;
break
;
case
FKCONSTR_ON_KEY_CASCADE
:
fk_trigger
->
funcname
=
"RI_FKey_cascade_del"
;
break
;
case
FKCONSTR_ON_KEY_SETNULL
:
fk_trigger
->
funcname
=
"RI_FKey_setnull_del"
;
break
;
case
FKCONSTR_ON_KEY_SETDEFAULT
:
fk_trigger
->
funcname
=
"RI_FKey_setdefault_del"
;
break
;
default:
elog
(
ERROR
,
"Only one ON DELETE action can be specified for FOREIGN KEY constraint"
);
break
;
}
fk_trigger
->
before
=
false
;
fk_trigger
->
row
=
true
;
fk_trigger
->
actions
[
0
]
=
'd'
;
fk_trigger
->
actions
[
1
]
=
'\0'
;
fk_trigger
->
lang
=
NULL
;
fk_trigger
->
text
=
NULL
;
fk_trigger
->
attr
=
NIL
;
fk_trigger
->
when
=
NULL
;
fk_trigger
->
isconstraint
=
true
;
fk_trigger
->
deferrable
=
fkconstraint
->
deferrable
;
fk_trigger
->
initdeferred
=
fkconstraint
->
initdeferred
;
fk_trigger
->
constrrelname
=
stmt
->
relname
;
fk_trigger
->
args
=
NIL
;
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
constr_name
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
stmt
->
relname
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
pktable_name
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
match_type
);
fk_attr
=
fkconstraint
->
fk_attrs
;
pk_attr
=
fkconstraint
->
pk_attrs
;
while
(
fk_attr
!=
NIL
)
{
id
=
(
Ident
*
)
lfirst
(
fk_attr
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
id
->
name
);
case
FKCONSTR_ON_KEY_NOACTION
:
fk_trigger
->
funcname
=
"RI_FKey_noaction_del"
;
break
;
case
FKCONSTR_ON_KEY_RESTRICT
:
fk_trigger
->
funcname
=
"RI_FKey_restrict_del"
;
break
;
case
FKCONSTR_ON_KEY_CASCADE
:
fk_trigger
->
funcname
=
"RI_FKey_cascade_del"
;
break
;
case
FKCONSTR_ON_KEY_SETNULL
:
fk_trigger
->
funcname
=
"RI_FKey_setnull_del"
;
break
;
case
FKCONSTR_ON_KEY_SETDEFAULT
:
fk_trigger
->
funcname
=
"RI_FKey_setdefault_del"
;
break
;
default:
elog
(
ERROR
,
"Only one ON DELETE action can be specified for FOREIGN KEY constraint"
);
break
;
}
fk_trigger
->
before
=
false
;
fk_trigger
->
row
=
true
;
fk_trigger
->
actions
[
0
]
=
'd'
;
fk_trigger
->
actions
[
1
]
=
'\0'
;
fk_trigger
->
lang
=
NULL
;
fk_trigger
->
text
=
NULL
;
fk_trigger
->
attr
=
NIL
;
fk_trigger
->
when
=
NULL
;
fk_trigger
->
isconstraint
=
true
;
fk_trigger
->
deferrable
=
fkconstraint
->
deferrable
;
fk_trigger
->
initdeferred
=
fkconstraint
->
initdeferred
;
fk_trigger
->
constrrelname
=
stmt
->
relname
;
id
=
(
Ident
*
)
lfirst
(
pk_attr
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
id
->
name
);
fk_trigger
->
args
=
NIL
;
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
constr_name
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
stmt
->
relname
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
pktable_name
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
match_type
);
fk_attr
=
fkconstraint
->
fk_attrs
;
pk_attr
=
fkconstraint
->
pk_attrs
;
while
(
fk_attr
!=
NIL
)
{
id
=
(
Ident
*
)
lfirst
(
fk_attr
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
id
->
name
);
fk_attr
=
lnext
(
fk_attr
);
pk_attr
=
lnext
(
pk_attr
);
}
id
=
(
Ident
*
)
lfirst
(
pk_attr
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
id
->
name
);
extras_after
=
lappend
(
extras_after
,
(
Node
*
)
fk_trigger
);
fk_attr
=
lnext
(
fk_attr
);
pk_attr
=
lnext
(
pk_attr
);
}
if
((
fkconstraint
->
actions
&
FKCONSTR_ON_UPDATE_MASK
)
!=
0
)
extras_after
=
lappend
(
extras_after
,
(
Node
*
)
fk_trigger
);
/*
* Build a CREATE CONSTRAINT TRIGGER statement for the
* ON UPDATE action fired on the PK table !!!
*
*/
fk_trigger
=
(
CreateTrigStmt
*
)
makeNode
(
CreateTrigStmt
);
fk_trigger
->
trigname
=
fkconstraint
->
constr_name
;
fk_trigger
->
relname
=
fkconstraint
->
pktable_name
;
switch
((
fkconstraint
->
actions
&
FKCONSTR_ON_UPDATE_MASK
)
>>
FKCONSTR_ON_UPDATE_SHIFT
)
{
/*
* Build a CREATE CONSTRAINT TRIGGER statement for the
* ON UPDATE action fired on the PK table !!!
*
*/
fk_trigger
=
(
CreateTrigStmt
*
)
makeNode
(
CreateTrigStmt
);
fk_trigger
->
trigname
=
fkconstraint
->
constr_name
;
fk_trigger
->
relname
=
fkconstraint
->
pktable_name
;
switch
((
fkconstraint
->
actions
&
FKCONSTR_ON_UPDATE_MASK
)
>>
FKCONSTR_ON_UPDATE_SHIFT
)
{
case
FKCONSTR_ON_KEY_RESTRICT
:
fk_trigger
->
funcname
=
"RI_FKey_restrict_upd"
;
break
;
case
FKCONSTR_ON_KEY_CASCADE
:
fk_trigger
->
funcname
=
"RI_FKey_cascade_upd"
;
break
;
case
FKCONSTR_ON_KEY_SETNULL
:
fk_trigger
->
funcname
=
"RI_FKey_setnull_upd"
;
break
;
case
FKCONSTR_ON_KEY_SETDEFAULT
:
fk_trigger
->
funcname
=
"RI_FKey_setdefault_upd"
;
break
;
default:
elog
(
ERROR
,
"Only one ON UPDATE action can be specified for FOREIGN KEY constraint"
);
break
;
}
fk_trigger
->
before
=
false
;
fk_trigger
->
row
=
true
;
fk_trigger
->
actions
[
0
]
=
'u'
;
fk_trigger
->
actions
[
1
]
=
'\0'
;
fk_trigger
->
lang
=
NULL
;
fk_trigger
->
text
=
NULL
;
fk_trigger
->
attr
=
NIL
;
fk_trigger
->
when
=
NULL
;
fk_trigger
->
isconstraint
=
true
;
fk_trigger
->
deferrable
=
fkconstraint
->
deferrable
;
fk_trigger
->
initdeferred
=
fkconstraint
->
initdeferred
;
fk_trigger
->
constrrelname
=
stmt
->
relname
;
fk_trigger
->
args
=
NIL
;
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
constr_name
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
stmt
->
relname
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
pktable_name
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
match_type
);
fk_attr
=
fkconstraint
->
fk_attrs
;
pk_attr
=
fkconstraint
->
pk_attrs
;
while
(
fk_attr
!=
NIL
)
{
id
=
(
Ident
*
)
lfirst
(
fk_attr
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
id
->
name
);
case
FKCONSTR_ON_KEY_NOACTION
:
fk_trigger
->
funcname
=
"RI_FKey_noaction_upd"
;
break
;
case
FKCONSTR_ON_KEY_RESTRICT
:
fk_trigger
->
funcname
=
"RI_FKey_restrict_upd"
;
break
;
case
FKCONSTR_ON_KEY_CASCADE
:
fk_trigger
->
funcname
=
"RI_FKey_cascade_upd"
;
break
;
case
FKCONSTR_ON_KEY_SETNULL
:
fk_trigger
->
funcname
=
"RI_FKey_setnull_upd"
;
break
;
case
FKCONSTR_ON_KEY_SETDEFAULT
:
fk_trigger
->
funcname
=
"RI_FKey_setdefault_upd"
;
break
;
default:
elog
(
ERROR
,
"Only one ON UPDATE action can be specified for FOREIGN KEY constraint"
);
break
;
}
fk_trigger
->
before
=
false
;
fk_trigger
->
row
=
true
;
fk_trigger
->
actions
[
0
]
=
'u'
;
fk_trigger
->
actions
[
1
]
=
'\0'
;
fk_trigger
->
lang
=
NULL
;
fk_trigger
->
text
=
NULL
;
fk_trigger
->
attr
=
NIL
;
fk_trigger
->
when
=
NULL
;
fk_trigger
->
isconstraint
=
true
;
fk_trigger
->
deferrable
=
fkconstraint
->
deferrable
;
fk_trigger
->
initdeferred
=
fkconstraint
->
initdeferred
;
fk_trigger
->
constrrelname
=
stmt
->
relname
;
id
=
(
Ident
*
)
lfirst
(
pk_attr
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
id
->
name
);
fk_trigger
->
args
=
NIL
;
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
constr_name
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
stmt
->
relname
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
pktable_name
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
fkconstraint
->
match_type
);
fk_attr
=
fkconstraint
->
fk_attrs
;
pk_attr
=
fkconstraint
->
pk_attrs
;
while
(
fk_attr
!=
NIL
)
{
id
=
(
Ident
*
)
lfirst
(
fk_attr
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
id
->
name
);
fk_attr
=
lnext
(
fk_attr
);
pk_attr
=
lnext
(
pk_attr
);
}
id
=
(
Ident
*
)
lfirst
(
pk_attr
);
fk_trigger
->
args
=
lappend
(
fk_trigger
->
args
,
id
->
name
);
extras_after
=
lappend
(
extras_after
,
(
Node
*
)
fk_trigger
);
fk_attr
=
lnext
(
fk_attr
);
pk_attr
=
lnext
(
pk_attr
);
}
extras_after
=
lappend
(
extras_after
,
(
Node
*
)
fk_trigger
);
}
}
...
...
src/backend/utils/adt/ri_triggers.c
View file @
b7b6d4bf
...
...
@@ -6,7 +6,7 @@
*
* 1999 Jan Wieck
*
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.1
1 2000/01/06 16:30:43
wieck Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.1
2 2000/01/06 20:46:51
wieck Exp $
*
* ----------
*/
...
...
@@ -466,6 +466,34 @@ RI_FKey_check_upd (FmgrInfo *proinfo)
}
/* ----------
* RI_FKey_noaction_del -
*
* This is here only to let the trigger manager trace for
* "triggered data change violation"
* ----------
*/
HeapTuple
RI_FKey_noaction_del
(
FmgrInfo
*
proinfo
)
{
return
NULL
;
}
/* ----------
* RI_FKey_noaction_upd -
*
* This is here only to let the trigger manager trace for
* "triggered data change violation"
* ----------
*/
HeapTuple
RI_FKey_noaction_upd
(
FmgrInfo
*
proinfo
)
{
return
NULL
;
}
/* ----------
* RI_FKey_cascade_del -
*
...
...
@@ -2252,6 +2280,101 @@ RI_FKey_setdefault_upd (FmgrInfo *proinfo)
}
/* ----------
* RI_FKey_keyequal_upd -
*
* Check if we have a key change on update.
*
* This is no real trigger procedure. It is used by the deferred
* trigger queue manager to detect "triggered data change violation".
* ----------
*/
bool
RI_FKey_keyequal_upd
(
void
)
{
TriggerData
*
trigdata
;
int
tgnargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
pk_rel
;
HeapTuple
new_row
;
HeapTuple
old_row
;
RI_QueryKey
qkey
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
/* ----------
* Check for the correct # of call arguments
* ----------
*/
tgnargs
=
trigdata
->
tg_trigger
->
tgnargs
;
tgargs
=
trigdata
->
tg_trigger
->
tgargs
;
if
(
tgnargs
<
4
||
(
tgnargs
%
2
)
!=
0
)
elog
(
ERROR
,
"wrong # of arguments in call to RI_FKey_keyequal_upd()"
);
if
(
tgnargs
>
RI_MAX_ARGUMENTS
)
elog
(
ERROR
,
"too many keys (%d max) in call to RI_FKey_keyequal_upd()"
,
RI_MAX_NUMKEYS
);
/* ----------
* Nothing to do if no column names to compare given
* ----------
*/
if
(
tgnargs
==
4
)
return
true
;
/* ----------
* Get the relation descriptors of the FK and PK tables and
* the new and old tuple.
* ----------
*/
fk_rel
=
heap_openr
(
tgargs
[
RI_FK_RELNAME_ARGNO
],
NoLock
);
pk_rel
=
trigdata
->
tg_relation
;
new_row
=
trigdata
->
tg_newtuple
;
old_row
=
trigdata
->
tg_trigtuple
;
switch
(
ri_DetermineMatchType
(
tgargs
[
RI_MATCH_TYPE_ARGNO
]))
{
/* ----------
* MATCH <UNSPECIFIED>
* ----------
*/
case
RI_MATCH_TYPE_UNSPECIFIED
:
elog
(
ERROR
,
"MATCH <unspecified> not implemented yet"
);
break
;
case
RI_MATCH_TYPE_FULL
:
ri_BuildQueryKeyFull
(
&
qkey
,
trigdata
->
tg_trigger
->
tgoid
,
0
,
fk_rel
,
pk_rel
,
tgnargs
,
tgargs
);
heap_close
(
fk_rel
,
NoLock
);
/* ----------
* Return if key's are equal
* ----------
*/
return
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
RI_KEYPAIR_PK_IDX
);
/* ----------
* Handle MATCH PARTIAL set null delete.
* ----------
*/
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
break
;
}
/* ----------
* Never reached
* ----------
*/
elog
(
ERROR
,
"internal error #9 in ri_triggers.c"
);
return
false
;
}
...
...
src/include/catalog/pg_proc.h
View file @
b7b6d4bf
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.11
0 1999/12/28 13:40:50
wieck Exp $
* $Id: pg_proc.h,v 1.11
1 2000/01/06 20:46:54
wieck Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
...
...
@@ -2142,6 +2142,10 @@ DATA(insert OID = 1652 ( RI_FKey_setdefault_del PGUID 11 f t f 0 f 0 "" 100 0 0
DESCR
(
"referential integrity ON DELETE SET DEFAULT"
);
DATA
(
insert
OID
=
1653
(
RI_FKey_setdefault_upd
PGUID
11
f
t
f
0
f
0
""
100
0
0
100
RI_FKey_setdefault_upd
-
));
DESCR
(
"referential integrity ON UPDATE SET DEFAULT"
);
DATA
(
insert
OID
=
1654
(
RI_FKey_noaction_del
PGUID
11
f
t
f
0
f
0
""
100
0
0
100
RI_FKey_setdefault_del
-
));
DESCR
(
"referential integrity ON DELETE NO ACTION"
);
DATA
(
insert
OID
=
1655
(
RI_FKey_noaction_upd
PGUID
11
f
t
f
0
f
0
""
100
0
0
100
RI_FKey_setdefault_upd
-
));
DESCR
(
"referential integrity ON UPDATE NO ACTION"
);
/* for mac type support */
DATA
(
insert
OID
=
436
(
macaddr_in
PGUID
11
f
t
t
1
f
829
"0"
100
0
0
100
macaddr_in
-
));
...
...
src/include/commands/trigger.h
View file @
b7b6d4bf
...
...
@@ -37,7 +37,9 @@ extern DLLIMPORT TriggerData *CurrentTriggerData;
#define TRIGGER_DEFERRED_DEFERRABLE 0x00000040
#define TRIGGER_DEFERRED_INITDEFERRED 0x00000080
#define TRIGGER_DEFERRED_HAS_BEFORE 0x00000100
#define TRIGGER_DEFERRED_MASK 0x000001F0
#define TRIGGER_DEFERRED_ROW_INSERTED 0x00000200
#define TRIGGER_DEFERRED_KEY_CHANGED 0x00000400
#define TRIGGER_DEFERRED_MASK 0x000007F0
#define TRIGGER_FIRED_BY_INSERT(event) \
(((TriggerEvent) (event) & TRIGGER_EVENT_OPMASK) == \
...
...
@@ -117,4 +119,10 @@ extern void DeferredTriggerSaveEvent(Relation rel, int event,
HeapTuple
oldtup
,
HeapTuple
newtup
);
/*
* in utils/adt/ri_triggers.c
*
*/
extern
bool
RI_FKey_keyequal_upd
(
void
);
#endif
/* TRIGGER_H */
src/include/utils/builtins.h
View file @
b7b6d4bf
...
...
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: builtins.h,v 1.9
3 1999/12/28 13:40:52
wieck Exp $
* $Id: builtins.h,v 1.9
4 2000/01/06 20:47:01
wieck Exp $
*
* NOTES
* This should normally only be included by fmgr.h.
...
...
@@ -623,6 +623,8 @@ float64 numeric_float8(Numeric num);
/* ri_triggers.c */
HeapTuple
RI_FKey_check_ins
(
FmgrInfo
*
proinfo
);
HeapTuple
RI_FKey_check_upd
(
FmgrInfo
*
proinfo
);
HeapTuple
RI_FKey_noaction_del
(
FmgrInfo
*
proinfo
);
HeapTuple
RI_FKey_noaction_upd
(
FmgrInfo
*
proinfo
);
HeapTuple
RI_FKey_cascade_del
(
FmgrInfo
*
proinfo
);
HeapTuple
RI_FKey_cascade_upd
(
FmgrInfo
*
proinfo
);
HeapTuple
RI_FKey_restrict_del
(
FmgrInfo
*
proinfo
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment