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
dc13d5d3
Commit
dc13d5d3
authored
Sep 04, 1997
by
Vadim B. Mikheev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Before row insertion triggers call.
parent
8d6e5f07
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
416 additions
and
87 deletions
+416
-87
src/backend/commands/copy.c
src/backend/commands/copy.c
+3
-3
src/backend/commands/trigger.c
src/backend/commands/trigger.c
+413
-84
No files found.
src/backend/commands/copy.c
View file @
dc13d5d3
...
...
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.2
8 1997/09/01 07:59:04
vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.2
9 1997/09/04 13:18:59
vadim Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -608,7 +608,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
skip_tuple
=
false
;
/* BEFORE ROW INSERT Triggers */
if
(
rel
->
trigdesc
&&
rel
->
trigdesc
->
n_before_row
[
TRIGGER_
ACTION
_INSERT
]
>
0
)
rel
->
trigdesc
->
n_before_row
[
TRIGGER_
EVENT
_INSERT
]
>
0
)
{
HeapTuple
newtuple
;
...
...
@@ -677,7 +677,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
}
/* AFTER ROW INSERT Triggers */
if
(
rel
->
trigdesc
&&
rel
->
trigdesc
->
n_after_row
[
TRIGGER_
ACTION
_INSERT
]
>
0
)
rel
->
trigdesc
->
n_after_row
[
TRIGGER_
EVENT
_INSERT
]
>
0
)
ExecARInsertTriggers
(
rel
,
tuple
);
}
...
...
src/backend/commands/trigger.c
View file @
dc13d5d3
...
...
@@ -9,7 +9,9 @@
#include "postgres.h"
#include "nodes/parsenodes.h"
#include "nodes/memnodes.h"
#include "commands/trigger.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
#include "catalog/pg_proc.h"
...
...
@@ -17,26 +19,300 @@
#include "catalog/pg_trigger.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/xact.h"
#include "storage/lmgr.h"
#include "storage/bufmgr.h"
#include "utils/mcxt.h"
#include "utils/inval.h"
#include "utils/builtins.h"
#ifndef NO_SECURITY
#include "miscadmin.h"
#include "utils/acl.h"
#include "utils/syscache.h"
#endif
TriggerData
*
CurrentTriggerData
=
NULL
;
void
RelationBuildTriggers
(
Relation
relation
);
void
FreeTriggerDesc
(
Relation
relation
);
static
void
DescribeTrigger
(
TriggerDesc
*
trigdesc
,
Trigger
*
trigger
);
extern
void
fmgr_info
(
Oid
procedureId
,
func_ptr
*
function
,
int
*
nargs
);
extern
GlobalMemory
CacheCxt
;
void
CreateTrigger
(
CreateTrigStmt
*
stmt
)
{
int16
tgtype
;
int16
tgattr
[
8
]
=
{
0
};
Datum
values
[
Natts_pg_trigger
];
char
nulls
[
Natts_pg_trigger
];
Relation
rel
;
Relation
tgrel
;
HeapScanDesc
tgscan
;
ScanKeyData
key
;
Relation
relrdesc
;
HeapTuple
tuple
;
ItemPointerData
oldTID
;
Relation
idescs
[
Num_pg_trigger_indices
];
Relation
ridescs
[
Num_pg_class_indices
];
MemoryContext
oldcxt
;
Oid
fargtypes
[
8
];
int
found
=
0
;
int
i
;
if
(
IsSystemRelationName
(
stmt
->
relname
)
)
elog
(
WARN
,
"CreateTrigger: can't create trigger for system relation %s"
,
stmt
->
relname
);
#ifndef NO_SECURITY
if
(
!
pg_ownercheck
(
GetPgUserName
(),
stmt
->
relname
,
RELNAME
))
elog
(
WARN
,
"%s: %s"
,
stmt
->
relname
,
aclcheck_error_strings
[
ACLCHECK_NOT_OWNER
]);
#endif
rel
=
heap_openr
(
stmt
->
relname
);
if
(
!
RelationIsValid
(
rel
)
)
elog
(
WARN
,
"CreateTrigger: there is no relation %s"
,
stmt
->
relname
);
RelationSetLockForWrite
(
rel
);
TRIGGER_CLEAR_TYPE
(
tgtype
);
if
(
stmt
->
before
)
TRIGGER_SETT_BEFORE
(
tgtype
);
if
(
stmt
->
row
)
TRIGGER_SETT_ROW
(
tgtype
);
for
(
i
=
0
;
i
<
3
&&
stmt
->
actions
[
i
];
i
++
)
{
switch
(
stmt
->
actions
[
i
]
)
{
case
'i'
:
if
(
TRIGGER_FOR_INSERT
(
tgtype
)
)
elog
(
WARN
,
"CreateTrigger: double INSERT event specified"
);
TRIGGER_SETT_INSERT
(
tgtype
);
break
;
case
'd'
:
if
(
TRIGGER_FOR_DELETE
(
tgtype
)
)
elog
(
WARN
,
"CreateTrigger: double DELETE event specified"
);
TRIGGER_SETT_DELETE
(
tgtype
);
break
;
case
'u'
:
if
(
TRIGGER_FOR_UPDATE
(
tgtype
)
)
elog
(
WARN
,
"CreateTrigger: double UPDATE event specified"
);
TRIGGER_SETT_UPDATE
(
tgtype
);
break
;
default:
elog
(
WARN
,
"CreateTrigger: unknown event specified"
);
break
;
}
}
/* Scan pg_trigger */
tgrel
=
heap_openr
(
TriggerRelationName
);
RelationSetLockForWrite
(
tgrel
);
ScanKeyEntryInitialize
(
&
key
,
0
,
Anum_pg_trigger_tgrelid
,
ObjectIdEqualRegProcedure
,
rel
->
rd_id
);
tgscan
=
heap_beginscan
(
tgrel
,
0
,
NowTimeQual
,
1
,
&
key
);
while
(
tuple
=
heap_getnext
(
tgscan
,
0
,
(
Buffer
*
)
NULL
),
PointerIsValid
(
tuple
))
{
Form_pg_trigger
pg_trigger
=
(
Form_pg_trigger
)
GETSTRUCT
(
tuple
);
if
(
namestrcmp
(
&
(
pg_trigger
->
tgname
),
stmt
->
trigname
)
==
0
)
elog
(
WARN
,
"CreateTrigger: trigger %s already defined on relation %s"
,
stmt
->
trigname
,
stmt
->
relname
);
else
found
++
;
}
heap_endscan
(
tgscan
);
memset
(
fargtypes
,
0
,
8
*
sizeof
(
Oid
));
tuple
=
SearchSysCacheTuple
(
PRONAME
,
PointerGetDatum
(
stmt
->
funcname
),
0
,
PointerGetDatum
(
fargtypes
),
0
);
if
(
!
HeapTupleIsValid
(
tuple
)
||
((
Form_pg_proc
)
GETSTRUCT
(
tuple
))
->
prorettype
!=
0
||
((
Form_pg_proc
)
GETSTRUCT
(
tuple
))
->
pronargs
!=
0
)
elog
(
WARN
,
"CreateTrigger: function %s () does not exist"
,
stmt
->
funcname
);
if
(
((
Form_pg_proc
)
GETSTRUCT
(
tuple
))
->
prolang
!=
ClanguageId
)
elog
(
WARN
,
"CreateTrigger: only C functions are supported"
);
memset
(
nulls
,
' '
,
Natts_pg_trigger
*
sizeof
(
char
));
values
[
Anum_pg_trigger_tgrelid
-
1
]
=
ObjectIdGetDatum
(
rel
->
rd_id
);
values
[
Anum_pg_trigger_tgname
-
1
]
=
NameGetDatum
(
namein
(
stmt
->
trigname
));
values
[
Anum_pg_trigger_tgfoid
-
1
]
=
ObjectIdGetDatum
(
tuple
->
t_oid
);
values
[
Anum_pg_trigger_tgtype
-
1
]
=
Int16GetDatum
(
tgtype
);
if
(
stmt
->
args
)
{
List
*
le
;
char
*
args
;
int16
nargs
=
length
(
stmt
->
args
);
int
len
=
0
;
foreach
(
le
,
stmt
->
args
)
{
char
*
ar
=
(
char
*
)
lfirst
(
le
);
len
+=
strlen
(
ar
)
+
4
;
}
args
=
(
char
*
)
palloc
(
len
+
1
);
args
[
0
]
=
0
;
foreach
(
le
,
stmt
->
args
)
sprintf
(
args
+
strlen
(
args
),
"%s
\\
000"
,
(
char
*
)
lfirst
(
le
));
values
[
Anum_pg_trigger_tgnargs
-
1
]
=
Int16GetDatum
(
nargs
);
values
[
Anum_pg_trigger_tgargs
-
1
]
=
PointerGetDatum
(
byteain
(
args
));
}
else
{
values
[
Anum_pg_trigger_tgnargs
-
1
]
=
Int16GetDatum
(
0
);
values
[
Anum_pg_trigger_tgargs
-
1
]
=
PointerGetDatum
(
byteain
(
""
));
}
values
[
Anum_pg_trigger_tgattr
-
1
]
=
PointerGetDatum
(
tgattr
);
tuple
=
heap_formtuple
(
tgrel
->
rd_att
,
values
,
nulls
);
heap_insert
(
tgrel
,
tuple
);
CatalogOpenIndices
(
Num_pg_trigger_indices
,
Name_pg_trigger_indices
,
idescs
);
CatalogIndexInsert
(
idescs
,
Num_pg_trigger_indices
,
tgrel
,
tuple
);
CatalogCloseIndices
(
Num_pg_trigger_indices
,
idescs
);
pfree
(
tuple
);
RelationUnsetLockForWrite
(
tgrel
);
heap_close
(
tgrel
);
pfree
(
DatumGetPointer
(
values
[
Anum_pg_trigger_tgname
-
1
]));
pfree
(
DatumGetPointer
(
values
[
Anum_pg_trigger_tgargs
-
1
]));
/* update pg_class */
relrdesc
=
heap_openr
(
RelationRelationName
);
tuple
=
ClassNameIndexScan
(
relrdesc
,
stmt
->
relname
);
if
(
!
PointerIsValid
(
tuple
)
)
{
heap_close
(
relrdesc
);
elog
(
WARN
,
"CreateTrigger: relation %s not found in pg_class"
,
stmt
->
relname
);
}
((
Form_pg_class
)
GETSTRUCT
(
tuple
))
->
reltriggers
=
found
+
1
;
RelationInvalidateHeapTuple
(
relrdesc
,
tuple
);
oldTID
=
tuple
->
t_ctid
;
heap_replace
(
relrdesc
,
&
oldTID
,
tuple
);
CatalogOpenIndices
(
Num_pg_class_indices
,
Name_pg_class_indices
,
ridescs
);
CatalogIndexInsert
(
ridescs
,
Num_pg_class_indices
,
relrdesc
,
tuple
);
CatalogCloseIndices
(
Num_pg_class_indices
,
ridescs
);
pfree
(
tuple
);
heap_close
(
relrdesc
);
CommandCounterIncrement
();
oldcxt
=
MemoryContextSwitchTo
((
MemoryContext
)
CacheCxt
);
FreeTriggerDesc
(
rel
);
rel
->
rd_rel
->
reltriggers
=
found
+
1
;
RelationBuildTriggers
(
rel
);
MemoryContextSwitchTo
(
oldcxt
);
heap_close
(
rel
);
return
;
}
void
DropTrigger
(
DropTrigStmt
*
stmt
)
{
Relation
rel
;
Relation
tgrel
;
HeapScanDesc
tgscan
;
ScanKeyData
key
;
Relation
relrdesc
;
HeapTuple
tuple
;
ItemPointerData
oldTID
;
Relation
ridescs
[
Num_pg_class_indices
];
MemoryContext
oldcxt
;
int
found
=
0
;
int
tgfound
=
0
;
#ifndef NO_SECURITY
if
(
!
pg_ownercheck
(
GetPgUserName
(),
stmt
->
relname
,
RELNAME
))
elog
(
WARN
,
"%s: %s"
,
stmt
->
relname
,
aclcheck_error_strings
[
ACLCHECK_NOT_OWNER
]);
#endif
rel
=
heap_openr
(
stmt
->
relname
);
if
(
!
RelationIsValid
(
rel
)
)
elog
(
WARN
,
"DropTrigger: there is no relation %s"
,
stmt
->
relname
);
RelationSetLockForWrite
(
rel
);
tgrel
=
heap_openr
(
TriggerRelationName
);
RelationSetLockForWrite
(
tgrel
);
ScanKeyEntryInitialize
(
&
key
,
0
,
Anum_pg_trigger_tgrelid
,
ObjectIdEqualRegProcedure
,
rel
->
rd_id
);
tgscan
=
heap_beginscan
(
tgrel
,
0
,
NowTimeQual
,
1
,
&
key
);
while
(
tuple
=
heap_getnext
(
tgscan
,
0
,
(
Buffer
*
)
NULL
),
PointerIsValid
(
tuple
))
{
Form_pg_trigger
pg_trigger
=
(
Form_pg_trigger
)
GETSTRUCT
(
tuple
);
if
(
namestrcmp
(
&
(
pg_trigger
->
tgname
),
stmt
->
trigname
)
==
0
)
{
heap_delete
(
tgrel
,
&
tuple
->
t_ctid
);
tgfound
++
;
}
else
found
++
;
}
if
(
tgfound
==
0
)
elog
(
WARN
,
"DropTrigger: there is no trigger %s on relation %s"
,
stmt
->
trigname
,
stmt
->
relname
);
if
(
tgfound
>
1
)
elog
(
NOTICE
,
"DropTrigger: found (and deleted) %d trigger %s on relation %s"
,
tgfound
,
stmt
->
trigname
,
stmt
->
relname
);
heap_endscan
(
tgscan
);
RelationUnsetLockForWrite
(
tgrel
);
heap_close
(
tgrel
);
/* update pg_class */
relrdesc
=
heap_openr
(
RelationRelationName
);
tuple
=
ClassNameIndexScan
(
relrdesc
,
stmt
->
relname
);
if
(
!
PointerIsValid
(
tuple
)
)
{
heap_close
(
relrdesc
);
elog
(
WARN
,
"DropTrigger: relation %s not found in pg_class"
,
stmt
->
relname
);
}
((
Form_pg_class
)
GETSTRUCT
(
tuple
))
->
reltriggers
=
found
;
RelationInvalidateHeapTuple
(
relrdesc
,
tuple
);
oldTID
=
tuple
->
t_ctid
;
heap_replace
(
relrdesc
,
&
oldTID
,
tuple
);
CatalogOpenIndices
(
Num_pg_class_indices
,
Name_pg_class_indices
,
ridescs
);
CatalogIndexInsert
(
ridescs
,
Num_pg_class_indices
,
relrdesc
,
tuple
);
CatalogCloseIndices
(
Num_pg_class_indices
,
ridescs
);
pfree
(
tuple
);
heap_close
(
relrdesc
);
CommandCounterIncrement
();
oldcxt
=
MemoryContextSwitchTo
((
MemoryContext
)
CacheCxt
);
FreeTriggerDesc
(
rel
);
rel
->
rd_rel
->
reltriggers
=
found
;
if
(
found
>
0
)
RelationBuildTriggers
(
rel
);
MemoryContextSwitchTo
(
oldcxt
);
heap_close
(
rel
);
return
;
}
void
RelationRemoveTriggers
(
Relation
rel
)
{
Relation
tgrel
;
HeapScanDesc
tgscan
;
ScanKeyData
key
;
HeapTuple
tup
;
tgrel
=
heap_openr
(
TriggerRelationName
);
RelationSetLockForWrite
(
tgrel
);
ScanKeyEntryInitialize
(
&
key
,
0
,
Anum_pg_trigger_tgrelid
,
ObjectIdEqualRegProcedure
,
rel
->
rd_id
);
tgscan
=
heap_beginscan
(
tgrel
,
0
,
NowTimeQual
,
1
,
&
key
);
while
(
tup
=
heap_getnext
(
tgscan
,
0
,
(
Buffer
*
)
NULL
),
PointerIsValid
(
tup
))
heap_delete
(
tgrel
,
&
tup
->
t_ctid
);
heap_endscan
(
tgscan
);
RelationUnsetLockForWrite
(
tgrel
);
heap_close
(
tgrel
);
}
void
RelationBuildTriggers
(
Relation
relation
)
{
...
...
@@ -66,6 +342,7 @@ RelationBuildTriggers (Relation relation)
ObjectIdGetDatum
(
relation
->
rd_id
));
tgrel
=
heap_openr
(
TriggerRelationName
);
RelationSetLockForRead
(
tgrel
);
irel
=
index_openr
(
TriggerRelidIndex
);
sd
=
index_beginscan
(
irel
,
false
,
1
,
&
skey
);
...
...
@@ -93,21 +370,11 @@ RelationBuildTriggers (Relation relation)
build
=
&
(
triggers
[
found
]);
build
->
tgname
=
nameout
(
&
(
pg_trigger
->
tgname
));
build
->
tgfunc
=
nameout
(
&
(
pg_trigger
->
tgfunc
));
build
->
tglang
=
pg_trigger
->
tglang
;
if
(
build
->
tglang
!=
ClanguageId
)
elog
(
WARN
,
"RelationBuildTriggers: unsupported language %u for trigger %s of rel %.*s"
,
build
->
tglang
,
build
->
tgname
,
NAMEDATALEN
,
relation
->
rd_rel
->
relname
.
data
);
build
->
tgfoid
=
pg_trigger
->
tgfoid
;
build
->
tgfunc
=
NULL
;
build
->
tgtype
=
pg_trigger
->
tgtype
;
build
->
tgnargs
=
pg_trigger
->
tgnargs
;
memcpy
(
build
->
tgattr
,
&
(
pg_trigger
->
tgattr
),
8
*
sizeof
(
int16
));
val
=
(
struct
varlena
*
)
fastgetattr
(
tuple
,
Anum_pg_trigger_tgtext
,
tgrel
->
rd_att
,
&
isnull
);
if
(
isnull
)
elog
(
WARN
,
"RelationBuildTriggers: tgtext IS NULL for rel %.*s"
,
NAMEDATALEN
,
relation
->
rd_rel
->
relname
.
data
);
build
->
tgtext
=
byteaout
(
val
);
val
=
(
struct
varlena
*
)
fastgetattr
(
tuple
,
Anum_pg_trigger_tgargs
,
tgrel
->
rd_att
,
&
isnull
);
...
...
@@ -134,13 +401,8 @@ RelationBuildTriggers (Relation relation)
p
+=
strlen
(
p
)
+
1
;
}
}
val
=
(
struct
varlena
*
)
fastgetattr
(
tuple
,
Anum_pg_trigger_tgwhen
,
tgrel
->
rd_att
,
&
isnull
);
if
(
!
isnull
)
build
->
tgwhen
=
textout
(
val
);
else
build
->
tg
when
=
NULL
;
build
->
tg
args
=
NULL
;
found
++
;
ReleaseBuffer
(
buffer
);
...
...
@@ -154,20 +416,76 @@ RelationBuildTriggers (Relation relation)
index_endscan
(
sd
);
pfree
(
sd
);
index_close
(
irel
);
RelationUnsetLockForRead
(
tgrel
);
heap_close
(
tgrel
);
/* Build trigdesc */
trigdesc
->
triggers
=
triggers
;
for
(
found
=
0
;
found
<
ntrigs
;
found
++
)
{
build
=
&
(
triggers
[
found
]);
DescribeTrigger
(
trigdesc
,
build
);
}
relation
->
trigdesc
=
trigdesc
;
}
void
FreeTriggerDesc
(
Relation
relation
)
{
TriggerDesc
*
trigdesc
=
relation
->
trigdesc
;
Trigger
***
t
;
Trigger
*
trigger
;
int
i
;
if
(
trigdesc
==
NULL
)
return
;
t
=
trigdesc
->
tg_before_statement
;
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
t
[
i
]
!=
NULL
)
pfree
(
t
[
i
]);
t
=
trigdesc
->
tg_before_row
;
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
t
[
i
]
!=
NULL
)
pfree
(
t
[
i
]);
t
=
trigdesc
->
tg_after_row
;
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
t
[
i
]
!=
NULL
)
pfree
(
t
[
i
]);
t
=
trigdesc
->
tg_after_statement
;
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
t
[
i
]
!=
NULL
)
pfree
(
t
[
i
]);
trigger
=
trigdesc
->
triggers
;
for
(
i
=
0
;
i
<
relation
->
rd_rel
->
reltriggers
;
i
++
)
{
pfree
(
trigger
->
tgname
);
if
(
trigger
->
tgnargs
>
0
)
{
while
(
--
(
trigger
->
tgnargs
)
>=
0
)
pfree
(
trigger
->
tgargs
[
trigger
->
tgnargs
]);
pfree
(
trigger
->
tgargs
);
}
trigger
++
;
}
pfree
(
trigdesc
->
triggers
);
pfree
(
trigdesc
);
relation
->
trigdesc
=
NULL
;
return
;
}
static
void
DescribeTrigger
(
TriggerDesc
*
trigdesc
,
Trigger
*
trigger
)
{
uint16
*
n
;
Trigger
***
t
,
***
tp
;
build
=
&
(
triggers
[
found
]);
if
(
TRIGGER_FOR_ROW
(
build
->
tgtype
)
)
/* Is ROW/STATEMENT trigger */
if
(
TRIGGER_FOR_ROW
(
trigger
->
tgtype
)
)
/* Is ROW/STATEMENT trigger */
{
if
(
TRIGGER_FOR_BEFORE
(
build
->
tgtype
)
)
if
(
TRIGGER_FOR_BEFORE
(
trigger
->
tgtype
)
)
{
n
=
trigdesc
->
n_before_row
;
t
=
trigdesc
->
tg_before_row
;
...
...
@@ -180,7 +498,7 @@ RelationBuildTriggers (Relation relation)
}
else
/* STATEMENT (NI) */
{
if
(
TRIGGER_FOR_BEFORE
(
build
->
tgtype
)
)
if
(
TRIGGER_FOR_BEFORE
(
trigger
->
tgtype
)
)
{
n
=
trigdesc
->
n_before_statement
;
t
=
trigdesc
->
tg_before_statement
;
...
...
@@ -192,59 +510,70 @@ RelationBuildTriggers (Relation relation)
}
}
if
(
TRIGGER_FOR_INSERT
(
build
->
tgtype
)
)
if
(
TRIGGER_FOR_INSERT
(
trigger
->
tgtype
)
)
{
tp
=
&
(
t
[
TRIGGER_ACTION
_INSERT
]);
tp
=
&
(
t
[
TRIGGER_EVENT
_INSERT
]);
if
(
*
tp
==
NULL
)
*
tp
=
(
Trigger
**
)
palloc
(
sizeof
(
Trigger
*
));
else
*
tp
=
(
Trigger
**
)
repalloc
(
*
tp
,
(
n
[
TRIGGER_ACTION
_INSERT
]
+
1
)
*
*
tp
=
(
Trigger
**
)
repalloc
(
*
tp
,
(
n
[
TRIGGER_EVENT
_INSERT
]
+
1
)
*
sizeof
(
Trigger
*
));
(
*
tp
)[
n
[
TRIGGER_ACTION_INSERT
]]
=
build
;
(
n
[
TRIGGER_ACTION
_INSERT
])
++
;
(
*
tp
)[
n
[
TRIGGER_EVENT_INSERT
]]
=
trigger
;
(
n
[
TRIGGER_EVENT
_INSERT
])
++
;
}
if
(
TRIGGER_FOR_DELETE
(
build
->
tgtype
)
)
if
(
TRIGGER_FOR_DELETE
(
trigger
->
tgtype
)
)
{
tp
=
&
(
t
[
TRIGGER_ACTION
_DELETE
]);
tp
=
&
(
t
[
TRIGGER_EVENT
_DELETE
]);
if
(
*
tp
==
NULL
)
*
tp
=
(
Trigger
**
)
palloc
(
sizeof
(
Trigger
*
));
else
*
tp
=
(
Trigger
**
)
repalloc
(
*
tp
,
(
n
[
TRIGGER_ACTION
_DELETE
]
+
1
)
*
*
tp
=
(
Trigger
**
)
repalloc
(
*
tp
,
(
n
[
TRIGGER_EVENT
_DELETE
]
+
1
)
*
sizeof
(
Trigger
*
));
(
*
tp
)[
n
[
TRIGGER_ACTION_DELETE
]]
=
build
;
(
n
[
TRIGGER_ACTION
_DELETE
])
++
;
(
*
tp
)[
n
[
TRIGGER_EVENT_DELETE
]]
=
trigger
;
(
n
[
TRIGGER_EVENT
_DELETE
])
++
;
}
if
(
TRIGGER_FOR_UPDATE
(
build
->
tgtype
)
)
if
(
TRIGGER_FOR_UPDATE
(
trigger
->
tgtype
)
)
{
tp
=
&
(
t
[
TRIGGER_ACTION
_UPDATE
]);
tp
=
&
(
t
[
TRIGGER_EVENT
_UPDATE
]);
if
(
*
tp
==
NULL
)
*
tp
=
(
Trigger
**
)
palloc
(
sizeof
(
Trigger
*
));
else
*
tp
=
(
Trigger
**
)
repalloc
(
*
tp
,
(
n
[
TRIGGER_ACTION
_UPDATE
]
+
1
)
*
*
tp
=
(
Trigger
**
)
repalloc
(
*
tp
,
(
n
[
TRIGGER_EVENT
_UPDATE
]
+
1
)
*
sizeof
(
Trigger
*
));
(
*
tp
)[
n
[
TRIGGER_ACTION_UPDATE
]]
=
build
;
(
n
[
TRIGGER_ACTION_UPDATE
])
++
;
}
(
*
tp
)[
n
[
TRIGGER_EVENT_UPDATE
]]
=
trigger
;
(
n
[
TRIGGER_EVENT_UPDATE
])
++
;
}
relation
->
trigdesc
=
trigdesc
;
}
void
FreeTriggerDesc
(
Relation
relation
)
{
return
;
}
HeapTuple
ExecBRInsertTriggers
(
Relation
rel
,
HeapTuple
tuple
)
{
int
ntrigs
=
rel
->
trigdesc
->
n_before_row
[
TRIGGER_EVENT_INSERT
];
Trigger
**
trigger
=
rel
->
trigdesc
->
tg_before_row
[
TRIGGER_EVENT_INSERT
];
HeapTuple
newtuple
=
tuple
;
int
nargs
;
int
i
;
return
(
tuple
);
CurrentTriggerData
=
(
TriggerData
*
)
palloc
(
sizeof
(
TriggerData
));
CurrentTriggerData
->
tg_event
=
TRIGGER_EVENT_INSERT
|
TRIGGER_EVENT_ROW
;
CurrentTriggerData
->
tg_relation
=
rel
;
CurrentTriggerData
->
tg_newtuple
=
NULL
;
for
(
i
=
0
;
i
<
ntrigs
;
i
++
)
{
CurrentTriggerData
->
tg_trigtuple
=
newtuple
;
CurrentTriggerData
->
tg_trigger
=
trigger
[
i
];
if
(
trigger
[
i
]
->
tgfunc
==
NULL
)
fmgr_info
(
trigger
[
i
]
->
tgfoid
,
&
(
trigger
[
i
]
->
tgfunc
),
&
nargs
);
newtuple
=
(
HeapTuple
)
(
(
*
(
trigger
[
i
]
->
tgfunc
))
()
);
if
(
newtuple
==
NULL
)
break
;
}
pfree
(
CurrentTriggerData
);
CurrentTriggerData
=
NULL
;
return
(
newtuple
);
}
void
...
...
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