@ -387,7 +387,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
& & CASE_EEOP_ALTERNATIVE_SUBPLAN ,
& & CASE_EEOP_AGG_STRICT_DESERIALIZE ,
& & CASE_EEOP_AGG_DESERIALIZE ,
& & CASE_EEOP_AGG_STRICT_INPUT_CHECK ,
& & CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS ,
& & CASE_EEOP_AGG_STRICT_INPUT_CHECK_NULLS ,
& & CASE_EEOP_AGG_INIT_TRANS ,
& & CASE_EEOP_AGG_STRICT_TRANS_CHECK ,
& & CASE_EEOP_AGG_PLAIN_TRANS_BYVAL ,
@ -631,14 +632,14 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_CASE ( EEOP_FUNCEXPR_STRICT )
{
FunctionCallInfo fcinfo = op - > d . func . fcinfo_data ;
bool * argnull = fcinfo - > argnull ;
NullableDatum * args = fcinfo - > args ;
int argno ;
Datum d ;
/* strict function, so check for NULL args */
for ( argno = 0 ; argno < op - > d . func . nargs ; argno + + )
{
if ( argnull [ argno ] )
if ( args [ argno ] . isnull )
{
* op - > resnull = true ;
goto strictfail ;
@ -1054,8 +1055,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
FunctionCallInfo fcinfo_out ;
fcinfo_out = op - > d . iocoerce . fcinfo_data_out ;
fcinfo_out - > arg [ 0 ] = * op - > resvalue ;
fcinfo_out - > argnull [ 0 ] = false ;
fcinfo_out - > args [ 0 ] . value = * op - > resvalue ;
fcinfo_out - > args [ 0 ] . isnull = false ;
fcinfo_out - > isnull = false ;
str = DatumGetCString ( FunctionCallInvoke ( fcinfo_out ) ) ;
@ -1071,8 +1072,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
Datum d ;
fcinfo_in = op - > d . iocoerce . fcinfo_data_in ;
fcinfo_in - > arg [ 0 ] = PointerGetDatum ( str ) ;
fcinfo_in - > argnull [ 0 ] = * op - > resnull ;
fcinfo_in - > args [ 0 ] . value = PointerGetDatum ( str ) ;
fcinfo_in - > args [ 0 ] . isnull = * op - > resnull ;
/* second and third arguments are already set up */
fcinfo_in - > isnull = false ;
@ -1099,23 +1100,23 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
{
/*
* IS DISTINCT FROM must evaluate arguments ( already done into
* fcinfo - > arg / argnull ) to determine whether they are NULL ; if
* either is NULL then the result is determined . If neither is
* NULL , then proceed to evaluate the comparison function , which
* is just the type ' s standard equality operator . We need not
* care whether that function is strict . Because the handling of
* nulls is different , we can ' t just reuse EEOP_FUNCEXPR .
* fcinfo - > args ) to determine whether they are NULL ; if either is
* NULL then the result is determined . If neither is NULL , then
* proceed to evaluate the comparison function , which is just the
* type ' s standard equality operator . We need not care whether
* that function is strict . Because the handling of nulls is
* different , we can ' t just reuse EEOP_FUNCEXPR .
*/
FunctionCallInfo fcinfo = op - > d . func . fcinfo_data ;
/* check function arguments for NULLness */
if ( fcinfo - > argnull [ 0 ] & & fcinfo - > argnull [ 1 ] )
if ( fcinfo - > args [ 0 ] . isnull & & fcinfo - > args [ 1 ] . isnull )
{
/* Both NULL? Then is not distinct... */
* op - > resvalue = BoolGetDatum ( false ) ;
* op - > resnull = false ;
}
else if ( fcinfo - > argnull [ 0 ] | | fcinfo - > argnull [ 1 ] )
else if ( fcinfo - > args [ 0 ] . isnull | | fcinfo - > args [ 1 ] . isnull )
{
/* Only one is NULL? Then is distinct... */
* op - > resvalue = BoolGetDatum ( true ) ;
@ -1141,12 +1142,12 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
{
FunctionCallInfo fcinfo = op - > d . func . fcinfo_data ;
if ( fcinfo - > argnull [ 0 ] & & fcinfo - > argnull [ 1 ] )
if ( fcinfo - > args [ 0 ] . isnull & & fcinfo - > args [ 1 ] . isnull )
{
* op - > resvalue = BoolGetDatum ( true ) ;
* op - > resnull = false ;
}
else if ( fcinfo - > argnull [ 0 ] | | fcinfo - > argnull [ 1 ] )
else if ( fcinfo - > args [ 0 ] . isnull | | fcinfo - > args [ 1 ] . isnull )
{
* op - > resvalue = BoolGetDatum ( false ) ;
* op - > resnull = false ;
@ -1167,12 +1168,12 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_CASE ( EEOP_NULLIF )
{
/*
* The arguments are already evaluated into fcinfo - > arg / argnull .
* The arguments are already evaluated into fcinfo - > args .
*/
FunctionCallInfo fcinfo = op - > d . func . fcinfo_data ;
/* if either argument is NULL they can't be equal */
if ( ! fcinfo - > argnull [ 0 ] & & ! fcinfo - > argnull [ 1 ] )
if ( ! fcinfo - > args [ 0 ] . isnull & & ! fcinfo - > args [ 1 ] . isnull )
{
Datum result ;
@ -1190,8 +1191,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
}
/* Arguments aren't equal, so return the first one */
* op - > resvalue = fcinfo - > arg [ 0 ] ;
* op - > resnull = fcinfo - > argnull [ 0 ] ;
* op - > resvalue = fcinfo - > args [ 0 ] . value ;
* op - > resnull = fcinfo - > args [ 0 ] . isnull ;
EEO_NEXT ( ) ;
}
@ -1257,7 +1258,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
/* force NULL result if strict fn and NULL input */
if ( op - > d . rowcompare_step . finfo - > fn_strict & &
( fcinfo - > argnull [ 0 ] | | fcinfo - > argnull [ 1 ] ) )
( fcinfo - > args [ 0 ] . isnull | | fcinfo - > args [ 1 ] . isnull ) )
{
* op - > resnull = true ;
EEO_JUMP ( op - > d . rowcompare_step . jumpnull ) ;
@ -1496,10 +1497,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
/* evaluate a strict aggregate deserialization function */
EEO_CASE ( EEOP_AGG_STRICT_DESERIALIZE )
{
bool * argnull = op - > d . agg_deserialize . fcinfo_data - > argnull ;
/* Don't call a strict deserialization function with NULL input */
if ( argnull [ 0 ] )
if ( op - > d . agg_deserialize . fcinfo_data - > args [ 0 ] . isnull )
EEO_JUMP ( op - > d . agg_deserialize . jumpnull ) ;
/* fallthrough */
@ -1529,7 +1528,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
* Check that a strict aggregate transition / combination function ' s
* input is not NULL .
*/
EEO_CASE ( EEOP_AGG_STRICT_INPUT_CHECK )
EEO_CASE ( EEOP_AGG_STRICT_INPUT_CHECK_NULLS )
{
int argno ;
bool * nulls = op - > d . agg_strict_input_check . nulls ;
@ -1543,6 +1542,20 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
EEO_NEXT ( ) ;
}
EEO_CASE ( EEOP_AGG_STRICT_INPUT_CHECK_ARGS )
{
int argno ;
NullableDatum * args = op - > d . agg_strict_input_check . args ;
int nargs = op - > d . agg_strict_input_check . nargs ;
for ( argno = 0 ; argno < nargs ; argno + + )
{
if ( args [ argno ] . isnull )
EEO_JUMP ( op - > d . agg_strict_input_check . jumpnull ) ;
}
EEO_NEXT ( ) ;
}
/*
* Initialize an aggregate ' s first value if necessary .
*/
@ -1613,7 +1626,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
Assert ( pertrans - > transtypeByVal ) ;
fcinfo = & pertrans - > transfn_fcinfo ;
fcinfo = pertrans - > transfn_fcinfo ;
/* cf. select_current_set() */
aggstate - > curaggcontext = op - > d . agg_trans . aggcontext ;
@ -1625,8 +1638,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
/* invoke transition function in per-tuple context */
oldContext = MemoryContextSwitchTo ( aggstate - > tmpcontext - > ecxt_per_tuple_memory ) ;
fcinfo - > arg [ 0 ] = pergroup - > transValue ;
fcinfo - > argnull [ 0 ] = pergroup - > transValueIsNull ;
fcinfo - > args [ 0 ] . value = pergroup - > transValue ;
fcinfo - > args [ 0 ] . isnull = pergroup - > transValueIsNull ;
fcinfo - > isnull = false ; /* just in case transfn doesn't set it */
newVal = FunctionCallInvoke ( fcinfo ) ;
@ -1664,7 +1677,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
Assert ( ! pertrans - > transtypeByVal ) ;
fcinfo = & pertrans - > transfn_fcinfo ;
fcinfo = pertrans - > transfn_fcinfo ;
/* cf. select_current_set() */
aggstate - > curaggcontext = op - > d . agg_trans . aggcontext ;
@ -1676,8 +1689,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
/* invoke transition function in per-tuple context */
oldContext = MemoryContextSwitchTo ( aggstate - > tmpcontext - > ecxt_per_tuple_memory ) ;
fcinfo - > arg [ 0 ] = pergroup - > transValue ;
fcinfo - > argnull [ 0 ] = pergroup - > transValueIsNull ;
fcinfo - > args [ 0 ] . value = pergroup - > transValue ;
fcinfo - > args [ 0 ] . isnull = pergroup - > transValueIsNull ;
fcinfo - > isnull = false ; /* just in case transfn doesn't set it */
newVal = FunctionCallInvoke ( fcinfo ) ;
@ -2075,7 +2088,7 @@ ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull)
{
ExprEvalStep * op = & state - > steps [ 0 ] ;
FunctionCallInfo fcinfo ;
bool * argnull ;
NullableDatum * args ;
int argno ;
Datum d ;
@ -2089,12 +2102,12 @@ ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull)
op + + ;
fcinfo = op - > d . func . fcinfo_data ;
argnull = fcinfo - > argnull ;
args = fcinfo - > args ;
/* strict function, so check for NULL args */
for ( argno = 0 ; argno < op - > d . func . nargs ; argno + + )
{
if ( argnull [ argno ] )
if ( args [ argno ] . isnull )
{
* isnull = true ;
return ( Datum ) 0 ;
@ -2220,14 +2233,14 @@ ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op,
FunctionCallInfo fcinfo = op - > d . func . fcinfo_data ;
PgStat_FunctionCallUsage fcusage ;
bool * argnull = fcinfo - > argnull ;
NullableDatum * args = fcinfo - > args ;
int argno ;
Datum d ;
/* strict function, so check for NULL args */
for ( argno = 0 ; argno < op - > d . func . nargs ; argno + + )
{
if ( argnull [ argno ] )
if ( args [ argno ] . isnull )
{
* op - > resnull = true ;
return ;
@ -2317,8 +2330,8 @@ ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
void
ExecEvalSQLValueFunction ( ExprState * state , ExprEvalStep * op )
{
LOCAL_FCINFO ( fcinfo , 0 ) ;
SQLValueFunction * svf = op - > d . sqlvaluefunction . svf ;
FunctionCallInfoData fcinfo ;
* op - > resnull = false ;
@ -2350,24 +2363,24 @@ ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op)
case SVFOP_CURRENT_ROLE :
case SVFOP_CURRENT_USER :
case SVFOP_USER :
InitFunctionCallInfoData ( fcinfo , NULL , 0 , InvalidOid , NULL , NULL ) ;
* op - > resvalue = current_user ( & fcinfo ) ;
* op - > resnull = fcinfo . isnull ;
InitFunctionCallInfoData ( * fcinfo , NULL , 0 , InvalidOid , NULL , NULL ) ;
* op - > resvalue = current_user ( fcinfo ) ;
* op - > resnull = fcinfo - > isnull ;
break ;
case SVFOP_SESSION_USER :
InitFunctionCallInfoData ( fcinfo , NULL , 0 , InvalidOid , NULL , NULL ) ;
* op - > resvalue = session_user ( & fcinfo ) ;
* op - > resnull = fcinfo . isnull ;
InitFunctionCallInfoData ( * fcinfo , NULL , 0 , InvalidOid , NULL , NULL ) ;
* op - > resvalue = session_user ( fcinfo ) ;
* op - > resnull = fcinfo - > isnull ;
break ;
case SVFOP_CURRENT_CATALOG :
InitFunctionCallInfoData ( fcinfo , NULL , 0 , InvalidOid , NULL , NULL ) ;
* op - > resvalue = current_database ( & fcinfo ) ;
* op - > resnull = fcinfo . isnull ;
InitFunctionCallInfoData ( * fcinfo , NULL , 0 , InvalidOid , NULL , NULL ) ;
* op - > resvalue = current_database ( fcinfo ) ;
* op - > resnull = fcinfo - > isnull ;
break ;
case SVFOP_CURRENT_SCHEMA :
InitFunctionCallInfoData ( fcinfo , NULL , 0 , InvalidOid , NULL , NULL ) ;
* op - > resvalue = current_schema ( & fcinfo ) ;
* op - > resnull = fcinfo . isnull ;
InitFunctionCallInfoData ( * fcinfo , NULL , 0 , InvalidOid , NULL , NULL ) ;
* op - > resvalue = current_schema ( fcinfo ) ;
* op - > resnull = fcinfo - > isnull ;
break ;
}
}
@ -2800,8 +2813,8 @@ ExecEvalMinMax(ExprState *state, ExprEvalStep *op)
int off ;
/* set at initialization */
Assert ( fcinfo - > argnull [ 0 ] = = false ) ;
Assert ( fcinfo - > argnull [ 1 ] = = false ) ;
Assert ( fcinfo - > args [ 0 ] . isnull = = false ) ;
Assert ( fcinfo - > args [ 1 ] . isnull = = false ) ;
/* default to null result */
* op - > resnull = true ;
@ -2823,8 +2836,8 @@ ExecEvalMinMax(ExprState *state, ExprEvalStep *op)
int cmpresult ;
/* apply comparison function */
fcinfo - > arg [ 0 ] = * op - > resvalue ;
fcinfo - > arg [ 1 ] = values [ off ] ;
fcinfo - > args [ 0 ] . value = * op - > resvalue ;
fcinfo - > args [ 1 ] . value = values [ off ] ;
fcinfo - > isnull = false ;
cmpresult = DatumGetInt32 ( FunctionCallInvoke ( fcinfo ) ) ;
@ -3324,7 +3337,7 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext
* Evaluate " scalar op ANY/ALL (array) " .
*
* Source array is in our result area , scalar arg is already evaluated into
* fcinfo - > arg [ 0 ] / argnull [ 0 ] .
* fcinfo - > args [ 0 ] .
*
* The operator always yields boolean , and we combine the results across all
* array elements using OR and AND ( for ANY and ALL respectively ) . Of course
@ -3376,7 +3389,7 @@ ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op)
* If the scalar is NULL , and the function is strict , return NULL ; no
* point in iterating the loop .
*/
if ( fcinfo - > argnull [ 0 ] & & strictfunc )
if ( fcinfo - > args [ 0 ] . isnull & & strictfunc )
{
* op - > resnull = true ;
return ;
@ -3416,20 +3429,20 @@ ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op)
/* Get array element, checking for NULL */
if ( bitmap & & ( * bitmap & bitmask ) = = 0 )
{
fcinfo - > arg [ 1 ] = ( Datum ) 0 ;
fcinfo - > argnull [ 1 ] = true ;
fcinfo - > args [ 1 ] . value = ( Datum ) 0 ;
fcinfo - > args [ 1 ] . isnull = true ;
}
else
{
elt = fetch_att ( s , typbyval , typlen ) ;
s = att_addlength_pointer ( s , typlen , s ) ;
s = ( char * ) att_align_nominal ( s , typalign ) ;
fcinfo - > arg [ 1 ] = elt ;
fcinfo - > argnull [ 1 ] = false ;
fcinfo - > args [ 1 ] . value = elt ;
fcinfo - > args [ 1 ] . isnull = false ;
}
/* Call comparison function */
if ( fcinfo - > argnull [ 1 ] & & strictfunc )
if ( fcinfo - > args [ 1 ] . isnull & & strictfunc )
{
fcinfo - > isnull = true ;
thisresult = ( Datum ) 0 ;
@ -4044,7 +4057,7 @@ ExecEvalSysVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
void
ExecAggInitGroup ( AggState * aggstate , AggStatePerTrans pertrans , AggStatePerGroup pergroup )
{
FunctionCallInfo fcinfo = & pertrans - > transfn_fcinfo ;
FunctionCallInfo fcinfo = pertrans - > transfn_fcinfo ;
MemoryContext oldContext ;
/*
@ -4055,7 +4068,7 @@ ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup
*/
oldContext = MemoryContextSwitchTo (
aggstate - > curaggcontext - > ecxt_per_tuple_memory ) ;
pergroup - > transValue = datumCopy ( fcinfo - > arg [ 1 ] ,
pergroup - > transValue = datumCopy ( fcinfo - > args [ 1 ] . value ,
pertrans - > transtypeByVal ,
pertrans - > transtypeLen ) ;
pergroup - > transValueIsNull = false ;