]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Expand virtual generated columns in constraint expressions
authorPeter Eisentraut <peter@eisentraut.org>
Mon, 15 Sep 2025 14:27:50 +0000 (16:27 +0200)
committerPeter Eisentraut <peter@eisentraut.org>
Mon, 15 Sep 2025 14:28:45 +0000 (16:28 +0200)
Virtual generated columns in constraint expressions need to be
expanded because the optimizer matches these expressions to qual
clauses.  Failing to do so can cause us to miss opportunities for
constraint exclusion.

Author: Richard Guo <guofenglinux@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/204804c0-798f-4c72-bd1f-36116024fda3%40eisentraut.org

src/backend/optimizer/util/plancat.c
src/test/regress/expected/generated_virtual.out
src/test/regress/sql/generated_virtual.sql

index 95671771c79af84dd4da3b69e8a1be4f7eae0e39..6d420bb427f0a580c2609eaa70f530d9a7c905aa 100644 (file)
@@ -42,6 +42,7 @@
 #include "parser/parse_relation.h"
 #include "parser/parsetree.h"
 #include "partitioning/partdesc.h"
+#include "rewrite/rewriteHandler.h"
 #include "rewrite/rewriteManip.h"
 #include "statistics/statistics.h"
 #include "storage/bufmgr.h"
@@ -1392,6 +1393,14 @@ get_relation_constraints(PlannerInfo *root,
                result = list_concat(result, rel->partition_qual);
        }
 
+       /*
+        * Expand virtual generated columns in the constraint expressions.
+        */
+       if (result)
+               result = (List *) expand_generated_columns_in_expr((Node *) result,
+                                                                                                                  relation,
+                                                                                                                  varno);
+
        table_close(relation, NoLock);
 
        return result;
index 3b40e15a95ad03b5b50cdb29509a29cfb5750201..e076977e986999493c376a02a12ad99987beaaac 100644 (file)
@@ -1614,3 +1614,26 @@ select * from gtest32 t group by grouping sets (a, b, c, d, e) having c = 20;
 -- Ensure that the virtual generated columns in ALTER COLUMN TYPE USING expression are expanded
 alter table gtest32 alter column e type bigint using b;
 drop table gtest32;
+-- Ensure that virtual generated columns in constraint expressions are expanded
+create table gtest33 (a int, b int generated always as (a * 2) virtual not null, check (b > 10));
+set constraint_exclusion to on;
+-- should get a dummy Result, not a seq scan
+explain (costs off)
+select * from gtest33 where b < 10;
+        QUERY PLAN        
+--------------------------
+ Result
+   One-Time Filter: false
+(2 rows)
+
+-- should get a dummy Result, not a seq scan
+explain (costs off)
+select * from gtest33 where b is null;
+        QUERY PLAN        
+--------------------------
+ Result
+   One-Time Filter: false
+(2 rows)
+
+reset constraint_exclusion;
+drop table gtest33;
index e2b31853e0132a5650391dfaaf1b160e701f9fea..63be8edb2496ecdf22c35b2754cc36cf606cf084 100644 (file)
@@ -859,3 +859,18 @@ select * from gtest32 t group by grouping sets (a, b, c, d, e) having c = 20;
 alter table gtest32 alter column e type bigint using b;
 
 drop table gtest32;
+
+-- Ensure that virtual generated columns in constraint expressions are expanded
+create table gtest33 (a int, b int generated always as (a * 2) virtual not null, check (b > 10));
+set constraint_exclusion to on;
+
+-- should get a dummy Result, not a seq scan
+explain (costs off)
+select * from gtest33 where b < 10;
+
+-- should get a dummy Result, not a seq scan
+explain (costs off)
+select * from gtest33 where b is null;
+
+reset constraint_exclusion;
+drop table gtest33;