Re: row_to_json(), NULL values, and AS - Mailing list pgsql-bugs
From | Tom Lane |
---|---|
Subject | Re: row_to_json(), NULL values, and AS |
Date | |
Msg-id | 18365.1529018904@sss.pgh.pa.us Whole thread Raw |
In response to | row_to_json(), NULL values, and AS (Neil Conway <neil.conway@gmail.com>) |
Responses |
Re: row_to_json(), NULL values, and AS
|
List | pgsql-bugs |
[ Hi Neil, long time no see ] Neil Conway <neil.conway@gmail.com> writes: > The following behavior does not seem self-consistent to me: Likewise. > In particular, it is unclear to me why removing the targetlist alias > in the subquery in the third example should change the result set of > the parent query. Looking at "explain verbose" output, it seems like it's not row_to_json's fault; rather, we seem to be mishandling expansion of the whole-row Var: regression=# explain verbose select json_agg(row_to_json(x)) from (select *, row_to_json(null) as jjj from generate_series(1, 3)) x; QUERY PLAN ----------------------------------------------------------------------------------------- Aggregate (cost=15.00..15.01 rows=1 width=32) Output: json_agg(row_to_json(ROW(generate_series.generate_series, NULL::json))) -> Function Scan on pg_catalog.generate_series (cost=0.00..10.00 rows=1000 width=4) Output: generate_series.generate_series Function Call: generate_series(1, 3) (5 rows) That's fine, but: regression=# explain verbose select json_agg(row_to_json(x)) from (select *, row_to_json(null) from generate_series(1, 3)) x; QUERY PLAN ----------------------------------------------------------------------------------------- Aggregate (cost=12.50..12.51 rows=1 width=32) Output: json_agg(NULL::json) -> Function Scan on pg_catalog.generate_series (cost=0.00..10.00 rows=1000 width=0) Output: generate_series.generate_series Function Call: generate_series(1, 3) (5 rows) That looks like it might be a bug in what we do with whole-row Vars during subquery flattening. But if you put an "offset 0" into the subquery to prevent flattening, you get different but just as weird misbehavior: regression=# explain verbose select json_agg(row_to_json(x)) from (select *, row_to_json(null) as jjj from generate_series(1, 3) offset 0) x; QUERY PLAN ------------------------------------------------------------------------------------------------ Aggregate (cost=25.00..25.02 rows=1 width=32) Output: json_agg(row_to_json(x.*)) -> Subquery Scan on x (cost=0.00..20.00 rows=1000 width=28) Output: x.* -> Function Scan on pg_catalog.generate_series (cost=0.00..10.00 rows=1000 width=36) Output: generate_series.generate_series, NULL::json Function Call: generate_series(1, 3) (7 rows) regression=# explain verbose select json_agg(row_to_json(x)) from (select *, row_to_json(null) from generate_series(1, 3) offset 0) x; QUERY PLAN ------------------------------------------------------------------------------------------ Aggregate (cost=22.50..22.52 rows=1 width=32) Output: json_agg((NULL::json)) -> Function Scan on pg_catalog.generate_series (cost=0.00..10.00 rows=1000 width=36) Output: NULL::integer, NULL::json Function Call: generate_series(1, 3) (5 rows) I'm not sure if this is just another artifact of the same problem. The extra parens in the json_agg() argument are suspicious to put it mildly, but I've not dug into it to see what the plan tree really looks like. regards, tom lane
pgsql-bugs by date: