Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Improve test coverage of ruleutils.c.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 6 Dec 2019 22:40:24 +0000 (17:40 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 6 Dec 2019 22:40:30 +0000 (17:40 -0500)
While fooling around with the EXPLAIN improvements I've been working
on, I noticed that there were some large gaps in our test coverage
of ruleutils.c, according to the code coverage report.  This commit
just adds a few test cases to improve coverage of:
get_name_for_var_field()
get_update_query_targetlist_def()
isSimpleNode()
get_sublink_expr()

src/test/regress/expected/create_view.out
src/test/regress/expected/rules.out
src/test/regress/sql/create_view.sql
src/test/regress/sql/rules.sql

index 9a92629fd79f40e5bead640d921c8e53f4f8d617..f10a3a7a127136f8a638cc70b263db206731620b 100644 (file)
@@ -1775,6 +1775,104 @@ select pg_get_ruledef(oid, true) from pg_rewrite
      43 AS col_b;
 (1 row)
 
+-- test extraction of FieldSelect field names (get_name_for_var_field)
+create view tt24v as
+with cte as materialized (select r from (values(1,2),(3,4)) r)
+select (r).column2 as col_a, (rr).column2 as col_b from
+  cte join (select rr from (values(1,7),(3,8)) rr limit 2) ss
+  on (r).column1 = (rr).column1;
+select pg_get_viewdef('tt24v', true);
+                       pg_get_viewdef                       
+------------------------------------------------------------
+  WITH cte AS MATERIALIZED (                               +
+          SELECT r.*::record AS r                          +
+            FROM ( VALUES (1,2), (3,4)) r                  +
+         )                                                 +
+  SELECT (cte.r).column2 AS col_a,                         +
+     (ss.rr).column2 AS col_b                              +
+    FROM cte                                               +
+      JOIN ( SELECT rr.*::record AS rr                     +
+            FROM ( VALUES (1,7), (3,8)) rr                 +
+          LIMIT 2) ss ON (cte.r).column1 = (ss.rr).column1;
+(1 row)
+
+create view tt25v as
+with cte as materialized (select pg_get_keywords() k)
+select (k).word from cte;
+select pg_get_viewdef('tt25v', true);
+             pg_get_viewdef             
+----------------------------------------
+  WITH cte AS MATERIALIZED (           +
+          SELECT pg_get_keywords() AS k+
+         )                             +
+  SELECT (cte.k).word AS word          +
+    FROM cte;
+(1 row)
+
+-- also check cases seen only in EXPLAIN
+explain (verbose, costs off)
+select * from tt24v;
+                                        QUERY PLAN                                        
+------------------------------------------------------------------------------------------
+ Hash Join
+   Output: (cte.r).column2, ((ROW("*VALUES*".column1, "*VALUES*".column2))).column2
+   Hash Cond: (((ROW("*VALUES*".column1, "*VALUES*".column2))).column1 = (cte.r).column1)
+   CTE cte
+     ->  Values Scan on "*VALUES*_1"
+           Output: ROW("*VALUES*_1".column1, "*VALUES*_1".column2)
+   ->  Limit
+         Output: (ROW("*VALUES*".column1, "*VALUES*".column2))
+         ->  Values Scan on "*VALUES*"
+               Output: ROW("*VALUES*".column1, "*VALUES*".column2)
+   ->  Hash
+         Output: cte.r
+         ->  CTE Scan on cte
+               Output: cte.r
+(14 rows)
+
+explain (verbose, costs off)
+select (r).column2 from (select r from (values(1,2),(3,4)) r limit 1) ss;
+                            QUERY PLAN                             
+-------------------------------------------------------------------
+ Subquery Scan on ss
+   Output: (ss.r).column2
+   ->  Limit
+         Output: (ROW("*VALUES*".column1, "*VALUES*".column2))
+         ->  Values Scan on "*VALUES*"
+               Output: ROW("*VALUES*".column1, "*VALUES*".column2)
+(6 rows)
+
+-- test pretty-print parenthesization rules, and SubLink deparsing
+create view tt26v as
+select x + y + z as c1,
+       (x * y) + z as c2,
+       x + (y * z) as c3,
+       (x + y) * z as c4,
+       x * (y + z) as c5,
+       x + (y + z) as c6,
+       x + (y # z) as c7,
+       (x > y) AND (y > z OR x > z) as c8,
+       (x > y) OR (y > z AND NOT (x > z)) as c9,
+       (x,y) <> ALL (values(1,2),(3,4)) as c10,
+       (x,y) <= ANY (values(1,2),(3,4)) as c11
+from (values(1,2,3)) v(x,y,z);
+select pg_get_viewdef('tt26v', true);
+                     pg_get_viewdef                     
+--------------------------------------------------------
+  SELECT v.x + v.y + v.z AS c1,                        +
+     v.x * v.y + v.z AS c2,                            +
+     v.x + v.y * v.z AS c3,                            +
+     (v.x + v.y) * v.z AS c4,                          +
+     v.x * (v.y + v.z) AS c5,                          +
+     v.x + (v.y + v.z) AS c6,                          +
+     v.x + (v.y # v.z) AS c7,                          +
+     v.x > v.y AND (v.y > v.z OR v.x > v.z) AS c8,     +
+     v.x > v.y OR v.y > v.z AND NOT v.x > v.z AS c9,   +
+     ((v.x, v.y) <> ALL ( VALUES (1,2), (3,4))) AS c10,+
+     ((v.x, v.y) <= ANY ( VALUES (1,2), (3,4))) AS c11 +
+    FROM ( VALUES (1,2,3)) v(x, y, z);
+(1 row)
+
 -- clean up all the random objects we made above
 DROP SCHEMA temp_view_test CASCADE;
 NOTICE:  drop cascades to 27 other objects
@@ -1806,7 +1904,7 @@ drop cascades to view aliased_view_2
 drop cascades to view aliased_view_3
 drop cascades to view aliased_view_4
 DROP SCHEMA testviewschm2 CASCADE;
-NOTICE:  drop cascades to 64 other objects
+NOTICE:  drop cascades to 67 other objects
 DETAIL:  drop cascades to table t1
 drop cascades to view temporal1
 drop cascades to view temporal2
@@ -1871,3 +1969,6 @@ drop cascades to view tt20v
 drop cascades to view tt21v
 drop cascades to view tt22v
 drop cascades to view tt23v
+drop cascades to view tt24v
+drop cascades to view tt25v
+drop cascades to view tt26v
index c9cc5694048c0c0fec4bad152025de553a56de53..80a07825b953b902b837ab88dfe93219fc77a056 100644 (file)
@@ -2974,6 +2974,30 @@ Rules:
     ON UPDATE TO rules_src DO INSTEAD  UPDATE rules_log trgt SET tag = 'updated'::text
   WHERE trgt.f1 = new.f1
 
+--
+-- Also check multiassignment deparsing.
+--
+create table rule_t1(f1 int, f2 int);
+create table rule_dest(f1 int, f2 int[], tag text);
+create rule rr as on update to rule_t1 do instead UPDATE rule_dest trgt
+  SET (f2[1], f1, tag) = (SELECT new.f2, new.f1, 'updated'::varchar)
+  WHERE trgt.f1 = new.f1 RETURNING new.*;
+\d+ rule_t1
+                                  Table "public.rule_t1"
+ Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description 
+--------+---------+-----------+----------+---------+---------+--------------+-------------
+ f1     | integer |           |          |         | plain   |              | 
+ f2     | integer |           |          |         | plain   |              | 
+Rules:
+    rr AS
+    ON UPDATE TO rule_t1 DO INSTEAD  UPDATE rule_dest trgt SET (f2[1], f1, tag) = ( SELECT new.f2,
+            new.f1,
+            'updated'::character varying AS "varchar")
+  WHERE trgt.f1 = new.f1
+  RETURNING new.f1,
+    new.f2
+
+drop table rule_t1, rule_dest;
 --
 -- check alter rename rule
 --
index be5d90727a9fa41e8145b53e7a6b1ef6fa404c8a..e7af0bf2fa46807f12ca33adbbb7058e51b35c16 100644 (file)
@@ -607,6 +607,41 @@ select pg_get_viewdef('tt23v', true);
 select pg_get_ruledef(oid, true) from pg_rewrite
   where ev_class = 'tt23v'::regclass and ev_type = '1';
 
+-- test extraction of FieldSelect field names (get_name_for_var_field)
+
+create view tt24v as
+with cte as materialized (select r from (values(1,2),(3,4)) r)
+select (r).column2 as col_a, (rr).column2 as col_b from
+  cte join (select rr from (values(1,7),(3,8)) rr limit 2) ss
+  on (r).column1 = (rr).column1;
+select pg_get_viewdef('tt24v', true);
+create view tt25v as
+with cte as materialized (select pg_get_keywords() k)
+select (k).word from cte;
+select pg_get_viewdef('tt25v', true);
+-- also check cases seen only in EXPLAIN
+explain (verbose, costs off)
+select * from tt24v;
+explain (verbose, costs off)
+select (r).column2 from (select r from (values(1,2),(3,4)) r limit 1) ss;
+
+-- test pretty-print parenthesization rules, and SubLink deparsing
+
+create view tt26v as
+select x + y + z as c1,
+       (x * y) + z as c2,
+       x + (y * z) as c3,
+       (x + y) * z as c4,
+       x * (y + z) as c5,
+       x + (y + z) as c6,
+       x + (y # z) as c7,
+       (x > y) AND (y > z OR x > z) as c8,
+       (x > y) OR (y > z AND NOT (x > z)) as c9,
+       (x,y) <> ALL (values(1,2),(3,4)) as c10,
+       (x,y) <= ANY (values(1,2),(3,4)) as c11
+from (values(1,2,3)) v(x,y,z);
+select pg_get_viewdef('tt26v', true);
+
 -- clean up all the random objects we made above
 DROP SCHEMA temp_view_test CASCADE;
 DROP SCHEMA testviewschm2 CASCADE;
index b7d7f434b6a5b8d15f5226f57f305bc705ee819e..744cf7ab546e09f36a47e9c0b1104a6e1b36a449 100644 (file)
@@ -1014,6 +1014,17 @@ create rule r4 as on insert to rules_src do instead insert into rules_log AS trg
 create rule r5 as on update to rules_src do instead UPDATE rules_log AS trgt SET tag = 'updated' WHERE trgt.f1 = new.f1;
 \d+ rules_src
 
+--
+-- Also check multiassignment deparsing.
+--
+create table rule_t1(f1 int, f2 int);
+create table rule_dest(f1 int, f2 int[], tag text);
+create rule rr as on update to rule_t1 do instead UPDATE rule_dest trgt
+  SET (f2[1], f1, tag) = (SELECT new.f2, new.f1, 'updated'::varchar)
+  WHERE trgt.f1 = new.f1 RETURNING new.*;
+\d+ rule_t1
+drop table rule_t1, rule_dest;
+
 --
 -- check alter rename rule
 --