]> granicus.if.org Git - postgresql/commitdiff
Turns out new IN implementation has got some problems in an UPDATE or
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 5 Mar 2003 20:01:04 +0000 (20:01 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 5 Mar 2003 20:01:04 +0000 (20:01 +0000)
DELETE with inherited target table.  Fix it; add a regression test.
Also, correct ancient misspelling of 'inherited'.

src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/optimizer/path/allpaths.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/prep/prepunion.c
src/include/optimizer/prep.h
src/test/regress/expected/inherit.out
src/test/regress/sql/inherit.sql

index 2698f084787f758ddd6d1c5a68becb19b4c0d80b..627f62c84f8c27d6cc541ca11ce9b0657fd27e09 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.244 2003/02/16 02:30:37 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.245 2003/03/05 20:01:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1481,12 +1481,16 @@ _copyQuery(Query *from)
        COPY_NODE_FIELD(limitCount);
        COPY_NODE_FIELD(setOperations);
        COPY_INTLIST_FIELD(resultRelations);
+       COPY_NODE_FIELD(in_info_list);
+       COPY_SCALAR_FIELD(hasJoinRTEs);
 
        /*
-        * We do not copy the planner internal fields: base_rel_list,
-        * other_rel_list, join_rel_list, equi_key_list, in_info_list,
-        * query_pathkeys, hasJoinRTEs.  That would get us into copying
-        * RelOptInfo/Path trees, which we don't want to do.
+        * We do not copy the other planner internal fields: base_rel_list,
+        * other_rel_list, join_rel_list, equi_key_list, query_pathkeys.
+        * That would get us into copying RelOptInfo/Path trees, which we don't
+        * want to do.  It is necessary to copy in_info_list and hasJoinRTEs
+        * for the benefit of inheritance_planner(), which may try to copy a
+        * Query in which these are already set.
         */
 
        return newnode;
index 378d8e44031895ae7357cddb4e4245684eeace53..6a0f36600979976a32290728e51ef66745ec5dee 100644 (file)
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.187 2003/02/16 02:30:37 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.188 2003/03/05 20:01:02 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -576,12 +576,14 @@ _equalQuery(Query *a, Query *b)
        COMPARE_NODE_FIELD(limitCount);
        COMPARE_NODE_FIELD(setOperations);
        COMPARE_INTLIST_FIELD(resultRelations);
+       COMPARE_NODE_FIELD(in_info_list);
+       COMPARE_SCALAR_FIELD(hasJoinRTEs);
 
        /*
-        * We do not check the internal-to-the-planner fields: base_rel_list,
-        * other_rel_list, join_rel_list, equi_key_list, in_info_list,
-        * query_pathkeys, hasJoinRTEs.  They might not be set yet, and in any
-        * case they should be derivable from the other fields.
+        * We do not check the other planner internal fields: base_rel_list,
+        * other_rel_list, join_rel_list, equi_key_list, query_pathkeys.
+        * They might not be set yet, and in any case they should be derivable
+        * from the other fields.
         */
        return true;
 }
index 24a604716b8af704046d4bca6db7d9ca2dff6ef3..99d979d57c07dd5fae16353531a5e0a877f5f1cd 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.97 2003/02/15 20:12:40 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.98 2003/03/05 20:01:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -115,7 +115,7 @@ set_base_rel_pathlists(Query *root)
                        /* RangeFunction --- generate a separate plan for it */
                        set_function_pathlist(root, rel, rte);
                }
-               else if ((inheritlist = expand_inherted_rtentry(root, rti, true))
+               else if ((inheritlist = expand_inherited_rtentry(root, rti, true))
                                 != NIL)
                {
                        /* Relation is root of an inheritance tree, process specially */
index c597e44f1d46b7b8ec0322dead4122c0d23dae17..c7c072fe2eba3e02a979726469a2229154c51f3b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.149 2003/03/05 18:38:14 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.150 2003/03/05 20:01:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -276,8 +276,8 @@ subquery_planner(Query *parse, double tuple_fraction)
         * grouping_planner.
         */
        if (parse->resultRelation &&
-        (lst = expand_inherted_rtentry(parse, parse->resultRelation, false))
-               != NIL)
+               (lst = expand_inherited_rtentry(parse, parse->resultRelation,
+                                                                               false)) != NIL)
                plan = inheritance_planner(parse, lst);
        else
                plan = grouping_planner(parse, tuple_fraction);
index 0f63d2306c72846aaa06b182589f18e73137aa1a..f0a64f2980c240924a1d82fa65460bd1fcea2354 100644 (file)
@@ -14,7 +14,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.90 2003/02/09 06:56:27 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.91 2003/03/05 20:01:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -642,7 +642,7 @@ find_all_inheritors(Oid parentrel)
 }
 
 /*
- * expand_inherted_rtentry
+ * expand_inherited_rtentry
  *             Check whether a rangetable entry represents an inheritance set.
  *             If so, add entries for all the child tables to the query's
  *             rangetable, and return an integer list of RT indexes for the
@@ -666,7 +666,7 @@ find_all_inheritors(Oid parentrel)
  * XXX probably should convert the result type to Relids?
  */
 List *
