Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
P
postgres-lambda-diff
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jakob Huber
postgres-lambda-diff
Commits
b5d0051e
Commit
b5d0051e
authored
22 years ago
by
Tom Lane
Browse files
Options
Downloads
Patches
Plain Diff
Fix multiple causes of breakage in plperl's error handling.
parent
b40bc9ea
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/pl/plperl/plperl.c
+34
-61
34 additions, 61 deletions
src/pl/plperl/plperl.c
with
34 additions
and
61 deletions
src/pl/plperl/plperl.c
+
34
−
61
View file @
b5d0051e
...
@@ -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.3
5
200
2
/0
9
/2
1 18:39:26
tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.3
6
200
3
/0
4
/2
0 21:15:34
tgl Exp $
*
*
**********************************************************************/
**********************************************************************/
...
@@ -92,8 +92,6 @@ typedef struct plperl_proc_desc
...
@@ -92,8 +92,6 @@ typedef struct plperl_proc_desc
* Global data
* Global data
**********************************************************************/
**********************************************************************/
static
int
plperl_firstcall
=
1
;
static
int
plperl_firstcall
=
1
;
static
int
plperl_call_level
=
0
;
static
int
plperl_restart_in_progress
=
0
;
static
PerlInterpreter
*
plperl_interp
=
NULL
;
static
PerlInterpreter
*
plperl_interp
=
NULL
;
static
HV
*
plperl_proc_hash
=
NULL
;
static
HV
*
plperl_proc_hash
=
NULL
;
...
@@ -143,6 +141,15 @@ plperl_init_all(void)
...
@@ -143,6 +141,15 @@ plperl_init_all(void)
if
(
!
plperl_firstcall
)
if
(
!
plperl_firstcall
)
return
;
return
;
/************************************************************
* Free the proc hash table
************************************************************/
if
(
plperl_proc_hash
!=
NULL
)
{
hv_undef
(
plperl_proc_hash
);
SvREFCNT_dec
((
SV
*
)
plperl_proc_hash
);
plperl_proc_hash
=
NULL
;
}
/************************************************************
/************************************************************
* Destroy the existing Perl interpreter
* Destroy the existing Perl interpreter
...
@@ -154,16 +161,6 @@ plperl_init_all(void)
...
@@ -154,16 +161,6 @@ plperl_init_all(void)
plperl_interp
=
NULL
;
plperl_interp
=
NULL
;
}
}
/************************************************************
* Free the proc hash table
************************************************************/
if
(
plperl_proc_hash
!=
NULL
)
{
hv_undef
(
plperl_proc_hash
);
SvREFCNT_dec
((
SV
*
)
plperl_proc_hash
);
plperl_proc_hash
=
NULL
;
}
/************************************************************
/************************************************************
* Now recreate a new Perl interpreter
* Now recreate a new Perl interpreter
************************************************************/
************************************************************/
...
@@ -202,8 +199,6 @@ plperl_init_interp(void)
...
@@ -202,8 +199,6 @@ plperl_init_interp(void)
perl_parse
(
plperl_interp
,
plperl_init_shared_libs
,
3
,
embedding
,
NULL
);
perl_parse
(
plperl_interp
,
plperl_init_shared_libs
,
3
,
embedding
,
NULL
);
perl_run
(
plperl_interp
);
perl_run
(
plperl_interp
);
/************************************************************
/************************************************************
* Initialize the proc and query hash tables
* Initialize the proc and query hash tables
************************************************************/
************************************************************/
...
@@ -212,7 +207,6 @@ plperl_init_interp(void)
...
@@ -212,7 +207,6 @@ plperl_init_interp(void)
}
}
/**********************************************************************
/**********************************************************************
* plperl_call_handler - This is the only visible function
* plperl_call_handler - This is the only visible function
* of the PL interpreter. The PostgreSQL
* of the PL interpreter. The PostgreSQL
...
@@ -229,7 +223,7 @@ plperl_call_handler(PG_FUNCTION_ARGS)
...
@@ -229,7 +223,7 @@ plperl_call_handler(PG_FUNCTION_ARGS)
Datum
retval
;
Datum
retval
;
/************************************************************
/************************************************************
* Initialize interpreter
s
on first call
* Initialize interpreter on first call
************************************************************/
************************************************************/
if
(
plperl_firstcall
)
if
(
plperl_firstcall
)
plperl_init_all
();
plperl_init_all
();
...
@@ -239,10 +233,6 @@ plperl_call_handler(PG_FUNCTION_ARGS)
...
@@ -239,10 +233,6 @@ plperl_call_handler(PG_FUNCTION_ARGS)
************************************************************/
************************************************************/
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
if
(
SPI_connect
()
!=
SPI_OK_CONNECT
)
elog
(
ERROR
,
"plperl: cannot connect to SPI manager"
);
elog
(
ERROR
,
"plperl: cannot connect to SPI manager"
);
/************************************************************
* Keep track about the nesting of Perl-SPI-Perl-... calls
************************************************************/
plperl_call_level
++
;
/************************************************************
/************************************************************
* Determine if called as function or trigger and
* Determine if called as function or trigger and
...
@@ -261,8 +251,6 @@ plperl_call_handler(PG_FUNCTION_ARGS)
...
@@ -261,8 +251,6 @@ plperl_call_handler(PG_FUNCTION_ARGS)
else
else
retval
=
plperl_func_handler
(
fcinfo
);
retval
=
plperl_func_handler
(
fcinfo
);
plperl_call_level
--
;
return
retval
;
return
retval
;
}
}
...
@@ -272,13 +260,11 @@ plperl_call_handler(PG_FUNCTION_ARGS)
...
@@ -272,13 +260,11 @@ plperl_call_handler(PG_FUNCTION_ARGS)
* create the anonymous subroutine whose text is in the SV.
* create the anonymous subroutine whose text is in the SV.
* Returns the SV containing the RV to the closure.
* Returns the SV containing the RV to the closure.
**********************************************************************/
**********************************************************************/
static
static
SV
*
SV
*
plperl_create_sub
(
char
*
s
,
bool
trusted
)
plperl_create_sub
(
char
*
s
,
bool
trusted
)
{
{
dSP
;
dSP
;
SV
*
subref
;
SV
*
subref
=
NULL
;
int
count
;
int
count
;
ENTER
;
ENTER
;
...
@@ -286,10 +272,23 @@ plperl_create_sub(char *s, bool trusted)
...
@@ -286,10 +272,23 @@ plperl_create_sub(char *s, bool trusted)
PUSHMARK
(
SP
);
PUSHMARK
(
SP
);
XPUSHs
(
sv_2mortal
(
newSVpv
(
s
,
0
)));
XPUSHs
(
sv_2mortal
(
newSVpv
(
s
,
0
)));
PUTBACK
;
PUTBACK
;
/*
* G_KEEPERR seems to be needed here, else we don't recognize compile
* errors properly. Perhaps it's because there's another level of eval
* inside mksafefunc?
*/
count
=
perl_call_pv
((
trusted
?
"mksafefunc"
:
"mkunsafefunc"
),
count
=
perl_call_pv
((
trusted
?
"mksafefunc"
:
"mkunsafefunc"
),
G_SCALAR
|
G_EVAL
|
G_KEEPERR
);
G_SCALAR
|
G_EVAL
|
G_KEEPERR
);
SPAGAIN
;
SPAGAIN
;
if
(
count
!=
1
)
{
PUTBACK
;
FREETMPS
;
LEAVE
;
elog
(
ERROR
,
"plperl: didn't get a return item from mksafefunc"
);
}
if
(
SvTRUE
(
ERRSV
))
if
(
SvTRUE
(
ERRSV
))
{
{
POPs
;
POPs
;
...
@@ -299,9 +298,6 @@ plperl_create_sub(char *s, bool trusted)
...
@@ -299,9 +298,6 @@ plperl_create_sub(char *s, bool trusted)
elog
(
ERROR
,
"creation of function failed: %s"
,
SvPV
(
ERRSV
,
PL_na
));
elog
(
ERROR
,
"creation of function failed: %s"
,
SvPV
(
ERRSV
,
PL_na
));
}
}
if
(
count
!=
1
)
elog
(
ERROR
,
"creation of function failed - no return from mksafefunc"
);
/*
/*
* need to make a deep copy of the return. it comes off the stack as a
* need to make a deep copy of the return. it comes off the stack as a
* temporary.
* temporary.
...
@@ -324,6 +320,7 @@ plperl_create_sub(char *s, bool trusted)
...
@@ -324,6 +320,7 @@ plperl_create_sub(char *s, bool trusted)
PUTBACK
;
PUTBACK
;
FREETMPS
;
FREETMPS
;
LEAVE
;
LEAVE
;
return
subref
;
return
subref
;
}
}
...
@@ -352,21 +349,18 @@ plperl_init_shared_libs(pTHX)
...
@@ -352,21 +349,18 @@ plperl_init_shared_libs(pTHX)
* plperl_call_perl_func() - calls a perl function through the RV
* plperl_call_perl_func() - calls a perl function through the RV
* stored in the prodesc structure. massages the input parms properly
* stored in the prodesc structure. massages the input parms properly
**********************************************************************/
**********************************************************************/
static
static
SV
*
SV
*
plperl_call_perl_func
(
plperl_proc_desc
*
desc
,
FunctionCallInfo
fcinfo
)
plperl_call_perl_func
(
plperl_proc_desc
*
desc
,
FunctionCallInfo
fcinfo
)
{
{
dSP
;
dSP
;
SV
*
retval
;
SV
*
retval
;
int
i
;
int
i
;
int
count
;
int
count
;
ENTER
;
ENTER
;
SAVETMPS
;
SAVETMPS
;
PUSHMARK
(
sp
);
PUSHMARK
(
SP
);
for
(
i
=
0
;
i
<
desc
->
nargs
;
i
++
)
for
(
i
=
0
;
i
<
desc
->
nargs
;
i
++
)
{
{
if
(
desc
->
arg_is_rel
[
i
])
if
(
desc
->
arg_is_rel
[
i
])
...
@@ -401,7 +395,9 @@ plperl_call_perl_func(plperl_proc_desc * desc, FunctionCallInfo fcinfo)
...
@@ -401,7 +395,9 @@ plperl_call_perl_func(plperl_proc_desc * desc, FunctionCallInfo fcinfo)
}
}
}
}
PUTBACK
;
PUTBACK
;
count
=
perl_call_sv
(
desc
->
reference
,
G_SCALAR
|
G_EVAL
|
G_KEEPERR
);
/* Do NOT use G_KEEPERR here */
count
=
perl_call_sv
(
desc
->
reference
,
G_SCALAR
|
G_EVAL
);
SPAGAIN
;
SPAGAIN
;
...
@@ -424,16 +420,14 @@ plperl_call_perl_func(plperl_proc_desc * desc, FunctionCallInfo fcinfo)
...
@@ -424,16 +420,14 @@ plperl_call_perl_func(plperl_proc_desc * desc, FunctionCallInfo fcinfo)
retval
=
newSVsv
(
POPs
);
retval
=
newSVsv
(
POPs
);
PUTBACK
;
PUTBACK
;
FREETMPS
;
FREETMPS
;
LEAVE
;
LEAVE
;
return
retval
;
return
retval
;
}
}
/**********************************************************************
/**********************************************************************
* plperl_func_handler() - Handler for regular function calls
* plperl_func_handler() - Handler for regular function calls
**********************************************************************/
**********************************************************************/
...
@@ -443,23 +437,10 @@ plperl_func_handler(PG_FUNCTION_ARGS)
...
@@ -443,23 +437,10 @@ plperl_func_handler(PG_FUNCTION_ARGS)
plperl_proc_desc
*
prodesc
;
plperl_proc_desc
*
prodesc
;
SV
*
perlret
;
SV
*
perlret
;
Datum
retval
;
Datum
retval
;
sigjmp_buf
save_restart
;
/* Find or compile the function */
/* Find or compile the function */
prodesc
=
compile_plperl_function
(
fcinfo
->
flinfo
->
fn_oid
,
false
);
prodesc
=
compile_plperl_function
(
fcinfo
->
flinfo
->
fn_oid
,
false
);
/* Set up error handling */
memcpy
(
&
save_restart
,
&
Warn_restart
,
sizeof
(
save_restart
));
if
(
sigsetjmp
(
Warn_restart
,
1
)
!=
0
)
{
memcpy
(
&
Warn_restart
,
&
save_restart
,
sizeof
(
Warn_restart
));
plperl_restart_in_progress
=
1
;
if
(
--
plperl_call_level
==
0
)
plperl_restart_in_progress
=
0
;
siglongjmp
(
Warn_restart
,
1
);
}
/************************************************************
/************************************************************
* Call the Perl function
* Call the Perl function
************************************************************/
************************************************************/
...
@@ -490,14 +471,6 @@ plperl_func_handler(PG_FUNCTION_ARGS)
...
@@ -490,14 +471,6 @@ plperl_func_handler(PG_FUNCTION_ARGS)
SvREFCNT_dec
(
perlret
);
SvREFCNT_dec
(
perlret
);
memcpy
(
&
Warn_restart
,
&
save_restart
,
sizeof
(
Warn_restart
));
if
(
plperl_restart_in_progress
)
{
if
(
--
plperl_call_level
==
0
)
plperl_restart_in_progress
=
0
;
siglongjmp
(
Warn_restart
,
1
);
}
return
retval
;
return
retval
;
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment