transformonce.patch
text/x-diff
Filename: transformonce.patch
Type: text/x-diff
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/parser/parse_expr.c | 27 | 20 |
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 9caf1e481a2..1dcbd70a509 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -3766,30 +3766,12 @@ transformJsonArrayQueryConstructor(ParseState *pstate,
ResTarget *target = makeNode(ResTarget);
JsonArrayAgg *agg = makeNode(JsonArrayAgg);
ColumnRef *colref = makeNode(ColumnRef);
- Query *query;
- ParseState *qpstate;
-
- /* Transform query only for counting target list entries. */
- qpstate = make_parsestate(pstate);
-
- query = transformStmt(qpstate, ctor->query);
-
- if (count_nonjunk_tlist_entries(query->targetList) != 1)
- ereport(ERROR,
- errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("subquery must return only one column"),
- parser_errposition(pstate, ctor->location));
-
- free_parsestate(qpstate);
+ Node *transformed;
colref->fields = list_make2(makeString(pstrdup("q")),
makeString(pstrdup("a")));
colref->location = ctor->location;
- /*
- * No formatting necessary, so set formatted_expr to be the same as
- * raw_expr.
- */
agg->arg = makeJsonValueExpr((Expr *) colref, (Expr *) colref,
ctor->format);
agg->absent_on_null = ctor->absent_on_null;
@@ -3820,7 +3802,32 @@ transformJsonArrayQueryConstructor(ParseState *pstate,
sublink->subselect = (Node *) select;
sublink->location = ctor->location;
- return transformExprRecurse(pstate, (Node *) sublink);
+ transformed = transformExprRecurse(pstate, (Node *) sublink);
+
+ /*
+ * Verify that the query (which has been installed as the subselect in the
+ * sublink) returns exactly one column after transformation.
+ */
+ {
+ Query *query;
+ RangeTblEntry *rte;
+
+ query = castNode(Query, (castNode(SubLink, transformed))->subselect);
+ Assert(list_length(query->rtable) == 1);
+
+ rte = linitial_node(RangeTblEntry, query->rtable);
+ Assert(rte->rtekind == RTE_SUBQUERY);
+
+ /* Transfer our attention to the subquery */
+ query = rte->subquery;
+ if (count_nonjunk_tlist_entries(query->targetList) != 1)
+ ereport(ERROR,
+ errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("subquery must return only one column"),
+ parser_errposition(pstate, ctor->location));
+ }
+
+ return transformed;
}
/*