-expand_inherted_rtentry(Query *parse, Index rti, bool dup_parent)
+expand_inherited_rtentry(Query *parse, Index rti, bool dup_parent)
 {
        RangeTblEntry *rte = rt_fetch(rti, parse->rtable);
        Oid                     parentOID;
index 681d1c2eb1dc20f35ebb12d277c76d314ad0c443..5cde6096a1e9d9454c64038b3f8e2cc612db6413 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: prep.h,v 1.37 2003/02/09 23:57:19 tgl Exp $
+ * $Id: prep.h,v 1.38 2003/03/05 20:01:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -52,7 +52,7 @@ extern Plan *plan_set_operations(Query *parse);
 
 extern List *find_all_inheritors(Oid parentrel);
 
-extern List *expand_inherted_rtentry(Query *parse, Index rti,
+extern List *expand_inherited_rtentry(Query *parse, Index rti,
                                                bool dup_parent);
 
 extern Node *adjust_inherited_attrs(Node *node,
index 6ca59e799bf35cc3c88295f1b92880573582b0d2..e6fc8bcb575f71d675ec48e0c29048f66ba252f8 100644 (file)
@@ -539,3 +539,34 @@ CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a);
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index 'z_pkey' for table 'z'
 INSERT INTO z VALUES (NULL, 'text'); -- should fail
 ERROR:  ExecInsert: Fail to add null value in not null attribute aa
+-- Check UPDATE with inherited target and an inherited source table
+create temp table foo(f1 int, f2 int);
+create temp table foo2(f3 int) inherits (foo);
+create temp table bar(f1 int, f2 int);
+create temp table bar2(f3 int) inherits (bar);
+insert into foo values(1,1);
+insert into foo values(3,3);
+insert into foo2 values(2,2,2);
+insert into foo2 values(3,3,3);
+insert into bar values(1,1);
+insert into bar values(2,2);
+insert into bar values(3,3);
+insert into bar values(4,4);
+insert into bar2 values(1,1,1);
+insert into bar2 values(2,2,2);
+insert into bar2 values(3,3,3);
+insert into bar2 values(4,4,4);
+update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
+SELECT relname, bar.* FROM bar, pg_class where bar.tableoid = pg_class.oid;
+ relname | f1 | f2  
+---------+----+-----
+ bar     |  4 |   4
+ bar     |  1 | 101
+ bar     |  2 | 102
+ bar     |  3 | 103
+ bar2    |  4 |   4
+ bar2    |  1 | 101
+ bar2    |  2 | 102
+ bar2    |  3 | 103
+(8 rows)
+
index d8d73f8860f95264c72e3b6222ed6f790aa912f8..a50b5e75f93b729d5a9448ca6308e613bf87e462 100644 (file)
@@ -96,3 +96,26 @@ SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid;
 -- Confirm PRIMARY KEY adds NOT NULL constraint to child table
 CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a);
 INSERT INTO z VALUES (NULL, 'text'); -- should fail
+
+-- Check UPDATE with inherited target and an inherited source table
+create temp table foo(f1 int, f2 int);
+create temp table foo2(f3 int) inherits (foo);
+create temp table bar(f1 int, f2 int);
+create temp table bar2(f3 int) inherits (bar);
+
+insert into foo values(1,1);
+insert into foo values(3,3);
+insert into foo2 values(2,2,2);
+insert into foo2 values(3,3,3);
+insert into bar values(1,1);
+insert into bar values(2,2);
+insert into bar values(3,3);
+insert into bar values(4,4);
+insert into bar2 values(1,1,1);
+insert into bar2 values(2,2,2);
+insert into bar2 values(3,3,3);
+insert into bar2 values(4,4,4);
+
+update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
+
+SELECT relname, bar.* FROM bar, pg_class where bar.tableoid = pg_class.oid;