@@ -126,6 +126,8 @@ static Node *transformTypeCast(ParseState *pstate, TypeCast *tc);
126126static Node * transformCollateClause (ParseState * pstate , CollateClause * c );
127127static Node * transformJsonObjectCtor (ParseState * pstate , JsonObjectCtor * ctor );
128128static Node * transformJsonArrayCtor (ParseState * pstate , JsonArrayCtor * ctor );
129+ static Node * transformJsonArrayQueryCtor (ParseState * pstate ,
130+ JsonArrayQueryCtor * ctor );
129131static Node * transformJsonObjectAgg (ParseState * pstate , JsonObjectAgg * agg );
130132static Node * transformJsonArrayAgg (ParseState * pstate , JsonArrayAgg * agg );
131133static Node * make_row_comparison_op (ParseState * pstate , List * opname ,
@@ -384,6 +386,10 @@ transformExprRecurse(ParseState *pstate, Node *expr)
384386 result = transformJsonArrayCtor (pstate , (JsonArrayCtor * ) expr );
385387 break ;
386388
389+ case T_JsonArrayQueryCtor :
390+ result = transformJsonArrayQueryCtor (pstate , (JsonArrayQueryCtor * ) expr );
391+ break ;
392+
387393 case T_JsonObjectAgg :
388394 result = transformJsonObjectAgg (pstate , (JsonObjectAgg * ) expr );
389395 break ;
@@ -3740,6 +3746,74 @@ transformJsonObjectCtor(ParseState *pstate, JsonObjectCtor *ctor)
37403746 return coerceJsonFuncExpr (pstate , (Node * ) fexpr , ctor -> output );
37413747}
37423748
3749+ /* Transform JSON_ARRAY(query [FORMAT] [RETURNING] [ON NULL]) into
3750+ * (SELECT JSON_ARRAYAGG(a [FORMAT] [RETURNING] [ON NULL]) FROM (query) q(a))
3751+ */
3752+ static Node *
3753+ transformJsonArrayQueryCtor (ParseState * pstate , JsonArrayQueryCtor * ctor )
3754+ {
3755+ SubLink * sublink = makeNode (SubLink );
3756+ SelectStmt * select = makeNode (SelectStmt );
3757+ RangeSubselect * range = makeNode (RangeSubselect );
3758+ Alias * alias = makeNode (Alias );
3759+ ResTarget * target = makeNode (ResTarget );
3760+ JsonArrayAgg * agg = makeNode (JsonArrayAgg );
3761+ JsonValueExpr * jsexpr = makeNode (JsonValueExpr );
3762+ ColumnRef * colref = makeNode (ColumnRef );
3763+ Query * query ;
3764+ ParseState * qpstate ;
3765+
3766+ /* Transform query only for counting target list entries. */
3767+ qpstate = make_parsestate (pstate );
3768+
3769+ query = transformStmt (qpstate , ctor -> query );
3770+
3771+ if (count_nonjunk_tlist_entries (query -> targetList ) != 1 )
3772+ ereport (ERROR ,
3773+ (errcode (ERRCODE_SYNTAX_ERROR ),
3774+ errmsg ("subquery must return only one column" ),
3775+ parser_errposition (pstate , ctor -> location )));
3776+
3777+ free_parsestate (qpstate );
3778+
3779+ colref -> fields = list_make2 (makeString (pstrdup ("q" )),
3780+ makeString (pstrdup ("a" )));
3781+ colref -> location = ctor -> location ;
3782+
3783+ jsexpr -> expr = (Expr * ) colref ;
3784+ jsexpr -> format = ctor -> format ;
3785+
3786+ agg -> arg = jsexpr ;
3787+ agg -> ctor .agg_order = NIL ;
3788+ agg -> ctor .output = ctor -> output ;
3789+ agg -> absent_on_null = ctor -> absent_on_null ;
3790+ agg -> ctor .location = ctor -> location ;
3791+
3792+ target -> name = NULL ;
3793+ target -> indirection = NIL ;
3794+ target -> val = (Node * ) agg ;
3795+ target -> location = ctor -> location ;
3796+
3797+ alias -> aliasname = pstrdup ("q" );
3798+ alias -> colnames = list_make1 (makeString (pstrdup ("a" )));
3799+
3800+ range -> lateral = false;
3801+ range -> subquery = ctor -> query ;
3802+ range -> alias = alias ;
3803+
3804+ select -> targetList = list_make1 (target );
3805+ select -> fromClause = list_make1 (range );
3806+
3807+ sublink -> subLinkType = EXPR_SUBLINK ;
3808+ sublink -> subLinkId = 0 ;
3809+ sublink -> testexpr = NULL ;
3810+ sublink -> operName = NIL ;
3811+ sublink -> subselect = (Node * ) select ;
3812+ sublink -> location = ctor -> location ;
3813+
3814+ return transformExprRecurse (pstate , (Node * ) sublink );
3815+ }
3816+
37433817static Node *
37443818transformJsonAggCtor (ParseState * pstate , JsonAggCtor * agg_ctor , List * args ,
37453819 Oid aggfnoid , Oid aggtype )
0 commit comments