@@ -123,6 +123,7 @@ static Node *transformIndirection(ParseState *pstate, A_Indirection *ind);
123123static Node * transformTypeCast (ParseState * pstate , TypeCast * tc );
124124static Node * transformCollateClause (ParseState * pstate , CollateClause * c );
125125static Node * transformJsonObjectCtor (ParseState * pstate , JsonObjectCtor * ctor );
126+ static Node * transformJsonArrayCtor (ParseState * pstate , JsonArrayCtor * ctor );
126127static Node * make_row_comparison_op (ParseState * pstate , List * opname ,
127128 List * largs , List * rargs , int location );
128129static Node * make_row_distinct_op (ParseState * pstate , List * opname ,
@@ -375,6 +376,10 @@ transformExprRecurse(ParseState *pstate, Node *expr)
375376 result = transformJsonObjectCtor (pstate , (JsonObjectCtor * ) expr );
376377 break ;
377378
379+ case T_JsonArrayCtor :
380+ result = transformJsonArrayCtor (pstate , (JsonArrayCtor * ) expr );
381+ break ;
382+
378383 default :
379384 /* should not reach here */
380385 elog (ERROR , "unrecognized node type: %d" , (int ) nodeTag (expr ));
@@ -3864,3 +3869,63 @@ transformJsonObjectCtor(ParseState *pstate, JsonObjectCtor *ctor)
38643869
38653870 return coerceJsonFuncExpr (pstate , (Node * ) fexpr , & returning , true);
38663871}
3872+
3873+ /*
3874+ * Transform JSON_ARRAY() constructor.
3875+ *
3876+ * JSON_ARRAY() is transformed into json[b]_build_array[_ext]() call
3877+ * depending on the output JSON format. The first argument of
3878+ * json[b]_build_array_ext() is absent_on_null.
3879+ *
3880+ * Then function call result is coerced to the target type.
3881+ */
3882+ static Node *
3883+ transformJsonArrayCtor (ParseState * pstate , JsonArrayCtor * ctor )
3884+ {
3885+ JsonReturning returning ;
3886+ FuncExpr * fexpr ;
3887+ List * args = NIL ;
3888+ Oid funcid ;
3889+ Oid funcrettype ;
3890+
3891+ /* transform element expressions, if any */
3892+ if (ctor -> exprs )
3893+ {
3894+ ListCell * lc ;
3895+
3896+ /* append the first absent_on_null argument */
3897+ args = lappend (args , makeBoolConst (ctor -> absent_on_null , false));
3898+
3899+ /* transform and append element arguments */
3900+ foreach (lc , ctor -> exprs )
3901+ {
3902+ JsonValueExpr * jsval = castNode (JsonValueExpr , lfirst (lc ));
3903+ Node * val = transformJsonValueExpr (pstate , jsval ,
3904+ JS_FORMAT_DEFAULT );
3905+
3906+ args = lappend (args , val );
3907+ }
3908+ }
3909+
3910+ transformJsonOutput (pstate , ctor -> output , true, & returning );
3911+
3912+ if (returning .format .type == JS_FORMAT_JSONB )
3913+ {
3914+ funcid = args ? F_JSONB_BUILD_ARRAY_EXT : F_JSONB_BUILD_ARRAY_NOARGS ;
3915+ funcrettype = JSONBOID ;
3916+ }
3917+ else
3918+ {
3919+ funcid = args ? F_JSON_BUILD_ARRAY_EXT : F_JSON_BUILD_ARRAY_NOARGS ;
3920+ funcrettype = JSONOID ;
3921+ }
3922+
3923+ fexpr = makeFuncExpr (funcid , funcrettype , args ,
3924+ InvalidOid , InvalidOid , COERCE_EXPLICIT_CALL );
3925+ fexpr -> location = ctor -> location ;
3926+ fexpr -> funcformat2 = FUNCFMT_JSON_ARRAY ;
3927+ fexpr -> funcformatopts = (Node * ) makeJsonCtorOpts (& returning , false,
3928+ ctor -> absent_on_null );
3929+
3930+ return coerceJsonFuncExpr (pstate , (Node * ) fexpr , & returning , true);
3931+ }
0 commit comments