mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
Modify all callers of datatype input and receive functions so that if these
functions are not strict, they will be called (passing a NULL first parameter) during any attempt to input a NULL value of their datatype. Currently, all our input functions are strict and so this commit does not change any behavior. However, this will make it possible to build domain input functions that centralize checking of domain constraints, thereby closing numerous holes in our domain support, as per previous discussion. While at it, I took the opportunity to introduce convenience functions InputFunctionCall, OutputFunctionCall, etc to use in code that calls I/O functions. This eliminates a lot of grotty-looking casts, but the main motivation is to make it easier to grep for these places if we ever need to touch them again.
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
/**********************************************************************
|
||||
* plperl.c - perl as a procedural language for PostgreSQL
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.107 2006/03/19 22:22:56 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.108 2006/04/04 19:35:37 tgl Exp $
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
@ -585,31 +585,35 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup)
|
||||
while ((val = hv_iternextsv(hvNew, &key, &klen)))
|
||||
{
|
||||
int attn = SPI_fnumber(tupdesc, key);
|
||||
Oid typinput;
|
||||
Oid typioparam;
|
||||
int32 atttypmod;
|
||||
FmgrInfo finfo;
|
||||
|
||||
if (attn <= 0 || tupdesc->attrs[attn - 1]->attisdropped)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||
errmsg("Perl hash contains nonexistent column \"%s\"",
|
||||
key)));
|
||||
/* XXX would be better to cache these lookups */
|
||||
getTypeInputInfo(tupdesc->attrs[attn - 1]->atttypid,
|
||||
&typinput, &typioparam);
|
||||
fmgr_info(typinput, &finfo);
|
||||
atttypmod = tupdesc->attrs[attn - 1]->atttypmod;
|
||||
if (SvOK(val) && SvTYPE(val) != SVt_NULL)
|
||||
{
|
||||
Oid typinput;
|
||||
Oid typioparam;
|
||||
FmgrInfo finfo;
|
||||
|
||||
/* XXX would be better to cache these lookups */
|
||||
getTypeInputInfo(tupdesc->attrs[attn - 1]->atttypid,
|
||||
&typinput, &typioparam);
|
||||
fmgr_info(typinput, &finfo);
|
||||
modvalues[slotsused] = FunctionCall3(&finfo,
|
||||
CStringGetDatum(SvPV(val, PL_na)),
|
||||
ObjectIdGetDatum(typioparam),
|
||||
Int32GetDatum(tupdesc->attrs[attn - 1]->atttypmod));
|
||||
modvalues[slotsused] = InputFunctionCall(&finfo,
|
||||
SvPV(val, PL_na),
|
||||
typioparam,
|
||||
atttypmod);
|
||||
modnulls[slotsused] = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
modvalues[slotsused] = (Datum) 0;
|
||||
modvalues[slotsused] = InputFunctionCall(&finfo,
|
||||
NULL,
|
||||
typioparam,
|
||||
atttypmod);
|
||||
modnulls[slotsused] = 'n';
|
||||
}
|
||||
modattrs[slotsused] = attn;
|
||||
@ -897,8 +901,8 @@ plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
tmp = DatumGetCString(FunctionCall1(&(desc->arg_out_func[i]),
|
||||
fcinfo->arg[i]));
|
||||
tmp = OutputFunctionCall(&(desc->arg_out_func[i]),
|
||||
fcinfo->arg[i]);
|
||||
sv = newSVpv(tmp, 0);
|
||||
#if PERL_BCDVERSION >= 0x5006000L
|
||||
if (GetDatabaseEncoding() == PG_UTF8)
|
||||
@ -1091,8 +1095,9 @@ plperl_func_handler(PG_FUNCTION_ARGS)
|
||||
/* Return NULL if Perl code returned undef */
|
||||
if (rsi && IsA(rsi, ReturnSetInfo))
|
||||
rsi->isDone = ExprEndResult;
|
||||
retval = InputFunctionCall(&prodesc->result_in_func, NULL,
|
||||
prodesc->result_typioparam, -1);
|
||||
fcinfo->isnull = true;
|
||||
retval = (Datum) 0;
|
||||
}
|
||||
else if (prodesc->fn_retistuple)
|
||||
{
|
||||
@ -1138,10 +1143,8 @@ plperl_func_handler(PG_FUNCTION_ARGS)
|
||||
|
||||
val = SvPV(perlret, PL_na);
|
||||
|
||||
retval = FunctionCall3(&prodesc->result_in_func,
|
||||
CStringGetDatum(val),
|
||||
ObjectIdGetDatum(prodesc->result_typioparam),
|
||||
Int32GetDatum(-1));
|
||||
retval = InputFunctionCall(&prodesc->result_in_func, val,
|
||||
prodesc->result_typioparam, -1);
|
||||
}
|
||||
|
||||
if (array_ret == NULL)
|
||||
@ -1534,7 +1537,7 @@ plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc)
|
||||
getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
|
||||
&typoutput, &typisvarlena);
|
||||
|
||||
outputstr = DatumGetCString(OidFunctionCall1(typoutput, attr));
|
||||
outputstr = OidOutputFunctionCall(typoutput, attr);
|
||||
|
||||
sv = newSVpv(outputstr, 0);
|
||||
#if PERL_BCDVERSION >= 0x5006000L
|
||||
@ -1750,19 +1753,23 @@ plperl_return_next(SV *sv)
|
||||
}
|
||||
else
|
||||
{
|
||||
Datum ret = (Datum) 0;
|
||||
bool isNull = true;
|
||||
Datum ret;
|
||||
bool isNull;
|
||||
|
||||
if (SvOK(sv) && SvTYPE(sv) != SVt_NULL)
|
||||
{
|
||||
char *val = SvPV(sv, PL_na);
|
||||
|
||||
ret = FunctionCall3(&prodesc->result_in_func,
|
||||
PointerGetDatum(val),
|
||||
ObjectIdGetDatum(prodesc->result_typioparam),
|
||||
Int32GetDatum(-1));
|
||||
ret = InputFunctionCall(&prodesc->result_in_func, val,
|
||||
prodesc->result_typioparam, -1);
|
||||
isNull = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = InputFunctionCall(&prodesc->result_in_func, NULL,
|
||||
prodesc->result_typioparam, -1);
|
||||
isNull = true;
|
||||
}
|
||||
|
||||
tuple = heap_form_tuple(current_call_data->ret_tdesc, &ret, &isNull);
|
||||
}
|
||||
@ -2118,9 +2125,9 @@ plperl_spi_exec_prepared(char* query, HV * attr, int argc, SV ** argv)
|
||||
/************************************************************
|
||||
* Set up arguments
|
||||
************************************************************/
|
||||
if ( argc > 0)
|
||||
if (argc > 0)
|
||||
{
|
||||
nulls = (char *)palloc( argc);
|
||||
nulls = (char *) palloc(argc);
|
||||
argvalues = (Datum *) palloc(argc * sizeof(Datum));
|
||||
}
|
||||
else
|
||||
@ -2129,21 +2136,22 @@ plperl_spi_exec_prepared(char* query, HV * attr, int argc, SV ** argv)
|
||||
argvalues = NULL;
|
||||
}
|
||||
|
||||
for ( i = 0; i < argc; i++)
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if ( SvTYPE( argv[i]) != SVt_NULL)
|
||||
if (SvTYPE(argv[i]) != SVt_NULL)
|
||||
{
|
||||
argvalues[i] =
|
||||
FunctionCall3( &qdesc->arginfuncs[i],
|
||||
CStringGetDatum( SvPV( argv[i], PL_na)),
|
||||
ObjectIdGetDatum( qdesc->argtypioparams[i]),
|
||||
Int32GetDatum(-1)
|
||||
);
|
||||
argvalues[i] = InputFunctionCall(&qdesc->arginfuncs[i],
|
||||
SvPV(argv[i], PL_na),
|
||||
qdesc->argtypioparams[i],
|
||||
-1);
|
||||
nulls[i] = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
argvalues[i] = (Datum) 0;
|
||||
argvalues[i] = InputFunctionCall(&qdesc->arginfuncs[i],
|
||||
NULL,
|
||||
qdesc->argtypioparams[i],
|
||||
-1);
|
||||
nulls[i] = 'n';
|
||||
}
|
||||
}
|
||||
@ -2247,9 +2255,9 @@ plperl_spi_query_prepared(char* query, int argc, SV ** argv)
|
||||
/************************************************************
|
||||
* Set up arguments
|
||||
************************************************************/
|
||||
if ( argc > 0)
|
||||
if (argc > 0)
|
||||
{
|
||||
nulls = (char *)palloc( argc);
|
||||
nulls = (char *) palloc(argc);
|
||||
argvalues = (Datum *) palloc(argc * sizeof(Datum));
|
||||
}
|
||||
else
|
||||
@ -2258,21 +2266,22 @@ plperl_spi_query_prepared(char* query, int argc, SV ** argv)
|
||||
argvalues = NULL;
|
||||
}
|
||||
|
||||
for ( i = 0; i < argc; i++)
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if ( SvTYPE( argv[i]) != SVt_NULL)
|
||||
if (SvTYPE(argv[i]) != SVt_NULL)
|
||||
{
|
||||
argvalues[i] =
|
||||
FunctionCall3( &qdesc->arginfuncs[i],
|
||||
CStringGetDatum( SvPV( argv[i], PL_na)),
|
||||
ObjectIdGetDatum( qdesc->argtypioparams[i]),
|
||||
Int32GetDatum(-1)
|
||||
);
|
||||
argvalues[i] = InputFunctionCall(&qdesc->arginfuncs[i],
|
||||
SvPV(argv[i], PL_na),
|
||||
qdesc->argtypioparams[i],
|
||||
-1);
|
||||
nulls[i] = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
argvalues[i] = (Datum) 0;
|
||||
argvalues[i] = InputFunctionCall(&qdesc->arginfuncs[i],
|
||||
NULL,
|
||||
qdesc->argtypioparams[i],
|
||||
-1);
|
||||
nulls[i] = 'n';
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user