@ -4510,39 +4510,40 @@ ExecEvalJsonConstructor(ExprState *state, ExprEvalStep *op,
ExprContext * econtext )
{
Datum res ;
JsonConstructorExpr * ctor = op - > d . json_constructor . constructor ;
JsonConstructorExprState * jcstate = op - > d . json_constructor . jcstate ;
JsonConstructorExpr * ctor = jcstate - > constructor ;
bool is_jsonb = ctor - > returning - > format - > format_type = = JS_FORMAT_JSONB ;
bool isnull = false ;
if ( ctor - > type = = JSCTOR_JSON_ARRAY )
res = ( is_jsonb ?
jsonb_build_array_worker :
json_build_array_worker ) ( op - > d . json_constructor . nargs ,
op - > d . json_constructor . arg_values ,
op - > d . json_constructor . arg_nulls ,
op - > d . json_constructor . arg_types ,
op - > d . json_constructor . constru ctor- > absent_on_null ) ;
json_build_array_worker ) ( jcstate - > nargs ,
jcstate - > arg_values ,
jcstate - > arg_nulls ,
jcstate - > arg_types ,
ctor - > absent_on_null ) ;
else if ( ctor - > type = = JSCTOR_JSON_OBJECT )
res = ( is_jsonb ?
jsonb_build_object_worker :
json_build_object_worker ) ( op - > d . json_constructor . nargs ,
op - > d . json_constructor . arg_values ,
op - > d . json_constructor . arg_nulls ,
op - > d . json_constructor . arg_types ,
op - > d . json_constructor . constru ctor- > absent_on_null ,
op - > d . json_constructor . constru ctor- > unique ) ;
json_build_object_worker ) ( jcstate - > nargs ,
jcstate - > arg_values ,
jcstate - > arg_nulls ,
jcstate - > arg_types ,
ctor - > absent_on_null ,
ctor - > unique ) ;
else if ( ctor - > type = = JSCTOR_JSON_SCALAR )
{
if ( op - > d . json_constructor . arg_nulls [ 0 ] )
if ( jcstate - > arg_nulls [ 0 ] )
{
res = ( Datum ) 0 ;
isnull = true ;
}
else
{
Datum value = op - > d . json_constructor . arg_values [ 0 ] ;
int category = op - > d . json_constructor . arg_type_cache [ 0 ] . category ;
Oid outfuncid = op - > d . json_constructor . arg_type_cache [ 0 ] . outfuncid ;
Datum value = jcstate - > arg_values [ 0 ] ;
int category = jcstate - > arg_type_cache [ 0 ] . category ;
Oid outfuncid = jcstate - > arg_type_cache [ 0 ] . outfuncid ;
if ( is_jsonb )
res = to_jsonb_worker ( value , category , outfuncid ) ;
@ -4552,14 +4553,14 @@ ExecEvalJsonConstructor(ExprState *state, ExprEvalStep *op,
}
else if ( ctor - > type = = JSCTOR_JSON_PARSE )
{
if ( op - > d . json_constructor . arg_nulls [ 0 ] )
if ( jcstate - > arg_nulls [ 0 ] )
{
res = ( Datum ) 0 ;
isnull = true ;
}
else
{
Datum value = op - > d . json_constructor . arg_values [ 0 ] ;
Datum value = jcstate - > arg_values [ 0 ] ;
text * js = DatumGetTextP ( value ) ;
if ( is_jsonb )
@ -4627,14 +4628,17 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
Datum res , bool * isNull , void * p , bool * error )
{
ExprState * estate = p ;
JsonExprState * jsestate ;
if ( estate ) /* coerce using specified expression */
return ExecEvalExpr ( estate , econtext , isNull ) ;
if ( op - > d . jsonexpr . jsexpr - > op ! = JSON_EXISTS_OP )
jsestate = op - > d . jsonexpr . jsestate ;
if ( jsestate - > jsexpr - > op ! = JSON_EXISTS_OP )
{
JsonCoercion * coercion = op - > d . jsonexpr . jsexpr - > result_coercion ;
JsonExpr * jexpr = op - > d . jsonexpr . jsexpr ;
JsonCoercion * coercion = jsestate - > jsexpr - > result_coercion ;
JsonExpr * jexpr = jsestate - > jsexpr ;
Jsonb * jb = * isNull ? NULL : DatumGetJsonbP ( res ) ;
if ( ( coercion & & coercion - > via_io ) | |
@ -4644,25 +4648,25 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
/* strip quotes and call typinput function */
char * str = * isNull ? NULL : JsonbUnquote ( jb ) ;
return InputFunctionCall ( & op - > d . jsonexpr . input . func , str ,
op - > d . jsonexpr . input . typioparam ,
return InputFunctionCall ( & jsestate - > input . func , str ,
jsestate - > input . typioparam ,
jexpr - > returning - > typmod ) ;
}
else if ( coercion & & coercion - > via_populate )
return json_populate_type ( res , JSONBOID ,
jexpr - > returning - > typid ,
jexpr - > returning - > typmod ,
& op - > d . jsonexpr . cache ,
& jsestate - > cache ,
econtext - > ecxt_per_query_memory ,
isNull ) ;
}
if ( op - > d . jsonexpr . result_expr )
if ( jsestate - > result_expr )
{
op - > d . jsonexpr . res_expr - > value = res ;
op - > d . jsonexpr . res_expr - > isnull = * isNull ;
jsestate - > res_expr - > value = res ;
jsestate - > res_expr - > isnull = * isNull ;
res = ExecEvalExpr ( op - > d . jsonexpr . result_expr , econtext , isNull ) ;
res = ExecEvalExpr ( jsestate - > result_expr , econtext , isNull ) ;
}
return res ;
@ -4895,7 +4899,8 @@ ExecEvalJsonExpr(ExprEvalStep *op, ExprContext *econtext,
{
ExecEvalJsonExprContext * cxt = pcxt ;
JsonPath * path = cxt - > path ;
JsonExpr * jexpr = op - > d . jsonexpr . jsexpr ;
JsonExprState * jsestate = op - > d . jsonexpr . jsestate ;
JsonExpr * jexpr = jsestate - > jsexpr ;
ExprState * estate = NULL ;
bool empty = false ;
Datum res = ( Datum ) 0 ;
@ -4904,7 +4909,7 @@ ExecEvalJsonExpr(ExprEvalStep *op, ExprContext *econtext,
{
case JSON_QUERY_OP :
res = JsonPathQuery ( item , path , jexpr - > wrapper , & empty , error ,
op - > d . jsonexpr . args ) ;
jsestate - > args ) ;
if ( error & & * error )
{
* resnull = true ;
@ -4917,7 +4922,7 @@ ExecEvalJsonExpr(ExprEvalStep *op, ExprContext *econtext,
{
struct JsonCoercionState * jcstate ;
JsonbValue * jbv = JsonPathValue ( item , path , & empty , error ,
op - > d . jsonexpr . args ) ;
jsestate - > args ) ;
if ( error & & * error )
return ( Datum ) 0 ;
@ -4940,8 +4945,8 @@ ExecEvalJsonExpr(ExprEvalStep *op, ExprContext *econtext,
/* Use coercion from SQL/JSON item type to the output type */
res = ExecPrepareJsonItemCoercion ( jbv ,
op - > d . jsonexpr . jsexpr - > returning ,
& op - > d . jsonexpr . coercions ,
jsestate - > jsexpr - > returning ,
& jsestate - > coercions ,
& jcstate ) ;
if ( jcstate - > coercion & &
@ -4973,27 +4978,27 @@ ExecEvalJsonExpr(ExprEvalStep *op, ExprContext *econtext,
/* coerce using specific expression */
estate = jcstate - > estate ;
op - > d . jsonexpr . coercion_expr - > value = res ;
op - > d . jsonexpr . coercion_expr - > isnull = * resnull ;
jsestate - > coercion_expr - > value = res ;
jsestate - > coercion_expr - > isnull = * resnull ;
break ;
}
case JSON_EXISTS_OP :
{
bool exists = JsonPathExists ( item , path ,
op - > d . jsonexpr . args ,
jsestate - > args ,
error ) ;
* resnull = error & & * error ;
res = BoolGetDatum ( exists ) ;
if ( ! op - > d . jsonexpr . result_expr )
if ( ! jsestate - > result_expr )
return res ;
/* coerce using result expression */
estate = op - > d . jsonexpr . result_expr ;
op - > d . jsonexpr . res_expr - > value = res ;
op - > d . jsonexpr . res_expr - > isnull = * resnull ;
estate = jsestate - > result_expr ;
jsestate - > res_expr - > value = res ;
jsestate - > res_expr - > isnull = * resnull ;
break ;
}
@ -5029,11 +5034,11 @@ ExecEvalJsonExpr(ExprEvalStep *op, ExprContext *econtext,
* Execute DEFAULT expression as a coercion expression , because
* its result is already coerced to the target type .
*/
estate = op - > d . jsonexpr . default_on_empty ;
estate = jsestate - > default_on_empty ;
else
/* Execute ON EMPTY behavior */
res = ExecEvalJsonBehavior ( econtext , jexpr - > on_empty ,
op - > d . jsonexpr . default_on_empty ,
jsestate - > default_on_empty ,
resnull ) ;
}
@ -5066,7 +5071,8 @@ void
ExecEvalJson ( ExprState * state , ExprEvalStep * op , ExprContext * econtext )
{
ExecEvalJsonExprContext cxt ;
JsonExpr * jexpr = op - > d . jsonexpr . jsexpr ;
JsonExprState * jsestate = op - > d . jsonexpr . jsestate ;
JsonExpr * jexpr = jsestate - > jsexpr ;
Datum item ;
Datum res = ( Datum ) 0 ;
JsonPath * path ;
@ -5078,7 +5084,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
* op - > resnull = true ; /* until we get a result */
* op - > resvalue = ( Datum ) 0 ;
if ( op - > d . jsonexpr . formatted_expr - > isnull | | op - > d . jsonexpr . pathspec - > isnull )
if ( jsestate - > formatted_expr - > isnull | | jsestate - > pathspec - > isnull )
{
/* execute domain checks for NULLs */
( void ) ExecEvalJsonExprCoercion ( op , econtext , res , op - > resnull ,
@ -5088,11 +5094,11 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
return ;
}
item = op - > d . jsonexpr . formatted_expr - > value ;
path = DatumGetJsonPathP ( op - > d . jsonexpr . pathspec - > value ) ;
item = jsestate - > formatted_expr - > value ;
path = DatumGetJsonPathP ( jsestate - > pathspec - > value ) ;
/* reset JSON path variable contexts */
foreach ( lc , op - > d . jsonexpr . args )
foreach ( lc , jsestate - > args )
{
JsonPathVariableEvalContext * var = lfirst ( lc ) ;
@ -5100,7 +5106,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
var - > evaluated = false ;
}
needSubtrans = ExecEvalJsonNeedsSubTransaction ( jexpr , & op - > d . jsonexpr . coercions ) ;
needSubtrans = ExecEvalJsonNeedsSubTransaction ( jexpr , & jsestate - > coercions ) ;
cxt . path = path ;
cxt . error = throwErrors ? NULL : & error ;
@ -5115,7 +5121,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
{
/* Execute ON ERROR behavior */
res = ExecEvalJsonBehavior ( econtext , jexpr - > on_error ,
op - > d . jsonexpr . default_on_error ,
jsestate - > default_on_error ,
op - > resnull ) ;
/* result is already coerced in DEFAULT behavior case */