Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit193a97c

Browse files
committed
Fix plperl's elog() function to convert elog(ERROR) into Perl croak(),
rather than longjmp'ing clear out of Perl and thereby leaving Perl ina broken state. Also some minor prettification of error messages.Still need to do something with spi_exec_query() error handling.
1 parentd5013ab commit193a97c

File tree

2 files changed

+74
-16
lines changed

2 files changed

+74
-16
lines changed

‎src/pl/plperl/SPI.xs

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,40 @@
1010
#include"spi_internal.h"
1111

1212

13+
/*
14+
* Implementation of plperl's elog() function
15+
*
16+
* If the error level is less than ERROR, we'll just emit the message and
17+
* return. When it is ERROR, elog() will longjmp, which we catch and
18+
* turn into a Perl croak(). Note we are assuming that elog() can't have
19+
* any internal failures that are so bad as to require a transaction abort.
20+
*
21+
* This is out-of-line to suppress "might be clobbered by longjmp" warnings.
22+
*/
23+
staticvoid
24+
do_spi_elog(intlevel,char*message)
25+
{
26+
MemoryContextoldcontext=CurrentMemoryContext;
27+
28+
PG_TRY();
29+
{
30+
elog(level,"%s",message);
31+
}
32+
PG_CATCH();
33+
{
34+
ErrorData*edata;
35+
36+
/* Must reset elog.c's state */
37+
MemoryContextSwitchTo(oldcontext);
38+
edata=CopyErrorData();
39+
FlushErrorState();
40+
41+
/* Punt the error to Perl */
42+
croak("%s",edata->message);
43+
}
44+
PG_END_TRY();
45+
}
46+
1347

1448
MODULE=SPIPREFIX=spi_
1549

@@ -21,8 +55,11 @@ spi_elog(level, message)
2155
intlevel
2256
char*message
2357
CODE:
24-
elog(level,message);
25-
58+
if (level>ERROR)/* no PANIC allowed thanks */
59+
level=ERROR;
60+
if (level<DEBUG5)
61+
level=DEBUG5;
62+
do_spi_elog(level,message);
2663

2764
int
2865
spi_DEBUG()
@@ -47,11 +84,13 @@ spi_spi_exec_query(query, ...)
4784
char*query;
4885
PREINIT:
4986
HV*ret_hash;
50-
intlimit=0;
87+
intlimit=0;
5188
CODE:
52-
if (items>2)Perl_croak(aTHX_"Usage: spi_exec_query(query, limit) or spi_exec_query(query)");
53-
if (items==2)limit=SvIV(ST(1));
54-
ret_hash=plperl_spi_exec(query,limit);
55-
RETVAL=newRV_noinc((SV*)ret_hash);
89+
if (items>2)
90+
croak("Usage: spi_exec_query(query, limit) or spi_exec_query(query)");
91+
if (items==2)
92+
limit=SvIV(ST(1));
93+
ret_hash=plperl_spi_exec(query,limit);
94+
RETVAL=newRV_noinc((SV*)ret_hash);
5695
OUTPUT:
5796
RETVAL

‎src/pl/plperl/plperl.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@
3333
* ENHANCEMENTS, OR MODIFICATIONS.
3434
*
3535
* IDENTIFICATION
36-
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.58 2004/11/18 21:35:42 tgl Exp $
36+
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.59 2004/11/20 19:07:40 tgl Exp $
3737
*
3838
**********************************************************************/
3939

4040
#include"postgres.h"
4141

4242
/* system stuff */
43+
#include<ctype.h>
4344
#include<fcntl.h>
4445
#include<unistd.h>
4546

@@ -281,6 +282,21 @@ plperl_safe_init(void)
281282
}
282283

283284

