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
18952f67
Commit
18952f67
authored
May 29, 2000
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Second round of fmgr changes: triggers are now invoked in new style,
CurrentTriggerData is history.
parent
147ccf5c
Changes
41
Show whitespace changes
Inline
Side-by-side
Showing
41 changed files
with
658 additions
and
666 deletions
+658
-666
contrib/fulltextindex/README
contrib/fulltextindex/README
+2
-1
contrib/fulltextindex/fti.c
contrib/fulltextindex/fti.c
+22
-24
contrib/fulltextindex/fticopy
contrib/fulltextindex/fticopy
+1
-1
contrib/lo/lo.c
contrib/lo/lo.c
+15
-17
contrib/lo/lo.sql.in
contrib/lo/lo.sql.in
+2
-2
contrib/noupdate/noup.c
contrib/noupdate/noup.c
+20
-26
contrib/noupdate/noup.source
contrib/noupdate/noup.source
+1
-1
contrib/spi/autoinc.c
contrib/spi/autoinc.c
+15
-17
contrib/spi/autoinc.source
contrib/spi/autoinc.source
+1
-1
contrib/spi/insert_username.c
contrib/spi/insert_username.c
+15
-16
contrib/spi/insert_username.source
contrib/spi/insert_username.source
+1
-1
contrib/spi/moddatetime.c
contrib/spi/moddatetime.c
+20
-22
contrib/spi/moddatetime.source
contrib/spi/moddatetime.source
+1
-1
contrib/spi/refint.c
contrib/spi/refint.c
+36
-48
contrib/spi/refint.source
contrib/spi/refint.source
+2
-2
contrib/spi/timetravel.c
contrib/spi/timetravel.c
+30
-35
contrib/spi/timetravel.source
contrib/spi/timetravel.source
+2
-2
doc/src/sgml/ref/create_language.sgml
doc/src/sgml/ref/create_language.sgml
+58
-44
doc/src/sgml/trigger.sgml
doc/src/sgml/trigger.sgml
+59
-23
src/backend/commands/command.c
src/backend/commands/command.c
+15
-10
src/backend/commands/trigger.c
src/backend/commands/trigger.c
+78
-67
src/backend/commands/user.c
src/backend/commands/user.c
+4
-10
src/backend/executor/execMain.c
src/backend/executor/execMain.c
+2
-5
src/backend/utils/adt/ri_triggers.c
src/backend/utils/adt/ri_triggers.c
+130
-156
src/backend/utils/adt/tid.c
src/backend/utils/adt/tid.c
+3
-1
src/backend/utils/adt/timestamp.c
src/backend/utils/adt/timestamp.c
+6
-4
src/backend/utils/fmgr/fmgr.c
src/backend/utils/fmgr/fmgr.c
+1
-2
src/include/catalog/catversion.h
src/include/catalog/catversion.h
+2
-2
src/include/catalog/pg_proc.h
src/include/catalog/pg_proc.h
+14
-14
src/include/commands/trigger.h
src/include/commands/trigger.h
+13
-4
src/include/commands/user.h
src/include/commands/user.h
+2
-2
src/include/executor/executor.h
src/include/executor/executor.h
+3
-1
src/include/fmgr.h
src/include/fmgr.h
+3
-1
src/include/nodes/nodes.h
src/include/nodes/nodes.h
+8
-2
src/include/utils/builtins.h
src/include/utils/builtins.h
+14
-23
src/pl/plperl/plperl.c
src/pl/plperl/plperl.c
+6
-12
src/pl/plpgsql/src/pl_handler.c
src/pl/plpgsql/src/pl_handler.c
+4
-14
src/pl/tcl/pltcl.c
src/pl/tcl/pltcl.c
+5
-11
src/test/regress/input/create_function_1.source
src/test/regress/input/create_function_1.source
+5
-5
src/test/regress/output/create_function_1.source
src/test/regress/output/create_function_1.source
+5
-5
src/test/regress/regress.c
src/test/regress/regress.c
+32
-31
No files found.
contrib/fulltextindex/README
View file @
18952f67
...
@@ -56,7 +56,8 @@ sub-string will fit.
...
@@ -56,7 +56,8 @@ sub-string will fit.
The create the function that contains the trigger::
The create the function that contains the trigger::
create function fti() returns opaque as '/path/to/fti.so' language 'C';
create function fti() returns opaque as
'/path/to/fti.so' language 'newC';
And finally define the trigger on the 'cds' table:
And finally define the trigger on the 'cds' table:
...
...
contrib/fulltextindex/fti.c
View file @
18952f67
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
Example:
Example:
create function fti() returns opaque as
create function fti() returns opaque as
'/home/boekhold/src/postgresql-6.2/contrib/fti/fti.so' language '
c
';
'/home/boekhold/src/postgresql-6.2/contrib/fti/fti.so' language '
newC
';
create table title_fti (string varchar(25), id oid);
create table title_fti (string varchar(25), id oid);
create index title_fti_idx on title_fti (string);
create index title_fti_idx on title_fti (string);
...
@@ -61,11 +61,11 @@ select p.* from product p, title_fti f1, title_fti f2 where
...
@@ -61,11 +61,11 @@ select p.* from product p, title_fti f1, title_fti f2 where
that can build the final query automatigally?
that can build the final query automatigally?
*/
*/
HeapTuple
fti
(
void
);
extern
Datum
fti
(
PG_FUNCTION_ARGS
);
char
*
breakup
(
char
*
,
char
*
);
static
char
*
breakup
(
char
*
,
char
*
);
bool
is_stopword
(
char
*
);
static
bool
is_stopword
(
char
*
);
bool
new_tuple
=
false
;
static
bool
new_tuple
=
false
;
/* THIS LIST MUST BE IN SORTED ORDER, A BINARY SEARCH IS USED!!!! */
/* THIS LIST MUST BE IN SORTED ORDER, A BINARY SEARCH IS USED!!!! */
...
@@ -93,9 +93,10 @@ static int nDeletePlans = 0;
...
@@ -93,9 +93,10 @@ static int nDeletePlans = 0;
static
EPlan
*
find_plan
(
char
*
ident
,
EPlan
**
eplan
,
int
*
nplans
);
static
EPlan
*
find_plan
(
char
*
ident
,
EPlan
**
eplan
,
int
*
nplans
);
/***********************************************************************/
/***********************************************************************/
HeapTuple
Datum
fti
()
fti
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
Trigger
*
trigger
;
/* to get trigger name */
Trigger
*
trigger
;
/* to get trigger name */
int
nargs
;
/* # of arguments */
int
nargs
;
/* # of arguments */
char
**
args
;
/* arguments */
char
**
args
;
/* arguments */
...
@@ -119,32 +120,29 @@ fti()
...
@@ -119,32 +120,29 @@ fti()
* function\n"); fflush(debug);
* function\n"); fflush(debug);
*/
*/
if
(
!
C
urrentTriggerData
)
if
(
!
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"Full Text Indexing:
triggers are not initialized
"
);
elog
(
ERROR
,
"Full Text Indexing:
not fired by trigger manager
"
);
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"Full Text Indexing: can't process STATEMENT events"
);
elog
(
ERROR
,
"Full Text Indexing: can't process STATEMENT events"
);
if
(
TRIGGER_FIRED_BEFORE
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BEFORE
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"Full Text Indexing: must be fired AFTER event"
);
elog
(
ERROR
,
"Full Text Indexing: must be fired AFTER event"
);
if
(
TRIGGER_FIRED_BY_INSERT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_INSERT
(
trigd
ata
->
tg_event
))
isinsert
=
true
;
isinsert
=
true
;
if
(
TRIGGER_FIRED_BY_UPDATE
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_UPDATE
(
trigd
ata
->
tg_event
))
{
{
isdelete
=
true
;
isdelete
=
true
;
isinsert
=
true
;
isinsert
=
true
;
}
}
if
(
TRIGGER_FIRED_BY_DELETE
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_DELETE
(
trigd
ata
->
tg_event
))
isdelete
=
true
;
isdelete
=
true
;
trigger
=
CurrentTriggerD
ata
->
tg_trigger
;
trigger
=
trigd
ata
->
tg_trigger
;
rel
=
CurrentTriggerD
ata
->
tg_relation
;
rel
=
trigd
ata
->
tg_relation
;
relname
=
SPI_getrelname
(
rel
);
relname
=
SPI_getrelname
(
rel
);
rettuple
=
CurrentTriggerD
ata
->
tg_trigtuple
;
rettuple
=
trigd
ata
->
tg_trigtuple
;
if
(
isdelete
&&
isinsert
)
/* is an UPDATE */
if
(
isdelete
&&
isinsert
)
/* is an UPDATE */
rettuple
=
CurrentTriggerData
->
tg_newtuple
;
rettuple
=
trigdata
->
tg_newtuple
;
CurrentTriggerData
=
NULL
;
/* invalidate 'normal' calls to this
* function */
if
((
ret
=
SPI_connect
())
<
0
)
if
((
ret
=
SPI_connect
())
<
0
)
elog
(
ERROR
,
"Full Text Indexing: SPI_connect failed, returned %d
\n
"
,
ret
);
elog
(
ERROR
,
"Full Text Indexing: SPI_connect failed, returned %d
\n
"
,
ret
);
...
@@ -289,10 +287,10 @@ fti()
...
@@ -289,10 +287,10 @@ fti()
}
}
SPI_finish
();
SPI_finish
();
return
(
rettuple
);
return
PointerGetDatum
(
rettuple
);
}
}
char
*
static
char
*
breakup
(
char
*
string
,
char
*
substring
)
breakup
(
char
*
string
,
char
*
substring
)
{
{
static
char
*
last_start
;
static
char
*
last_start
;
...
@@ -342,7 +340,7 @@ breakup(char *string, char *substring)
...
@@ -342,7 +340,7 @@ breakup(char *string, char *substring)
}
}
/* copied from src/backend/parser/keywords.c and adjusted for our situation*/
/* copied from src/backend/parser/keywords.c and adjusted for our situation*/
bool
static
bool
is_stopword
(
char
*
text
)
is_stopword
(
char
*
text
)
{
{
char
**
StopLow
;
/* for list of stop-words */
char
**
StopLow
;
/* for list of stop-words */
...
...
contrib/fulltextindex/fticopy
View file @
18952f67
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
#
#
# create function fti() returns opaque as
# create function fti() returns opaque as
# '/path/to/fti/file/fti.so'
# '/path/to/fti/file/fti.so'
# language 'C';
# language '
new
C';
#
#
# create trigger my_fti_trigger after update or insert or delete
# create trigger my_fti_trigger after update or insert or delete
# on mytable
# on mytable
...
...
contrib/lo/lo.c
View file @
18952f67
/*
/*
* PostgreSQL type definitions for managed LargeObjects.
* PostgreSQL type definitions for managed LargeObjects.
*
*
* $Id: lo.c,v 1.
2 1999/05/25 16:05:45 momjian
Exp $
* $Id: lo.c,v 1.
3 2000/05/29 01:59:02 tgl
Exp $
*
*
*/
*/
...
@@ -37,7 +37,7 @@ Blob *lo_in(char *str); /* Create from String */
...
@@ -37,7 +37,7 @@ Blob *lo_in(char *str); /* Create from String */
char
*
lo_out
(
Blob
*
addr
);
/* Output oid as String */
char
*
lo_out
(
Blob
*
addr
);
/* Output oid as String */
Oid
lo_oid
(
Blob
*
addr
);
/* Return oid as an oid */
Oid
lo_oid
(
Blob
*
addr
);
/* Return oid as an oid */
Blob
*
lo
(
Oid
oid
);
/* Return Blob based on oid */
Blob
*
lo
(
Oid
oid
);
/* Return Blob based on oid */
HeapTuple
lo_manage
(
void
);
/* Trigger handler */
Datum
lo_manage
(
PG_FUNCTION_ARGS
);
/* Trigger handler */
/*
/*
* This creates a large object, and set's its OID to the value in the
* This creates a large object, and set's its OID to the value in the
...
@@ -139,9 +139,10 @@ lo(Oid oid)
...
@@ -139,9 +139,10 @@ lo(Oid oid)
/*
/*
* This handles the trigger that protects us from orphaned large objects
* This handles the trigger that protects us from orphaned large objects
*/
*/
HeapTuple
Datum
lo_manage
(
void
)
lo_manage
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
attnum
;
/* attribute number to monitor */
int
attnum
;
/* attribute number to monitor */
char
**
args
;
/* Args containing attr name */
char
**
args
;
/* Args containing attr name */
TupleDesc
tupdesc
;
/* Tuple Descriptor */
TupleDesc
tupdesc
;
/* Tuple Descriptor */
...
@@ -150,28 +151,25 @@ lo_manage(void)
...
@@ -150,28 +151,25 @@ lo_manage(void)
HeapTuple
newtuple
=
NULL
;
/* The new value for tuple */
HeapTuple
newtuple
=
NULL
;
/* The new value for tuple */
HeapTuple
trigtuple
;
/* The original value of tuple */
HeapTuple
trigtuple
;
/* The original value of tuple */
if
(
!
C
urrentTriggerData
)
if
(
!
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"lo:
triggers are not initialized
"
);
elog
(
ERROR
,
"lo:
not fired by trigger manager
"
);
/*
/*
* Fetch some values from
CurrentTriggerD
ata
* Fetch some values from
trigd
ata
*/
*/
newtuple
=
CurrentTriggerD
ata
->
tg_newtuple
;
newtuple
=
trigd
ata
->
tg_newtuple
;
trigtuple
=
CurrentTriggerD
ata
->
tg_trigtuple
;
trigtuple
=
trigd
ata
->
tg_trigtuple
;
tupdesc
=
CurrentTriggerD
ata
->
tg_relation
->
rd_att
;
tupdesc
=
trigd
ata
->
tg_relation
->
rd_att
;
args
=
CurrentTriggerD
ata
->
tg_trigger
->
tgargs
;
args
=
trigd
ata
->
tg_trigger
->
tgargs
;
/* tuple to return to Executor */
/* tuple to return to Executor */
if
(
TRIGGER_FIRED_BY_UPDATE
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_UPDATE
(
trigd
ata
->
tg_event
))
rettuple
=
newtuple
;
rettuple
=
newtuple
;
else
else
rettuple
=
trigtuple
;
rettuple
=
trigtuple
;
/* Are we deleting the row? */
/* Are we deleting the row? */
isdelete
=
TRIGGER_FIRED_BY_DELETE
(
CurrentTriggerData
->
tg_event
);
isdelete
=
TRIGGER_FIRED_BY_DELETE
(
trigdata
->
tg_event
);
/* Were done with it */
CurrentTriggerData
=
NULL
;
/* Get the column were interested in */
/* Get the column were interested in */
attnum
=
SPI_fnumber
(
tupdesc
,
args
[
0
]);
attnum
=
SPI_fnumber
(
tupdesc
,
args
[
0
]);
...
@@ -214,5 +212,5 @@ lo_manage(void)
...
@@ -214,5 +212,5 @@ lo_manage(void)
}
}
}
}
return
(
rettuple
);
return
PointerGetDatum
(
rettuple
);
}
}
contrib/lo/lo.sql.in
View file @
18952f67
--
--
-- PostgreSQL code for LargeObjects
-- PostgreSQL code for LargeObjects
--
--
-- $Id: lo.sql.in,v 1.
1 1998/06/16 07:07:11 momjian
Exp $
-- $Id: lo.sql.in,v 1.
2 2000/05/29 01:59:02 tgl
Exp $
--
--
load '_OBJWD_/lo_DLSUFFIX_';
load '_OBJWD_/lo_DLSUFFIX_';
...
@@ -47,7 +47,7 @@ create function lo(oid)
...
@@ -47,7 +47,7 @@ create function lo(oid)
create function lo_manage()
create function lo_manage()
returns opaque
returns opaque
as '_OBJWD_/lo_DLSUFFIX_'
as '_OBJWD_/lo_DLSUFFIX_'
language '
c
';
language '
newC
';
-- This allows us to map lo to oid
-- This allows us to map lo to oid
--
--
...
...
contrib/noupdate/noup.c
View file @
18952f67
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
#include "commands/trigger.h"
/* -"- and triggers */
#include "commands/trigger.h"
/* -"- and triggers */
#include <ctype.h>
/* tolower () */
#include <ctype.h>
/* tolower () */
HeapTuple
noup
(
void
);
extern
Datum
noup
(
PG_FUNCTION_ARGS
);
/*
/*
* noup () -- revoke permission on column
* noup () -- revoke permission on column
...
@@ -16,9 +16,10 @@ HeapTuple noup(void);
...
@@ -16,9 +16,10 @@ HeapTuple noup(void);
* EXECUTE PROCEDURE noup ('col').
* EXECUTE PROCEDURE noup ('col').
*/
*/
HeapTuple
/* have to return HeapTuple to Executor */
Datum
noup
()
noup
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
Trigger
*
trigger
;
/* to get trigger name */
Trigger
*
trigger
;
/* to get trigger name */
int
nargs
;
/* # of args specified in CREATE TRIGGER */
int
nargs
;
/* # of args specified in CREATE TRIGGER */
char
**
args
;
/* arguments: column names and table name */
char
**
args
;
/* arguments: column names and table name */
...
@@ -36,42 +37,35 @@ noup()
...
@@ -36,42 +37,35 @@ noup()
*/
*/
/* Called by trigger manager ? */
/* Called by trigger manager ? */
if
(
!
C
urrentTriggerData
)
if
(
!
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
WARN
,
"noup: triggers are not initialized
"
);
elog
(
ERROR
,
"noup: not fired by trigger manager
"
);
/* Should be called for ROW trigger */
/* Should be called for ROW trigger */
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
trigd
ata
->
tg_event
))
elog
(
WARN
,
"noup: can't process STATEMENT events"
);
elog
(
ERROR
,
"noup: can't process STATEMENT events"
);
/* Not should be called for INSERT */
/* Not should be called for INSERT */
if
(
TRIGGER_FIRED_BY_INSERT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_INSERT
(
trigd
ata
->
tg_event
))
elog
(
WARN
,
"noup: can't process INSERT events"
);
elog
(
ERROR
,
"noup: can't process INSERT events"
);
/* Not should be called for DELETE */
/* Not should be called for DELETE */
else
if
(
TRIGGER_FIRED_BY_DELETE
(
CurrentTriggerD
ata
->
tg_event
))
else
if
(
TRIGGER_FIRED_BY_DELETE
(
trigd
ata
->
tg_event
))
elog
(
WARN
,
"noup: can't process DELETE events"
);
elog
(
ERROR
,
"noup: can't process DELETE events"
);
/* check new Tuple */
/* check new Tuple */
tuple
=
CurrentTriggerD
ata
->
tg_newtuple
;
tuple
=
trigd
ata
->
tg_newtuple
;
trigger
=
CurrentTriggerD
ata
->
tg_trigger
;
trigger
=
trigd
ata
->
tg_trigger
;
nargs
=
trigger
->
tgnargs
;
nargs
=
trigger
->
tgnargs
;
args
=
trigger
->
tgargs
;
args
=
trigger
->
tgargs
;
nkeys
=
nargs
;
nkeys
=
nargs
;
rel
=
CurrentTriggerD
ata
->
tg_relation
;
rel
=
trigd
ata
->
tg_relation
;
tupdesc
=
rel
->
rd_att
;
tupdesc
=
rel
->
rd_att
;
/*
* Setting CurrentTriggerData to NULL prevents direct calls to trigger
* functions in queries. Normally, trigger functions have to be called
* by trigger manager code only.
*/
CurrentTriggerData
=
NULL
;
/* Connect to SPI manager */
/* Connect to SPI manager */
if
((
ret
=
SPI_connect
())
<
0
)
if
((
ret
=
SPI_connect
())
<
0
)
elog
(
WARN
,
"noup: SPI_connect returned %d"
,
ret
);
elog
(
ERROR
,
"noup: SPI_connect returned %d"
,
ret
);
/*
/*
* We use SPI plan preparation feature, so allocate space to place key
* We use SPI plan preparation feature, so allocate space to place key
...
@@ -87,7 +81,7 @@ noup()
...
@@ -87,7 +81,7 @@ noup()
/* Bad guys may give us un-existing column in CREATE TRIGGER */
/* Bad guys may give us un-existing column in CREATE TRIGGER */
if
(
fnumber
<
0
)
if
(
fnumber
<
0
)
elog
(
WARN
,
"noup: there is no attribute %s in relation %s"
,
elog
(
ERROR
,
"noup: there is no attribute %s in relation %s"
,
args
[
i
],
SPI_getrelname
(
rel
));
args
[
i
],
SPI_getrelname
(
rel
));
/* Well, get binary (in internal format) value of column */
/* Well, get binary (in internal format) value of column */
...
@@ -99,13 +93,13 @@ noup()
...
@@ -99,13 +93,13 @@ noup()
if
(
!
isnull
)
if
(
!
isnull
)
{
{
elog
(
WARN
,
"%s: update not allowed"
,
args
[
i
]);
elog
(
NOTICE
,
"%s: update not allowed"
,
args
[
i
]);
SPI_finish
();
SPI_finish
();
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
}
}
SPI_finish
();
SPI_finish
();
return
(
tuple
);
return
PointerGetDatum
(
tuple
);
}
}
contrib/noupdate/noup.source
View file @
18952f67
...
@@ -3,5 +3,5 @@ DROP FUNCTION noup ();
...
@@ -3,5 +3,5 @@ DROP FUNCTION noup ();
CREATE FUNCTION noup ()
CREATE FUNCTION noup ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/noup_DLSUFFIX_'
AS '_OBJWD_/noup_DLSUFFIX_'
LANGUAGE '
c
'
LANGUAGE '
newC
'
;
;
contrib/spi/autoinc.c
View file @
18952f67
...
@@ -2,13 +2,13 @@
...
@@ -2,13 +2,13 @@
#include "executor/spi.h"
/* this is what you need to work with SPI */
#include "executor/spi.h"
/* this is what you need to work with SPI */
#include "commands/trigger.h"
/* -"- and triggers */
#include "commands/trigger.h"
/* -"- and triggers */
HeapTuple
autoinc
(
void
);
extern
Datum
autoinc
(
PG_FUNCTION_ARGS
);
extern
int4
nextval
(
struct
varlena
*
seqin
);
extern
int4
nextval
(
struct
varlena
*
seqin
);
HeapTuple
Datum
autoinc
()
autoinc
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
Trigger
*
trigger
;
/* to get trigger name */
Trigger
*
trigger
;
/* to get trigger name */
int
nargs
;
/* # of arguments */
int
nargs
;
/* # of arguments */
int
*
chattrs
;
/* attnums of attributes to change */
int
*
chattrs
;
/* attnums of attributes to change */
...
@@ -22,24 +22,24 @@ autoinc()
...
@@ -22,24 +22,24 @@ autoinc()
bool
isnull
;
bool
isnull
;
int
i
;
int
i
;
if
(
!
C
urrentTriggerData
)
if
(
!
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"autoinc:
triggers are not initialized
"
);
elog
(
ERROR
,
"autoinc:
not fired by trigger manager
"
);
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"autoinc: can't process STATEMENT events"
);
elog
(
ERROR
,
"autoinc: can't process STATEMENT events"
);
if
(
TRIGGER_FIRED_AFTER
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_AFTER
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"autoinc: must be fired before event"
);
elog
(
ERROR
,
"autoinc: must be fired before event"
);
if
(
TRIGGER_FIRED_BY_INSERT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_INSERT
(
trigd
ata
->
tg_event
))
rettuple
=
CurrentTriggerD
ata
->
tg_trigtuple
;
rettuple
=
trigd
ata
->
tg_trigtuple
;
else
if
(
TRIGGER_FIRED_BY_UPDATE
(
CurrentTriggerD
ata
->
tg_event
))
else
if
(
TRIGGER_FIRED_BY_UPDATE
(
trigd
ata
->
tg_event
))
rettuple
=
CurrentTriggerD
ata
->
tg_newtuple
;
rettuple
=
trigd
ata
->
tg_newtuple
;
else
else
elog
(
ERROR
,
"autoinc: can't process DELETE events"
);
elog
(
ERROR
,
"autoinc: can't process DELETE events"
);
rel
=
CurrentTriggerD
ata
->
tg_relation
;
rel
=
trigd
ata
->
tg_relation
;
relname
=
SPI_getrelname
(
rel
);
relname
=
SPI_getrelname
(
rel
);
trigger
=
CurrentTriggerD
ata
->
tg_trigger
;
trigger
=
trigd
ata
->
tg_trigger
;
nargs
=
trigger
->
tgnargs
;
nargs
=
trigger
->
tgnargs
;
if
(
nargs
<=
0
||
nargs
%
2
!=
0
)
if
(
nargs
<=
0
||
nargs
%
2
!=
0
)
...
@@ -48,8 +48,6 @@ autoinc()
...
@@ -48,8 +48,6 @@ autoinc()
args
=
trigger
->
tgargs
;
args
=
trigger
->
tgargs
;
tupdesc
=
rel
->
rd_att
;
tupdesc
=
rel
->
rd_att
;
CurrentTriggerData
=
NULL
;
chattrs
=
(
int
*
)
palloc
(
nargs
/
2
*
sizeof
(
int
));
chattrs
=
(
int
*
)
palloc
(
nargs
/
2
*
sizeof
(
int
));
newvals
=
(
Datum
*
)
palloc
(
nargs
/
2
*
sizeof
(
Datum
));
newvals
=
(
Datum
*
)
palloc
(
nargs
/
2
*
sizeof
(
Datum
));
...
@@ -96,5 +94,5 @@ autoinc()
...
@@ -96,5 +94,5 @@ autoinc()
pfree
(
chattrs
);
pfree
(
chattrs
);
pfree
(
newvals
);
pfree
(
newvals
);
return
(
rettuple
);
return
PointerGetDatum
(
rettuple
);
}
}
contrib/spi/autoinc.source
View file @
18952f67
...
@@ -3,4 +3,4 @@ DROP FUNCTION autoinc();
...
@@ -3,4 +3,4 @@ DROP FUNCTION autoinc();
CREATE FUNCTION autoinc()
CREATE FUNCTION autoinc()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/autoinc_DLSUFFIX_'
AS '_OBJWD_/autoinc_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
contrib/spi/insert_username.c
View file @
18952f67
...
@@ -10,11 +10,12 @@
...
@@ -10,11 +10,12 @@
#include "commands/trigger.h"
/* -"- and triggers */
#include "commands/trigger.h"
/* -"- and triggers */
#include "miscadmin.h"
/* for GetPgUserName() */
#include "miscadmin.h"
/* for GetPgUserName() */
HeapTuple
insert_username
(
void
);
extern
Datum
insert_username
(
PG_FUNCTION_ARGS
);
HeapTuple
Datum
insert_username
()
insert_username
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
Trigger
*
trigger
;
/* to get trigger name */
Trigger
*
trigger
;
/* to get trigger name */
int
nargs
;
/* # of arguments */
int
nargs
;
/* # of arguments */
Datum
newval
;
/* new value of column */
Datum
newval
;
/* new value of column */
...
@@ -26,24 +27,24 @@ insert_username()
...
@@ -26,24 +27,24 @@ insert_username()
int
attnum
;
int
attnum
;
/* sanity checks from autoinc.c */
/* sanity checks from autoinc.c */
if
(
!
C
urrentTriggerData
)
if
(
!
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"insert_username:
triggers are not initialized
"
);
elog
(
ERROR
,
"insert_username:
not fired by trigger manager
"
);
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"insert_username: can't process STATEMENT events"
);
elog
(
ERROR
,
"insert_username: can't process STATEMENT events"
);
if
(
TRIGGER_FIRED_AFTER
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_AFTER
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"insert_username: must be fired before event"
);
elog
(
ERROR
,
"insert_username: must be fired before event"
);
if
(
TRIGGER_FIRED_BY_INSERT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_INSERT
(
trigd
ata
->
tg_event
))
rettuple
=
CurrentTriggerD
ata
->
tg_trigtuple
;
rettuple
=
trigd
ata
->
tg_trigtuple
;
else
if
(
TRIGGER_FIRED_BY_UPDATE
(
CurrentTriggerD
ata
->
tg_event
))
else
if
(
TRIGGER_FIRED_BY_UPDATE
(
trigd
ata
->
tg_event
))
rettuple
=
CurrentTriggerD
ata
->
tg_newtuple
;
rettuple
=
trigd
ata
->
tg_newtuple
;
else
else
elog
(
ERROR
,
"insert_username: can't process DELETE events"
);
elog
(
ERROR
,
"insert_username: can't process DELETE events"
);
rel
=
CurrentTriggerD
ata
->
tg_relation
;
rel
=
trigd
ata
->
tg_relation
;
relname
=
SPI_getrelname
(
rel
);
relname
=
SPI_getrelname
(
rel
);
trigger
=
CurrentTriggerD
ata
->
tg_trigger
;
trigger
=
trigd
ata
->
tg_trigger
;
nargs
=
trigger
->
tgnargs
;
nargs
=
trigger
->
tgnargs
;
if
(
nargs
!=
1
)
if
(
nargs
!=
1
)
...
@@ -52,8 +53,6 @@ insert_username()
...
@@ -52,8 +53,6 @@ insert_username()
args
=
trigger
->
tgargs
;
args
=
trigger
->
tgargs
;
tupdesc
=
rel
->
rd_att
;
tupdesc
=
rel
->
rd_att
;
CurrentTriggerData
=
NULL
;
attnum
=
SPI_fnumber
(
tupdesc
,
args
[
0
]);
attnum
=
SPI_fnumber
(
tupdesc
,
args
[
0
]);
if
(
attnum
<
0
)
if
(
attnum
<
0
)
...
@@ -73,5 +72,5 @@ insert_username()
...
@@ -73,5 +72,5 @@ insert_username()
pfree
(
relname
);
pfree
(
relname
);
return
(
rettuple
);
return
PointerGetDatum
(
rettuple
);
}
}
contrib/spi/insert_username.source
View file @
18952f67
...
@@ -3,4 +3,4 @@ DROP FUNCTION insert_username();
...
@@ -3,4 +3,4 @@ DROP FUNCTION insert_username();
CREATE FUNCTION insert_username()
CREATE FUNCTION insert_username()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/insert_username_DLSUFFIX_'
AS '_OBJWD_/insert_username_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
contrib/spi/moddatetime.c
View file @
18952f67
...
@@ -8,18 +8,19 @@ a modification datetime stamp in a record when that record is UPDATEd.
...
@@ -8,18 +8,19 @@ a modification datetime stamp in a record when that record is UPDATEd.
Credits
Credits
This is 95%+ based on autoinc.c, which I used as a starting point as I do
This is 95%+ based on autoinc.c, which I used as a starting point as I do
not really know what I am doing. I also had help from
not really know what I am doing. I also had help from
Jan Wieck <jwieck@debis.com> who told me about the
datetime
_in("now") function.
Jan Wieck <jwieck@debis.com> who told me about the
timestamp
_in("now") function.
OH, me, I'm Terry Mackintosh <terry@terrym.com>
OH, me, I'm Terry Mackintosh <terry@terrym.com>
*/
*/
#include "executor/spi.h"
/* this is what you need to work with SPI */
#include "executor/spi.h"
/* this is what you need to work with SPI */
#include "commands/trigger.h"
/* -"- and triggers */
#include "commands/trigger.h"
/* -"- and triggers */
HeapTuple
moddatetime
(
void
);
extern
Datum
moddatetime
(
PG_FUNCTION_ARGS
);
HeapTuple
Datum
moddatetime
()
moddatetime
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
Trigger
*
trigger
;
/* to get trigger name */
Trigger
*
trigger
;
/* to get trigger name */
int
nargs
;
/* # of arguments */
int
nargs
;
/* # of arguments */
int
attnum
;
/* positional number of field to change */
int
attnum
;
/* positional number of field to change */
...
@@ -30,26 +31,26 @@ moddatetime()
...
@@ -30,26 +31,26 @@ moddatetime()
HeapTuple
rettuple
=
NULL
;
HeapTuple
rettuple
=
NULL
;
TupleDesc
tupdesc
;
/* tuple description */
TupleDesc
tupdesc
;
/* tuple description */
if
(
!
C
urrentTriggerData
)
if
(
!
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"moddatetime:
triggers are not initialized
."
);
elog
(
ERROR
,
"moddatetime:
not fired by trigger manager
."
);
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"moddatetime: can't process STATEMENT events."
);
elog
(
ERROR
,
"moddatetime: can't process STATEMENT events."
);
if
(
TRIGGER_FIRED_AFTER
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_AFTER
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"moddatetime: must be fired before event."
);
elog
(
ERROR
,
"moddatetime: must be fired before event."
);
if
(
TRIGGER_FIRED_BY_INSERT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_INSERT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"moddatetime: must be fired before event."
);
elog
(
ERROR
,
"moddatetime: must be fired before event."
);
else
if
(
TRIGGER_FIRED_BY_UPDATE
(
CurrentTriggerD
ata
->
tg_event
))
else
if
(
TRIGGER_FIRED_BY_UPDATE
(
trigd
ata
->
tg_event
))
rettuple
=
CurrentTriggerD
ata
->
tg_newtuple
;
rettuple
=
trigd
ata
->
tg_newtuple
;
else
else
elog
(
ERROR
,
"moddatetime: can't process DELETE events."
);
elog
(
ERROR
,
"moddatetime: can't process DELETE events."
);
rel
=
CurrentTriggerD
ata
->
tg_relation
;
rel
=
trigd
ata
->
tg_relation
;
relname
=
SPI_getrelname
(
rel
);
relname
=
SPI_getrelname
(
rel
);
trigger
=
CurrentTriggerD
ata
->
tg_trigger
;
trigger
=
trigd
ata
->
tg_trigger
;
nargs
=
trigger
->
tgnargs
;
nargs
=
trigger
->
tgnargs
;
...
@@ -60,11 +61,8 @@ moddatetime()
...
@@ -60,11 +61,8 @@ moddatetime()
/* must be the field layout? */
/* must be the field layout? */
tupdesc
=
rel
->
rd_att
;
tupdesc
=
rel
->
rd_att
;
/* Why do this? */
CurrentTriggerData
=
NULL
;
/* Get the current datetime. */
/* Get the current datetime. */
newdt
=
datetime
_in
(
"now"
);
newdt
=
(
Datum
)
timestamp
_in
(
"now"
);
/*
/*
* This gets the position in the turple of the field we want. args[0]
* This gets the position in the turple of the field we want. args[0]
...
@@ -82,12 +80,12 @@ moddatetime()
...
@@ -82,12 +80,12 @@ moddatetime()
args
[
0
]);
args
[
0
]);
/*
/*
* OK, this is where we make sure the
datetime
field that we are
* OK, this is where we make sure the
timestamp
field that we are
* modifying is really a
datetime
field. Hay, error checking, what a
* modifying is really a
timestamp
field. Hay, error checking, what a
* novel idea !-)
* novel idea !-)
*/
*/
if
(
SPI_gettypeid
(
tupdesc
,
attnum
)
!=
DATETIME
OID
)
if
(
SPI_gettypeid
(
tupdesc
,
attnum
)
!=
TIMESTAMP
OID
)
elog
(
ERROR
,
"moddatetime (%s): attribute %s must be of
DATETIME
type"
,
elog
(
ERROR
,
"moddatetime (%s): attribute %s must be of
TIMESTAMP
type"
,
relname
,
args
[
0
]);
relname
,
args
[
0
]);
/* 1 is the number of items in the arrays attnum and newdt.
/* 1 is the number of items in the arrays attnum and newdt.
...
@@ -106,5 +104,5 @@ moddatetime()
...
@@ -106,5 +104,5 @@ moddatetime()
/* Clean up */
/* Clean up */
pfree
(
relname
);
pfree
(
relname
);
return
(
rettuple
);
return
PointerGetDatum
(
rettuple
);
}
}
contrib/spi/moddatetime.source
View file @
18952f67
...
@@ -3,4 +3,4 @@ DROP FUNCTION moddatetime();
...
@@ -3,4 +3,4 @@ DROP FUNCTION moddatetime();
CREATE FUNCTION moddatetime()
CREATE FUNCTION moddatetime()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/moddatetime_DLSUFFIX_'
AS '_OBJWD_/moddatetime_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
contrib/spi/refint.c
View file @
18952f67
...
@@ -8,10 +8,8 @@
...
@@ -8,10 +8,8 @@
#include <ctype.h>
/* tolower () */
#include <ctype.h>
/* tolower () */
extern
Datum
check_primary_key
(
PG_FUNCTION_ARGS
);
extern
Datum
check_foreign_key
(
PG_FUNCTION_ARGS
);
HeapTuple
check_primary_key
(
void
);
HeapTuple
check_foreign_key
(
void
);
typedef
struct
typedef
struct
...
@@ -38,9 +36,10 @@ static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
...
@@ -38,9 +36,10 @@ static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
* check_primary_key ('Fkey1', 'Fkey2', 'Ptable', 'Pkey1', 'Pkey2').
* check_primary_key ('Fkey1', 'Fkey2', 'Ptable', 'Pkey1', 'Pkey2').
*/
*/
HeapTuple
/* have to return HeapTuple to Executor */
Datum
check_primary_key
()
check_primary_key
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
Trigger
*
trigger
;
/* to get trigger name */
Trigger
*
trigger
;
/* to get trigger name */
int
nargs
;
/* # of args specified in CREATE TRIGGER */
int
nargs
;
/* # of args specified in CREATE TRIGGER */
char
**
args
;
/* arguments: column names and table name */
char
**
args
;
/* arguments: column names and table name */
...
@@ -57,33 +56,35 @@ check_primary_key()
...
@@ -57,33 +56,35 @@ check_primary_key()
int
ret
;
int
ret
;
int
i
;
int
i
;
/*
* Some checks first...
*/
#ifdef DEBUG_QUERY
#ifdef DEBUG_QUERY
elog
(
NOTICE
,
"Check_primary_key Enter Function"
);
elog
(
NOTICE
,
"Check_primary_key Enter Function"
);
#endif
#endif
/*
* Some checks first...
*/
/* Called by trigger manager ? */
/* Called by trigger manager ? */
if
(
!
C
urrentTriggerData
)
if
(
!
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"check_primary_key:
triggers are not initialized
"
);
elog
(
ERROR
,
"check_primary_key:
not fired by trigger manager
"
);
/* Should be called for ROW trigger */
/* Should be called for ROW trigger */
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"check_primary_key: can't process STATEMENT events"
);
elog
(
ERROR
,
"check_primary_key: can't process STATEMENT events"
);
/* If INSERTion then must check Tuple to being inserted */
/* If INSERTion then must check Tuple to being inserted */
if
(
TRIGGER_FIRED_BY_INSERT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_INSERT
(
trigd
ata
->
tg_event
))
tuple
=
CurrentTriggerD
ata
->
tg_trigtuple
;
tuple
=
trigd
ata
->
tg_trigtuple
;
/* Not should be called for DELETE */
/* Not should be called for DELETE */
else
if
(
TRIGGER_FIRED_BY_DELETE
(
CurrentTriggerD
ata
->
tg_event
))
else
if
(
TRIGGER_FIRED_BY_DELETE
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"check_primary_key: can't process DELETE events"
);
elog
(
ERROR
,
"check_primary_key: can't process DELETE events"
);
/* If UPDATion the must check new Tuple, not old one */
/* If UPDATion the must check new Tuple, not old one */
else
else
tuple
=
CurrentTriggerD
ata
->
tg_newtuple
;
tuple
=
trigd
ata
->
tg_newtuple
;
trigger
=
CurrentTriggerD
ata
->
tg_trigger
;
trigger
=
trigd
ata
->
tg_trigger
;
nargs
=
trigger
->
tgnargs
;
nargs
=
trigger
->
tgnargs
;
args
=
trigger
->
tgargs
;
args
=
trigger
->
tgargs
;
...
@@ -92,16 +93,9 @@ check_primary_key()
...
@@ -92,16 +93,9 @@ check_primary_key()
nkeys
=
nargs
/
2
;
nkeys
=
nargs
/
2
;
relname
=
args
[
nkeys
];
relname
=
args
[
nkeys
];
rel
=
CurrentTriggerD
ata
->
tg_relation
;
rel
=
trigd
ata
->
tg_relation
;
tupdesc
=
rel
->
rd_att
;
tupdesc
=
rel
->
rd_att
;
/*
* Setting CurrentTriggerData to NULL prevents direct calls to trigger
* functions in queries. Normally, trigger functions have to be called
* by trigger manager code only.
*/
CurrentTriggerData
=
NULL
;
/* Connect to SPI manager */
/* Connect to SPI manager */
if
((
ret
=
SPI_connect
())
<
0
)
if
((
ret
=
SPI_connect
())
<
0
)
elog
(
ERROR
,
"check_primary_key: SPI_connect returned %d"
,
ret
);
elog
(
ERROR
,
"check_primary_key: SPI_connect returned %d"
,
ret
);
...
@@ -145,7 +139,7 @@ check_primary_key()
...
@@ -145,7 +139,7 @@ check_primary_key()
if
(
isnull
)
if
(
isnull
)
{
{
SPI_finish
();
SPI_finish
();
return
(
tuple
);
return
PointerGetDatum
(
tuple
);
}
}
if
(
plan
->
nplans
<=
0
)
/* Get typeId of column */
if
(
plan
->
nplans
<=
0
)
/* Get typeId of column */
...
@@ -207,7 +201,7 @@ check_primary_key()
...
@@ -207,7 +201,7 @@ check_primary_key()
SPI_finish
();
SPI_finish
();
return
(
tuple
);
return
PointerGetDatum
(
tuple
);
}
}
/*
/*
...
@@ -222,9 +216,10 @@ check_primary_key()
...
@@ -222,9 +216,10 @@ check_primary_key()
* 'Ftable1', 'Fkey11', 'Fkey12', 'Ftable2', 'Fkey21', 'Fkey22').
* 'Ftable1', 'Fkey11', 'Fkey12', 'Ftable2', 'Fkey21', 'Fkey22').
*/
*/
HeapTuple
/* have to return HeapTuple to Executor */
Datum
check_foreign_key
()
check_foreign_key
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
Trigger
*
trigger
;
/* to get trigger name */
Trigger
*
trigger
;
/* to get trigger name */
int
nargs
;
/* # of args specified in CREATE TRIGGER */
int
nargs
;
/* # of args specified in CREATE TRIGGER */
char
**
args
;
/* arguments: as described above */
char
**
args
;
/* arguments: as described above */
...
@@ -258,19 +253,19 @@ check_foreign_key()
...
@@ -258,19 +253,19 @@ check_foreign_key()
*/
*/
/* Called by trigger manager ? */
/* Called by trigger manager ? */
if
(
!
C
urrentTriggerData
)
if
(
!
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"check_foreign_key:
triggers are not initialized
"
);
elog
(
ERROR
,
"check_foreign_key:
not fired by trigger manager
"
);
/* Should be called for ROW trigger */
/* Should be called for ROW trigger */
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"check_foreign_key: can't process STATEMENT events"
);
elog
(
ERROR
,
"check_foreign_key: can't process STATEMENT events"
);
/* Not should be called for INSERT */
/* Not should be called for INSERT */
if
(
TRIGGER_FIRED_BY_INSERT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_INSERT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"check_foreign_key: can't process INSERT events"
);
elog
(
ERROR
,
"check_foreign_key: can't process INSERT events"
);
/* Have to check tg_trigtuple - tuple being deleted */
/* Have to check tg_trigtuple - tuple being deleted */
trigtuple
=
CurrentTriggerD
ata
->
tg_trigtuple
;
trigtuple
=
trigd
ata
->
tg_trigtuple
;
/*
/*
* But if this is UPDATE then we have to return tg_newtuple. Also, if
* But if this is UPDATE then we have to return tg_newtuple. Also, if
...
@@ -278,12 +273,12 @@ check_foreign_key()
...
@@ -278,12 +273,12 @@ check_foreign_key()
* do.
* do.
*/
*/
is_update
=
0
;
is_update
=
0
;
if
(
TRIGGER_FIRED_BY_UPDATE
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_UPDATE
(
trigd
ata
->
tg_event
))
{
{
newtuple
=
CurrentTriggerD
ata
->
tg_newtuple
;
newtuple
=
trigd
ata
->
tg_newtuple
;
is_update
=
1
;
is_update
=
1
;
}
}
trigger
=
CurrentTriggerD
ata
->
tg_trigger
;
trigger
=
trigd
ata
->
tg_trigger
;
nargs
=
trigger
->
tgnargs
;
nargs
=
trigger
->
tgnargs
;
args
=
trigger
->
tgargs
;
args
=
trigger
->
tgargs
;
...
@@ -304,16 +299,9 @@ check_foreign_key()
...
@@ -304,16 +299,9 @@ check_foreign_key()
elog
(
ERROR
,
"check_foreign_key: invalid number of arguments %d for %d references"
,
elog
(
ERROR
,
"check_foreign_key: invalid number of arguments %d for %d references"
,
nargs
+
2
,
nrefs
);
nargs
+
2
,
nrefs
);
rel
=
CurrentTriggerD
ata
->
tg_relation
;
rel
=
trigd
ata
->
tg_relation
;
tupdesc
=
rel
->
rd_att
;
tupdesc
=
rel
->
rd_att
;
/*
* Setting CurrentTriggerData to NULL prevents direct calls to trigger
* functions in queries. Normally, trigger functions have to be called
* by trigger manager code only.
*/
CurrentTriggerData
=
NULL
;
/* Connect to SPI manager */
/* Connect to SPI manager */
if
((
ret
=
SPI_connect
())
<
0
)
if
((
ret
=
SPI_connect
())
<
0
)
elog
(
ERROR
,
"check_foreign_key: SPI_connect returned %d"
,
ret
);
elog
(
ERROR
,
"check_foreign_key: SPI_connect returned %d"
,
ret
);
...
@@ -364,7 +352,7 @@ check_foreign_key()
...
@@ -364,7 +352,7 @@ check_foreign_key()
if
(
isnull
)
if
(
isnull
)
{
{
SPI_finish
();
SPI_finish
();
return
((
newtuple
==
NULL
)
?
trigtuple
:
newtuple
);
return
PointerGetDatum
((
newtuple
==
NULL
)
?
trigtuple
:
newtuple
);
}
}
/*
/*
...
@@ -527,7 +515,7 @@ check_foreign_key()
...
@@ -527,7 +515,7 @@ check_foreign_key()
if
(
newtuple
!=
NULL
&&
isequal
)
if
(
newtuple
!=
NULL
&&
isequal
)
{
{
SPI_finish
();
SPI_finish
();
return
(
newtuple
);
return
PointerGetDatum
(
newtuple
);
}
}
/*
/*
...
@@ -571,7 +559,7 @@ check_foreign_key()
...
@@ -571,7 +559,7 @@ check_foreign_key()
SPI_finish
();
SPI_finish
();
return
((
newtuple
==
NULL
)
?
trigtuple
:
newtuple
);
return
PointerGetDatum
((
newtuple
==
NULL
)
?
trigtuple
:
newtuple
);
}
}
static
EPlan
*
static
EPlan
*
...
...
contrib/spi/refint.source
View file @
18952f67
...
@@ -4,11 +4,11 @@ DROP FUNCTION check_foreign_key ();
...
@@ -4,11 +4,11 @@ DROP FUNCTION check_foreign_key ();
CREATE FUNCTION check_primary_key ()
CREATE FUNCTION check_primary_key ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/refint_DLSUFFIX_'
AS '_OBJWD_/refint_DLSUFFIX_'
LANGUAGE '
c
'
LANGUAGE '
newC
'
;
;
CREATE FUNCTION check_foreign_key ()
CREATE FUNCTION check_foreign_key ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/refint_DLSUFFIX_'
AS '_OBJWD_/refint_DLSUFFIX_'
LANGUAGE '
c
'
LANGUAGE '
newC
'
;
;
contrib/spi/timetravel.c
View file @
18952f67
...
@@ -10,8 +10,8 @@
...
@@ -10,8 +10,8 @@
#define ABSTIMEOID 702
/* it should be in pg_type.h */
#define ABSTIMEOID 702
/* it should be in pg_type.h */
AbsoluteTime
currabstime
(
void
);
AbsoluteTime
currabstime
(
void
);
HeapTuple
timetravel
(
void
);
Datum
timetravel
(
PG_FUNCTION_ARGS
);
int32
set_timetravel
(
Name
relname
,
int32
on
);
Datum
set_timetravel
(
PG_FUNCTION_ARGS
);
typedef
struct
typedef
struct
{
{
...
@@ -47,9 +47,10 @@ static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
...
@@ -47,9 +47,10 @@ static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
* timetravel ('date_on', 'date_off').
* timetravel ('date_on', 'date_off').
*/
*/
HeapTuple
/* have to return HeapTuple to Executor */
Datum
timetravel
()
timetravel
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
Trigger
*
trigger
;
/* to get trigger name */
Trigger
*
trigger
;
/* to get trigger name */
char
**
args
;
/* arguments */
char
**
args
;
/* arguments */
int
attnum
[
2
];
/* fnumbers of start/stop columns */
int
attnum
[
2
];
/* fnumbers of start/stop columns */
...
@@ -78,27 +79,27 @@ timetravel()
...
@@ -78,27 +79,27 @@ timetravel()
*/
*/
/* Called by trigger manager ? */
/* Called by trigger manager ? */
if
(
!
C
urrentTriggerData
)
if
(
!
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"timetravel:
triggers are not initialized
"
);
elog
(
ERROR
,
"timetravel:
not fired by trigger manager
"
);
/* Should be called for ROW trigger */
/* Should be called for ROW trigger */
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"timetravel: can't process STATEMENT events"
);
elog
(
ERROR
,
"timetravel: can't process STATEMENT events"
);
/* Should be called BEFORE */
/* Should be called BEFORE */
if
(
TRIGGER_FIRED_AFTER
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_AFTER
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"timetravel: must be fired before event"
);
elog
(
ERROR
,
"timetravel: must be fired before event"
);
/* INSERT ? */
/* INSERT ? */
if
(
TRIGGER_FIRED_BY_INSERT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_INSERT
(
trigd
ata
->
tg_event
))
isinsert
=
true
;
isinsert
=
true
;
if
(
TRIGGER_FIRED_BY_UPDATE
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_UPDATE
(
trigd
ata
->
tg_event
))
newtuple
=
CurrentTriggerD
ata
->
tg_newtuple
;
newtuple
=
trigd
ata
->
tg_newtuple
;
trigtuple
=
CurrentTriggerD
ata
->
tg_trigtuple
;
trigtuple
=
trigd
ata
->
tg_trigtuple
;
rel
=
CurrentTriggerD
ata
->
tg_relation
;
rel
=
trigd
ata
->
tg_relation
;
relname
=
SPI_getrelname
(
rel
);
relname
=
SPI_getrelname
(
rel
);
/* check if TT is OFF for this relation */
/* check if TT is OFF for this relation */
...
@@ -108,10 +109,10 @@ timetravel()
...
@@ -108,10 +109,10 @@ timetravel()
if
(
i
<
nTTOff
)
/* OFF - nothing to do */
if
(
i
<
nTTOff
)
/* OFF - nothing to do */
{
{
pfree
(
relname
);
pfree
(
relname
);
return
((
newtuple
!=
NULL
)
?
newtuple
:
trigtuple
);
return
PointerGetDatum
((
newtuple
!=
NULL
)
?
newtuple
:
trigtuple
);
}
}
trigger
=
CurrentTriggerD
ata
->
tg_trigger
;
trigger
=
trigd
ata
->
tg_trigger
;
if
(
trigger
->
tgnargs
!=
2
)
if
(
trigger
->
tgnargs
!=
2
)
elog
(
ERROR
,
"timetravel (%s): invalid (!= 2) number of arguments %d"
,
elog
(
ERROR
,
"timetravel (%s): invalid (!= 2) number of arguments %d"
,
...
@@ -121,13 +122,6 @@ timetravel()
...
@@ -121,13 +122,6 @@ timetravel()
tupdesc
=
rel
->
rd_att
;
tupdesc
=
rel
->
rd_att
;
natts
=
tupdesc
->
natts
;
natts
=
tupdesc
->
natts
;
/*
* Setting CurrentTriggerData to NULL prevents direct calls to trigger
* functions in queries. Normally, trigger functions have to be called
* by trigger manager code only.
*/
CurrentTriggerData
=
NULL
;
for
(
i
=
0
;
i
<
2
;
i
++
)
for
(
i
=
0
;
i
<
2
;
i
++
)
{
{
attnum
[
i
]
=
SPI_fnumber
(
tupdesc
,
args
[
i
]);
attnum
[
i
]
=
SPI_fnumber
(
tupdesc
,
args
[
i
]);
...
@@ -175,11 +169,11 @@ timetravel()
...
@@ -175,11 +169,11 @@ timetravel()
pfree
(
relname
);
pfree
(
relname
);
if
(
chnattrs
<=
0
)
if
(
chnattrs
<=
0
)
return
(
trigtuple
);
return
PointerGetDatum
(
trigtuple
);
rettuple
=
SPI_modifytuple
(
rel
,
trigtuple
,
chnattrs
,
rettuple
=
SPI_modifytuple
(
rel
,
trigtuple
,
chnattrs
,
chattrs
,
newvals
,
NULL
);
chattrs
,
newvals
,
NULL
);
return
(
rettuple
);
return
PointerGetDatum
(
rettuple
);
}
}
oldon
=
SPI_getbinval
(
trigtuple
,
tupdesc
,
attnum
[
0
],
&
isnull
);
oldon
=
SPI_getbinval
(
trigtuple
,
tupdesc
,
attnum
[
0
],
&
isnull
);
...
@@ -210,13 +204,13 @@ timetravel()
...
@@ -210,13 +204,13 @@ timetravel()
if
(
newoff
!=
NOEND_ABSTIME
)
if
(
newoff
!=
NOEND_ABSTIME
)
{
{
pfree
(
relname
);
/* allocated in upper executor context */
pfree
(
relname
);
/* allocated in upper executor context */
return
(
NULL
);
return
PointerGetDatum
(
NULL
);
}
}
}
}
else
if
(
oldoff
!=
NOEND_ABSTIME
)
/* DELETE */
else
if
(
oldoff
!=
NOEND_ABSTIME
)
/* DELETE */
{
{
pfree
(
relname
);
pfree
(
relname
);
return
(
NULL
);
return
PointerGetDatum
(
NULL
);
}
}
newoff
=
GetCurrentAbsoluteTime
();
newoff
=
GetCurrentAbsoluteTime
();
...
@@ -325,16 +319,18 @@ timetravel()
...
@@ -325,16 +319,18 @@ timetravel()
pfree
(
relname
);
pfree
(
relname
);
return
(
rettuple
);
return
PointerGetDatum
(
rettuple
);
}
}
/*
/*
* set_timetravel () --
* set_timetravel (
relname, on
) --
* turn timetravel for specified relation ON/OFF
* turn timetravel for specified relation ON/OFF
*/
*/
int32
Datum
set_timetravel
(
Name
relname
,
int32
on
)
set_timetravel
(
PG_FUNCTION_ARGS
)
{
{
Name
relname
=
PG_GETARG_NAME
(
0
);
int32
on
=
PG_GETARG_INT32
(
1
);
char
*
rname
;
char
*
rname
;
char
*
d
;
char
*
d
;
char
*
s
;
char
*
s
;
...
@@ -347,7 +343,7 @@ set_timetravel(Name relname, int32 on)
...
@@ -347,7 +343,7 @@ set_timetravel(Name relname, int32 on)
if
(
i
<
nTTOff
)
/* OFF currently */
if
(
i
<
nTTOff
)
/* OFF currently */
{
{
if
(
on
==
0
)
if
(
on
==
0
)
return
(
0
);
PG_RETURN_INT32
(
0
);
/* turn ON */
/* turn ON */
free
(
TTOff
[
i
]);
free
(
TTOff
[
i
]);
...
@@ -360,12 +356,12 @@ set_timetravel(Name relname, int32 on)
...
@@ -360,12 +356,12 @@ set_timetravel(Name relname, int32 on)
TTOff
=
realloc
(
TTOff
,
(
nTTOff
-
1
)
*
sizeof
(
char
*
));
TTOff
=
realloc
(
TTOff
,
(
nTTOff
-
1
)
*
sizeof
(
char
*
));
}
}
nTTOff
--
;
nTTOff
--
;
return
(
0
);
PG_RETURN_INT32
(
0
);
}
}
/* ON currently */
/* ON currently */
if
(
on
!=
0
)
if
(
on
!=
0
)
return
(
1
);
PG_RETURN_INT32
(
1
);
/* turn OFF */
/* turn OFF */
if
(
nTTOff
==
0
)
if
(
nTTOff
==
0
)
...
@@ -380,8 +376,7 @@ set_timetravel(Name relname, int32 on)
...
@@ -380,8 +376,7 @@ set_timetravel(Name relname, int32 on)
pfree
(
rname
);
pfree
(
rname
);
nTTOff
++
;
nTTOff
++
;
return
(
1
);
PG_RETURN_INT32
(
1
);
}
}
AbsoluteTime
AbsoluteTime
...
...
contrib/spi/timetravel.source
View file @
18952f67
...
@@ -4,9 +4,9 @@ DROP FUNCTION set_timetravel(name, int4);
...
@@ -4,9 +4,9 @@ DROP FUNCTION set_timetravel(name, int4);
CREATE FUNCTION timetravel()
CREATE FUNCTION timetravel()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/timetravel_DLSUFFIX_'
AS '_OBJWD_/timetravel_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION set_timetravel(name, int4)
CREATE FUNCTION set_timetravel(name, int4)
RETURNS int4
RETURNS int4
AS '_OBJWD_/timetravel_DLSUFFIX_'
AS '_OBJWD_/timetravel_DLSUFFIX_'
LANGUAGE '
c'
;
LANGUAGE '
newC' WITH (isStrict)
;
doc/src/sgml/ref/create_language.sgml
View file @
18952f67
<!--
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.
9 2000/03/26 18:32:27 petere
Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.
10 2000/05/29 01:59:06 tgl
Exp $
Postgres documentation
Postgres documentation
-->
-->
...
@@ -160,44 +160,42 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
...
@@ -160,44 +160,42 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
<title>
<title>
Writing PL handlers
Writing PL handlers
</title>
</title>
<note>
<para>
In <productname>Postgres</productname> 7.1 and later, call handlers
must adhere to the "new style" function manager interface.
</para>
</note>
<para>
<para>
The call handler for a procedural language must be written
The call handler for a procedural language must be written
in a compile
r
language such as 'C' and registered with
in a compile
d
language such as 'C' and registered with
<productname>Postgres</productname> as a function taking
<productname>Postgres</productname> as a function taking
no arguments and returning the
no arguments and returning the
<type>opaque</type> type, a placeholder for unspecified or undefined types.
.
<type>opaque</type> type, a placeholder for unspecified or undefined types.
This prevents the call handler from being
This prevents the call handler from being
called directly as a function from queries.
called directly as a function from queries.
(However, arguments may be supplied in the actual call when a
PL function in the language offered by the handler is to be executed.)
</para>
</para>
<para>
<para>
However, arguments must be supplied on the actual call when a
The call handler is called in the same way as any other new-style
PL function or trigger
function: it receives a pointer to a FunctionCallInfoData struct
procedure in the language offered by the handler is to be
containing argument values and information about the called function,
executed.
and it is expected to return a Datum result (and possibly set the
<itemizedlist>
<literal>isnull</literal> field of the FunctionCallInfoData struct,
<listitem>
if it wishes to return an SQL NULL result). The difference between
<para>
a call handler and an ordinary callee function is that the
When called from the trigger manager, the only argument is
<literal>flinfo->fn_oid</literal> field of the FunctionCallInfoData
the object ID from the procedure's <filename>pg_proc</filename>
struct will contain the OID of the PL function to be called, not of
entry. All other
the call handler itself. The call handler must use this field to
information from the trigger manager is found in the
determine which function to execute. Also, the passed argument list
global <structname>CurrentTriggerData</structname> pointer.
has been set up according to the declaration of the target PL function,
</para>
not of the call handler.
</listitem>
<listitem>
<para>
When called from the function manager, the arguments are
the object ID of the procedure's <filename>pg_proc</filename>
entry, the number
of arguments given to the PL function, the arguments in a
<structname>FmgrValues</structname> structure and a pointer
to a boolean where the
function tells the caller if the return value is the SQL
NULL value.
</para>
</listitem>
</itemizedlist>
</para>
</para>
<para>
<para>
It's up to the call handler to fetch the
It's up to the call handler to fetch the
<filename>pg_proc</filename> entry and
<filename>pg_proc</filename> entry and
...
@@ -212,6 +210,28 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
...
@@ -212,6 +210,28 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
file or anything else that tells the call handler what to
file or anything else that tells the call handler what to
do in detail.
do in detail.
</para>
</para>
<para>
Often, the same function is called many times per SQL statement.
A call handler can avoid repeated lookups of information about the
called function by using the <literal>flinfo->fn_extra</literal> field.
This will initially be NULL, but can be set by the call handler to
point at information about the PL function. On subsequent calls,
if <literal>flinfo->fn_extra</literal> is already non-NULL then it
can be used and the information lookup step skipped. The call handler
must be careful that <literal>flinfo->fn_extra</literal> is made to
point at memory that will live at least until the end of the current
query, since an FmgrInfo data structure could be kept that long.
</para>
<para>
When a PL function is invoked as a trigger, no explicit arguments
are passed, but the FunctionCallInfoData's
<literal>context</literal> field points at a TriggerData node,
rather than being NULL as it is in a plain function call.
A PL handler should provide mechanisms for PL functions to get
at the trigger information.
</para>
</refsect2>
</refsect2>
<refsect2 id="R2-SQL-CREATELANGUAGE-4">
<refsect2 id="R2-SQL-CREATELANGUAGE-4">
...
@@ -275,39 +295,33 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
...
@@ -275,39 +295,33 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
#include "executor/spi.h"
#include "executor/spi.h"
#include "commands/trigger.h"
#include "commands/trigger.h"
#include "utils/elog.h"
#include "utils/elog.h"
#include "fmgr.h"
/* for FmgrValues struct */
#include "fmgr.h"
#include "access/heapam.h"
#include "access/heapam.h"
#include "utils/syscache.h"
#include "utils/syscache.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "catalog/pg_type.h"
Datum
Datum
plsample_call_handler(
plsample_call_handler(PG_FUNCTION_ARGS)
Oid prooid,
int pronargs,
FmgrValues *proargs,
bool *isNull)
{
{
Datum retval;
Datum retval;
TriggerData *trigdata;
if (CurrentTriggerData == NULL) {
if (CALLED_AS_TRIGGER(fcinfo))
{
/*
/*
* Called as a
function
* Called as a
trigger procedure
*/
*/
TriggerData *trigdata = (TriggerData *) fcinfo->context;
retval = ...
retval = ...
} else {
} else {
/*
/*
* Called as a
trigger procedure
* Called as a
function
*/
*/
trigdata = CurrentTriggerData;
CurrentTriggerData = NULL;
retval = ...
retval = ...
}
}
*isNull = false;
return retval;
return retval;
}
}
</programlisting>
</programlisting>
...
@@ -325,7 +339,7 @@ plsample_call_handler(
...
@@ -325,7 +339,7 @@ plsample_call_handler(
<programlisting>
<programlisting>
CREATE FUNCTION plsample_call_handler () RETURNS opaque
CREATE FUNCTION plsample_call_handler () RETURNS opaque
AS '/usr/local/pgsql/lib/plsample.so'
AS '/usr/local/pgsql/lib/plsample.so'
LANGUAGE 'C';
LANGUAGE '
new
C';
CREATE PROCEDURAL LANGUAGE 'plsample'
CREATE PROCEDURAL LANGUAGE 'plsample'
HANDLER plsample_call_handler
HANDLER plsample_call_handler
LANCOMPILER 'PL/Sample';
LANCOMPILER 'PL/Sample';
...
...
doc/src/sgml/trigger.sgml
View file @
18952f67
...
@@ -15,13 +15,14 @@
...
@@ -15,13 +15,14 @@
<para>
<para>
If a trigger event occurs, the trigger manager (called by the Executor)
If a trigger event occurs, the trigger manager (called by the Executor)
initializes the global structure TriggerData *CurrentTriggerData (described
sets up a TriggerData information structure (described below) and calls
below) and calls
the trigger function to handle the event.
the trigger function to handle the event.
</para>
</para>
<para>
<para>
The trigger function must be created before the trigger is created as a
The trigger function must be created before the trigger is created as a
function taking no arguments and returns opaque.
function taking no arguments and returning opaque. If the function is
written in C, it must follow the "new style" function manager interface.
</para>
</para>
<para>
<para>
...
@@ -106,7 +107,7 @@ CREATE TRIGGER <replaceable>trigger</replaceable> [ BEFORE | AFTER ] [ INSERT |
...
@@ -106,7 +107,7 @@ CREATE TRIGGER <replaceable>trigger</replaceable> [ BEFORE | AFTER ] [ INSERT |
<term><replaceable>args</replaceable></term>
<term><replaceable>args</replaceable></term>
<listitem>
<listitem>
<para>
<para>
The arguments passed to the function in the
Current
TriggerData structure.
The arguments passed to the function in the TriggerData structure.
The purpose of passing arguments to the function is to allow different
The purpose of passing arguments to the function is to allow different
triggers with similar requirements to call the same function.
triggers with similar requirements to call the same function.
</para>
</para>
...
@@ -179,11 +180,35 @@ CREATE TRIGGER <replaceable>trigger</replaceable> [ BEFORE | AFTER ] [ INSERT |
...
@@ -179,11 +180,35 @@ CREATE TRIGGER <replaceable>trigger</replaceable> [ BEFORE | AFTER ] [ INSERT |
<title>Interaction with the Trigger Manager</title>
<title>Interaction with the Trigger Manager</title>
<para>
<para>
As mentioned above, when function is called by the trigger manager,
This section describes the low-level details of the interface to a
structure TriggerData *CurrentTriggerData is NOT NULL and initialized. So
trigger function. This information is only needed when writing a
it is better to check CurrentTriggerData against being NULL at the start
trigger function in C. If you are using a higher-level function
and set it to NULL just after fetching the information to prevent calls to
language then these details are handled for you.
a trigger function not from the trigger manager.
</para>
<note>
<para>
The interface described here applies for
<productname>Postgres</productname> 7.1 and later.
Earlier versions passed the TriggerData pointer in a global
variable CurrentTriggerData.
</para>
</note>
<para>
When a function is called by the trigger manager, it is not passed any
normal parameters, but it is passed a "context" pointer pointing to a
TriggerData structure. C functions can check whether they were called
from the trigger manager or not by executing the macro
<literal>CALLED_AS_TRIGGER(fcinfo)</literal>, which expands to
<programlisting>
((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
</programlisting>
If this returns TRUE, then it is safe to cast fcinfo->context to type
<literal>TriggerData *</literal> and make use of the pointed-to
TriggerData structure.
The function must <emphasis>not</emphasis> alter the TriggerData
structure or any of the data it points to.
</para>
</para>
<para>
<para>
...
@@ -192,6 +217,7 @@ CREATE TRIGGER <replaceable>trigger</replaceable> [ BEFORE | AFTER ] [ INSERT |
...
@@ -192,6 +217,7 @@ CREATE TRIGGER <replaceable>trigger</replaceable> [ BEFORE | AFTER ] [ INSERT |
<programlisting>
<programlisting>
typedef struct TriggerData
typedef struct TriggerData
{
{
NodeTag type;
TriggerEvent tg_event;
TriggerEvent tg_event;
Relation tg_relation;
Relation tg_relation;
HeapTuple tg_trigtuple;
HeapTuple tg_trigtuple;
...
@@ -203,6 +229,15 @@ typedef struct TriggerData
...
@@ -203,6 +229,15 @@ typedef struct TriggerData
where the members are defined as follows:
where the members are defined as follows:
<variablelist>
<variablelist>
<varlistentry>
<term>type</term>
<listitem>
<para>
Always <literal>T_TriggerData</literal> if this is a trigger event.
</para>
</listitem>
</varlistentry>
<varlistentry>
<varlistentry>
<term>tg_event</term>
<term>tg_event</term>
<listitem>
<listitem>
...
@@ -410,11 +445,12 @@ execution of Q) or after Q is done.
...
@@ -410,11 +445,12 @@ execution of Q) or after Q is done.
#include "executor/spi.h" /* this is what you need to work with SPI */
#include "executor/spi.h" /* this is what you need to work with SPI */
#include "commands/trigger.h" /* -"- and triggers */
#include "commands/trigger.h" /* -"- and triggers */
HeapTuple trigf(void
);
extern Datum trigf(PG_FUNCTION_ARGS
);
HeapTuple
Datum
trigf()
trigf(
PG_FUNCTION_ARGS
)
{
{
TriggerData *trigdata = (TriggerData *) fcinfo->context;
TupleDesc tupdesc;
TupleDesc tupdesc;
HeapTuple rettuple;
HeapTuple rettuple;
char *when;
char *when;
...
@@ -422,27 +458,27 @@ trigf()
...
@@ -422,27 +458,27 @@ trigf()
bool isnull;
bool isnull;
int ret, i;
int ret, i;
if (!CurrentTriggerData)
/* Make sure trigdata is pointing at what I expect */
elog(NOTICE, "trigf: triggers are not initialized");
if (!CALLED_AS_TRIGGER(fcinfo))
elog(ERROR, "trigf: not fired by trigger manager");
/* tuple to return to Executor */
/* tuple to return to Executor */
if (TRIGGER_FIRED_BY_UPDATE(
CurrentTriggerD
ata->tg_event))
if (TRIGGER_FIRED_BY_UPDATE(
trigd
ata->tg_event))
rettuple =
CurrentTriggerD
ata->tg_newtuple;
rettuple =
trigd
ata->tg_newtuple;
else
else
rettuple =
CurrentTriggerD
ata->tg_trigtuple;
rettuple =
trigd
ata->tg_trigtuple;
/* check for NULLs ? */
/* check for NULLs ? */
if (!TRIGGER_FIRED_BY_DELETE(
CurrentTriggerD
ata->tg_event) &&
if (!TRIGGER_FIRED_BY_DELETE(
trigd
ata->tg_event) &&
TRIGGER_FIRED_BEFORE(
CurrentTriggerD
ata->tg_event))
TRIGGER_FIRED_BEFORE(
trigd
ata->tg_event))
checknull = true;
checknull = true;
if (TRIGGER_FIRED_BEFORE(
CurrentTriggerD
ata->tg_event))
if (TRIGGER_FIRED_BEFORE(
trigd
ata->tg_event))
when = "before";
when = "before";
else
else
when = "after ";
when = "after ";
tupdesc = CurrentTriggerData->tg_relation->rd_att;
tupdesc = trigdata->tg_relation->rd_att;
CurrentTriggerData = NULL;
/* Connect to SPI manager */
/* Connect to SPI manager */
if ((ret = SPI_connect()) < 0)
if ((ret = SPI_connect()) < 0)
...
@@ -467,7 +503,7 @@ trigf()
...
@@ -467,7 +503,7 @@ trigf()
rettuple = NULL;
rettuple = NULL;
}
}
return (rettuple);
return
PointerGetDatum
(rettuple);
}
}
</programlisting>
</programlisting>
</para>
</para>
...
...
src/backend/commands/command.c
View file @
18952f67
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.7
2 2000/05/28 17:55:54
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.7
3 2000/05/29 01:59:06
tgl Exp $
*
*
* NOTES
* NOTES
* The PortalExecutorHeapMemory crap needs to be eliminated
* The PortalExecutorHeapMemory crap needs to be eliminated
...
@@ -1159,19 +1159,24 @@ AlterTableAddConstraint(const char *relationName,
...
@@ -1159,19 +1159,24 @@ AlterTableAddConstraint(const char *relationName,
while
(
HeapTupleIsValid
(
tuple
=
heap_getnext
(
scan
,
0
)))
while
(
HeapTupleIsValid
(
tuple
=
heap_getnext
(
scan
,
0
)))
{
{
TriggerData
newtrigdata
;
/* Make a call to the check function */
/* No parameters are passed, but we do set a context */
FunctionCallInfoData
fcinfo
;
TriggerData
trigdata
;
newtrigdata
.
tg_event
=
TRIGGER_EVENT_INSERT
|
TRIGGER_EVENT_ROW
;
MemSet
(
&
fcinfo
,
0
,
sizeof
(
fcinfo
));
newtrigdata
.
tg_relation
=
rel
;
/* We assume RI_FKey_check_ins won't look at flinfo... */
newtrigdata
.
tg_trigtuple
=
tuple
;
newtrigdata
.
tg_newtuple
=
NULL
;
newtrigdata
.
tg_trigger
=
&
trig
;
CurrentTriggerData
=
&
newtrigdata
;
trigdata
.
type
=
T_TriggerData
;
trigdata
.
tg_event
=
TRIGGER_EVENT_INSERT
|
TRIGGER_EVENT_ROW
;
trigdata
.
tg_relation
=
rel
;
trigdata
.
tg_trigtuple
=
tuple
;
trigdata
.
tg_newtuple
=
NULL
;
trigdata
.
tg_trigger
=
&
trig
;
RI_FKey_check_ins
(
NULL
)
;
fcinfo
.
context
=
(
Node
*
)
&
trigdata
;
/* Make a call to the check function */
RI_FKey_check_ins
(
&
fcinfo
);
}
}
heap_endscan
(
scan
);
heap_endscan
(
scan
);
heap_close
(
rel
,
NoLock
);
/* close rel but keep
heap_close
(
rel
,
NoLock
);
/* close rel but keep
...
...
src/backend/commands/trigger.c
View file @
18952f67
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.6
6 2000/05/28 20:34:50
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.6
7 2000/05/29 01:59:06
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -32,14 +32,12 @@
...
@@ -32,14 +32,12 @@
#include "utils/syscache.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
#include "utils/tqual.h"
DLLIMPORT
TriggerData
*
CurrentTriggerData
=
NULL
;
/* XXX no points for style */
extern
TupleTableSlot
*
EvalPlanQual
(
EState
*
estate
,
Index
rti
,
ItemPointer
tid
);
static
void
DescribeTrigger
(
TriggerDesc
*
trigdesc
,
Trigger
*
trigger
);
static
void
DescribeTrigger
(
TriggerDesc
*
trigdesc
,
Trigger
*
trigger
);
static
HeapTuple
GetTupleForTrigger
(
EState
*
estate
,
ItemPointer
tid
,
static
HeapTuple
GetTupleForTrigger
(
EState
*
estate
,
ItemPointer
tid
,
TupleTableSlot
**
newSlot
);
TupleTableSlot
**
newSlot
);
static
HeapTuple
ExecCallTriggerFunc
(
Trigger
*
trigger
,
TriggerData
*
trigdata
);
void
void
...
@@ -507,7 +505,7 @@ RelationBuildTriggers(Relation relation)
...
@@ -507,7 +505,7 @@ RelationBuildTriggers(Relation relation)
build
->
tgoid
=
htup
->
t_data
->
t_oid
;
build
->
tgoid
=
htup
->
t_data
->
t_oid
;
build
->
tgname
=
nameout
(
&
pg_trigger
->
tgname
);
build
->
tgname
=
nameout
(
&
pg_trigger
->
tgname
);
build
->
tgfoid
=
pg_trigger
->
tgfoid
;
build
->
tgfoid
=
pg_trigger
->
tgfoid
;
build
->
tgfunc
.
fn_
addr
=
NULL
;
build
->
tgfunc
.
fn_
oid
=
InvalidOid
;
/* mark FmgrInfo as uninitialized */
build
->
tgtype
=
pg_trigger
->
tgtype
;
build
->
tgtype
=
pg_trigger
->
tgtype
;
build
->
tgenabled
=
pg_trigger
->
tgenabled
;
build
->
tgenabled
=
pg_trigger
->
tgenabled
;
build
->
tgisconstraint
=
pg_trigger
->
tgisconstraint
;
build
->
tgisconstraint
=
pg_trigger
->
tgisconstraint
;
...
@@ -757,45 +755,66 @@ equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
...
@@ -757,45 +755,66 @@ equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
return
true
;
return
true
;
}
}
static
HeapTuple
static
HeapTuple
ExecCallTriggerFunc
(
Trigger
*
trigger
)
ExecCallTriggerFunc
(
Trigger
*
trigger
,
TriggerData
*
trigdata
)
{
{
if
(
trigger
->
tgfunc
.
fn_addr
==
NULL
)
FunctionCallInfoData
fcinfo
;
Datum
result
;
/*
* Fmgr lookup info is cached in the Trigger structure,
* so that we need not repeat the lookup on every call.
*/
if
(
trigger
->
tgfunc
.
fn_oid
==
InvalidOid
)
fmgr_info
(
trigger
->
tgfoid
,
&
trigger
->
tgfunc
);
fmgr_info
(
trigger
->
tgfoid
,
&
trigger
->
tgfunc
);
return
(
HeapTuple
)
((
*
fmgr_faddr
(
&
trigger
->
tgfunc
))
());
/*
* Call the function, passing no arguments but setting a context.
*/
MemSet
(
&
fcinfo
,
0
,
sizeof
(
fcinfo
));
fcinfo
.
flinfo
=
&
trigger
->
tgfunc
;
fcinfo
.
context
=
(
Node
*
)
trigdata
;
result
=
FunctionCallInvoke
(
&
fcinfo
);
/*
* Trigger protocol allows function to return a null pointer,
* but NOT to set the isnull result flag.
*/
if
(
fcinfo
.
isnull
)
elog
(
ERROR
,
"ExecCallTriggerFunc: function %u returned NULL"
,
fcinfo
.
flinfo
->
fn_oid
);
return
(
HeapTuple
)
DatumGetPointer
(
result
);
}
}
HeapTuple
HeapTuple
ExecBRInsertTriggers
(
Relation
rel
,
HeapTuple
trigtuple
)
ExecBRInsertTriggers
(
Relation
rel
,
HeapTuple
trigtuple
)
{
{
TriggerData
*
SaveTriggerData
;
int
ntrigs
=
rel
->
trigdesc
->
n_before_row
[
TRIGGER_EVENT_INSERT
];
int
ntrigs
=
rel
->
trigdesc
->
n_before_row
[
TRIGGER_EVENT_INSERT
];
Trigger
**
trigger
=
rel
->
trigdesc
->
tg_before_row
[
TRIGGER_EVENT_INSERT
];
Trigger
**
trigger
=
rel
->
trigdesc
->
tg_before_row
[
TRIGGER_EVENT_INSERT
];
HeapTuple
newtuple
=
trigtuple
;
HeapTuple
newtuple
=
trigtuple
;
HeapTuple
oldtuple
;
HeapTuple
oldtuple
;
TriggerData
LocTriggerData
;
int
i
;
int
i
;
SaveTriggerData
=
(
TriggerData
*
)
palloc
(
sizeof
(
TriggerData
))
;
LocTriggerData
.
type
=
T_TriggerData
;
SaveTriggerData
->
tg_event
=
TRIGGER_EVENT_INSERT
|
TRIGGER_EVENT_ROW
|
TRIGGER_EVENT_BEFORE
;
LocTriggerData
.
tg_event
=
TRIGGER_EVENT_INSERT
|
TRIGGER_EVENT_ROW
|
TRIGGER_EVENT_BEFORE
;
SaveTriggerData
->
tg_relation
=
rel
;
LocTriggerData
.
tg_relation
=
rel
;
SaveTriggerData
->
tg_newtuple
=
NULL
;
LocTriggerData
.
tg_newtuple
=
NULL
;
for
(
i
=
0
;
i
<
ntrigs
;
i
++
)
for
(
i
=
0
;
i
<
ntrigs
;
i
++
)
{
{
if
(
!
trigger
[
i
]
->
tgenabled
)
if
(
!
trigger
[
i
]
->
tgenabled
)
continue
;
continue
;
CurrentTriggerData
=
SaveTriggerData
;
LocTriggerData
.
tg_trigtuple
=
oldtuple
=
newtuple
;
CurrentTriggerData
->
tg_trigtuple
=
oldtuple
=
newtuple
;
LocTriggerData
.
tg_trigger
=
trigger
[
i
];
CurrentTriggerData
->
tg_trigger
=
trigger
[
i
];
newtuple
=
ExecCallTriggerFunc
(
trigger
[
i
],
&
LocTriggerData
);
newtuple
=
ExecCallTriggerFunc
(
trigger
[
i
]);
if
(
newtuple
==
NULL
)
if
(
newtuple
==
NULL
)
break
;
break
;
else
if
(
oldtuple
!=
newtuple
&&
oldtuple
!=
trigtuple
)
else
if
(
oldtuple
!=
newtuple
&&
oldtuple
!=
trigtuple
)
heap_freetuple
(
oldtuple
);
heap_freetuple
(
oldtuple
);
}
}
CurrentTriggerData
=
NULL
;
pfree
(
SaveTriggerData
);
return
newtuple
;
return
newtuple
;
}
}
...
@@ -810,9 +829,9 @@ bool
...
@@ -810,9 +829,9 @@ bool
ExecBRDeleteTriggers
(
EState
*
estate
,
ItemPointer
tupleid
)
ExecBRDeleteTriggers
(
EState
*
estate
,
ItemPointer
tupleid
)
{
{
Relation
rel
=
estate
->
es_result_relation_info
->
ri_RelationDesc
;
Relation
rel
=
estate
->
es_result_relation_info
->
ri_RelationDesc
;
TriggerData
*
SaveTriggerData
;
int
ntrigs
=
rel
->
trigdesc
->
n_before_row
[
TRIGGER_EVENT_DELETE
];
int
ntrigs
=
rel
->
trigdesc
->
n_before_row
[
TRIGGER_EVENT_DELETE
];
Trigger
**
trigger
=
rel
->
trigdesc
->
tg_before_row
[
TRIGGER_EVENT_DELETE
];
Trigger
**
trigger
=
rel
->
trigdesc
->
tg_before_row
[
TRIGGER_EVENT_DELETE
];
TriggerData
LocTriggerData
;
HeapTuple
trigtuple
;
HeapTuple
trigtuple
;
HeapTuple
newtuple
=
NULL
;
HeapTuple
newtuple
=
NULL
;
TupleTableSlot
*
newSlot
;
TupleTableSlot
*
newSlot
;
...
@@ -822,25 +841,22 @@ ExecBRDeleteTriggers(EState *estate, ItemPointer tupleid)
...
@@ -822,25 +841,22 @@ ExecBRDeleteTriggers(EState *estate, ItemPointer tupleid)
if
(
trigtuple
==
NULL
)
if
(
trigtuple
==
NULL
)
return
false
;
return
false
;
SaveTriggerData
=
(
TriggerData
*
)
palloc
(
sizeof
(
TriggerData
))
;
LocTriggerData
.
type
=
T_TriggerData
;
SaveTriggerData
->
tg_event
=
TRIGGER_EVENT_DELETE
|
TRIGGER_EVENT_ROW
|
TRIGGER_EVENT_BEFORE
;
LocTriggerData
.
tg_event
=
TRIGGER_EVENT_DELETE
|
TRIGGER_EVENT_ROW
|
TRIGGER_EVENT_BEFORE
;
SaveTriggerData
->
tg_relation
=
rel
;
LocTriggerData
.
tg_relation
=
rel
;
SaveTriggerData
->
tg_newtuple
=
NULL
;
LocTriggerData
.
tg_newtuple
=
NULL
;
for
(
i
=
0
;
i
<
ntrigs
;
i
++
)
for
(
i
=
0
;
i
<
ntrigs
;
i
++
)
{
{
if
(
!
trigger
[
i
]
->
tgenabled
)
if
(
!
trigger
[
i
]
->
tgenabled
)
continue
;
continue
;
CurrentTriggerData
=
SaveTriggerData
;
LocTriggerData
.
tg_trigtuple
=
trigtuple
;
CurrentTriggerData
->
tg_trigtuple
=
trigtuple
;
LocTriggerData
.
tg_trigger
=
trigger
[
i
];
CurrentTriggerData
->
tg_trigger
=
trigger
[
i
];
newtuple
=
ExecCallTriggerFunc
(
trigger
[
i
],
&
LocTriggerData
);
newtuple
=
ExecCallTriggerFunc
(
trigger
[
i
]);
if
(
newtuple
==
NULL
)
if
(
newtuple
==
NULL
)
break
;
break
;
if
(
newtuple
!=
trigtuple
)
if
(
newtuple
!=
trigtuple
)
heap_freetuple
(
newtuple
);
heap_freetuple
(
newtuple
);
}
}
CurrentTriggerData
=
NULL
;
pfree
(
SaveTriggerData
);
heap_freetuple
(
trigtuple
);
heap_freetuple
(
trigtuple
);
return
(
newtuple
==
NULL
)
?
false
:
true
;
return
(
newtuple
==
NULL
)
?
false
:
true
;
...
@@ -860,9 +876,9 @@ HeapTuple
...
@@ -860,9 +876,9 @@ HeapTuple
ExecBRUpdateTriggers
(
EState
*
estate
,
ItemPointer
tupleid
,
HeapTuple
newtuple
)
ExecBRUpdateTriggers
(
EState
*
estate
,
ItemPointer
tupleid
,
HeapTuple
newtuple
)
{
{
Relation
rel
=
estate
->
es_result_relation_info
->
ri_RelationDesc
;
Relation
rel
=
estate
->
es_result_relation_info
->
ri_RelationDesc
;
TriggerData
*
SaveTriggerData
;
int
ntrigs
=
rel
->
trigdesc
->
n_before_row
[
TRIGGER_EVENT_UPDATE
];
int
ntrigs
=
rel
->
trigdesc
->
n_before_row
[
TRIGGER_EVENT_UPDATE
];
Trigger
**
trigger
=
rel
->
trigdesc
->
tg_before_row
[
TRIGGER_EVENT_UPDATE
];
Trigger
**
trigger
=
rel
->
trigdesc
->
tg_before_row
[
TRIGGER_EVENT_UPDATE
];
TriggerData
LocTriggerData
;
HeapTuple
trigtuple
;
HeapTuple
trigtuple
;
HeapTuple
oldtuple
;
HeapTuple
oldtuple
;
HeapTuple
intuple
=
newtuple
;
HeapTuple
intuple
=
newtuple
;
...
@@ -880,25 +896,22 @@ ExecBRUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple)
...
@@ -880,25 +896,22 @@ ExecBRUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple)
if
(
newSlot
!=
NULL
)
if
(
newSlot
!=
NULL
)
intuple
=
newtuple
=
ExecRemoveJunk
(
estate
->
es_junkFilter
,
newSlot
);
intuple
=
newtuple
=
ExecRemoveJunk
(
estate
->
es_junkFilter
,
newSlot
);
SaveTriggerData
=
(
TriggerData
*
)
palloc
(
sizeof
(
TriggerData
))
;
LocTriggerData
.
type
=
T_TriggerData
;
SaveTriggerData
->
tg_event
=
TRIGGER_EVENT_UPDATE
|
TRIGGER_EVENT_ROW
|
TRIGGER_EVENT_BEFORE
;
LocTriggerData
.
tg_event
=
TRIGGER_EVENT_UPDATE
|
TRIGGER_EVENT_ROW
|
TRIGGER_EVENT_BEFORE
;
SaveTriggerData
->
tg_relation
=
rel
;
LocTriggerData
.
tg_relation
=
rel
;
for
(
i
=
0
;
i
<
ntrigs
;
i
++
)
for
(
i
=
0
;
i
<
ntrigs
;
i
++
)
{
{
if
(
!
trigger
[
i
]
->
tgenabled
)
if
(
!
trigger
[
i
]
->
tgenabled
)
continue
;
continue
;
CurrentTriggerData
=
SaveTriggerData
;
LocTriggerData
.
tg_trigtuple
=
trigtuple
;
CurrentTriggerData
->
tg_trigtuple
=
trigtuple
;
LocTriggerData
.
tg_newtuple
=
oldtuple
=
newtuple
;
CurrentTriggerData
->
tg_newtuple
=
oldtuple
=
newtuple
;
LocTriggerData
.
tg_trigger
=
trigger
[
i
];
CurrentTriggerData
->
tg_trigger
=
trigger
[
i
];
newtuple
=
ExecCallTriggerFunc
(
trigger
[
i
],
&
LocTriggerData
);
newtuple
=
ExecCallTriggerFunc
(
trigger
[
i
]);
if
(
newtuple
==
NULL
)
if
(
newtuple
==
NULL
)
break
;
break
;
else
if
(
oldtuple
!=
newtuple
&&
oldtuple
!=
intuple
)
else
if
(
oldtuple
!=
newtuple
&&
oldtuple
!=
intuple
)
heap_freetuple
(
oldtuple
);
heap_freetuple
(
oldtuple
);
}
}
CurrentTriggerData
=
NULL
;
pfree
(
SaveTriggerData
);
heap_freetuple
(
trigtuple
);
heap_freetuple
(
trigtuple
);
return
newtuple
;
return
newtuple
;
}
}
...
@@ -1167,7 +1180,7 @@ static void
...
@@ -1167,7 +1180,7 @@ static void
deferredTriggerExecute
(
DeferredTriggerEvent
event
,
int
itemno
)
deferredTriggerExecute
(
DeferredTriggerEvent
event
,
int
itemno
)
{
{
Relation
rel
;
Relation
rel
;
TriggerData
Save
TriggerData
;
TriggerData
Loc
TriggerData
;
HeapTupleData
oldtuple
;
HeapTupleData
oldtuple
;
HeapTupleData
newtuple
;
HeapTupleData
newtuple
;
HeapTuple
rettuple
;
HeapTuple
rettuple
;
...
@@ -1200,30 +1213,31 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno)
...
@@ -1200,30 +1213,31 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno)
* Setup the trigger information
* Setup the trigger information
* ----------
* ----------
*/
*/
SaveTriggerData
.
tg_event
=
(
event
->
dte_event
&
TRIGGER_EVENT_OPMASK
)
|
LocTriggerData
.
type
=
T_TriggerData
;
LocTriggerData
.
tg_event
=
(
event
->
dte_event
&
TRIGGER_EVENT_OPMASK
)
|
TRIGGER_EVENT_ROW
;
TRIGGER_EVENT_ROW
;
Save
TriggerData
.
tg_relation
=
rel
;
Loc
TriggerData
.
tg_relation
=
rel
;
switch
(
event
->
dte_event
&
TRIGGER_EVENT_OPMASK
)
switch
(
event
->
dte_event
&
TRIGGER_EVENT_OPMASK
)
{
{
case
TRIGGER_EVENT_INSERT
:
case
TRIGGER_EVENT_INSERT
:
Save
TriggerData
.
tg_trigtuple
=
&
newtuple
;
Loc
TriggerData
.
tg_trigtuple
=
&
newtuple
;
Save
TriggerData
.
tg_newtuple
=
NULL
;
Loc
TriggerData
.
tg_newtuple
=
NULL
;
Save
TriggerData
.
tg_trigger
=
Loc
TriggerData
.
tg_trigger
=
rel
->
trigdesc
->
tg_after_row
[
TRIGGER_EVENT_INSERT
][
itemno
];
rel
->
trigdesc
->
tg_after_row
[
TRIGGER_EVENT_INSERT
][
itemno
];
break
;
break
;
case
TRIGGER_EVENT_UPDATE
:
case
TRIGGER_EVENT_UPDATE
:
Save
TriggerData
.
tg_trigtuple
=
&
oldtuple
;
Loc
TriggerData
.
tg_trigtuple
=
&
oldtuple
;
Save
TriggerData
.
tg_newtuple
=
&
newtuple
;
Loc
TriggerData
.
tg_newtuple
=
&
newtuple
;
Save
TriggerData
.
tg_trigger
=
Loc
TriggerData
.
tg_trigger
=
rel
->
trigdesc
->
tg_after_row
[
TRIGGER_EVENT_UPDATE
][
itemno
];
rel
->
trigdesc
->
tg_after_row
[
TRIGGER_EVENT_UPDATE
][
itemno
];
break
;
break
;
case
TRIGGER_EVENT_DELETE
:
case
TRIGGER_EVENT_DELETE
:
Save
TriggerData
.
tg_trigtuple
=
&
oldtuple
;
Loc
TriggerData
.
tg_trigtuple
=
&
oldtuple
;
Save
TriggerData
.
tg_newtuple
=
NULL
;
Loc
TriggerData
.
tg_newtuple
=
NULL
;
Save
TriggerData
.
tg_trigger
=
Loc
TriggerData
.
tg_trigger
=
rel
->
trigdesc
->
tg_after_row
[
TRIGGER_EVENT_DELETE
][
itemno
];
rel
->
trigdesc
->
tg_after_row
[
TRIGGER_EVENT_DELETE
][
itemno
];
break
;
break
;
}
}
...
@@ -1233,9 +1247,7 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno)
...
@@ -1233,9 +1247,7 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno)
* updated tuple.
* updated tuple.
* ----------
* ----------
*/
*/
CurrentTriggerData
=
&
SaveTriggerData
;
rettuple
=
ExecCallTriggerFunc
(
LocTriggerData
.
tg_trigger
,
&
LocTriggerData
);
rettuple
=
ExecCallTriggerFunc
(
SaveTriggerData
.
tg_trigger
);
CurrentTriggerData
=
NULL
;
if
(
rettuple
!=
NULL
&&
rettuple
!=
&
oldtuple
&&
rettuple
!=
&
newtuple
)
if
(
rettuple
!=
NULL
&&
rettuple
!=
&
oldtuple
&&
rettuple
!=
&
newtuple
)
heap_freetuple
(
rettuple
);
heap_freetuple
(
rettuple
);
...
@@ -1778,7 +1790,7 @@ DeferredTriggerSaveEvent(Relation rel, int event,
...
@@ -1778,7 +1790,7 @@ DeferredTriggerSaveEvent(Relation rel, int event,
Trigger
**
triggers
;
Trigger
**
triggers
;
ItemPointerData
oldctid
;
ItemPointerData
oldctid
;
ItemPointerData
newctid
;
ItemPointerData
newctid
;
TriggerData
Save
TriggerData
;
TriggerData
Loc
TriggerData
;
if
(
deftrig_cxt
==
NULL
)
if
(
deftrig_cxt
==
NULL
)
elog
(
ERROR
,
elog
(
ERROR
,
...
@@ -1891,15 +1903,14 @@ DeferredTriggerSaveEvent(Relation rel, int event,
...
@@ -1891,15 +1903,14 @@ DeferredTriggerSaveEvent(Relation rel, int event,
if
(
!
is_ri_trigger
)
if
(
!
is_ri_trigger
)
continue
;
continue
;
SaveTriggerData
.
tg_event
=
TRIGGER_EVENT_UPDATE
;
LocTriggerData
.
type
=
T_TriggerData
;
SaveTriggerData
.
tg_relation
=
rel
;
LocTriggerData
.
tg_event
=
TRIGGER_EVENT_UPDATE
;
SaveTriggerData
.
tg_trigtuple
=
oldtup
;
LocTriggerData
.
tg_relation
=
rel
;
SaveTriggerData
.
tg_newtuple
=
newtup
;
LocTriggerData
.
tg_trigtuple
=
oldtup
;
SaveTriggerData
.
tg_trigger
=
triggers
[
i
];
LocTriggerData
.
tg_newtuple
=
newtup
;
LocTriggerData
.
tg_trigger
=
triggers
[
i
];
CurrentTriggerData
=
&
SaveTriggerData
;
key_unchanged
=
RI_FKey_keyequal_upd
(
&
LocTriggerData
);
key_unchanged
=
RI_FKey_keyequal_upd
();
CurrentTriggerData
=
NULL
;
if
(
key_unchanged
)
if
(
key_unchanged
)
{
{
...
...
src/backend/commands/user.c
View file @
18952f67
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $
Id: user.c,v 1.54 2000/05/28 17:55:55
tgl Exp $
* $
Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.55 2000/05/29 01:59:07
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -168,20 +168,14 @@ write_password_file(Relation rel)
...
@@ -168,20 +168,14 @@ write_password_file(Relation rel)
/* This is the wrapper for triggers. */
/* This is the wrapper for triggers. */
HeapTuple
Datum
update_pg_pwd
(
void
)
update_pg_pwd
(
PG_FUNCTION_ARGS
)
{
{
Relation
rel
=
heap_openr
(
ShadowRelationName
,
AccessExclusiveLock
);
Relation
rel
=
heap_openr
(
ShadowRelationName
,
AccessExclusiveLock
);
write_password_file
(
rel
);
write_password_file
(
rel
);
heap_close
(
rel
,
AccessExclusiveLock
);
heap_close
(
rel
,
AccessExclusiveLock
);
return
PointerGetDatum
(
NULL
);
/*
* This is a trigger, so clean out the information provided by the
* trigger manager.
*/
CurrentTriggerData
=
NULL
;
return
NULL
;
}
}
...
...
src/backend/executor/execMain.c
View file @
18952f67
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.11
3 2000/04/12 17:15:08 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.11
4 2000/05/29 01:59:07 tgl
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -46,9 +46,6 @@
...
@@ -46,9 +46,6 @@
#include "utils/builtins.h"
#include "utils/builtins.h"
#include "utils/syscache.h"
#include "utils/syscache.h"
/* XXX no points for style */
extern
TupleTableSlot
*
EvalPlanQual
(
EState
*
estate
,
Index
rti
,
ItemPointer
tid
);
/* decls for local routines only used within this module */
/* decls for local routines only used within this module */
static
TupleDesc
InitPlan
(
CmdType
operation
,
static
TupleDesc
InitPlan
(
CmdType
operation
,
...
@@ -1974,7 +1971,7 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
...
@@ -1974,7 +1971,7 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
*/
*/
*
tid
=
tuple
.
t_self
;
*
tid
=
tuple
.
t_self
;
return
(
EvalPlanQualNext
(
estate
)
);
return
EvalPlanQualNext
(
estate
);
}
}
static
TupleTableSlot
*
static
TupleTableSlot
*
...
...
src/backend/utils/adt/ri_triggers.c
View file @
18952f67
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
*
*
* 1999 Jan Wieck
* 1999 Jan Wieck
*
*
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.1
4 2000/04/12 17:15:51 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.1
5 2000/05/29 01:59:08 tgl
Exp $
*
*
* ----------
* ----------
*/
*/
...
@@ -20,7 +20,6 @@
...
@@ -20,7 +20,6 @@
*/
*/
#include "postgres.h"
#include "postgres.h"
#include "fmgr.h"
#include "access/heapam.h"
#include "access/heapam.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_operator.h"
...
@@ -28,10 +27,11 @@
...
@@ -28,10 +27,11 @@
#include "commands/trigger.h"
#include "commands/trigger.h"
#include "executor/spi.h"
#include "executor/spi.h"
#include "executor/spi_priv.h"
#include "executor/spi_priv.h"
#include "fmgr.h"
#include "lib/hasht.h"
#include "utils/builtins.h"
#include "utils/builtins.h"
#include "utils/mcxt.h"
#include "utils/mcxt.h"
#include "utils/syscache.h"
#include "utils/syscache.h"
#include "lib/hasht.h"
/* ----------
/* ----------
...
@@ -105,7 +105,6 @@ typedef struct RI_QueryHashEntry
...
@@ -105,7 +105,6 @@ typedef struct RI_QueryHashEntry
typedef
struct
RI_OpreqHashEntry
typedef
struct
RI_OpreqHashEntry
{
{
Oid
typeid
;
Oid
typeid
;
Oid
oprfnid
;
FmgrInfo
oprfmgrinfo
;
FmgrInfo
oprfmgrinfo
;
}
RI_OpreqHashEntry
;
}
RI_OpreqHashEntry
;
...
@@ -147,13 +146,13 @@ static void ri_HashPreparedPlan(RI_QueryKey *key, void *plan);
...
@@ -147,13 +146,13 @@ static void ri_HashPreparedPlan(RI_QueryKey *key, void *plan);
/* ----------
/* ----------
* RI_FKey_check -
* RI_FKey_check -
*
*
* Check foreign key exist
a
nce (combined for INSERT and UPDATE).
* Check foreign key exist
e
nce (combined for INSERT and UPDATE).
* ----------
* ----------
*/
*/
static
HeapTuple
static
Datum
RI_FKey_check
(
FmgrInfo
*
proinfo
)
RI_FKey_check
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -168,15 +167,13 @@ RI_FKey_check(FmgrInfo *proinfo)
...
@@ -168,15 +167,13 @@ RI_FKey_check(FmgrInfo *proinfo)
int
i
;
int
i
;
int
match_type
;
int
match_type
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_check() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_check() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -275,7 +272,7 @@ RI_FKey_check(FmgrInfo *proinfo)
...
@@ -275,7 +272,7 @@ RI_FKey_check(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_check()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_check()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -284,7 +281,7 @@ RI_FKey_check(FmgrInfo *proinfo)
...
@@ -284,7 +281,7 @@ RI_FKey_check(FmgrInfo *proinfo)
if
(
match_type
==
RI_MATCH_TYPE_PARTIAL
)
if
(
match_type
==
RI_MATCH_TYPE_PARTIAL
)
{
{
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
ri_BuildQueryKeyFull
(
&
qkey
,
trigdata
->
tg_trigger
->
tgoid
,
ri_BuildQueryKeyFull
(
&
qkey
,
trigdata
->
tg_trigger
->
tgoid
,
...
@@ -303,7 +300,7 @@ RI_FKey_check(FmgrInfo *proinfo)
...
@@ -303,7 +300,7 @@ RI_FKey_check(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
pk_rel
,
NoLock
);
heap_close
(
pk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_SOME_NULL
:
case
RI_KEYS_SOME_NULL
:
/* ----------
/* ----------
...
@@ -324,7 +321,7 @@ RI_FKey_check(FmgrInfo *proinfo)
...
@@ -324,7 +321,7 @@ RI_FKey_check(FmgrInfo *proinfo)
"and NON-NULL key values"
,
"and NON-NULL key values"
,
tgargs
[
RI_CONSTRAINT_NAME_ARGNO
]);
tgargs
[
RI_CONSTRAINT_NAME_ARGNO
]);
heap_close
(
pk_rel
,
NoLock
);
heap_close
(
pk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_MATCH_TYPE_UNSPECIFIED
:
case
RI_MATCH_TYPE_UNSPECIFIED
:
/* ----------
/* ----------
...
@@ -333,7 +330,7 @@ RI_FKey_check(FmgrInfo *proinfo)
...
@@ -333,7 +330,7 @@ RI_FKey_check(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
pk_rel
,
NoLock
);
heap_close
(
pk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
/* ----------
/* ----------
...
@@ -345,7 +342,7 @@ RI_FKey_check(FmgrInfo *proinfo)
...
@@ -345,7 +342,7 @@ RI_FKey_check(FmgrInfo *proinfo)
*/
*/
elog
(
ERROR
,
"MATCH PARTIAL not yet implemented"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet implemented"
);
heap_close
(
pk_rel
,
NoLock
);
heap_close
(
pk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
...
@@ -459,40 +456,40 @@ RI_FKey_check(FmgrInfo *proinfo)
...
@@ -459,40 +456,40 @@ RI_FKey_check(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_check()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_check()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Never reached
* Never reached
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #1 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #1 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
* RI_FKey_check_ins -
* RI_FKey_check_ins -
*
*
* Check foreign key exist
a
nce at insert event on FK table.
* Check foreign key exist
e
nce at insert event on FK table.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_check_ins
(
FmgrInfo
*
proinfo
)
RI_FKey_check_ins
(
PG_FUNCTION_ARGS
)
{
{
return
RI_FKey_check
(
pro
info
);
return
RI_FKey_check
(
fc
info
);
}
}
/* ----------
/* ----------
* RI_FKey_check_upd -
* RI_FKey_check_upd -
*
*
* Check foreign key exist
a
nce at update event on FK table.
* Check foreign key exist
e
nce at update event on FK table.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_check_upd
(
FmgrInfo
*
proinfo
)
RI_FKey_check_upd
(
PG_FUNCTION_ARGS
)
{
{
return
RI_FKey_check
(
pro
info
);
return
RI_FKey_check
(
fc
info
);
}
}
...
@@ -504,10 +501,10 @@ RI_FKey_check_upd(FmgrInfo *proinfo)
...
@@ -504,10 +501,10 @@ RI_FKey_check_upd(FmgrInfo *proinfo)
* integrity constraint.
* integrity constraint.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_noaction_del
(
FmgrInfo
*
proinfo
)
RI_FKey_noaction_del
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -520,15 +517,13 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
...
@@ -520,15 +517,13 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
bool
isnull
;
bool
isnull
;
int
i
;
int
i
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_noaction_del() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_noaction_del() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -553,7 +548,7 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
...
@@ -553,7 +548,7 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
if
(
tgnargs
==
4
)
if
(
tgnargs
==
4
)
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Get the relation descriptors of the FK and PK tables and
* Get the relation descriptors of the FK and PK tables and
...
@@ -590,7 +585,7 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
...
@@ -590,7 +585,7 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
fk_rel
,
NoLock
);
heap_close
(
fk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
/* ----------
/* ----------
...
@@ -685,7 +680,7 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
...
@@ -685,7 +680,7 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_noaction_del()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_noaction_del()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Handle MATCH PARTIAL restrict delete.
* Handle MATCH PARTIAL restrict delete.
...
@@ -693,7 +688,7 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
...
@@ -693,7 +688,7 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
*/
*/
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
...
@@ -701,7 +696,7 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
...
@@ -701,7 +696,7 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #2 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #2 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -713,10 +708,10 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
...
@@ -713,10 +708,10 @@ RI_FKey_noaction_del(FmgrInfo *proinfo)
* integrity constraint.
* integrity constraint.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_noaction_upd
(
FmgrInfo
*
proinfo
)
RI_FKey_noaction_upd
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -730,15 +725,13 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
...
@@ -730,15 +725,13 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
bool
isnull
;
bool
isnull
;
int
i
;
int
i
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_noaction_upd() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_noaction_upd() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -763,7 +756,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
...
@@ -763,7 +756,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
if
(
tgnargs
==
4
)
if
(
tgnargs
==
4
)
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Get the relation descriptors of the FK and PK tables and
* Get the relation descriptors of the FK and PK tables and
...
@@ -801,7 +794,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
...
@@ -801,7 +794,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
fk_rel
,
NoLock
);
heap_close
(
fk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
/* ----------
/* ----------
...
@@ -818,7 +811,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
...
@@ -818,7 +811,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
*/
*/
if
(
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
if
(
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
RI_KEYPAIR_PK_IDX
))
RI_KEYPAIR_PK_IDX
))
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
elog
(
NOTICE
,
"SPI_connect() failed in RI_FKey_noaction_upd()"
);
elog
(
NOTICE
,
"SPI_connect() failed in RI_FKey_noaction_upd()"
);
...
@@ -904,7 +897,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
...
@@ -904,7 +897,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_noaction_upd()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_noaction_upd()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Handle MATCH PARTIAL noaction update.
* Handle MATCH PARTIAL noaction update.
...
@@ -912,7 +905,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
...
@@ -912,7 +905,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
*/
*/
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
...
@@ -920,7 +913,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
...
@@ -920,7 +913,7 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #3 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #3 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -930,10 +923,10 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
...
@@ -930,10 +923,10 @@ RI_FKey_noaction_upd(FmgrInfo *proinfo)
* Cascaded delete foreign key references at delete event on PK table.
* Cascaded delete foreign key references at delete event on PK table.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_cascade_del
(
FmgrInfo
*
proinfo
)
RI_FKey_cascade_del
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -946,15 +939,13 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
...
@@ -946,15 +939,13 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
bool
isnull
;
bool
isnull
;
int
i
;
int
i
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_cascade_del() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_cascade_del() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -979,7 +970,7 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
...
@@ -979,7 +970,7 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
if
(
tgnargs
==
4
)
if
(
tgnargs
==
4
)
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Get the relation descriptors of the FK and PK tables and
* Get the relation descriptors of the FK and PK tables and
...
@@ -1016,7 +1007,7 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
...
@@ -1016,7 +1007,7 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
fk_rel
,
NoLock
);
heap_close
(
fk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
/* ----------
/* ----------
...
@@ -1100,7 +1091,7 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
...
@@ -1100,7 +1091,7 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_cascade_del()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_cascade_del()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Handle MATCH PARTIAL cascaded delete.
* Handle MATCH PARTIAL cascaded delete.
...
@@ -1108,7 +1099,7 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
...
@@ -1108,7 +1099,7 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
*/
*/
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
...
@@ -1116,7 +1107,7 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
...
@@ -1116,7 +1107,7 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #4 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #4 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -1126,10 +1117,10 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
...
@@ -1126,10 +1117,10 @@ RI_FKey_cascade_del(FmgrInfo *proinfo)
* Cascaded update/delete foreign key references at update event on PK table.
* Cascaded update/delete foreign key references at update event on PK table.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_cascade_upd
(
FmgrInfo
*
proinfo
)
RI_FKey_cascade_upd
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -1144,15 +1135,13 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
...
@@ -1144,15 +1135,13 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
int
i
;
int
i
;
int
j
;
int
j
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_cascade_upd() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_cascade_upd() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -1177,7 +1166,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
...
@@ -1177,7 +1166,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
if
(
tgnargs
==
4
)
if
(
tgnargs
==
4
)
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Get the relation descriptors of the FK and PK tables and
* Get the relation descriptors of the FK and PK tables and
...
@@ -1215,7 +1204,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
...
@@ -1215,7 +1204,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
fk_rel
,
NoLock
);
heap_close
(
fk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
/* ----------
/* ----------
...
@@ -1232,7 +1221,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
...
@@ -1232,7 +1221,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
*/
*/
if
(
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
if
(
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
RI_KEYPAIR_PK_IDX
))
RI_KEYPAIR_PK_IDX
))
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
elog
(
NOTICE
,
"SPI_connect() failed in RI_FKey_cascade_upd()"
);
elog
(
NOTICE
,
"SPI_connect() failed in RI_FKey_cascade_upd()"
);
...
@@ -1328,7 +1317,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
...
@@ -1328,7 +1317,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_cascade_upd()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_cascade_upd()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Handle MATCH PARTIAL cascade update.
* Handle MATCH PARTIAL cascade update.
...
@@ -1336,7 +1325,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
...
@@ -1336,7 +1325,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
*/
*/
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
...
@@ -1344,7 +1333,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
...
@@ -1344,7 +1333,7 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #5 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #5 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -1361,10 +1350,10 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
...
@@ -1361,10 +1350,10 @@ RI_FKey_cascade_upd(FmgrInfo *proinfo)
* equivalent.
* equivalent.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_restrict_del
(
FmgrInfo
*
proinfo
)
RI_FKey_restrict_del
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -1377,15 +1366,13 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
...
@@ -1377,15 +1366,13 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
bool
isnull
;
bool
isnull
;
int
i
;
int
i
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_restrict_del() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_restrict_del() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -1410,7 +1397,7 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
...
@@ -1410,7 +1397,7 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
if
(
tgnargs
==
4
)
if
(
tgnargs
==
4
)
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Get the relation descriptors of the FK and PK tables and
* Get the relation descriptors of the FK and PK tables and
...
@@ -1447,7 +1434,7 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
...
@@ -1447,7 +1434,7 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
fk_rel
,
NoLock
);
heap_close
(
fk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
/* ----------
/* ----------
...
@@ -1542,7 +1529,7 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
...
@@ -1542,7 +1529,7 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_restrict_del()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_restrict_del()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Handle MATCH PARTIAL restrict delete.
* Handle MATCH PARTIAL restrict delete.
...
@@ -1550,7 +1537,7 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
...
@@ -1550,7 +1537,7 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
*/
*/
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
...
@@ -1558,7 +1545,7 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
...
@@ -1558,7 +1545,7 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #6 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #6 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -1575,10 +1562,10 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
...
@@ -1575,10 +1562,10 @@ RI_FKey_restrict_del(FmgrInfo *proinfo)
* equivalent.
* equivalent.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_restrict_upd
(
FmgrInfo
*
proinfo
)
RI_FKey_restrict_upd
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -1592,15 +1579,13 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
...
@@ -1592,15 +1579,13 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
bool
isnull
;
bool
isnull
;
int
i
;
int
i
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_restrict_upd() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_restrict_upd() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -1625,7 +1610,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
...
@@ -1625,7 +1610,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
if
(
tgnargs
==
4
)
if
(
tgnargs
==
4
)
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Get the relation descriptors of the FK and PK tables and
* Get the relation descriptors of the FK and PK tables and
...
@@ -1663,7 +1648,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
...
@@ -1663,7 +1648,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
fk_rel
,
NoLock
);
heap_close
(
fk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
/* ----------
/* ----------
...
@@ -1680,7 +1665,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
...
@@ -1680,7 +1665,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
*/
*/
if
(
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
if
(
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
RI_KEYPAIR_PK_IDX
))
RI_KEYPAIR_PK_IDX
))
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
elog
(
NOTICE
,
"SPI_connect() failed in RI_FKey_restrict_upd()"
);
elog
(
NOTICE
,
"SPI_connect() failed in RI_FKey_restrict_upd()"
);
...
@@ -1766,7 +1751,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
...
@@ -1766,7 +1751,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_restrict_upd()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_restrict_upd()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Handle MATCH PARTIAL restrict update.
* Handle MATCH PARTIAL restrict update.
...
@@ -1774,7 +1759,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
...
@@ -1774,7 +1759,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
*/
*/
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
...
@@ -1782,7 +1767,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
...
@@ -1782,7 +1767,7 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #7 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #7 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -1792,10 +1777,10 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
...
@@ -1792,10 +1777,10 @@ RI_FKey_restrict_upd(FmgrInfo *proinfo)
* Set foreign key references to NULL values at delete event on PK table.
* Set foreign key references to NULL values at delete event on PK table.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_setnull_del
(
FmgrInfo
*
proinfo
)
RI_FKey_setnull_del
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -1808,15 +1793,13 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
...
@@ -1808,15 +1793,13 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
bool
isnull
;
bool
isnull
;
int
i
;
int
i
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_setnull_del() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_setnull_del() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -1841,7 +1824,7 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
...
@@ -1841,7 +1824,7 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
if
(
tgnargs
==
4
)
if
(
tgnargs
==
4
)
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Get the relation descriptors of the FK and PK tables and
* Get the relation descriptors of the FK and PK tables and
...
@@ -1878,7 +1861,7 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
...
@@ -1878,7 +1861,7 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
fk_rel
,
NoLock
);
heap_close
(
fk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
/* ----------
/* ----------
...
@@ -1973,7 +1956,7 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
...
@@ -1973,7 +1956,7 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_setnull_del()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_setnull_del()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Handle MATCH PARTIAL set null delete.
* Handle MATCH PARTIAL set null delete.
...
@@ -1981,7 +1964,7 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
...
@@ -1981,7 +1964,7 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
*/
*/
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
...
@@ -1989,7 +1972,7 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
...
@@ -1989,7 +1972,7 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #8 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #8 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -1999,10 +1982,10 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
...
@@ -1999,10 +1982,10 @@ RI_FKey_setnull_del(FmgrInfo *proinfo)
* Set foreign key references to NULL at update event on PK table.
* Set foreign key references to NULL at update event on PK table.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_setnull_upd
(
FmgrInfo
*
proinfo
)
RI_FKey_setnull_upd
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -2018,15 +2001,13 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
...
@@ -2018,15 +2001,13 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
int
match_type
;
int
match_type
;
bool
use_cached_query
;
bool
use_cached_query
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_setnull_upd() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_setnull_upd() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -2051,7 +2032,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
...
@@ -2051,7 +2032,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
if
(
tgnargs
==
4
)
if
(
tgnargs
==
4
)
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Get the relation descriptors of the FK and PK tables and
* Get the relation descriptors of the FK and PK tables and
...
@@ -2090,7 +2071,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
...
@@ -2090,7 +2071,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
fk_rel
,
NoLock
);
heap_close
(
fk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
/* ----------
/* ----------
...
@@ -2108,7 +2089,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
...
@@ -2108,7 +2089,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
*/
*/
if
(
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
if
(
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
RI_KEYPAIR_PK_IDX
))
RI_KEYPAIR_PK_IDX
))
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
elog
(
NOTICE
,
"SPI_connect() failed in RI_FKey_setnull_upd()"
);
elog
(
NOTICE
,
"SPI_connect() failed in RI_FKey_setnull_upd()"
);
...
@@ -2231,7 +2212,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
...
@@ -2231,7 +2212,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_setnull_upd()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_setnull_upd()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Handle MATCH PARTIAL set null update.
* Handle MATCH PARTIAL set null update.
...
@@ -2239,7 +2220,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
...
@@ -2239,7 +2220,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
*/
*/
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
...
@@ -2247,7 +2228,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
...
@@ -2247,7 +2228,7 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #9 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #9 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -2257,10 +2238,10 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
...
@@ -2257,10 +2238,10 @@ RI_FKey_setnull_upd(FmgrInfo *proinfo)
* Set foreign key references to defaults at delete event on PK table.
* Set foreign key references to defaults at delete event on PK table.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_setdefault_del
(
FmgrInfo
*
proinfo
)
RI_FKey_setdefault_del
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -2273,15 +2254,13 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
...
@@ -2273,15 +2254,13 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
bool
isnull
;
bool
isnull
;
int
i
;
int
i
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_setdefault_del() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_setdefault_del() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -2306,7 +2285,7 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
...
@@ -2306,7 +2285,7 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
if
(
tgnargs
==
4
)
if
(
tgnargs
==
4
)
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Get the relation descriptors of the FK and PK tables and
* Get the relation descriptors of the FK and PK tables and
...
@@ -2343,7 +2322,7 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
...
@@ -2343,7 +2322,7 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
fk_rel
,
NoLock
);
heap_close
(
fk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
/* ----------
/* ----------
...
@@ -2485,7 +2464,7 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
...
@@ -2485,7 +2464,7 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_setdefault_del()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_setdefault_del()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Handle MATCH PARTIAL set null delete.
* Handle MATCH PARTIAL set null delete.
...
@@ -2493,7 +2472,7 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
...
@@ -2493,7 +2472,7 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
*/
*/
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
...
@@ -2501,7 +2480,7 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
...
@@ -2501,7 +2480,7 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #10 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #10 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -2511,10 +2490,10 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
...
@@ -2511,10 +2490,10 @@ RI_FKey_setdefault_del(FmgrInfo *proinfo)
* Set foreign key references to defaults at update event on PK table.
* Set foreign key references to defaults at update event on PK table.
* ----------
* ----------
*/
*/
HeapTuple
Datum
RI_FKey_setdefault_upd
(
FmgrInfo
*
proinfo
)
RI_FKey_setdefault_upd
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -2529,15 +2508,13 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
...
@@ -2529,15 +2508,13 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
int
i
;
int
i
;
int
match_type
;
int
match_type
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
ReferentialIntegritySnapshotOverride
=
true
;
ReferentialIntegritySnapshotOverride
=
true
;
/* ----------
/* ----------
* Check that this is a valid trigger call on the right time and event.
* Check that this is a valid trigger call on the right time and event.
* ----------
* ----------
*/
*/
if
(
trigdata
==
NULL
)
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"RI_FKey_setdefault_upd() not fired by trigger manager"
);
elog
(
ERROR
,
"RI_FKey_setdefault_upd() not fired by trigger manager"
);
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
if
(
!
TRIGGER_FIRED_AFTER
(
trigdata
->
tg_event
)
||
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
!
TRIGGER_FIRED_FOR_ROW
(
trigdata
->
tg_event
))
...
@@ -2562,7 +2539,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
...
@@ -2562,7 +2539,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
if
(
tgnargs
==
4
)
if
(
tgnargs
==
4
)
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Get the relation descriptors of the FK and PK tables and
* Get the relation descriptors of the FK and PK tables and
...
@@ -2602,7 +2579,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
...
@@ -2602,7 +2579,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
heap_close
(
fk_rel
,
NoLock
);
heap_close
(
fk_rel
,
NoLock
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
case
RI_KEYS_NONE_NULL
:
case
RI_KEYS_NONE_NULL
:
/* ----------
/* ----------
...
@@ -2619,7 +2596,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
...
@@ -2619,7 +2596,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
*/
*/
if
(
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
if
(
ri_KeysEqual
(
pk_rel
,
old_row
,
new_row
,
&
qkey
,
RI_KEYPAIR_PK_IDX
))
RI_KEYPAIR_PK_IDX
))
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
elog
(
NOTICE
,
"SPI_connect() failed in RI_FKey_setdefault_upd()"
);
elog
(
NOTICE
,
"SPI_connect() failed in RI_FKey_setdefault_upd()"
);
...
@@ -2769,7 +2746,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
...
@@ -2769,7 +2746,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
if
(
SPI_finish
()
!=
SPI_OK_FINISH
)
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_setdefault_upd()"
);
elog
(
NOTICE
,
"SPI_finish() failed in RI_FKey_setdefault_upd()"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
/* ----------
/* ----------
* Handle MATCH PARTIAL set null delete.
* Handle MATCH PARTIAL set null delete.
...
@@ -2777,7 +2754,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
...
@@ -2777,7 +2754,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
*/
*/
case
RI_MATCH_TYPE_PARTIAL
:
case
RI_MATCH_TYPE_PARTIAL
:
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
elog
(
ERROR
,
"MATCH PARTIAL not yet supported"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
/* ----------
/* ----------
...
@@ -2785,7 +2762,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
...
@@ -2785,7 +2762,7 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
* ----------
* ----------
*/
*/
elog
(
ERROR
,
"internal error #11 in ri_triggers.c"
);
elog
(
ERROR
,
"internal error #11 in ri_triggers.c"
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
...
@@ -2794,14 +2771,13 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
...
@@ -2794,14 +2771,13 @@ RI_FKey_setdefault_upd(FmgrInfo *proinfo)
*
*
* Check if we have a key change on update.
* Check if we have a key change on update.
*
*
* This is no real trigger procedure. It is used by the deferred
* This is no
t a
real trigger procedure. It is used by the deferred
* trigger queue manager to detect "triggered data change violation".
* trigger queue manager to detect "triggered data change violation".
* ----------
* ----------
*/
*/
bool
bool
RI_FKey_keyequal_upd
(
void
)
RI_FKey_keyequal_upd
(
TriggerData
*
trigdata
)
{
{
TriggerData
*
trigdata
;
int
tgnargs
;
int
tgnargs
;
char
**
tgargs
;
char
**
tgargs
;
Relation
fk_rel
;
Relation
fk_rel
;
...
@@ -2810,9 +2786,6 @@ RI_FKey_keyequal_upd(void)
...
@@ -2810,9 +2786,6 @@ RI_FKey_keyequal_upd(void)
HeapTuple
old_row
;
HeapTuple
old_row
;
RI_QueryKey
qkey
;
RI_QueryKey
qkey
;
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
/* ----------
/* ----------
* Check for the correct # of call arguments
* Check for the correct # of call arguments
* ----------
* ----------
...
@@ -3262,8 +3235,10 @@ ri_OneKeyEqual(Relation rel, int column, HeapTuple oldtup, HeapTuple newtup,
...
@@ -3262,8 +3235,10 @@ ri_OneKeyEqual(Relation rel, int column, HeapTuple oldtup, HeapTuple newtup,
/* ----------
/* ----------
* ri_AttributesEqual -
* ri_AttributesEqual -
*
*
* Call the type specific '=' operator comparis
i
on function
* Call the type specific '=' operator comparison function
* for two values.
* for two values.
*
* NB: we have already checked that neither value is null.
* ----------
* ----------
*/
*/
static
bool
static
bool
...
@@ -3271,7 +3246,6 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
...
@@ -3271,7 +3246,6 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
{
{
RI_OpreqHashEntry
*
entry
;
RI_OpreqHashEntry
*
entry
;
bool
found
;
bool
found
;
Datum
result
;
/* ----------
/* ----------
* On the first call initialize the hashtable
* On the first call initialize the hashtable
...
@@ -3291,6 +3265,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
...
@@ -3291,6 +3265,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
/* ----------
/* ----------
* If not found, lookup the OPERNAME system cache for it
* If not found, lookup the OPERNAME system cache for it
* to get the func OID, then do the function manager lookup,
* and remember that info.
* and remember that info.
* ----------
* ----------
*/
*/
...
@@ -3307,7 +3282,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
...
@@ -3307,7 +3282,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
if
(
!
HeapTupleIsValid
(
opr_tup
))
if
(
!
HeapTupleIsValid
(
opr_tup
))
elog
(
ERROR
,
"ri_AttributesEqual(): cannot find '=' operator "
elog
(
ERROR
,
"ri_AttributesEqual(): cannot find '=' operator "
"for type %
d
"
,
typeid
);
"for type %
u
"
,
typeid
);
opr_struct
=
(
Form_pg_operator
)
GETSTRUCT
(
opr_tup
);
opr_struct
=
(
Form_pg_operator
)
GETSTRUCT
(
opr_tup
);
entry
=
(
RI_OpreqHashEntry
*
)
hash_search
(
ri_opreq_cache
,
entry
=
(
RI_OpreqHashEntry
*
)
hash_search
(
ri_opreq_cache
,
...
@@ -3315,15 +3290,14 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
...
@@ -3315,15 +3290,14 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
if
(
entry
==
NULL
)
if
(
entry
==
NULL
)
elog
(
FATAL
,
"can't insert into RI operator cache"
);
elog
(
FATAL
,
"can't insert into RI operator cache"
);
entry
->
oprfnid
=
opr_struct
->
oprcode
;
entry
->
typeid
=
typeid
;
memset
(
&
(
entry
->
oprfmgrinfo
),
0
,
sizeof
(
FmgrI
nfo
));
fmgr_info
(
opr_struct
->
oprcode
,
&
(
entry
->
oprfmgri
nfo
));
}
}
/* ----------
/* ----------
* Call the type specific '=' function
* Call the type specific '=' function
* ----------
* ----------
*/
*/
fmgr_info
(
entry
->
oprfnid
,
&
(
entry
->
oprfmgrinfo
));
return
DatumGetBool
(
FunctionCall2
(
&
(
entry
->
oprfmgrinfo
),
result
=
(
Datum
)
(
*
fmgr_faddr
(
&
(
entry
->
oprfmgrinfo
)))
(
oldvalue
,
newvalue
);
oldvalue
,
newvalue
));
return
(
bool
)
result
;
}
}
src/backend/utils/adt/tid.c
View file @
18952f67
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.1
6 2000/04/12 17:15:51 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/tid.c,v 1.1
7 2000/05/29 01:59:08 tgl
Exp $
*
*
* NOTES
* NOTES
* input routine largely stolen from boxin().
* input routine largely stolen from boxin().
...
@@ -17,6 +17,8 @@
...
@@ -17,6 +17,8 @@
*/
*/
#include "postgres.h"
#include "postgres.h"
#include "access/heapam.h"
#include "utils/builtins.h"
#include "utils/builtins.h"
#define LDELIM '('
#define LDELIM '('
...
...
src/backend/utils/adt/timestamp.c
View file @
18952f67
...
@@ -8,16 +8,17 @@
...
@@ -8,16 +8,17 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.2
6 2000/04/14 15:22:10 thomas
Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.2
7 2000/05/29 01:59:08 tgl
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
#include "postgres.h"
#include <ctype.h>
#include <ctype.h>
#include <math.h>
#include <math.h>
#include <sys/types.h>
#include <errno.h>
#include <errno.h>
#include <sys/types.h>
#include "postgres.h"
#ifdef HAVE_FLOAT_H
#ifdef HAVE_FLOAT_H
#include <float.h>
#include <float.h>
#endif
#endif
...
@@ -28,6 +29,7 @@
...
@@ -28,6 +29,7 @@
#include <sys/timeb.h>
#include <sys/timeb.h>
#endif
#endif
#include "access/xact.h"
#include "miscadmin.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/builtins.h"
...
...
src/backend/utils/fmgr/fmgr.c
View file @
18952f67
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.4
0 2000/05/28 17:56:07
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.4
1 2000/05/29 01:59:09
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -17,7 +17,6 @@
...
@@ -17,7 +17,6 @@
#include "catalog/pg_language.h"
#include "catalog/pg_language.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_proc.h"
#include "commands/trigger.h"
/* TEMPORARY: for CurrentTriggerData */
#include "utils/builtins.h"
#include "utils/builtins.h"
#include "utils/fmgrtab.h"
#include "utils/fmgrtab.h"
#include "utils/syscache.h"
#include "utils/syscache.h"
...
...
src/include/catalog/catversion.h
View file @
18952f67
...
@@ -37,7 +37,7 @@
...
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: catversion.h,v 1.2
2 2000/05/28 17:56:16
tgl Exp $
* $Id: catversion.h,v 1.2
3 2000/05/29 01:59:10
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -53,6 +53,6 @@
...
@@ -53,6 +53,6 @@
*/
*/
/* yyyymmddN */
/* yyyymmddN */
#define CATALOG_VERSION_NO 20000528
1
#define CATALOG_VERSION_NO 20000528
2
#endif
#endif
src/include/catalog/pg_proc.h
View file @
18952f67
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pg_proc.h,v 1.13
4 2000/05/28 17:56:16
tgl Exp $
* $Id: pg_proc.h,v 1.13
5 2000/05/29 01:59:10
tgl Exp $
*
*
* NOTES
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
* The script catalog/genbki.sh reads this file and generates .bki
...
@@ -2103,7 +2103,7 @@ DESCR("less-than");
...
@@ -2103,7 +2103,7 @@ DESCR("less-than");
DATA
(
insert
OID
=
1656
(
lztext_le
PGUID
11
f
t
t
t
2
f
16
"1625 1625"
100
0
1
0
lztext_le
-
));
DATA
(
insert
OID
=
1656
(
lztext_le
PGUID
11
f
t
t
t
2
f
16
"1625 1625"
100
0
1
0
lztext_le
-
));
DESCR
(
"less-than-or-equal"
);
DESCR
(
"less-than-or-equal"
);
DATA
(
insert
OID
=
1689
(
update_pg_pwd
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
update_pg_pwd
-
));
DATA
(
insert
OID
=
1689
(
update_pg_pwd
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
update_pg_pwd
-
));
DESCR
(
"update pg_pwd file"
);
DESCR
(
"update pg_pwd file"
);
/* Oracle Compatibility Related Functions - By Edmund Mergl <E.Mergl@bawue.de> */
/* Oracle Compatibility Related Functions - By Edmund Mergl <E.Mergl@bawue.de> */
...
@@ -2163,29 +2163,29 @@ DATA(insert OID = 1643 ( pg_get_indexdef PGUID 11 f t f t 1 f 25 "26" 100 0
...
@@ -2163,29 +2163,29 @@ DATA(insert OID = 1643 ( pg_get_indexdef PGUID 11 f t f t 1 f 25 "26" 100 0
DESCR
(
"index description"
);
DESCR
(
"index description"
);
/* Generic referential integrity constraint triggers */
/* Generic referential integrity constraint triggers */
DATA
(
insert
OID
=
1644
(
RI_FKey_check_ins
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_check_ins
-
));
DATA
(
insert
OID
=
1644
(
RI_FKey_check_ins
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_check_ins
-
));
DESCR
(
"referential integrity FOREIGN KEY ... REFERENCES"
);
DESCR
(
"referential integrity FOREIGN KEY ... REFERENCES"
);
DATA
(
insert
OID
=
1645
(
RI_FKey_check_upd
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_check_upd
-
));
DATA
(
insert
OID
=
1645
(
RI_FKey_check_upd
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_check_upd
-
));
DESCR
(
"referential integrity FOREIGN KEY ... REFERENCES"
);
DESCR
(
"referential integrity FOREIGN KEY ... REFERENCES"
);
DATA
(
insert
OID
=
1646
(
RI_FKey_cascade_del
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_cascade_del
-
));
DATA
(
insert
OID
=
1646
(
RI_FKey_cascade_del
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_cascade_del
-
));
DESCR
(
"referential integrity ON DELETE CASCADE"
);
DESCR
(
"referential integrity ON DELETE CASCADE"
);
DATA
(
insert
OID
=
1647
(
RI_FKey_cascade_upd
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_cascade_upd
-
));
DATA
(
insert
OID
=
1647
(
RI_FKey_cascade_upd
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_cascade_upd
-
));
DESCR
(
"referential integrity ON UPDATE CASCADE"
);
DESCR
(
"referential integrity ON UPDATE CASCADE"
);
DATA
(
insert
OID
=
1648
(
RI_FKey_restrict_del
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_restrict_del
-
));
DATA
(
insert
OID
=
1648
(
RI_FKey_restrict_del
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_restrict_del
-
));
DESCR
(
"referential integrity ON DELETE RESTRICT"
);
DESCR
(
"referential integrity ON DELETE RESTRICT"
);
DATA
(
insert
OID
=
1649
(
RI_FKey_restrict_upd
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_restrict_upd
-
));
DATA
(
insert
OID
=
1649
(
RI_FKey_restrict_upd
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_restrict_upd
-
));
DESCR
(
"referential integrity ON UPDATE RESTRICT"
);
DESCR
(
"referential integrity ON UPDATE RESTRICT"
);
DATA
(
insert
OID
=
1650
(
RI_FKey_setnull_del
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_setnull_del
-
));
DATA
(
insert
OID
=
1650
(
RI_FKey_setnull_del
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_setnull_del
-
));
DESCR
(
"referential integrity ON DELETE SET NULL"
);
DESCR
(
"referential integrity ON DELETE SET NULL"
);
DATA
(
insert
OID
=
1651
(
RI_FKey_setnull_upd
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_setnull_upd
-
));
DATA
(
insert
OID
=
1651
(
RI_FKey_setnull_upd
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_setnull_upd
-
));
DESCR
(
"referential integrity ON UPDATE SET NULL"
);
DESCR
(
"referential integrity ON UPDATE SET NULL"
);
DATA
(
insert
OID
=
1652
(
RI_FKey_setdefault_del
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_setdefault_del
-
));
DATA
(
insert
OID
=
1652
(
RI_FKey_setdefault_del
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_setdefault_del
-
));
DESCR
(
"referential integrity ON DELETE SET DEFAULT"
);
DESCR
(
"referential integrity ON DELETE SET DEFAULT"
);
DATA
(
insert
OID
=
1653
(
RI_FKey_setdefault_upd
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_setdefault_upd
-
));
DATA
(
insert
OID
=
1653
(
RI_FKey_setdefault_upd
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_setdefault_upd
-
));
DESCR
(
"referential integrity ON UPDATE SET DEFAULT"
);
DESCR
(
"referential integrity ON UPDATE SET DEFAULT"
);
DATA
(
insert
OID
=
1654
(
RI_FKey_noaction_del
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_noaction_del
-
));
DATA
(
insert
OID
=
1654
(
RI_FKey_noaction_del
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_noaction_del
-
));
DESCR
(
"referential integrity ON DELETE NO ACTION"
);
DESCR
(
"referential integrity ON DELETE NO ACTION"
);
DATA
(
insert
OID
=
1655
(
RI_FKey_noaction_upd
PGUID
1
1
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_noaction_upd
-
));
DATA
(
insert
OID
=
1655
(
RI_FKey_noaction_upd
PGUID
1
2
f
t
f
t
0
f
0
""
100
0
0
100
RI_FKey_noaction_upd
-
));
DESCR
(
"referential integrity ON UPDATE NO ACTION"
);
DESCR
(
"referential integrity ON UPDATE NO ACTION"
);
DATA
(
insert
OID
=
1666
(
varbiteq
PGUID
11
f
t
t
t
2
f
16
"1562 1562"
100
0
1
0
varbiteq
-
));
DATA
(
insert
OID
=
1666
(
varbiteq
PGUID
11
f
t
t
t
2
f
16
"1562 1562"
100
0
1
0
varbiteq
-
));
...
...
src/include/commands/trigger.h
View file @
18952f67
/*-------------------------------------------------------------------------
/*-------------------------------------------------------------------------
*
*
* trigger.h
* trigger.h
*
prototypes for trigger.c
.
*
Declarations for trigger handling
.
*
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: trigger.h,v 1.
19 2000/04/12 17:16:32 momjian
Exp $
* $Id: trigger.h,v 1.
20 2000/05/29 01:59:11 tgl
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -16,10 +16,19 @@
...
@@ -16,10 +16,19 @@
#include "nodes/execnodes.h"
#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
#include "nodes/parsenodes.h"
/*
* TriggerData is the node type that is passed as fmgr "context" info
* when a function is called by the trigger manager.
*/
#define CALLED_AS_TRIGGER(fcinfo) \
((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
typedef
uint32
TriggerEvent
;
typedef
uint32
TriggerEvent
;
typedef
struct
TriggerData
typedef
struct
TriggerData
{
{
NodeTag
type
;
TriggerEvent
tg_event
;
TriggerEvent
tg_event
;
Relation
tg_relation
;
Relation
tg_relation
;
HeapTuple
tg_trigtuple
;
HeapTuple
tg_trigtuple
;
...
@@ -27,7 +36,7 @@ typedef struct TriggerData
...
@@ -27,7 +36,7 @@ typedef struct TriggerData
Trigger
*
tg_trigger
;
Trigger
*
tg_trigger
;
}
TriggerData
;
}
TriggerData
;
extern
DLLIMPORT
TriggerData
*
CurrentTriggerData
;
/* TriggerEvent bit flags */
#define TRIGGER_EVENT_INSERT 0x00000000
#define TRIGGER_EVENT_INSERT 0x00000000
#define TRIGGER_EVENT_DELETE 0x00000001
#define TRIGGER_EVENT_DELETE 0x00000001
...
@@ -136,6 +145,6 @@ extern void DeferredTriggerSaveEvent(Relation rel, int event,
...
@@ -136,6 +145,6 @@ extern void DeferredTriggerSaveEvent(Relation rel, int event,
* in utils/adt/ri_triggers.c
* in utils/adt/ri_triggers.c
*
*
*/
*/
extern
bool
RI_FKey_keyequal_upd
(
void
);
extern
bool
RI_FKey_keyequal_upd
(
TriggerData
*
trigdata
);
#endif
/* TRIGGER_H */
#endif
/* TRIGGER_H */
src/include/commands/user.h
View file @
18952f67
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
* user.h
* user.h
*
*
*
*
*
*
$Id: user.h,v 1.12 2000/05/29 01:59:11 tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -21,6 +21,6 @@ extern void CreateGroup(CreateGroupStmt *stmt);
...
@@ -21,6 +21,6 @@ extern void CreateGroup(CreateGroupStmt *stmt);
extern
void
AlterGroup
(
AlterGroupStmt
*
stmt
,
const
char
*
tag
);
extern
void
AlterGroup
(
AlterGroupStmt
*
stmt
,
const
char
*
tag
);
extern
void
DropGroup
(
DropGroupStmt
*
stmt
);
extern
void
DropGroup
(
DropGroupStmt
*
stmt
);
extern
HeapTuple
update_pg_pwd
(
void
);
extern
Datum
update_pg_pwd
(
PG_FUNCTION_ARGS
);
#endif
/* USER_H */
#endif
/* USER_H */
src/include/executor/executor.h
View file @
18952f67
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: executor.h,v 1.4
2 2000/01/26 05:58:05 momjian
Exp $
* $Id: executor.h,v 1.4
3 2000/05/29 01:59:11 tgl
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -59,6 +59,8 @@ extern TupleTableSlot *ExecutorRun(QueryDesc *queryDesc, EState *estate,
...
@@ -59,6 +59,8 @@ extern TupleTableSlot *ExecutorRun(QueryDesc *queryDesc, EState *estate,
extern
void
ExecutorEnd
(
QueryDesc
*
queryDesc
,
EState
*
estate
);
extern
void
ExecutorEnd
(
QueryDesc
*
queryDesc
,
EState
*
estate
);
extern
void
ExecConstraints
(
char
*
caller
,
Relation
rel
,
HeapTuple
tuple
,
extern
void
ExecConstraints
(
char
*
caller
,
Relation
rel
,
HeapTuple
tuple
,
EState
*
estate
);
EState
*
estate
);
extern
TupleTableSlot
*
EvalPlanQual
(
EState
*
estate
,
Index
rti
,
ItemPointer
tid
);
/*
/*
* prototypes from functions in execProcnode.c
* prototypes from functions in execProcnode.c
...
...
src/include/fmgr.h
View file @
18952f67
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: fmgr.h,v 1.
1 2000/05/28 17:56:12
tgl Exp $
* $Id: fmgr.h,v 1.
2 2000/05/29 01:59:09
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -107,6 +107,7 @@ extern void fmgr_info(Oid functionId, FmgrInfo *finfo);
...
@@ -107,6 +107,7 @@ extern void fmgr_info(Oid functionId, FmgrInfo *finfo);
#define PG_GETARG_BOOL(n) DatumGetBool(fcinfo->arg[n])
#define PG_GETARG_BOOL(n) DatumGetBool(fcinfo->arg[n])
#define PG_GETARG_OID(n) DatumGetObjectId(fcinfo->arg[n])
#define PG_GETARG_OID(n) DatumGetObjectId(fcinfo->arg[n])
#define PG_GETARG_POINTER(n) DatumGetPointer(fcinfo->arg[n])
#define PG_GETARG_POINTER(n) DatumGetPointer(fcinfo->arg[n])
#define PG_GETARG_NAME(n) DatumGetName(fcinfo->arg[n])
/* these macros hide the pass-by-reference-ness of the datatype: */
/* these macros hide the pass-by-reference-ness of the datatype: */
#define PG_GETARG_FLOAT4(n) DatumGetFloat4(fcinfo->arg[n])
#define PG_GETARG_FLOAT4(n) DatumGetFloat4(fcinfo->arg[n])
#define PG_GETARG_FLOAT8(n) DatumGetFloat8(fcinfo->arg[n])
#define PG_GETARG_FLOAT8(n) DatumGetFloat8(fcinfo->arg[n])
...
@@ -133,6 +134,7 @@ extern void fmgr_info(Oid functionId, FmgrInfo *finfo);
...
@@ -133,6 +134,7 @@ extern void fmgr_info(Oid functionId, FmgrInfo *finfo);
#define PG_RETURN_BOOL(x) return BoolGetDatum(x)
#define PG_RETURN_BOOL(x) return BoolGetDatum(x)
#define PG_RETURN_OID(x) return ObjectIdGetDatum(x)
#define PG_RETURN_OID(x) return ObjectIdGetDatum(x)
#define PG_RETURN_POINTER(x) return PointerGetDatum(x)
#define PG_RETURN_POINTER(x) return PointerGetDatum(x)
#define PG_RETURN_NAME(x) return NameGetDatum(x)
/* these macros hide the pass-by-reference-ness of the datatype: */
/* these macros hide the pass-by-reference-ness of the datatype: */
#define PG_RETURN_FLOAT4(x) return Float4GetDatum(x)
#define PG_RETURN_FLOAT4(x) return Float4GetDatum(x)
#define PG_RETURN_FLOAT8(x) return Float8GetDatum(x)
#define PG_RETURN_FLOAT8(x) return Float8GetDatum(x)
...
...
src/include/nodes/nodes.h
View file @
18952f67
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: nodes.h,v 1.6
7 2000/04/12 17:16:40 momjian
Exp $
* $Id: nodes.h,v 1.6
8 2000/05/29 01:59:12 tgl
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -223,7 +223,13 @@ typedef enum NodeTag
...
@@ -223,7 +223,13 @@ typedef enum NodeTag
T_CaseExpr
,
T_CaseExpr
,
T_CaseWhen
,
T_CaseWhen
,
T_RowMark
,
T_RowMark
,
T_FkConstraint
T_FkConstraint
,
/*---------------------
* TAGS FOR FUNCTION-CALL CONTEXT AND RESULTINFO NODES (cf. fmgr.h)
*---------------------
*/
T_TriggerData
=
800
/* in commands/trigger.h */
}
NodeTag
;
}
NodeTag
;
/*
/*
...
...
src/include/utils/builtins.h
View file @
18952f67
...
@@ -7,23 +7,14 @@
...
@@ -7,23 +7,14 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: builtins.h,v 1.111 2000/04/16 04:41:03 tgl Exp $
* $Id: builtins.h,v 1.112 2000/05/29 01:59:13 tgl Exp $
*
* NOTES
* This should normally only be included by fmgr.h.
* Under no circumstances should it ever be included before
* including fmgr.h!
* fmgr.h does not seem to include this file, so don't know where this
* comment came from. Backend code must include this stuff explicitly
* as far as I can tell...
* - thomas 1998-06-08
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
#ifndef BUILTINS_H
#ifndef BUILTINS_H
#define BUILTINS_H
#define BUILTINS_H
#include "
access/heapam.h"
/* for HeapTuple */
#include "
fmgr.h"
#include "nodes/relation.h"
/* for amcostestimate parameters */
#include "nodes/relation.h"
/* for amcostestimate parameters */
#include "storage/itemptr.h"
#include "storage/itemptr.h"
#include "utils/array.h"
#include "utils/array.h"
...
@@ -648,17 +639,17 @@ bool lztext_lt(lztext *lz1, lztext *lz2);
...
@@ -648,17 +639,17 @@ bool lztext_lt(lztext *lz1, lztext *lz2);
bool
lztext_le
(
lztext
*
lz1
,
lztext
*
lz2
);
bool
lztext_le
(
lztext
*
lz1
,
lztext
*
lz2
);
/* ri_triggers.c */
/* ri_triggers.c */
extern
HeapTuple
RI_FKey_check_ins
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_check_ins
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_check_upd
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_check_upd
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_noaction_del
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_noaction_del
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_noaction_upd
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_noaction_upd
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_cascade_del
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_cascade_del
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_cascade_upd
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_cascade_upd
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_restrict_del
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_restrict_del
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_restrict_upd
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_restrict_upd
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_setnull_del
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_setnull_del
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_setnull_upd
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_setnull_upd
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_setdefault_del
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_setdefault_del
(
PG_FUNCTION_ARGS
);
extern
HeapTuple
RI_FKey_setdefault_upd
(
FmgrInfo
*
proinfo
);
extern
Datum
RI_FKey_setdefault_upd
(
PG_FUNCTION_ARGS
);
#endif
/* BUILTINS_H */
#endif
/* BUILTINS_H */
src/pl/plperl/plperl.c
View file @
18952f67
...
@@ -33,7 +33,7 @@
...
@@ -33,7 +33,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
* ENHANCEMENTS, OR MODIFICATIONS.
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.
7 2000/05/28 17:56:26
tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.
8 2000/05/29 01:59:13
tgl Exp $
*
*
**********************************************************************/
**********************************************************************/
...
@@ -283,18 +283,18 @@ plperl_call_handler(PG_FUNCTION_ARGS)
...
@@ -283,18 +283,18 @@ plperl_call_handler(PG_FUNCTION_ARGS)
* Determine if called as function or trigger and
* Determine if called as function or trigger and
* call appropriate subhandler
* call appropriate subhandler
************************************************************/
************************************************************/
if
(
CurrentTriggerData
==
NULL
)
if
(
CALLED_AS_TRIGGER
(
fcinfo
))
retval
=
plperl_func_handler
(
fcinfo
);
else
{
{
elog
(
ERROR
,
"plperl: can't use perl in triggers yet."
);
elog
(
ERROR
,
"plperl: can't use perl in triggers yet."
);
/*
/*
* retval =
(Datum) plperl_trigger_handler(fcinfo
);
* retval =
PointerGetDatum(plperl_trigger_handler(fcinfo)
);
*/
*/
/* make the compiler happy */
/* make the compiler happy */
retval
=
(
Datum
)
0
;
retval
=
(
Datum
)
0
;
}
}
else
retval
=
plperl_func_handler
(
fcinfo
);
plperl_call_level
--
;
plperl_call_level
--
;
...
@@ -687,7 +687,7 @@ plperl_func_handler(PG_FUNCTION_ARGS)
...
@@ -687,7 +687,7 @@ plperl_func_handler(PG_FUNCTION_ARGS)
static
HeapTuple
static
HeapTuple
plperl_trigger_handler
(
PG_FUNCTION_ARGS
)
plperl_trigger_handler
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
char
internal_proname
[
512
];
char
internal_proname
[
512
];
char
*
stroid
;
char
*
stroid
;
Tcl_HashEntry
*
hashent
;
Tcl_HashEntry
*
hashent
;
...
@@ -710,12 +710,6 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
...
@@ -710,12 +710,6 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
sigjmp_buf
save_restart
;
sigjmp_buf
save_restart
;
/************************************************************
* Save the current trigger data local
************************************************************/
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
/************************************************************
/************************************************************
* Build our internal proc name from the functions Oid
* Build our internal proc name from the functions Oid
************************************************************/
************************************************************/
...
...
src/pl/plpgsql/src/pl_handler.c
View file @
18952f67
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
* procedural language
* procedural language
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.
4 2000/05/28 17:56:28
tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.
5 2000/05/29 01:59:14
tgl Exp $
*
*
* This software is copyrighted by Jan Wieck - Hamburg.
* This software is copyrighted by Jan Wieck - Hamburg.
*
*
...
@@ -69,21 +69,10 @@ static PLpgSQL_function *compiled_functions = NULL;
...
@@ -69,21 +69,10 @@ static PLpgSQL_function *compiled_functions = NULL;
Datum
Datum
plpgsql_call_handler
(
PG_FUNCTION_ARGS
)
plpgsql_call_handler
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
bool
isTrigger
=
CALLED_AS_TRIGGER
(
fcinfo
);
bool
isTrigger
;
PLpgSQL_function
*
func
;
PLpgSQL_function
*
func
;
Datum
retval
;
Datum
retval
;
/* ----------
* Save the current trigger data local
*
* XXX this should go away in favor of using fcinfo->context
* ----------
*/
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
isTrigger
=
(
trigdata
!=
NULL
);
/* ----------
/* ----------
* Connect to SPI manager
* Connect to SPI manager
* ----------
* ----------
...
@@ -136,7 +125,8 @@ plpgsql_call_handler(PG_FUNCTION_ARGS)
...
@@ -136,7 +125,8 @@ plpgsql_call_handler(PG_FUNCTION_ARGS)
* ----------
* ----------
*/
*/
if
(
isTrigger
)
if
(
isTrigger
)
retval
=
PointerGetDatum
(
plpgsql_exec_trigger
(
func
,
trigdata
));
retval
=
PointerGetDatum
(
plpgsql_exec_trigger
(
func
,
(
TriggerData
*
)
fcinfo
->
context
));
else
else
retval
=
plpgsql_exec_function
(
func
,
fcinfo
);
retval
=
plpgsql_exec_function
(
func
,
fcinfo
);
...
...
src/pl/tcl/pltcl.c
View file @
18952f67
...
@@ -31,7 +31,7 @@
...
@@ -31,7 +31,7 @@
* ENHANCEMENTS, OR MODIFICATIONS.
* ENHANCEMENTS, OR MODIFICATIONS.
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.2
3 2000/05/28 17:56:29
tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.2
4 2000/05/29 01:59:15
tgl Exp $
*
*
**********************************************************************/
**********************************************************************/
...
@@ -390,10 +390,10 @@ pltcl_call_handler(PG_FUNCTION_ARGS)
...
@@ -390,10 +390,10 @@ pltcl_call_handler(PG_FUNCTION_ARGS)
* Determine if called as function or trigger and
* Determine if called as function or trigger and
* call appropriate subhandler
* call appropriate subhandler
************************************************************/
************************************************************/
if
(
C
urrentTriggerData
==
NULL
)
if
(
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
retval
=
pltcl_func_handler
(
fcinfo
);
retval
=
PointerGetDatum
(
pltcl_trigger_handler
(
fcinfo
)
);
else
else
retval
=
(
Datum
)
pltcl_trigger
_handler
(
fcinfo
);
retval
=
pltcl_func
_handler
(
fcinfo
);
pltcl_call_level
--
;
pltcl_call_level
--
;
...
@@ -734,7 +734,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
...
@@ -734,7 +734,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS)
static
HeapTuple
static
HeapTuple
pltcl_trigger_handler
(
PG_FUNCTION_ARGS
)
pltcl_trigger_handler
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
;
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
char
internal_proname
[
512
];
char
internal_proname
[
512
];
char
*
stroid
;
char
*
stroid
;
Tcl_HashEntry
*
hashent
;
Tcl_HashEntry
*
hashent
;
...
@@ -757,12 +757,6 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
...
@@ -757,12 +757,6 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS)
sigjmp_buf
save_restart
;
sigjmp_buf
save_restart
;
/************************************************************
* Save the current trigger data local
************************************************************/
trigdata
=
CurrentTriggerData
;
CurrentTriggerData
=
NULL
;
/************************************************************
/************************************************************
* Build our internal proc name from the functions Oid
* Build our internal proc name from the functions Oid
************************************************************/
************************************************************/
...
...
src/test/regress/input/create_function_1.source
View file @
18952f67
...
@@ -15,27 +15,27 @@ CREATE FUNCTION widget_out(opaque)
...
@@ -15,27 +15,27 @@ CREATE FUNCTION widget_out(opaque)
CREATE FUNCTION check_primary_key ()
CREATE FUNCTION check_primary_key ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/../../../contrib/spi/refint_DLSUFFIX_'
AS '_OBJWD_/../../../contrib/spi/refint_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION check_foreign_key ()
CREATE FUNCTION check_foreign_key ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/../../../contrib/spi/refint_DLSUFFIX_'
AS '_OBJWD_/../../../contrib/spi/refint_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION autoinc ()
CREATE FUNCTION autoinc ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/../../../contrib/spi/autoinc_DLSUFFIX_'
AS '_OBJWD_/../../../contrib/spi/autoinc_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION funny_dup17 ()
CREATE FUNCTION funny_dup17 ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/regress_DLSUFFIX_'
AS '_OBJWD_/regress_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION ttdummy ()
CREATE FUNCTION ttdummy ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/regress_DLSUFFIX_'
AS '_OBJWD_/regress_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION set_ttdummy (int4)
CREATE FUNCTION set_ttdummy (int4)
RETURNS int4
RETURNS int4
...
...
src/test/regress/output/create_function_1.source
View file @
18952f67
...
@@ -13,23 +13,23 @@ CREATE FUNCTION widget_out(opaque)
...
@@ -13,23 +13,23 @@ CREATE FUNCTION widget_out(opaque)
CREATE FUNCTION check_primary_key ()
CREATE FUNCTION check_primary_key ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/../../../contrib/spi/refint_DLSUFFIX_'
AS '_OBJWD_/../../../contrib/spi/refint_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION check_foreign_key ()
CREATE FUNCTION check_foreign_key ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/../../../contrib/spi/refint_DLSUFFIX_'
AS '_OBJWD_/../../../contrib/spi/refint_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION autoinc ()
CREATE FUNCTION autoinc ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/../../../contrib/spi/autoinc_DLSUFFIX_'
AS '_OBJWD_/../../../contrib/spi/autoinc_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION funny_dup17 ()
CREATE FUNCTION funny_dup17 ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/regress_DLSUFFIX_'
AS '_OBJWD_/regress_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION ttdummy ()
CREATE FUNCTION ttdummy ()
RETURNS opaque
RETURNS opaque
AS '_OBJWD_/regress_DLSUFFIX_'
AS '_OBJWD_/regress_DLSUFFIX_'
LANGUAGE '
c
';
LANGUAGE '
newC
';
CREATE FUNCTION set_ttdummy (int4)
CREATE FUNCTION set_ttdummy (int4)
RETURNS int4
RETURNS int4
AS '_OBJWD_/regress_DLSUFFIX_'
AS '_OBJWD_/regress_DLSUFFIX_'
...
...
src/test/regress/regress.c
View file @
18952f67
/*
/*
* $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.3
6 2000/04/12 17:17:21 momjian
Exp $
* $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.3
7 2000/05/29 01:59:15 tgl
Exp $
*/
*/
#include <float.h>
/* faked on sunos */
#include <float.h>
/* faked on sunos */
...
@@ -306,11 +306,12 @@ static int fd17b_level = 0;
...
@@ -306,11 +306,12 @@ static int fd17b_level = 0;
static
int
fd17a_level
=
0
;
static
int
fd17a_level
=
0
;
static
bool
fd17b_recursion
=
true
;
static
bool
fd17b_recursion
=
true
;
static
bool
fd17a_recursion
=
true
;
static
bool
fd17a_recursion
=
true
;
HeapTuple
funny_dup17
(
void
);
extern
Datum
funny_dup17
(
PG_FUNCTION_ARGS
);
HeapTuple
/* have to return HeapTuple to Executor */
Datum
funny_dup17
()
funny_dup17
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
TransactionId
*
xid
;
TransactionId
*
xid
;
int
*
level
;
int
*
level
;
bool
*
recursion
;
bool
*
recursion
;
...
@@ -325,10 +326,13 @@ funny_dup17()
...
@@ -325,10 +326,13 @@ funny_dup17()
int
selected
=
0
;
int
selected
=
0
;
int
ret
;
int
ret
;
tuple
=
CurrentTriggerData
->
tg_trigtuple
;
if
(
!
CALLED_AS_TRIGGER
(
fcinfo
))
rel
=
CurrentTriggerData
->
tg_relation
;
elog
(
ERROR
,
"funny_dup17: not fired by trigger manager"
);
tuple
=
trigdata
->
tg_trigtuple
;
rel
=
trigdata
->
tg_relation
;
tupdesc
=
rel
->
rd_att
;
tupdesc
=
rel
->
rd_att
;
if
(
TRIGGER_FIRED_BEFORE
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BEFORE
(
trigd
ata
->
tg_event
))
{
{
xid
=
&
fd17b_xid
;
xid
=
&
fd17b_xid
;
level
=
&
fd17b_level
;
level
=
&
fd17b_level
;
...
@@ -343,8 +347,6 @@ funny_dup17()
...
@@ -343,8 +347,6 @@ funny_dup17()
when
=
"AFTER "
;
when
=
"AFTER "
;
}
}
CurrentTriggerData
=
NULL
;
if
(
!
TransactionIdIsCurrentTransactionId
(
*
xid
))
if
(
!
TransactionIdIsCurrentTransactionId
(
*
xid
))
{
{
*
xid
=
GetCurrentTransactionId
();
*
xid
=
GetCurrentTransactionId
();
...
@@ -355,11 +357,11 @@ funny_dup17()
...
@@ -355,11 +357,11 @@ funny_dup17()
if
(
*
level
==
17
)
if
(
*
level
==
17
)
{
{
*
recursion
=
false
;
*
recursion
=
false
;
return
tuple
;
return
PointerGetDatum
(
tuple
)
;
}
}
if
(
!
(
*
recursion
))
if
(
!
(
*
recursion
))
return
tuple
;
return
PointerGetDatum
(
tuple
)
;
(
*
level
)
++
;
(
*
level
)
++
;
...
@@ -412,10 +414,10 @@ funny_dup17()
...
@@ -412,10 +414,10 @@ funny_dup17()
if
(
*
level
==
0
)
if
(
*
level
==
0
)
*
xid
=
InvalidTransactionId
;
*
xid
=
InvalidTransactionId
;
return
tuple
;
return
PointerGetDatum
(
tuple
)
;
}
}
HeapTuple
ttdummy
(
void
);
extern
Datum
ttdummy
(
PG_FUNCTION_ARGS
);
int32
set_ttdummy
(
int32
on
);
int32
set_ttdummy
(
int32
on
);
extern
int4
nextval
(
struct
varlena
*
seqin
);
extern
int4
nextval
(
struct
varlena
*
seqin
);
...
@@ -425,9 +427,10 @@ extern int4 nextval(struct varlena * seqin);
...
@@ -425,9 +427,10 @@ extern int4 nextval(struct varlena * seqin);
static
void
*
splan
=
NULL
;
static
void
*
splan
=
NULL
;
static
bool
ttoff
=
false
;
static
bool
ttoff
=
false
;
HeapTuple
Datum
ttdummy
()
ttdummy
(
PG_FUNCTION_ARGS
)
{
{
TriggerData
*
trigdata
=
(
TriggerData
*
)
fcinfo
->
context
;
Trigger
*
trigger
;
/* to get trigger name */
Trigger
*
trigger
;
/* to get trigger name */
char
**
args
;
/* arguments */
char
**
args
;
/* arguments */
int
attnum
[
2
];
/* fnumbers of start/stop columns */
int
attnum
[
2
];
/* fnumbers of start/stop columns */
...
@@ -448,30 +451,30 @@ ttdummy()
...
@@ -448,30 +451,30 @@ ttdummy()
int
ret
;
int
ret
;
int
i
;
int
i
;
if
(
!
C
urrentTriggerData
)
if
(
!
C
ALLED_AS_TRIGGER
(
fcinfo
)
)
elog
(
ERROR
,
"ttdummy:
triggers are not initialized
"
);
elog
(
ERROR
,
"ttdummy:
not fired by trigger manager
"
);
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_FOR_STATEMENT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"ttdummy: can't process STATEMENT events"
);
elog
(
ERROR
,
"ttdummy: can't process STATEMENT events"
);
if
(
TRIGGER_FIRED_AFTER
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_AFTER
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"ttdummy: must be fired before event"
);
elog
(
ERROR
,
"ttdummy: must be fired before event"
);
if
(
TRIGGER_FIRED_BY_INSERT
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_INSERT
(
trigd
ata
->
tg_event
))
elog
(
ERROR
,
"ttdummy: can't process INSERT event"
);
elog
(
ERROR
,
"ttdummy: can't process INSERT event"
);
if
(
TRIGGER_FIRED_BY_UPDATE
(
CurrentTriggerD
ata
->
tg_event
))
if
(
TRIGGER_FIRED_BY_UPDATE
(
trigd
ata
->
tg_event
))
newtuple
=
CurrentTriggerD
ata
->
tg_newtuple
;
newtuple
=
trigd
ata
->
tg_newtuple
;
trigtuple
=
CurrentTriggerD
ata
->
tg_trigtuple
;
trigtuple
=
trigd
ata
->
tg_trigtuple
;
rel
=
CurrentTriggerD
ata
->
tg_relation
;
rel
=
trigd
ata
->
tg_relation
;
relname
=
SPI_getrelname
(
rel
);
relname
=
SPI_getrelname
(
rel
);
/* check if TT is OFF for this relation */
/* check if TT is OFF for this relation */
if
(
ttoff
)
/* OFF - nothing to do */
if
(
ttoff
)
/* OFF - nothing to do */
{
{
pfree
(
relname
);
pfree
(
relname
);
return
(
newtuple
!=
NULL
)
?
newtuple
:
trigtuple
;
return
PointerGetDatum
((
newtuple
!=
NULL
)
?
newtuple
:
trigtuple
)
;
}
}
trigger
=
CurrentTriggerD
ata
->
tg_trigger
;
trigger
=
trigd
ata
->
tg_trigger
;
if
(
trigger
->
tgnargs
!=
2
)
if
(
trigger
->
tgnargs
!=
2
)
elog
(
ERROR
,
"ttdummy (%s): invalid (!= 2) number of arguments %d"
,
elog
(
ERROR
,
"ttdummy (%s): invalid (!= 2) number of arguments %d"
,
...
@@ -481,8 +484,6 @@ ttdummy()
...
@@ -481,8 +484,6 @@ ttdummy()
tupdesc
=
rel
->
rd_att
;
tupdesc
=
rel
->
rd_att
;
natts
=
tupdesc
->
natts
;
natts
=
tupdesc
->
natts
;
CurrentTriggerData
=
NULL
;
for
(
i
=
0
;
i
<
2
;
i
++
)
for
(
i
=
0
;
i
<
2
;
i
++
)
{
{
attnum
[
i
]
=
SPI_fnumber
(
tupdesc
,
args
[
i
]);
attnum
[
i
]
=
SPI_fnumber
(
tupdesc
,
args
[
i
]);
...
@@ -517,13 +518,13 @@ ttdummy()
...
@@ -517,13 +518,13 @@ ttdummy()
if
(
newoff
!=
TTDUMMY_INFINITY
)
if
(
newoff
!=
TTDUMMY_INFINITY
)
{
{
pfree
(
relname
);
/* allocated in upper executor context */
pfree
(
relname
);
/* allocated in upper executor context */
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
}
}
else
if
(
oldoff
!=
TTDUMMY_INFINITY
)
/* DELETE */
else
if
(
oldoff
!=
TTDUMMY_INFINITY
)
/* DELETE */
{
{
pfree
(
relname
);
pfree
(
relname
);
return
NULL
;
return
PointerGetDatum
(
NULL
)
;
}
}
{
{
...
@@ -618,7 +619,7 @@ ttdummy()
...
@@ -618,7 +619,7 @@ ttdummy()
pfree
(
relname
);
pfree
(
relname
);
return
rettuple
;
return
PointerGetDatum
(
rettuple
)
;
}
}
int32
int32
...
...
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