@@ -122,6 +122,7 @@ static Node *transformIndirection(ParseState *pstate, A_Indirection *ind);
122122static Node * transformTypeCast (ParseState * pstate , TypeCast * tc );
123123static Node * transformCollateClause (ParseState * pstate , CollateClause * c );
124124static Node * transformJsonObjectCtor (ParseState * pstate , JsonObjectCtor * ctor );
125+ static Node * transformJsonArrayCtor (ParseState * pstate , JsonArrayCtor * ctor );
125126static Node * make_row_comparison_op (ParseState * pstate , List * opname ,
126127 List * largs , List * rargs , int location );
127128static Node * make_row_distinct_op (ParseState * pstate , List * opname ,
@@ -374,6 +375,10 @@ transformExprRecurse(ParseState *pstate, Node *expr)
374375 result = transformJsonObjectCtor (pstate , (JsonObjectCtor * ) expr );
375376 break ;
376377
378+ case T_JsonArrayCtor :
379+ result = transformJsonArrayCtor (pstate , (JsonArrayCtor * ) expr );
380+ break ;
381+
377382 default :
378383 /* should not reach here */
379384 elog (ERROR , "unrecognized node type: %d" , (int ) nodeTag (expr ));
@@ -3995,3 +4000,68 @@ transformJsonObjectCtor(ParseState *pstate, JsonObjectCtor *ctor)
39954000
39964001 return coerceJsonFuncExpr (pstate , (Node * ) jsctor , jsctor -> returning , true);
39974002}
4003+
4004+ /*
4005+ * Transform JSON_ARRAY() constructor.
4006+ *
4007+ * JSON_ARRAY() is transformed into json[b]_build_array[_ext]() call
4008+ * depending on the output JSON format. The first argument of
4009+ * json[b]_build_array_ext() is absent_on_null.
4010+ *
4011+ * Then function call result is coerced to the target type.
4012+ */
4013+ static Node *
4014+ transformJsonArrayCtor (ParseState * pstate , JsonArrayCtor * ctor )
4015+ {
4016+ JsonReturning returning ;
4017+ JsonCtorExpr * jsctor ;
4018+ FuncExpr * fexpr ;
4019+ List * args = NIL ;
4020+ Oid funcid ;
4021+ Oid funcrettype ;
4022+
4023+ /* transform element expressions, if any */
4024+ if (ctor -> exprs )
4025+ {
4026+ ListCell * lc ;
4027+
4028+ /* append the first absent_on_null argument */
4029+ args = lappend (args , makeBoolConst (ctor -> absent_on_null , false));
4030+
4031+ /* transform and append element arguments */
4032+ foreach (lc , ctor -> exprs )
4033+ {
4034+ JsonValueExpr * jsval = castNode (JsonValueExpr , lfirst (lc ));
4035+ Node * val = transformJsonValueExpr (pstate , jsval ,
4036+ JS_FORMAT_DEFAULT );
4037+
4038+ args = lappend (args , val );
4039+ }
4040+ }
4041+
4042+ transformJsonOutput (pstate , ctor -> output , true, & returning );
4043+
4044+ if (returning .format .type == JS_FORMAT_JSONB )
4045+ {
4046+ funcid = args ? F_JSONB_BUILD_ARRAY_EXT : F_JSONB_BUILD_ARRAY_NOARGS ;
4047+ funcrettype = JSONBOID ;
4048+ }
4049+ else
4050+ {
4051+ funcid = args ? F_JSON_BUILD_ARRAY_EXT : F_JSON_BUILD_ARRAY_NOARGS ;
4052+ funcrettype = JSONOID ;
4053+ }
4054+
4055+ fexpr = makeFuncExpr (funcid , funcrettype , args ,
4056+ InvalidOid , InvalidOid , COERCE_EXPLICIT_CALL );
4057+ fexpr -> location = ctor -> location ;
4058+
4059+ jsctor = makeNode (JsonCtorExpr );
4060+ jsctor -> func = fexpr ;
4061+ jsctor -> type = JSCTOR_JSON_ARRAY ;
4062+ jsctor -> returning = returning ;
4063+ jsctor -> unique = false;
4064+ jsctor -> absent_on_null = ctor -> absent_on_null ;
4065+
4066+ return coerceJsonFuncExpr (pstate , (Node * ) jsctor , & returning , true);
4067+ }
0 commit comments