Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5069fef

Browse files
author
Richard Guo
committed
Expand virtual generated columns for ALTER COLUMN TYPE
For the subcommand ALTER COLUMN TYPE of the ALTER TABLE command, the USING expression may reference virtual generated columns. These columns must be expanded before the expression is fed through expression_planner and the expression-execution machinery. Failing to do so can result in incorrect rewrite decisions, and can also lead to "ERROR: unexpected virtual generated column reference". Reported-by: Alexander Lakhin <[email protected]> Reviewed-by: jian he <[email protected]> Discussion: https://postgr.es/m/[email protected]
1 parent 62a47ae commit 5069fef

File tree

3 files changed

+30
-19
lines changed

3 files changed

+30
-19
lines changed

src/backend/commands/tablecmds.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14484,6 +14484,9 @@ ATPrepAlterColumnType(List **wqueue,
1448414484
/* Fix collations after all else */
1448514485
assign_expr_collations(pstate, transform);
1448614486

14487+
/* Expand virtual generated columns in the expr. */
14488+
transform = expand_generated_columns_in_expr(transform, rel, 1);
14489+
1448714490
/* Plan the expr now so we can accurately assess the need to rewrite. */
1448814491
transform = (Node *) expression_planner((Expr *) transform);
1448914492

src/test/regress/expected/generated_virtual.out

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,7 +1479,8 @@ create table gtest32 (
14791479
a int primary key,
14801480
b int generated always as (a * 2),
14811481
c int generated always as (10 + 10),
1482-
d int generated always as (coalesce(a, 100))
1482+
d int generated always as (coalesce(a, 100)),
1483+
e int
14831484
);
14841485
insert into gtest32 values (1), (2);
14851486
analyze gtest32;
@@ -1563,41 +1564,44 @@ select t2.* from gtest32 t1 left join gtest32 t2 on false;
15631564
QUERY PLAN
15641565
------------------------------------------------------
15651566
Nested Loop Left Join
1566-
Output: a, (a * 2), (20), (COALESCE(a, 100))
1567+
Output: a, (a * 2), (20), (COALESCE(a, 100)), e
15671568
Join Filter: false
15681569
-> Seq Scan on generated_virtual_tests.gtest32 t1
1569-
Output: t1.a, t1.b, t1.c, t1.d
1570+
Output: t1.a, t1.b, t1.c, t1.d, t1.e
15701571
-> Result
1571-
Output: a, 20, COALESCE(a, 100)
1572+
Output: a, e, 20, COALESCE(a, 100)
15721573
One-Time Filter: false
15731574
(8 rows)
15741575

15751576
select t2.* from gtest32 t1 left join gtest32 t2 on false;
1576-
a | b | c | d
1577-
---+---+---+---
1578-
| | |
1579-
| | |
1577+
a | b | c | d | e
1578+
---+---+---+---+---
1579+
| | | |
1580+
| | | |
15801581
(2 rows)
15811582

15821583
explain (verbose, costs off)
1583-
select * from gtest32 t group by grouping sets (a, b, c, d) having c = 20;
1584+
select * from gtest32 t group by grouping sets (a, b, c, d, e) having c = 20;
15841585
QUERY PLAN
15851586
-----------------------------------------------------
15861587
HashAggregate
1587-
Output: a, ((a * 2)), (20), (COALESCE(a, 100))
1588+
Output: a, ((a * 2)), (20), (COALESCE(a, 100)), e
15881589
Hash Key: t.a
15891590
Hash Key: (t.a * 2)
15901591
Hash Key: 20
15911592
Hash Key: COALESCE(t.a, 100)
1593+
Hash Key: t.e
15921594
Filter: ((20) = 20)
15931595
-> Seq Scan on generated_virtual_tests.gtest32 t
1594-
Output: a, (a * 2), 20, COALESCE(a, 100)
1595-
(9 rows)
1596+
Output: a, (a * 2), 20, COALESCE(a, 100), e
1597+
(10 rows)
15961598

1597-
select * from gtest32 t group by grouping sets (a, b, c, d) having c = 20;
1598-
a | b | c | d
1599-
---+---+----+---
1600-
| | 20 |
1599+
select * from gtest32 t group by grouping sets (a, b, c, d, e) having c = 20;
1600+
a | b | c | d | e
1601+
---+---+----+---+---
1602+
| | 20 | |
16011603
(1 row)
16021604

1605+
-- Ensure that the virtual generated columns in ALTER COLUMN TYPE USING expression are expanded
1606+
alter table gtest32 alter column e type bigint using b;
16031607
drop table gtest32;

src/test/regress/sql/generated_virtual.sql

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,8 @@ create table gtest32 (
797797
a int primary key,
798798
b int generated always as (a * 2),
799799
c int generated always as (10 + 10),
800-
d int generated always as (coalesce(a, 100))
800+
d int generated always as (coalesce(a, 100)),
801+
e int
801802
);
802803

803804
insert into gtest32 values (1), (2);
@@ -838,7 +839,10 @@ select t2.* from gtest32 t1 left join gtest32 t2 on false;
838839
select t2.* from gtest32 t1 left join gtest32 t2 on false;
839840

840841
explain (verbose, costs off)
841-
select * from gtest32 t group by grouping sets (a, b, c, d) having c = 20;
842-
select * from gtest32 t group by grouping sets (a, b, c, d) having c = 20;
842+
select * from gtest32 t group by grouping sets (a, b, c, d, e) having c = 20;
843+
select * from gtest32 t group by grouping sets (a, b, c, d, e) having c = 20;
844+
845+
-- Ensure that the virtual generated columns in ALTER COLUMN TYPE USING expression are expanded
846+
alter table gtest32 alter column e type bigint using b;
843847

844848
drop table gtest32;

0 commit comments

Comments
 (0)