285+
/*
286+
* Perl likes to put a newline after its error messages; clean up such
287+
*/
288+
staticchar*
289+
strip_trailing_ws(constchar*msg)
290+
{
291+
char*res=pstrdup(msg);
292+
intlen=strlen(res);
293+
294+
while (len>0&&isspace((unsignedchar)res[len-1]))
295+
res[--len]='\0';
296+
returnres;
297+
}
298+
299+
284300
staticHV*
285301
plperl_hash_from_tuple(HeapTupletuple,TupleDesctupdesc)
286302
{
@@ -496,7 +512,7 @@ plperl_get_elem(HV *hash, char *key)
496512
{
497513
SV**svp=hv_fetch(hash,key,strlen(key), FALSE);
498514
if (!svp)
499-
elog(ERROR,"plperl: key'%s' not found",key);
515+
elog(ERROR,"plperl: key\"%s\" not found",key);
500516
returnSvTYPE(*svp)==SVt_NULL ?NULL :SvPV(*svp,PL_na);
501517
}
502518

@@ -533,7 +549,7 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup, Oid fn_oid)
533549
plkeys=plperl_get_keys(hvNew);
534550
natts=av_len(plkeys)+1;
535551
if (natts!=tupdesc->natts)
536-
elog(ERROR,"plperl: $_TD->{new} has an incorrect number of keys.");
552+
elog(ERROR,"plperl: $_TD->{new} has an incorrect number of keys");
537553

538554
modattrs=palloc0(natts*sizeof(int));
539555
modvalues=palloc0(natts*sizeof(Datum));
@@ -550,7 +566,7 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup, Oid fn_oid)
550566
attn=modattrs[i]=SPI_fnumber(tupdesc,platt);
551567

552568
if (attn==SPI_ERROR_NOATTRIBUTE)
553-
elog(ERROR,"plperl: invalid attribute`%s' in tuple.",platt);
569+
elog(ERROR,"plperl: invalid attribute\"%s\" in tuple",platt);
554570
atti=attn-1;
555571

556572
plval=plperl_get_elem(hvNew,platt);
@@ -581,7 +597,7 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup, Oid fn_oid)
581597
pfree(modvalues);
582598
pfree(modnulls);
583599
if (rtup==NULL)
584-
elog(ERROR,"plperl: SPI_modifytuple failed -- error:%d",SPI_result);
600+
elog(ERROR,"plperl: SPI_modifytuple failed -- error: %d",SPI_result);
585601

586602
returnrtup;
587603
}
@@ -690,7 +706,8 @@ plperl_create_sub(char *s, bool trusted)
690706
PUTBACK;
691707
FREETMPS;
692708
LEAVE;
693-
elog(ERROR,"creation of function failed: %s",SvPV(ERRSV,PL_na));
709+
elog(ERROR,"creation of function failed: %s",
710+
strip_trailing_ws(SvPV(ERRSV,PL_na)));
694711
}
695712

696713
/*
@@ -816,7 +833,8 @@ plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
816833
PUTBACK;
817834
FREETMPS;
818835
LEAVE;
819-
elog(ERROR,"error from function: %s",SvPV(ERRSV,PL_na));
836+
elog(ERROR,"error from function: %s",
837+
strip_trailing_ws(SvPV(ERRSV,PL_na)));
820838
}
821839

822840
retval=newSVsv(POPs);
@@ -860,7 +878,7 @@ plperl_call_perl_trigger_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo, S
860878
PUTBACK;
861879
FREETMPS;
862880
LEAVE;
863-
elog(ERROR,"plperl:didn't get a return item from function");
881+
elog(ERROR,"didn't get a return item from trigger function");
864882
}
865883

866884
if (SvTRUE(ERRSV))
@@ -869,7 +887,8 @@ plperl_call_perl_trigger_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo, S
869887
PUTBACK;
870888
FREETMPS;
871889
LEAVE;
872-
elog(ERROR,"plperl: error from function: %s",SvPV(ERRSV,PL_na));
890+
elog(ERROR,"error from trigger function: %s",
891+
strip_trailing_ws(SvPV(ERRSV,PL_na)));
873892
}
874893

875894
retval=newSVsv(POPs);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp