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

Commit04b4092

Browse files
committed
Add code to check that IF/WHILE/EXIT test expressions are boolean,
and try to coerce the values to boolean if not. Per recent discussions.
1 parent55d85f4 commit04b4092

File tree

1 file changed

+74
-110
lines changed

1 file changed

+74
-110
lines changed

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 74 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.92 2003/09/28 23:37:45 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.93 2003/10/01 21:47:42 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -52,7 +52,6 @@
5252
#include"utils/array.h"
5353
#include"utils/builtins.h"
5454
#include"utils/lsyscache.h"
55-
#include"utils/syscache.h"
5655

5756

5857
staticconstchar*constraise_skip_msg="RAISE";
@@ -151,6 +150,9 @@ static void exec_eval_datum(PLpgSQL_execstate * estate,
151150
staticintexec_eval_integer(PLpgSQL_execstate*estate,
152151
PLpgSQL_expr*expr,
153152
bool*isNull);
153+
staticboolexec_eval_boolean(PLpgSQL_execstate*estate,
154+
PLpgSQL_expr*expr,
155+
bool*isNull);
154156
staticDatumexec_eval_expr(PLpgSQL_execstate*estate,
155157
PLpgSQL_expr*expr,
156158
bool*isNull,
@@ -164,6 +166,7 @@ static void exec_move_row(PLpgSQL_execstate * estate,
164166
staticHeapTuplemake_tuple_from_row(PLpgSQL_execstate*estate,
165167
PLpgSQL_row*row,
166168
TupleDesctupdesc);
169+
staticchar*convert_value_to_string(Datumvalue,Oidvaltype);
167170
staticDatumexec_cast_value(Datumvalue,Oidvaltype,
168171
Oidreqtype,
169172
FmgrInfo*reqinput,
@@ -1111,14 +1114,13 @@ exec_stmt_getdiag(PLpgSQL_execstate * estate, PLpgSQL_stmt_getdiag * stmt)
11111114
staticint
11121115
exec_stmt_if(PLpgSQL_execstate*estate,PLpgSQL_stmt_if*stmt)
11131116
{
1114-
Datumvalue;
1115-
Oidvaltype;
1117+
boolvalue;
11161118
boolisnull= false;
11171119

1118-
value=exec_eval_expr(estate,stmt->cond,&isnull,&valtype);
1120+
value=exec_eval_boolean(estate,stmt->cond,&isnull);
11191121
exec_eval_cleanup(estate);
11201122

1121-
if (!isnull&&DatumGetBool(value))
1123+
if (!isnull&&value)
11221124
{
11231125
if (stmt->true_body!=NULL)
11241126
returnexec_stmts(estate,stmt->true_body);
@@ -1183,16 +1185,16 @@ exec_stmt_loop(PLpgSQL_execstate * estate, PLpgSQL_stmt_loop * stmt)
11831185
staticint
11841186
exec_stmt_while(PLpgSQL_execstate*estate,PLpgSQL_stmt_while*stmt)
11851187
{
1186-
Datumvalue;
1187-
Oidvaltype;
1188+
boolvalue;
11881189
boolisnull= false;
11891190
intrc;
11901191

11911192
for (;;)
11921193
{
1193-
value=exec_eval_expr(estate,stmt->cond,&isnull,&valtype);
1194+
value=exec_eval_boolean(estate,stmt->cond,&isnull);
11941195
exec_eval_cleanup(estate);
1195-
if (isnull|| !DatumGetBool(value))
1196+
1197+
if (isnull|| !value)
11961198
break;
11971199

11981200
rc=exec_stmts(estate,stmt->body);
@@ -1540,18 +1542,17 @@ exec_stmt_select(PLpgSQL_execstate * estate, PLpgSQL_stmt_select * stmt)
15401542
staticint
15411543
exec_stmt_exit(PLpgSQL_execstate*estate,PLpgSQL_stmt_exit*stmt)
15421544
{
1543-
Datumvalue;
1544-
Oidvaltype;
1545-
boolisnull= false;
1546-
15471545
/*
15481546
* If the exit has a condition, check that it's true
15491547
*/
15501548
if (stmt->cond!=NULL)
15511549
{
1552-
value=exec_eval_expr(estate,stmt->cond,&isnull,&valtype);
1550+
boolvalue;
1551+
boolisnull= false;
1552+
1553+
value=exec_eval_boolean(estate,stmt->cond,&isnull);
15531554
exec_eval_cleanup(estate);
1554-
if (isnull|| !DatumGetBool(value))
1555+
if (isnull|| !value)
15551556
returnPLPGSQL_RC_OK;
15561557
}
15571558

@@ -1785,9 +1786,6 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt)
17851786
Oidparamtypeid;
17861787
Datumparamvalue;
17871788
boolparamisnull;
1788-
HeapTupletypetup;
1789-
Form_pg_typetypeStruct;
1790-
FmgrInfofinfo_output;
17911789
char*extval;
17921790
intpidx=0;
17931791
charc[2]= {0,0};
@@ -1822,22 +1820,7 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt)
18221820
if (paramisnull)
18231821
extval="<NULL>";
18241822
else
1825-
{
1826-
typetup=SearchSysCache(TYPEOID,
1827-
ObjectIdGetDatum(paramtypeid),
1828-
0,0,0);
1829-
if (!HeapTupleIsValid(typetup))
1830-
elog(ERROR,"cache lookup failed for type %u",
1831-
paramtypeid);
1832-
typeStruct= (Form_pg_type)GETSTRUCT(typetup);
1833-
1834-
fmgr_info(typeStruct->typoutput,&finfo_output);
1835-
extval=DatumGetCString(FunctionCall3(&finfo_output,
1836-
paramvalue,
1837-
ObjectIdGetDatum(typeStruct->typelem),
1838-
Int32GetDatum(-1)));
1839-
ReleaseSysCache(typetup);
1840-
}
1823+
extval=convert_value_to_string(paramvalue,paramtypeid);
18411824
plpgsql_dstring_append(&ds,extval);
18421825
pidx++;
18431826
continue;
@@ -2091,9 +2074,6 @@ exec_stmt_dynexecute(PLpgSQL_execstate * estate,
20912074
boolisnull= false;
20922075
Oidrestype;
20932076
char*querystr;
2094-
HeapTupletypetup;
2095-
Form_pg_typetypeStruct;
2096-
FmgrInfofinfo_output;
20972077
intexec_res;
20982078

20992079
/*
@@ -2106,23 +2086,9 @@ exec_stmt_dynexecute(PLpgSQL_execstate * estate,
21062086
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
21072087
errmsg("cannot EXECUTE a null querystring")));
21082088

2109-
/*
2110-
* Get the C-String representation.
2111-
*/
2112-
typetup=SearchSysCache(TYPEOID,
2113-
ObjectIdGetDatum(restype),
2114-
0,0,0);
2115-
if (!HeapTupleIsValid(typetup))
2116-
elog(ERROR,"cache lookup failed for type %u",restype);
2117-
typeStruct= (Form_pg_type)GETSTRUCT(typetup);
2089+
/* Get the C-String representation */
2090+
querystr=convert_value_to_string(query,restype);
21182091

2119-
fmgr_info(typeStruct->typoutput,&finfo_output);
2120-
querystr=DatumGetCString(FunctionCall3(&finfo_output,
2121-
query,
2122-
ObjectIdGetDatum(typeStruct->typelem),
2123-
Int32GetDatum(-1)));
2124-
2125-
ReleaseSysCache(typetup);
21262092
exec_eval_cleanup(estate);
21272093

21282094
/*
@@ -2211,9 +2177,6 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
22112177
intrc=PLPGSQL_RC_OK;
22122178
inti;
22132179
intn;
2214-
HeapTupletypetup;
2215-
Form_pg_typetypeStruct;
2216-
FmgrInfofinfo_output;
22172180
void*plan;
22182181
Portalportal;
22192182
boolfound= false;
@@ -2238,23 +2201,9 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
22382201
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
22392202
errmsg("cannot EXECUTE a null querystring")));
22402203

2241-
/*
2242-
* Get the C-String representation.
2243-
*/
2244-
typetup=SearchSysCache(TYPEOID,
2245-
ObjectIdGetDatum(restype),
2246-
0,0,0);
2247-
if (!HeapTupleIsValid(typetup))
2248-
elog(ERROR,"cache lookup failed for type %u",restype);
2249-
typeStruct= (Form_pg_type)GETSTRUCT(typetup);
2250-
2251-
fmgr_info(typeStruct->typoutput,&finfo_output);
2252-
querystr=DatumGetCString(FunctionCall3(&finfo_output,
2253-
query,
2254-
ObjectIdGetDatum(typeStruct->typelem),
2255-
Int32GetDatum(-1)));
2204+
/* Get the C-String representation */
2205+
querystr=convert_value_to_string(query,restype);
22562206

2257-
ReleaseSysCache(typetup);
22582207
exec_eval_cleanup(estate);
22592208

22602209
/*
@@ -2428,9 +2377,6 @@ exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt)
24282377
DatumqueryD;
24292378
Oidrestype;
24302379
char*querystr;
2431-
HeapTupletypetup;
2432-
Form_pg_typetypeStruct;
2433-
FmgrInfofinfo_output;
24342380
void*curplan;
24352381

24362382
/* ----------
@@ -2445,24 +2391,9 @@ exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt)
24452391
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
24462392
errmsg("cannot EXECUTE a null querystring")));
24472393

2448-
/* ----------
2449-
* Get the C-String representation.
2450-
* ----------
2451-
*/
2452-
typetup=SearchSysCache(TYPEOID,
2453-
ObjectIdGetDatum(restype),
2454-
0,0,0);
2455-
if (!HeapTupleIsValid(typetup))
2456-
elog(ERROR,"cache lookup failed for type %u",restype);
2457-
typeStruct= (Form_pg_type)GETSTRUCT(typetup);
2458-
2459-
fmgr_info(typeStruct->typoutput,&finfo_output);
2460-
querystr=DatumGetCString(FunctionCall3(&finfo_output,
2461-
queryD,
2462-
ObjectIdGetDatum(typeStruct->typelem),
2463-
Int32GetDatum(-1)));
2464-
2465-
ReleaseSysCache(typetup);
2394+
/* Get the C-String representation */
2395+
querystr=convert_value_to_string(queryD,restype);
2396+
24662397
exec_eval_cleanup(estate);
24672398

24682399
/* ----------
@@ -3131,6 +3062,28 @@ exec_eval_integer(PLpgSQL_execstate * estate,
31313062
returnDatumGetInt32(exprdatum);
31323063
}
31333064

3065+
/* ----------
3066+
* exec_eval_booleanEvaluate an expression, coerce result to bool
3067+
*
3068+
* Note we do not do exec_eval_cleanup here; the caller must do it at
3069+
* some later point.
3070+
* ----------
3071+
*/
3072+
staticbool
3073+
exec_eval_boolean(PLpgSQL_execstate*estate,
3074+
PLpgSQL_expr*expr,
3075+
bool*isNull)
3076+
{
3077+
Datumexprdatum;
3078+
Oidexprtypeid;
3079+
3080+
exprdatum=exec_eval_expr(estate,expr,isNull,&exprtypeid);
3081+
exprdatum=exec_simple_cast_value(exprdatum,exprtypeid,
3082+
BOOLOID,-1,
3083+
isNull);
3084+
returnDatumGetBool(exprdatum);
3085+
}
3086+
31343087
/* ----------
31353088
* exec_eval_exprEvaluate an expression and return
31363089
*the result Datum.
@@ -3560,6 +3513,31 @@ make_tuple_from_row(PLpgSQL_execstate * estate,
35603513
returntuple;
35613514
}
35623515

3516+
/* ----------
3517+
* convert_value_to_stringConvert a non-null Datum to C string
3518+
*
3519+
* Note: callers generally assume that the result is a palloc'd string and
3520+
* should be pfree'd. This is not all that safe an assumption ...
3521+
* ----------
3522+
*/
3523+
staticchar*
3524+
convert_value_to_string(Datumvalue,Oidvaltype)
3525+
{
3526+
OidtypOutput;
3527+
OidtypElem;
3528+
booltypIsVarlena;
3529+
FmgrInfofinfo_output;
3530+
3531+
getTypeOutputInfo(valtype,&typOutput,&typElem,&typIsVarlena);
3532+
3533+
fmgr_info(typOutput,&finfo_output);
3534+
3535+
returnDatumGetCString(FunctionCall3(&finfo_output,
3536+
value,
3537+
ObjectIdGetDatum(typElem),
3538+
Int32GetDatum(-1)));
3539+
}
3540+
35633541
/* ----------
35643542
* exec_cast_valueCast a value if required
35653543
* ----------
@@ -3580,29 +3558,14 @@ exec_cast_value(Datum value, Oid valtype,
35803558
*/
35813559
if (valtype!=reqtype||reqtypmod!=-1)
35823560
{
3583-
HeapTupletypetup;
3584-
Form_pg_typetypeStruct;
3585-
FmgrInfofinfo_output;
35863561
char*extval;
35873562

3588-
typetup=SearchSysCache(TYPEOID,
3589-
ObjectIdGetDatum(valtype),
3590-
0,0,0);
3591-
if (!HeapTupleIsValid(typetup))
3592-
elog(ERROR,"cache lookup failed for type %u",valtype);
3593-
typeStruct= (Form_pg_type)GETSTRUCT(typetup);
3594-
3595-
fmgr_info(typeStruct->typoutput,&finfo_output);
3596-
extval=DatumGetCString(FunctionCall3(&finfo_output,
3597-
value,
3598-
ObjectIdGetDatum(typeStruct->typelem),
3599-
Int32GetDatum(-1)));
3563+
extval=convert_value_to_string(value,valtype);
36003564
value=FunctionCall3(reqinput,
36013565
CStringGetDatum(extval),
36023566
ObjectIdGetDatum(reqtypelem),
36033567
Int32GetDatum(reqtypmod));
36043568
pfree(extval);
3605-
ReleaseSysCache(typetup);
36063569
}
36073570
}
36083571

@@ -3631,6 +3594,7 @@ exec_simple_cast_value(Datum value, Oid valtype,
36313594
FmgrInfofinfo_input;
36323595

36333596
getTypeInputInfo(reqtype,&typInput,&typElem);
3597+
36343598
fmgr_info(typInput,&finfo_input);
36353599

36363600
value=exec_cast_value(value,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp