Dumped SQL failed to execute with ERROR "GROUP BY position -1 is not in select list"

Started by Haotian Chenalmost 3 years ago5 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

won't retrysuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t48816
psql -h localhost -U postgres

Built from patchset v5 (message #5), July 27, 2026 at 11:43 PM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t48816_5 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t48816_5 && git checkout t48816_5

Patchset v5 (message #5) is on t48816_5

Jump to latest
#1Haotian Chen
charliett2233@outlook.com

Hi hackers,

I found that dumped view SQL failed to execute due to the explicit cast

of negative number, and I took a look at the defined SQL in view and then

found -1 in the group by clause. I suppose it’s the main reason the sql

cannot be executed and raised ERROR "GROUP BY position -1 is not in select list"

postgres=# create view v1 as select * from t1 group by a,b,-1::int;

CREATE VIEW

postgres=# \d+ v1;

View "public.v1"

Column | Type | Collation | Nullable | Default | Storage | Description

--------+---------+-----------+----------+---------+---------+-------------

a | integer | | | | plain |

b | integer | | | | plain |

View definition:

SELECT a,

b

FROM t1

GROUP BY a, b, (- 1);

After exploring codes, I suppose we should treat operator plus constant

as -'nnn'::typename instead of const, my patch just did this by handling

Opexpr especially, but I am not sure it’s the best way or not, BTW do you

guys have any suggestions and another approach?

--
Best Regards,
Haotian

Attachments:

v1-0001-fix-dump-view-fails-with-group-by-clause.patchapplication/octet-stream; name=v1-0001-fix-dump-view-fails-with-group-by-clause.patchDownload+32-2
#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Haotian Chen (#1)
Re: Dumped SQL failed to execute with ERROR "GROUP BY position -1 is not in select list"

Haotian Chen <charliett2233@outlook.com> writes:

postgres=# create view v1 as select * from t1 group by a,b,-1::int;
CREATE VIEW

Hmm, surely that is a contrived case?

After exploring codes, I suppose we should treat operator plus constant
as -'nnn'::typename instead of const, my patch just did this by handling
Opexpr especially, but I am not sure it's the best way or not,

Yeah, after some time looking at alternatives, I agree that hacking up
get_rule_sortgroupclause some more is the least risky way to make this
work. We could imagine changing the parser instead but people might
be depending on the current parsing behavior.

I don't like your patch too much though, particularly not the arbitrary
(and undocumented) change in get_const_expr; that seems way too likely
to have unexpected side-effects. Also, I think that relying on
generate_operator_name to produce exactly '-' (and not, say,
'pg_catalog.-') is unwise as well as unduly expensive.

There are, I think, precisely two operators we need to worry about here,
namely int4um and numeric_uminus. It'd be cheaper and more reliable to
identify those by OID. (If the underlying Const is neither int4 nor
numeric, it'll end up getting labeled with a typecast, so that we don't
need to worry about anything else.)

As for getting the right thing to be printed, I think what we might
want is to effectively const-fold the expression into a negative
Const, and then we can just apply get_const_expr with showtype=1.
(So we'd end with output like '-1'::integer or similar.)

We could do worse than to implement that by actual const-folding,
ie call expression_planner. Efficiency-wise that's not great, but
this is such a weird edge case that I don't think we need to sweat
about making it fast. The alternative of hand-rolled constant
folding code isn't very appealing.

regards, tom lane

#3Haotian Chen
charliett2233@outlook.com
In reply to: Tom Lane (#2)
答复: Dumped SQL failed to execute with ERROR "GROUP BY position -1 is not in select list"

Hmm, surely that is a contrived case?

Sorry for forgetting to paste the reproduction. It should be as follows.

###
psql -d postgres -c 'create table t1(a int, b int, c int)'
psql -d postgres -c 'create view v1 as select a,b,c, -1::int from t1 group by 1,2,3,4'
pg_dumpall > /tmp/ddl.sql
psql -d postgres -c 'drop view v1'
psql -d postgres -c 'drop table t1'
psql -d postgres -f /tmp/ddl.sql

psql:/tmp/ddl.sql:111: ERROR: GROUP BY position -1 is not in select list
LINE 7: GROUP BY a, b, c, (- 1);
^
psql:/tmp/ddl.sql:114: ERROR: relation "public.v1" does not exist
###

There are, I think, precisely two operators we need to worry about here,
namely int4um and numeric_uminus. It'd be cheaper and more reliable to
identify those by OID.

Yes, I updated my patch and just used oid numbers 558 and 1751 stand for
int4um and numeric_uminus. Maybe we could define a macro for them,
but seems unnecessary.

We could do worse than to implement that by actual const-folding,
ie call expression_planner.

After exploring more codes, I also suppose expression_planner is a good choice.

Regards,
Haotian

发件人: Tom Lane <tgl@sss.pgh.pa.us>
日期: 星期六, 2023年12月2日 03:57
收件人: Haotian Chen <charliett2233@outlook.com>
抄送: pgsql-hackers@postgresql.org <pgsql-hackers@postgresql.org>
主题: Re: Dumped SQL failed to execute with ERROR "GROUP BY position -1 is not in select list"
Haotian Chen <charliett2233@outlook.com> writes:

postgres=# create view v1 as select * from t1 group by a,b,-1::int;
CREATE VIEW

Hmm, surely that is a contrived case?

After exploring codes, I suppose we should treat operator plus constant
as -'nnn'::typename instead of const, my patch just did this by handling
Opexpr especially, but I am not sure it's the best way or not,

Yeah, after some time looking at alternatives, I agree that hacking up
get_rule_sortgroupclause some more is the least risky way to make this
work. We could imagine changing the parser instead but people might
be depending on the current parsing behavior.

I don't like your patch too much though, particularly not the arbitrary
(and undocumented) change in get_const_expr; that seems way too likely
to have unexpected side-effects. Also, I think that relying on
generate_operator_name to produce exactly '-' (and not, say,
'pg_catalog.-') is unwise as well as unduly expensive.

There are, I think, precisely two operators we need to worry about here,
namely int4um and numeric_uminus. It'd be cheaper and more reliable to
identify those by OID. (If the underlying Const is neither int4 nor
numeric, it'll end up getting labeled with a typecast, so that we don't
need to worry about anything else.)

As for getting the right thing to be printed, I think what we might
want is to effectively const-fold the expression into a negative
Const, and then we can just apply get_const_expr with showtype=1.
(So we'd end with output like '-1'::integer or similar.)

We could do worse than to implement that by actual const-folding,
ie call expression_planner. Efficiency-wise that's not great, but
this is such a weird edge case that I don't think we need to sweat
about making it fast. The alternative of hand-rolled constant
folding code isn't very appealing.

regards, tom lane

Attachments:

v2-0001-fix-dump-view-fails-with-group-by-clause.patchapplication/octet-stream; name=v2-0001-fix-dump-view-fails-with-group-by-clause.patchDownload+22-1
#4David Rowley
dgrowleyml@gmail.com
In reply to: Haotian Chen (#3)
Re: Dumped SQL failed to execute with ERROR "GROUP BY position -1 is not in select list"

On Mon, 4 Dec 2023 at 02:38, Haotian Chen <charliett2233@outlook.com> wrote:

Yes, I updated my patch and just used oid numbers 558 and 1751 stand for
int4um and numeric_uminus. Maybe we could define a macro for them,
but seems unnecessary.

The thing to do here is modify pg_operator.dat and give both of these
operators an "oid_symbol". Perhaps Int4NegOperator is ok. (I think
Int4UnaryMinusOperator might be on the verbose side.). The code that
parses pg_operator.dat will then define that constant in
pg_operator_d.h. You can then use that and the other ones you defined
for the numeric operator instead of hard coding the Oids in the patch.

David

#5Haotian Chen
charliett2233@outlook.com
In reply to: David Rowley (#4)
Re: Dumped SQL failed to execute with ERROR "GROUP BY position -1 is not in select list"

The thing to do here is modify pg_operator.dat and give both of these
operators an "oid_symbol". Perhaps Int4NegOperator is ok.

Thanks for suggestions, I replaced hacking oids with Int4NegOperator and NumericNegOperator.
And I also updated some comments and commit message.

Please feel free to review latest version patch v3-0001-Printing-const-folder-expression-in-ruleutils.c.patch

Best regards,
Haotian

From: David Rowley <dgrowleyml@gmail.com>
Date: Monday, December 4, 2023 at 06:08
To: Haotian Chen <charliett2233@outlook.com>
Cc: Tom Lane <tgl@sss.pgh.pa.us>, pgsql-hackers@postgresql.org <pgsql-hackers@postgresql.org>
Subject: Re: Dumped SQL failed to execute with ERROR "GROUP BY position -1 is not in select list"
On Mon, 4 Dec 2023 at 02:38, Haotian Chen <charliett2233@outlook.com> wrote:

Yes, I updated my patch and just used oid numbers 558 and 1751 stand for
int4um and numeric_uminus. Maybe we could define a macro for them,
but seems unnecessary.

The thing to do here is modify pg_operator.dat and give both of these
operators an "oid_symbol". Perhaps Int4NegOperator is ok. (I think
Int4UnaryMinusOperator might be on the verbose side.). The code that
parses pg_operator.dat will then define that constant in
pg_operator_d.h. You can then use that and the other ones you defined
for the numeric operator instead of hard coding the Oids in the patch.

David

Attachments:

t48816_5
v3-0001-Printing-const-folder-expression-in-ruleutils.c.patchapplication/octet-stream; name=v3-0001-Printing-const-folder-expression-in-ruleutils.c.patchDownload+27-3