Re: bug: virtual generated column can be partition key
Yura Sokolov <y.sokolov@postgrespro.ru>
From: Yura Sokolov <y.sokolov@postgrespro.ru>
To: jian he <jian.universality@gmail.com>,
PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2025-05-06T09:57:29Z
Lists: pgsql-hackers
21.04.2025 05:30, jian he пишет: > hi. > While trying to make the virtual generated column be part of the partition key, > I found this bug. > it also influences the stored generated column, i added a test > on generated_stored.sql. > > CREATE TABLE gtest_part_key ( > f1 date NOT NULL, f2 bigint, > f3 bigint GENERATED ALWAYS AS (f2 * 2) VIRTUAL) > PARTITION BY RANGE (f3); > > ERROR: cannot use generated column in partition key > LINE 4: PARTITION BY RANGE (f3); > ^ > DETAIL: Column "f3" is a generated column. > > the following is essentially the same as above, it should also fail. > > CREATE TABLE gtest_part_key ( > f1 date NOT NULL, f2 bigint, > f3 bigint GENERATED ALWAYS AS (f2 * 2) VIRTUAL) > PARTITION BY RANGE ((f3)); I don't understand why latter should fail? Documentation says [1]: > PostgreSQL allows you to declare that a table is divided into partitions. > The table that is divided is referred to as a partitioned table. > The declaration includes the partitioning method as described above, > plus a list of columns or expressions to be used as the partition key. Note: "list of columns or EXPRESSIONS"! In first case you pass list of columns (which contains single column f3). I don't get which internal restriction forces it to fail, really, but ok: there is restriction on COLUMNS LIST and it must be obeyed. But in second case you pass EXPRESSION, and I don't think same restriction should be applied. More over, if you look into comments on restriction on GENERATED columns [2] [3], you will find this restriction is because of nature of STORED generated columns, and it doesn't bound to VIRTUAL ones. Indeed, there is suggestion for future to treat GENERATED VIRTUAL columns as expressions. So, if you want to force some restriction, you should force it only against STORED columns, but not VIRTUAL ones. Of cause, if VIRTUAL column depends on STORED one, it is still should be forbidden. Certainly, it is my opinion and I could be mistaken somewhere. For example, you may say "it is too hard to check dependency of VIRTUAL column at the moment, so it is simpler to forbid them as well". But then it should be clearly stated in commit messages and code comments. [1] https://www.postgresql.org/docs/17/ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE [2] https://github.com/postgres/postgres/blob/caa76b91a60681dff0bf193b64d4dcdc1014e036/src/backend/commands/tablecmds.c#L19735-L19741 [3] https://github.com/postgres/postgres/blob/caa76b91a60681dff0bf193b64d4dcdc1014e036/src/backend/commands/tablecmds.c#L19821-L19828 -- regards Yura Sokolov aka funny-falcon
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Tighten check for generated column in partition key expression
- 7f239c72a897 13.23 landed
- 04345d7a423a 14.20 landed
- 643a5e96c788 15.15 landed
- 7180d56c5609 16.11 landed
- 0b44f2443f69 17.7 landed
- ba99c9491c44 18.1 landed
- 040cc5f3c782 19 (unreleased) landed
-
Stamp 18beta1.
- caa76b91a606 18.0 cited