Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions src/backend/parser/parse_agg.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,6 @@ transformAggregateCall(ParseState *pstate, Aggref *agg,
int save_next_resno;
ListCell *lc;

/*
* Before separating the args into direct and aggregated args, make a list
* of their data type OIDs for use later.
*/
foreach(lc, args)
{
Expr *arg = (Expr *) lfirst(lc);

argtypes = lappend_oid(argtypes, exprType((Node *) arg));
}
agg->aggargtypes = argtypes;

if (AGGKIND_IS_ORDERED_SET(agg->aggkind))
{
/*
Expand Down Expand Up @@ -238,6 +226,29 @@ transformAggregateCall(ParseState *pstate, Aggref *agg,
agg->aggorder = torder;
agg->aggdistinct = tdistinct;

/*
* Now build the aggargtypes list with the type OIDs of the direct and
* aggregated args, ignoring any resjunk entries that might have been
* added by ORDER BY/DISTINCT processing. We can't do this earlier
* because said processing can modify some args' data types, in particular
* by resolving previously-unresolved "unknown" literals.
*/
foreach(lc, agg->aggdirectargs)
{
Expr *arg = (Expr *) lfirst(lc);

argtypes = lappend_oid(argtypes, exprType((Node *) arg));
}
foreach(lc, tlist)
{
TargetEntry *tle = (TargetEntry *) lfirst(lc);

if (tle->resjunk)
continue; /* ignore junk */
argtypes = lappend_oid(argtypes, exprType((Node *) tle->expr));
}
agg->aggargtypes = argtypes;

check_agglevels_and_constraints(pstate, (Node *) agg);
}

Expand Down
7 changes: 7 additions & 0 deletions src/test/regress/expected/jsonb.out
Original file line number Diff line number Diff line change
Expand Up @@ -1558,6 +1558,13 @@ SELECT jsonb_object_agg(name, type) FROM foo;
INSERT INTO foo VALUES (999999, NULL, 'bar');
SELECT jsonb_object_agg(name, type) FROM foo;
ERROR: field name must not be null
-- edge case for parser
SELECT jsonb_object_agg(DISTINCT 'a', 'abc');
jsonb_object_agg
------------------
{"a": "abc"}
(1 row)

-- jsonb_object
-- empty object, one dimension
SELECT jsonb_object('{}');
Expand Down
7 changes: 7 additions & 0 deletions src/test/regress/expected/jsonb_optimizer.out
Original file line number Diff line number Diff line change
Expand Up @@ -1560,6 +1560,13 @@ SELECT jsonb_object_agg(name, type) FROM foo;
INSERT INTO foo VALUES (999999, NULL, 'bar');
SELECT jsonb_object_agg(name, type) FROM foo;
ERROR: field name must not be null
-- edge case for parser
SELECT jsonb_object_agg(DISTINCT 'a', 'abc');
jsonb_object_agg
------------------
{"a": "abc"}
(1 row)

-- jsonb_object
-- empty object, one dimension
SELECT jsonb_object('{}');
Expand Down
3 changes: 3 additions & 0 deletions src/test/regress/sql/jsonb.sql
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ SELECT jsonb_object_agg(name, type) FROM foo;
INSERT INTO foo VALUES (999999, NULL, 'bar');
SELECT jsonb_object_agg(name, type) FROM foo;

-- edge case for parser
SELECT jsonb_object_agg(DISTINCT 'a', 'abc');

-- jsonb_object

-- empty object, one dimension
Expand Down
Loading