Add support for pushdown of Append and MergeAppend nodes.
authorPavan Deolasee <[email protected]>
Thu, 10 Mar 2016 11:13:32 +0000 (16:43 +0530)
committerPavan Deolasee <[email protected]>
Thu, 10 Mar 2016 11:13:32 +0000 (16:43 +0530)
While dealing with Append and MergeAppend pathnodes, we shouldn't be looking at
the Varno in the "distribution" information because each append subpath comes
from a different relation. So we devise a mechanism to compare distribution
strategies without comparing the Varnos.

Expected outputs of many test cases is also updated because Append and
MergeAppend plans are now pushed down to the datanodes when possible.

"misc" test case exhibited certain failures because of incorrect evaluation of
a "volatile" function on the datanode. This turned out to be an old bug which
should be fixed separately. There were existing failures, masked by incorrect
acceptance of the test output. All such sqls are now disabled from "misc" and
copied to xl_known_bugs. Once the bug related to the volatile functions is
fixed, we would enable those sqls again

17 files changed:
src/backend/nodes/equalfuncs.c
src/backend/optimizer/util/pathnode.c
src/include/nodes/nodes.h
src/test/regress/expected/aggregates.out
src/test/regress/expected/alter_table.out
src/test/regress/expected/collate.out
src/test/regress/expected/equivclass.out
src/test/regress/expected/inherit.out
src/test/regress/expected/insert_conflict.out
src/test/regress/expected/tablesample.out
src/test/regress/expected/union.out
src/test/regress/expected/xc_for_update.out
src/test/regress/expected/xl_known_bugs.out
src/test/regress/input/misc.source
src/test/regress/output/misc.source
src/test/regress/parallel_schedule
src/test/regress/sql/xl_known_bugs.sql

index 629e227cc77e6570eba48b261d79cf0f10a3e1cd..6c4b02fcab66e855558cb2daf81bc63428d12f07 100644 (file)
@@ -139,21 +139,44 @@ _equalIntoClause(const IntoClause *a, const IntoClause *b)
  */
 
 static bool
-_equalVar(const Var *a, const Var *b)
+_equalVarInternal(const Var *a, const Var *b, bool compareVarno)
 {
-       COMPARE_SCALAR_FIELD(varno);
+       if (compareVarno)
+               COMPARE_SCALAR_FIELD(varno);
        COMPARE_SCALAR_FIELD(varattno);
        COMPARE_SCALAR_FIELD(vartype);
        COMPARE_SCALAR_FIELD(vartypmod);
        COMPARE_SCALAR_FIELD(varcollid);
        COMPARE_SCALAR_FIELD(varlevelsup);
-       COMPARE_SCALAR_FIELD(varnoold);
+       if (compareVarno)
+               COMPARE_SCALAR_FIELD(varnoold);
        COMPARE_SCALAR_FIELD(varoattno);
        COMPARE_LOCATION_FIELD(location);
 
        return true;
 }
 
+static bool
+_equalVar(const Var *a, const Var *b)
+{
+       return _equalVarInternal(a, b, true);
+}
+
+/*
+ * Compare all fields in Var except varno
+ */
+bool
+equalVarExceptVarno(const void *a, const void *b)
+{
+       if (a == b)
+               return true;
+
+       if (a == NULL || b == NULL)
+               return false;
+
+       return _equalVarInternal(a, b, false);
+}
+
 static bool
 _equalConst(const Const *a, const Const *b)
 {
@@ -2565,14 +2588,32 @@ _equalXmlSerialize(const XmlSerialize *a, const XmlSerialize *b)
 
 #ifdef XCP
 static bool
-_equalDistribution(const Distribution *a, const Distribution *b)
+_equalDistribution(const Distribution *a, const Distribution *b,
+               bool exceptVarno)
 {
        COMPARE_SCALAR_FIELD(distributionType);
-       COMPARE_NODE_FIELD(distributionExpr);
        COMPARE_BITMAPSET_FIELD(nodes);
+       if (exceptVarno &&
+               a->distributionExpr && IsA(a->distributionExpr, Var) &&
+               b->distributionExpr && IsA(b->distributionExpr, Var))
+               return equalVarExceptVarno(a->distributionExpr, b->distributionExpr);
+       else
+               COMPARE_NODE_FIELD(distributionExpr);
 
        return true;
 }
+
+bool
+equalDistribution(const void *a, const void *b)
+{
+       if (a == b)
+               return true;
+
+       if (a == NULL || b == NULL)
+               return false;
+
+       return _equalDistribution(a, b, true);
+}
 #endif
 
 static bool
@@ -3429,7 +3470,7 @@ equal(const void *a, const void *b)
                        break;
 #ifdef XCP
                case T_Distribution:
-                       retval = _equalDistribution(a, b);
+                       retval = _equalDistribution(a, b, false);
                        break;
 #endif
                case T_RoleSpec:
index de84adade87e27fe22df1f3a9549c36b45bd3686..bab743aae1b391308cc53e15c3d2de5eaab06de7 100644 (file)
@@ -2037,7 +2037,16 @@ create_append_path(RelOptInfo *rel, List *subpaths, Relids required_outer)
                {
                        subpath = (Path *) lfirst(l);
 
-                       if (equal(distribution, subpath->distribution))
+                       /*
+                        * For Append and MergeAppend paths, we are most often dealing with
+                        * different relations, appended together. So its very likely that
+                        * the distribution for each relation will have a different varno.
+                        * But we should be able to push down Append and MergeAppend as
+                        * long as rest of the distribution information matches.
+                        *
+                        * equalDistribution() compares everything except the varnos
+                        */
+                       if (equalDistribution(distribution, subpath->distribution))
                        {
                                /*
                                 * Both distribution and subpath->distribution may be NULL at
@@ -2150,7 +2159,10 @@ create_merge_append_path(PlannerInfo *root,
                {
                        subpath = (Path *) lfirst(l);
 
-                       if (distribution && equal(distribution, subpath->distribution))
+                       /*
+                        * See comments in Append path
+                        */
+                       if (distribution && equalDistribution(distribution, subpath->distribution))
                        {
                                if (subpath->distribution->restrictNodes)
                                        distribution->restrictNodes = bms_union(
index 18d7f4f6b23c87b09a28c976edc3f1128ba6864f..ce46ff661f473f69023243962164cefb49de1da0 100644 (file)
@@ -585,6 +585,7 @@ extern void *copyObject(const void *obj);
 /*
  * nodes/equalfuncs.c
  */
+extern bool equalDistribution(const void *a, const void *b);
 extern bool equal(const void *a, const void *b);
 
 
index 2012e5778a5ecf3e8f55ff9c379dff6f31030ced..44c323f18f45bd5c95dc66fb57cbbfd26ce94d5b 100644 (file)
@@ -797,19 +797,17 @@ insert into minmaxtest2 values(15), (16);
 insert into minmaxtest3 values(17), (18);
 explain (costs off, nodes off)
   select min(f1), max(f1) from minmaxtest;
-                QUERY PLAN                 
--------------------------------------------
+                   QUERY PLAN                    
+-------------------------------------------------
  Aggregate
-   ->  Append
-         ->  Remote Subquery Scan on all
-               ->  Seq Scan on minmaxtest
-         ->  Remote Subquery Scan on all
-               ->  Seq Scan on minmaxtest1
-         ->  Remote Subquery Scan on all
-               ->  Seq Scan on minmaxtest2
-         ->  Remote Subquery Scan on all
-               ->  Seq Scan on minmaxtest3
-(10 rows)
+   ->  Remote Subquery Scan on all
+         ->  Aggregate
+               ->  Append
+                     ->  Seq Scan on minmaxtest
+                     ->  Seq Scan on minmaxtest1
+                     ->  Seq Scan on minmaxtest2
+                     ->  Seq Scan on minmaxtest3
+(8 rows)
 
 select min(f1), max(f1) from minmaxtest;
  min | max 
@@ -820,21 +818,19 @@ select min(f1), max(f1) from minmaxtest;
 -- DISTINCT doesn't do anything useful here, but it shouldn't fail
 explain (costs off)
   select distinct min(f1), max(f1) from minmaxtest;
-                              QUERY PLAN                               
------------------------------------------------------------------------
+                           QUERY PLAN                            
+-----------------------------------------------------------------
  HashAggregate
-   Group Key: min(minmaxtest.f1), max(minmaxtest.f1)
+   Group Key: min((min(f1))), max((max(f1)))
    ->  Aggregate
-         ->  Append
-               ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                     ->  Seq Scan on minmaxtest
-               ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                     ->  Seq Scan on minmaxtest1
-               ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                     ->  Seq Scan on minmaxtest2
-               ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                     ->  Seq Scan on minmaxtest3
-(12 rows)
+         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
+               ->  Aggregate
+                     ->  Append
+                           ->  Seq Scan on minmaxtest
+                           ->  Seq Scan on minmaxtest1
+                           ->  Seq Scan on minmaxtest2
+                           ->  Seq Scan on minmaxtest3
+(10 rows)
 
 select distinct min(f1), max(f1) from minmaxtest;
  min | max 
index 03e5a7ba9d9580b97672c48238014d6ec8159c16..37d83cbfc57b0b12c94fbf1cceb27bd6f7230dbe 100644 (file)
@@ -386,68 +386,59 @@ alter table nv_child_2011 add check (d between '2011-01-01'::date and '2011-12-3
 explain (costs off, nodes off) select * from nv_parent where d between '2011-08-01' and '2011-08-31';
                                    QUERY PLAN                                    
 ---------------------------------------------------------------------------------
- Append
-   ->  Remote Subquery Scan on all
+ Remote Subquery Scan on all
+   ->  Append
          ->  Seq Scan on nv_parent
                Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
-   ->  Remote Subquery Scan on all
          ->  Seq Scan on nv_child_2010
                Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
-   ->  Remote Subquery Scan on all
          ->  Seq Scan on nv_child_2011
                Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
-(10 rows)
+(8 rows)
 
 create table nv_child_2009 (check (d between '2009-01-01'::date and '2009-12-31'::date)) inherits (nv_parent);
 explain (costs off, nodes off) select * from nv_parent where d between '2011-08-01'::date and '2011-08-31'::date;
                                    QUERY PLAN                                    
 ---------------------------------------------------------------------------------
- Append
-   ->  Remote Subquery Scan on all
+ Remote Subquery Scan on all
+   ->  Append
          ->  Seq Scan on nv_parent
                Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
-   ->  Remote Subquery Scan on all
          ->  Seq Scan on nv_child_2010
                Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
-   ->  Remote Subquery Scan on all
          ->  Seq Scan on nv_child_2011
                Filter: ((d >= '08-01-2011'::date) AND (d <= '08-31-2011'::date))
-(10 rows)
+(8 rows)
 
 explain (costs off, nodes off) select * from nv_parent where d between '2009-08-01'::date and '2009-08-31'::date;
                                    QUERY PLAN                                    
 ---------------------------------------------------------------------------------
- Append
-   ->  Remote Subquery Scan on all
+ Remote Subquery Scan on all
+   ->  Append
          ->  Seq Scan on nv_parent
                Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-   ->  Remote Subquery Scan on all
          ->  Seq Scan on nv_child_2010
                Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-   ->  Remote Subquery Scan on all
          ->  Seq Scan on nv_child_2011
                Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-   ->  Remote Subquery Scan on all
          ->  Seq Scan on nv_child_2009
                Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-(13 rows)
+(10 rows)
 
 -- after validation, the constraint should be used
 alter table nv_child_2011 VALIDATE CONSTRAINT nv_child_2011_d_check;
 explain (costs off, nodes off) select * from nv_parent where d between '2009-08-01'::date and '2009-08-31'::date;
                                    QUERY PLAN                                    
 ---------------------------------------------------------------------------------
- Append
-   ->  Remote Subquery Scan on all
+ Remote Subquery Scan on all
+   ->  Append
          ->  Seq Scan on nv_parent
                Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-   ->  Remote Subquery Scan on all
          ->  Seq Scan on nv_child_2010
                Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-   ->  Remote Subquery Scan on all
          ->  Seq Scan on nv_child_2009
                Filter: ((d >= '08-01-2009'::date) AND (d <= '08-31-2009'::date))
-(10 rows)
+(8 rows)
 
 -- add an inherited NOT VALID constraint
 alter table nv_parent add check (d between '2001-01-01'::date and '2099-12-31'::date) not valid;
index 2c037682f339c50bc334593ceb12c0ba4cc24ea9..313378a922105bb3783d045be3eb3a3637ae7863 100644 (file)
@@ -429,12 +429,12 @@ HINT:  Use the COLLATE clause to set the collation explicitly.
 ---+-----
  1 | abc
  2 | Abc
- 3 | bbc
- 4 | ABD
  1 | abc
  2 | Abc
  3 | bbc
  4 | ABD
+ 3 | bbc
+ 4 | ABD
 (8 rows)
 
 SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; -- fail
index 3c8af50ce77d4dfa2ae16516d2761c8766019c19..4be2ba05470cbffa92b4db635c22b31ff02a191c 100644 (file)
@@ -236,18 +236,17 @@ explain (costs off)
                            QUERY PLAN                            
 -----------------------------------------------------------------
  Nested Loop
-   Join Filter: ((((ec1_1.ff + 2) + 1)) = ec1.f1)
+   Join Filter: (x = ec1.f1)
    ->  Remote Subquery Scan on all (datanode_1)
          ->  Index Scan using ec1_pkey on ec1
                Index Cond: (ff = '42'::bigint)
-   ->  Append
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Seq Scan on ec1 ec1_1
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Seq Scan on ec1 ec1_2
+   ->  Materialize
          ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Seq Scan on ec1 ec1_3
-(12 rows)
+               ->  Append
+                     ->  Seq Scan on ec1 ec1_1
+                     ->  Seq Scan on ec1 ec1_2
+                     ->  Seq Scan on ec1 ec1_3
+(11 rows)
 
 explain (costs off)
   select * from ec1,
@@ -261,22 +260,21 @@ explain (costs off)
                                QUERY PLAN                                
 -------------------------------------------------------------------------
  Nested Loop
-   Join Filter: ((((ec1_1.ff + 2) + 1)) = ec1.f1)
+   Join Filter: (x = ec1.f1)
    ->  Remote Subquery Scan on all (datanode_1)
          ->  Index Scan using ec1_pkey on ec1
                Index Cond: ((ff = '42'::bigint) AND (ff = '42'::bigint))
                Filter: (ff = f1)
-   ->  Append
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Seq Scan on ec1 ec1_1
-                     Filter: (((ff + 2) + 1) = '42'::bigint)
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Seq Scan on ec1 ec1_2
-                     Filter: (((ff + 3) + 1) = '42'::bigint)
+   ->  Materialize
          ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Seq Scan on ec1 ec1_3
-                     Filter: ((ff + 4) = '42'::bigint)
-(16 rows)
+               ->  Append
+                     ->  Seq Scan on ec1 ec1_1
+                           Filter: (((ff + 2) + 1) = '42'::bigint)
+                     ->  Seq Scan on ec1 ec1_2
+                           Filter: (((ff + 3) + 1) = '42'::bigint)
+                     ->  Seq Scan on ec1 ec1_3
+                           Filter: ((ff + 4) = '42'::bigint)
+(15 rows)
 
 explain (costs off)
   select * from ec1,
@@ -296,28 +294,25 @@ explain (costs off)
                                  QUERY PLAN                                  
 -----------------------------------------------------------------------------
  Nested Loop
-   Join Filter: ((((ec1_1.ff + 2) + 1)) = (((ec1_4.ff + 2) + 1)))
-   ->  Append
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
+   Join Filter: (x = x)
+   ->  Remote Subquery Scan on all (datanode_1,datanode_2)
+         ->  Append
                ->  Seq Scan on ec1 ec1_4
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
                ->  Seq Scan on ec1 ec1_5
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
                ->  Seq Scan on ec1 ec1_6
    ->  Materialize
          ->  Nested Loop
-               Join Filter: ((((ec1_1.ff + 2) + 1)) = ec1.f1)
+               Join Filter: (x = ec1.f1)
                ->  Remote Subquery Scan on all (datanode_1)
                      ->  Index Scan using ec1_pkey on ec1
                            Index Cond: (ff = '42'::bigint)
-               ->  Append
-                     ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                           ->  Seq Scan on ec1 ec1_1
-                     ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                           ->  Seq Scan on ec1 ec1_2
+               ->  Materialize
                      ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                           ->  Seq Scan on ec1 ec1_3
-(22 rows)
+                           ->  Append
+                                 ->  Seq Scan on ec1 ec1_1
+                                 ->  Seq Scan on ec1 ec1_2
+                                 ->  Seq Scan on ec1 ec1_3
+(19 rows)
 
 -- let's try that as a mergejoin
 set enable_mergejoin = on;
@@ -341,18 +336,17 @@ explain (costs off)
                            QUERY PLAN                            
 -----------------------------------------------------------------
  Nested Loop
-   Join Filter: ((((ec1_1.ff + 2) + 1)) = ec1.f1)
+   Join Filter: (x = ec1.f1)
    ->  Remote Subquery Scan on all (datanode_1)
          ->  Index Scan using ec1_pkey on ec1
                Index Cond: (ff = '42'::bigint)
-   ->  Append
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Seq Scan on ec1 ec1_1
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Seq Scan on ec1 ec1_2
+   ->  Materialize
          ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Seq Scan on ec1 ec1_3
-(12 rows)
+               ->  Append
+                     ->  Seq Scan on ec1 ec1_1
+                     ->  Seq Scan on ec1 ec1_2
+                     ->  Seq Scan on ec1 ec1_3
+(11 rows)
 
 -- let's try that as a mergejoin
 set enable_mergejoin = on;
index 224972d5a6269400c9ab9157571472495b2fba58..6adf1695eed2b4ed9da618667a64ac1a2b85bc47 100644 (file)
@@ -777,42 +777,40 @@ 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);
-ERROR:  could not plan this distributed update
-DETAIL:  correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
 --select tableoid::regclass::text as relname, bar.* from bar order by 1,2;
 -- In Postgres-XL OIDs are not consistent across the cluster. Hence above
 -- queries do not show any result. Hence in order to ensure data consistency, we
 -- add following SQLs. In case above set of queries start producing valid
 -- results in XC, we should remove the following set
 SELECT * FROM bar ORDER BY f1, f2;
- f1 | f2 
-----+----
-  1 |  1
-  1 |  1
-  2 |  2
-  2 |  2
-  3 |  3
-  3 |  3
-  4 |  4
-  4 |  4
+ f1 | f2  
+----+-----
+  1 | 101
+  1 | 101
+  2 | 102
+  2 | 102
+  3 | 103
+  3 | 103
+  4 |   4
+  4 |   4
 (8 rows)
 
 SELECT * FROM ONLY bar ORDER BY f1, f2;
- f1 | f2 
-----+----
-  1 |  1
-  2 |  2
-  3 |  3
-  4 |  4
+ f1 | f2  
+----+-----
+  1 | 101
+  2 | 102
+  3 | 103
+  4 |   4
 (4 rows)
 
 SELECT * FROM bar2 ORDER BY f1, f2;
- f1 | f2 | f3 
-----+----+----
-  1 |  1 |  1
-  2 |  2 |  2
-  3 |  3 |  3
-  4 |  4 |  4
+ f1 | f2  | f3 
+----+-----+----
+  1 | 101 |  1
+  2 | 102 |  2
+  3 | 103 |  3
+  4 |   4 |  4
 (4 rows)
 
 -- Check UPDATE with inherited target and an appendrel subquery
@@ -820,8 +818,6 @@ update bar set f2 = f2 + 100
 from
   ( select f1 from foo union all select f1+3 from foo ) ss
 where bar.f1 = ss.f1;
-ERROR:  could not plan this distributed update
-DETAIL:  correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
 --select tableoid::regclass::text as relname, bar.* from bar order by 1,2;
 /* Test multiple inheritance of column defaults */
 CREATE TABLE firstparent (tomorrow date default now()::date + 1);
@@ -1371,29 +1367,28 @@ analyze patest2;
 analyze int4_tbl;
 explain (costs off, num_nodes off, nodes off)
 select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
-                        QUERY PLAN                        
-----------------------------------------------------------
+                           QUERY PLAN                           
+----------------------------------------------------------------
  Nested Loop
    ->  Limit
          ->  Remote Subquery Scan on all
                ->  Limit
                      ->  Seq Scan on int4_tbl
                            Filter: (f1 = 0)
-   ->  Append
+   ->  Materialize
          ->  Remote Subquery Scan on all
-               ->  Seq Scan on patest0
-                     Filter: (int4_tbl.f1 = id)
-         ->  Remote Subquery Scan on all
-               ->  Bitmap Heap Scan on patest1
-                     Recheck Cond: (id = int4_tbl.f1)
-                     ->  Bitmap Index Scan on patest1i
-                           Index Cond: (id = int4_tbl.f1)
-         ->  Remote Subquery Scan on all
-               ->  Bitmap Heap Scan on patest2
-                     Recheck Cond: (id = int4_tbl.f1)
-                     ->  Bitmap Index Scan on patest2i
-                           Index Cond: (id = int4_tbl.f1)
-(20 rows)
+               ->  Append
+                     ->  Seq Scan on patest0
+                           Filter: (int4_tbl.f1 = id)
+                     ->  Bitmap Heap Scan on patest1
+                           Recheck Cond: (id = int4_tbl.f1)
+                           ->  Bitmap Index Scan on patest1i
+                                 Index Cond: (id = int4_tbl.f1)
+                     ->  Bitmap Heap Scan on patest2
+                           Recheck Cond: (id = int4_tbl.f1)
+                           ->  Bitmap Index Scan on patest2i
+                                 Index Cond: (id = int4_tbl.f1)
+(19 rows)
 
 select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
  id | x | f1 
@@ -1406,27 +1401,26 @@ select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on
 drop index patest2i;
 explain (costs off, num_nodes off, nodes off)
 select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
-                        QUERY PLAN                        
-----------------------------------------------------------
+                           QUERY PLAN                           
+----------------------------------------------------------------
  Nested Loop
    ->  Limit
          ->  Remote Subquery Scan on all
                ->  Limit
                      ->  Seq Scan on int4_tbl
                            Filter: (f1 = 0)
-   ->  Append
+   ->  Materialize
          ->  Remote Subquery Scan on all
-               ->  Seq Scan on patest0
-                     Filter: (int4_tbl.f1 = id)
-         ->  Remote Subquery Scan on all
-               ->  Bitmap Heap Scan on patest1
-                     Recheck Cond: (id = int4_tbl.f1)
-                     ->  Bitmap Index Scan on patest1i
-                           Index Cond: (id = int4_tbl.f1)
-         ->  Remote Subquery Scan on all
-               ->  Seq Scan on patest2
-                     Filter: (int4_tbl.f1 = id)
-(18 rows)
+               ->  Append
+                     ->  Seq Scan on patest0
+                           Filter: (int4_tbl.f1 = id)
+                     ->  Bitmap Heap Scan on patest1
+                           Recheck Cond: (id = int4_tbl.f1)
+                           ->  Bitmap Index Scan on patest1i
+                                 Index Cond: (id = int4_tbl.f1)
+                     ->  Seq Scan on patest2
+                           Filter: (int4_tbl.f1 = id)
+(17 rows)
 
 select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
  id | x | f1 
@@ -1462,31 +1456,25 @@ insert into matest3 (name) values ('Test 5');
 insert into matest3 (name) values ('Test 6');
 set enable_indexscan = off;  -- force use of seqscan/sort, so no merge
 explain (verbose, costs off, nodes off) select * from matest0 order by 1-id;
-                         QUERY PLAN                         
-------------------------------------------------------------
- Sort
-   Output: matest0.id, matest0.name, ((1 - matest0.id))
-   Sort Key: ((1 - matest0.id))
-   ->  Result
-         Output: matest0.id, matest0.name, (1 - matest0.id)
-         ->  Append
-               ->  Remote Subquery Scan on all
-                     Output: matest0.id, matest0.name
+                            QUERY PLAN                            
+------------------------------------------------------------------
+ Remote Subquery Scan on all
+   Output: id, name, (1 - id)
+   ->  Sort
+         Output: matest0.id, matest0.name, ((1 - matest0.id))
+         Sort Key: ((1 - matest0.id))
+         ->  Result
+               Output: matest0.id, matest0.name, (1 - matest0.id)
+               ->  Append
                      ->  Seq Scan on public.matest0
                            Output: matest0.id, matest0.name
-               ->  Remote Subquery Scan on all
-                     Output: matest1.id, matest1.name
                      ->  Seq Scan on public.matest1
                            Output: matest1.id, matest1.name
-               ->  Remote Subquery Scan on all
-                     Output: matest2.id, matest2.name
                      ->  Seq Scan on public.matest2
                            Output: matest2.id, matest2.name
-               ->  Remote Subquery Scan on all
-                     Output: matest3.id, matest3.name
                      ->  Seq Scan on public.matest3
                            Output: matest3.id, matest3.name
-(22 rows)
+(16 rows)
 
 select * from matest0 order by 1-id;
  id |  name  
@@ -1500,28 +1488,24 @@ select * from matest0 order by 1-id;
 (6 rows)
 
 explain (verbose, costs off) select min(1-id) from matest0;
-                           QUERY PLAN                            
------------------------------------------------------------------
+                        QUERY PLAN                         
+-----------------------------------------------------------
  Aggregate
-   Output: min((1 - matest0.id))
-   ->  Append
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               Output: matest0.id
-               ->  Seq Scan on public.matest0
-                     Output: matest0.id
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               Output: matest1.id
-               ->  Seq Scan on public.matest1
-                     Output: matest1.id
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               Output: matest2.id
-               ->  Seq Scan on public.matest2
-                     Output: matest2.id
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               Output: matest3.id
-               ->  Seq Scan on public.matest3
-                     Output: matest3.id
-(19 rows)
+   Output: min((min((1 - id))))
+   ->  Remote Subquery Scan on all (datanode_1,datanode_2)
+         Output: min((1 - id))
+         ->  Aggregate
+               Output: min((1 - matest0.id))
+               ->  Append
+                     ->  Seq Scan on public.matest0
+                           Output: matest0.id
+                     ->  Seq Scan on public.matest1
+                           Output: matest1.id
+                     ->  Seq Scan on public.matest2
+                           Output: matest2.id
+                     ->  Seq Scan on public.matest3
+                           Output: matest3.id
+(15 rows)
 
 select min(1-id) from matest0;
  min 
@@ -1532,30 +1516,25 @@ select min(1-id) from matest0;
 reset enable_indexscan;
 set enable_seqscan = off;  -- plan with fewest seqscans should be merge
 explain (verbose, costs off, nodes off) select * from matest0 order by 1-id;
-                               QUERY PLAN                               
-------------------------------------------------------------------------
- Merge Append
-   Sort Key: ((1 - matest0.id))
-   ->  Remote Subquery Scan on all
-         Output: matest0.id, matest0.name, (1 - matest0.id)
-         ->  Index Scan using matest0i on public.matest0
+                             QUERY PLAN                              
+---------------------------------------------------------------------
+ Remote Subquery Scan on all
+   Output: id, name, (1 - id)
+   ->  Sort
+         Output: matest0.id, matest0.name, ((1 - matest0.id))
+         Sort Key: ((1 - matest0.id))
+         ->  Result
                Output: matest0.id, matest0.name, (1 - matest0.id)
-   ->  Remote Subquery Scan on all
-         Output: matest1.id, matest1.name, (1 - matest1.id)
-         ->  Index Scan using matest1i on public.matest1
-               Output: matest1.id, matest1.name, (1 - matest1.id)
-   ->  Remote Subquery Scan on all
-         Output: matest2.id, matest2.name, (1 - matest2.id)
-         ->  Sort
-               Output: matest2.id, matest2.name, ((1 - matest2.id))
-               Sort Key: ((1 - matest2.id))
-               ->  Seq Scan on public.matest2
-                     Output: matest2.id, matest2.name, (1 - matest2.id)
-   ->  Remote Subquery Scan on all
-         Output: matest3.id, matest3.name, (1 - matest3.id)
-         ->  Index Scan using matest3i on public.matest3
-               Output: matest3.id, matest3.name, (1 - matest3.id)
-(21 rows)
+               ->  Append
+                     ->  Index Scan using matest0i on public.matest0
+                           Output: matest0.id, matest0.name
+                     ->  Index Scan using matest1i on public.matest1
+                           Output: matest1.id, matest1.name
+                     ->  Seq Scan on public.matest2
+                           Output: matest2.id, matest2.name
+                     ->  Index Scan using matest3i on public.matest3
+                           Output: matest3.id, matest3.name
+(16 rows)
 
 select * from matest0 order by 1-id;
  id |  name  
@@ -1569,42 +1548,27 @@ select * from matest0 order by 1-id;
 (6 rows)
 
 explain (verbose, costs off) select min(1-id) from matest0;
-                                   QUERY PLAN                                   
---------------------------------------------------------------------------------
- Result
-   Output: $0
-   InitPlan 1 (returns $0)
-     ->  Limit
-           Output: ((1 - matest0.id))
-           ->  Result
-                 Output: ((1 - matest0.id))
-                 ->  Merge Append
-                       Sort Key: ((1 - matest0.id))
-                       ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                             Output: matest0.id, (1 - matest0.id)
-                             ->  Index Scan using matest0i on public.matest0
-                                   Output: matest0.id, (1 - matest0.id)
-                                   Index Cond: ((1 - matest0.id) IS NOT NULL)
-                       ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                             Output: matest1.id, (1 - matest1.id)
-                             ->  Index Scan using matest1i on public.matest1
-                                   Output: matest1.id, (1 - matest1.id)
-                                   Index Cond: ((1 - matest1.id) IS NOT NULL)
-                       ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                             Output: matest2.id, (1 - matest2.id)
-                             ->  Sort
-                                   Output: matest2.id, ((1 - matest2.id))
-                                   Sort Key: ((1 - matest2.id))
-                                   ->  Bitmap Heap Scan on public.matest2
-                                         Output: matest2.id, (1 - matest2.id)
-                                         Filter: ((1 - matest2.id) IS NOT NULL)
-                                         ->  Bitmap Index Scan on matest2_pkey
-                       ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                             Output: matest3.id, (1 - matest3.id)
-                             ->  Index Scan using matest3i on public.matest3
-                                   Output: matest3.id, (1 - matest3.id)
-                                   Index Cond: ((1 - matest3.id) IS NOT NULL)
-(33 rows)
+                                  QUERY PLAN                                  
+------------------------------------------------------------------------------
+ Aggregate
+   Output: min((min((1 - id))))
+   ->  Remote Subquery Scan on all (datanode_1,datanode_2)
+         Output: min((1 - id))
+         ->  Aggregate
+               Output: min((1 - matest0.id))
+               ->  Append
+                     ->  Index Only Scan using matest0_pkey on public.matest0
+                           Output: matest0.id
+                     ->  Bitmap Heap Scan on public.matest1
+                           Output: matest1.id
+                           ->  Bitmap Index Scan on matest1_pkey
+                     ->  Bitmap Heap Scan on public.matest2
+                           Output: matest2.id
+                           ->  Bitmap Index Scan on matest2_pkey
+                     ->  Bitmap Heap Scan on public.matest3
+                           Output: matest3.id
+                           ->  Bitmap Index Scan on matest3_pkey
+(18 rows)
 
 select min(1-id) from matest0;
  min 
@@ -1631,27 +1595,29 @@ explain (costs off)
 select t1.* from matest0 t1, matest0 t2
 where t1.b = t2.b and t2.c = t2.d
 order by t1.b limit 10;
-                                 QUERY PLAN                                  
------------------------------------------------------------------------------
+                                       QUERY PLAN                                        
+-----------------------------------------------------------------------------------------
  Limit
-   ->  Merge Join
-         Merge Cond: (t1.b = t2.b)
-         ->  Merge Append
-               Sort Key: t1.b
-               ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                     ->  Index Scan using matest0i on matest0 t1
-               ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                     ->  Index Scan using matest1i on matest1 t1_1
-         ->  Materialize
-               ->  Merge Append
-                     Sort Key: t2.b
-                     ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                           ->  Index Scan using matest0i on matest0 t2
-                                 Filter: (c = d)
-                     ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-                           ->  Index Scan using matest1i on matest1 t2_1
-                                 Filter: (c = d)
-(18 rows)
+   ->  Remote Subquery Scan on all (datanode_1,datanode_2)
+         ->  Limit
+               ->  Sort
+                     Sort Key: b
+                     ->  Hash Join
+                           Hash Cond: (b = b)
+                           ->  Remote Subquery Scan on all (datanode_1,datanode_2)
+                                 Distribute results by H: b
+                                 ->  Append
+                                       ->  Seq Scan on matest0 t1
+                                       ->  Seq Scan on matest1 t1_1
+                           ->  Hash
+                                 ->  Remote Subquery Scan on all (datanode_1,datanode_2)
+                                       Distribute results by H: b
+                                       ->  Append
+                                             ->  Seq Scan on matest0 t2
+                                                   Filter: (c = d)
+                                             ->  Seq Scan on matest1 t2_1
+                                                   Filter: (c = d)
+(20 rows)
 
 reset enable_nestloop;
 drop table matest0 cascade;
@@ -1687,15 +1653,13 @@ SELECT 42, 42, hundred FROM tenk1
 ORDER BY thousand, tenthous;
                                QUERY PLAN                               
 ------------------------------------------------------------------------
- Merge Append
-   Sort Key: tenk1.thousand, tenk1.tenthous
-   ->  Remote Subquery Scan on all
-         ->  Index Only Scan using tenk1_thous_tenthous on tenk1
-   ->  Remote Subquery Scan on all
-         ->  Sort
-               Sort Key: (42), (42)
+ Remote Subquery Scan on all
+   ->  Sort
+         Sort Key: tenk1.thousand, tenk1.tenthous
+         ->  Append
+               ->  Index Only Scan using tenk1_thous_tenthous on tenk1
                ->  Index Only Scan using tenk1_hundred on tenk1 tenk1_1
-(8 rows)
+(6 rows)
 
 explain (costs off, num_nodes off, nodes off)
 SELECT thousand, tenthous FROM tenk1
index 24df7d8e5fc3b6b5b72ddb3972680b9e32c6c08f..49a9b9fe1eacf4ebe898cc3f93c01a7ba4e44166 100644 (file)
@@ -529,10 +529,10 @@ insert into cities values ('Las Vegas', 5.83E+5, 2001) on conflict (name) do upd
 select * from cities;
      name      | population | altitude 
 ---------------+------------+----------
+ Madison       |     191300 |      845
  San Francisco |     724000 |       63
  Mariposa      |       1200 |     1953
  Las Vegas     |     583000 |     2001
- Madison       |     191300 |      845
  Sacramento    |  466400000 |       30
 (5 rows)
 
@@ -551,10 +551,10 @@ select * from capitals;
 select * from cities;
      name      | population | altitude 
 ---------------+------------+----------
+ Madison       |     191300 |      845
  San Francisco |     724000 |       63
  Mariposa      |       1200 |     1953
  Las Vegas     |     583000 |     2001
- Madison       |     191300 |      845
  Sacramento    |  466400000 |       30
  Las Vegas     |     583000 |     2222
 (6 rows)
@@ -564,10 +564,10 @@ insert into cities values ('Las Vegas', 5.86E+5, 2223) on conflict (name) do upd
 select * from cities;
      name      | population | altitude 
 ---------------+------------+----------
+ Madison       |     191300 |      845
  San Francisco |     724000 |       63
  Mariposa      |       1200 |     1953
  Las Vegas     |     586000 |     2223
- Madison       |     191300 |      845
  Sacramento    |  466400000 |       30
  Las Vegas     |     583000 |     2222
 (6 rows)
index 6ad56e4ceb2c6c7c52936821ca7eb29cb57ddfc3..12e87f06f80f5ee5fb2c3803c514a3814a70942e 100644 (file)
@@ -183,23 +183,21 @@ EXPLAIN (COSTS OFF)
 -- check inheritance behavior
 explain (costs off)
   select count(*) from person tablesample bernoulli (100);
-                           QUERY PLAN                            
------------------------------------------------------------------
+                         QUERY PLAN                          
+-------------------------------------------------------------
  Aggregate
-   ->  Append
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Sample Scan on person
-                     Sampling: bernoulli ('100'::real)
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Sample Scan on emp
-                     Sampling: bernoulli ('100'::real)
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Sample Scan on student
-                     Sampling: bernoulli ('100'::real)
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Sample Scan on stud_emp
-                     Sampling: bernoulli ('100'::real)
-(14 rows)
+   ->  Remote Subquery Scan on all (datanode_1,datanode_2)
+         ->  Aggregate
+               ->  Append
+                     ->  Sample Scan on person
+                           Sampling: bernoulli ('100'::real)
+                     ->  Sample Scan on emp
+                           Sampling: bernoulli ('100'::real)
+                     ->  Sample Scan on student
+                           Sampling: bernoulli ('100'::real)
+                     ->  Sample Scan on stud_emp
+                           Sampling: bernoulli ('100'::real)
+(12 rows)
 
 select count(*) from person tablesample bernoulli (100);
  count 
index cbc4a90655774f1a41c1c18bda86ce9aed3db5f1..7751fdaa5a25caec1bff08a04e00454a4d23ac91 100644 (file)
@@ -482,14 +482,13 @@ explain (num_nodes off, nodes off, costs off)
  WHERE ab = 'ab';
                     QUERY PLAN                     
 ---------------------------------------------------
- Append
-   ->  Remote Subquery Scan on all
+ Remote Subquery Scan on all
+   ->  Append
          ->  Index Scan using t1_ab_idx on t1
                Index Cond: ((a || b) = 'ab'::text)
-   ->  Remote Subquery Scan on all
          ->  Index Only Scan using t2_pkey on t2
                Index Cond: (ab = 'ab'::text)
-(7 rows)
+(6 rows)
 
 explain (num_nodes off, nodes off, costs off)
  SELECT * FROM
@@ -528,20 +527,19 @@ explain (costs off)
    UNION ALL
    SELECT ab FROM t2) t
   ORDER BY 1 LIMIT 8;
-                           QUERY PLAN                            
------------------------------------------------------------------
+                        QUERY PLAN                         
+-----------------------------------------------------------
  Limit
-   ->  Merge Append
-         Sort Key: ((t1.a || t1.b))
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Index Scan using t1_ab_idx on t1
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Index Scan using t1c_ab_idx on t1c
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Index Scan using t2_pkey on t2
-         ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-               ->  Index Scan using t2c_pkey on t2c
-(11 rows)
+   ->  Remote Subquery Scan on all (datanode_1,datanode_2)
+         ->  Limit
+               ->  Sort
+                     Sort Key: ((t1.a || t1.b))
+                     ->  Append
+                           ->  Seq Scan on t1
+                           ->  Seq Scan on t1c
+                           ->  Seq Scan on t2
+                           ->  Seq Scan on t2c
+(10 rows)
 
   SELECT * FROM
   (SELECT a || b AS ab FROM t1
@@ -573,19 +571,16 @@ select event_id
        union all
        select event_id from other_events) ss
  order by event_id;
-                           QUERY PLAN                           
-----------------------------------------------------------------
- Merge Append
-   Sort Key: events.event_id
-   ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-         ->  Index Scan using events_pkey on events
-   ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-         ->  Sort
-               Sort Key: events_child.event_id
+                     QUERY PLAN                      
+-----------------------------------------------------
+ Remote Subquery Scan on all (datanode_1,datanode_2)
+   ->  Sort
+         Sort Key: events.event_id
+         ->  Append
+               ->  Seq Scan on events
                ->  Seq Scan on events_child
-   ->  Remote Subquery Scan on all (datanode_1,datanode_2)
-         ->  Index Scan using other_events_pkey on other_events
-(10 rows)
+               ->  Seq Scan on other_events
+(7 rows)
 
 drop table events_child, events, other_events;
 reset enable_indexonlyscan;
@@ -706,17 +701,15 @@ select * from
   join int4_tbl on f1 = expensivefunc(x);
                             QUERY PLAN                            
 ------------------------------------------------------------------
- Nested Loop
-   ->  Remote Subquery Scan on all
+ Remote Subquery Scan on all
+   ->  Nested Loop
          ->  Seq Scan on int4_tbl
-   ->  Append
-         ->  Remote Subquery Scan on all
+         ->  Append
                ->  Index Scan using t3i on t3 a
                      Index Cond: (expensivefunc(x) = int4_tbl.f1)
-         ->  Remote Subquery Scan on all
                ->  Index Scan using t3i on t3 b
                      Index Cond: (expensivefunc(x) = int4_tbl.f1)
-(10 rows)
+(8 rows)
 
 select * from
   (select * from t3 a union all select * from t3 b) ss
index d6cbf7cbc439911291a9a8d0119a68eb0dc94a75..8b5c5afe203c2a68938396e19099373b91acbfff 100644 (file)
@@ -693,8 +693,8 @@ explain (costs off, num_nodes off, nodes off, verbose on)  WITH q1 AS (SELECT *
 select * from p1 order by 1 for update;
   a  |  b  
 -----+-----
-  55 |  66
   77 |  88
+  55 |  66
  111 | 222
  123 | 345
 (4 rows)
@@ -702,18 +702,16 @@ select * from p1 order by 1 for update;
 explain (costs off, num_nodes off, nodes off, verbose on)  select * from p1 for update;
                           QUERY PLAN                          
 --------------------------------------------------------------
- LockRows
-   Output: p1.a, p1.b, p1.ctid, p1.tableoid
-   ->  Append
-         ->  Remote Subquery Scan on all
-               Output: p1.a, p1.b, p1.ctid, p1.tableoid
+ Remote Subquery Scan on all
+   Output: a, b, ctid, tableoid
+   ->  LockRows
+         Output: p1.a, p1.b, p1.ctid, p1.tableoid
+         ->  Append
                ->  Seq Scan on public.p1
                      Output: p1.a, p1.b, p1.ctid, p1.tableoid
-         ->  Remote Subquery Scan on all
-               Output: c1.a, c1.b, c1.ctid, c1.tableoid
                ->  Seq Scan on public.c1
                      Output: c1.a, c1.b, c1.ctid, c1.tableoid
-(11 rows)
+(9 rows)
 
 select * from c1 order by 1 for update;
   a  |  b  |  d  |  e  
index 45f43702c212b02b1ceb97696e40f42de939c377..d0e588b4c1e441482c3db3247ef88787617725cf 100644 (file)
@@ -212,3 +212,486 @@ ERROR:  cannot drop table my_tab1 because other objects depend on it
 DETAIL:  function f1() depends on type my_tab1
 HINT:  Use DROP ... CASCADE to drop the dependent objects too.
 --------------------------------------------------
+-- 
+-- versions
+--
+-- Bugs related to pushing down volatile functions to datanodes - copied from
+-- misc.sql
+--
+-- postquel functions
+--
+--
+-- mike does post_hacking,
+-- joe and sally play basketball, and
+-- everyone else does nothing.
+--
+SELECT p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2;
+ name |    name     
+------+-------------
+ mike | posthacking
+(1 row)
+
+--
+-- as above, but jeff also does post_hacking.
+--
+SELECT p.name, name(p.hobbies) FROM person* p ORDER BY 1,2;
+ name |    name     
+------+-------------
+ mike | posthacking
+(1 row)
+
+--
+-- the next two queries demonstrate how functions generate bogus duplicates.
+-- this is a "feature" ..
+--
+SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r
+  ORDER BY 1,2;
+ name | name 
+------+------
+(0 rows)
+
+SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r ORDER BY 1,2;
+ name | name 
+------+------
+(0 rows)
+
+--
+-- mike needs advil and peet's coffee,
+-- joe and sally need hightops, and
+-- everyone else is fine.
+--
+SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p ORDER BY 1,2,3;
+ name | name | name 
+------+------+------
+(0 rows)
+
+--
+-- as above, but jeff needs advil and peet's coffee as well.
+--
+SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p ORDER BY 1,2,3;
+ name | name | name 
+------+------+------
+(0 rows)
+
+--
+-- just like the last two, but make sure that the target list fixup and
+-- unflattening is being done correctly.
+--
+SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2,3;
+ name | name | name 
+------+------+------
+(0 rows)
+
+SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p ORDER BY 1,2,3;
+ name | name | name 
+------+------+------
+(0 rows)
+
+SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p ORDER BY 1,2,3;
+ name | name | name 
+------+------+------
+(0 rows)
+
+SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p ORDER BY 1,2,3;
+ name | name | name 
+------+------+------
+(0 rows)
+
+SELECT user_relns() AS user_relns
+   ORDER BY user_relns;
+         user_relns          
+-----------------------------
+ a
+ a_star
+ abstime_tbl
+ aggtest
+ aggtype
+ array_index_op_test
+ array_op_test
+ arrtest
+ atim_tab
+ b
+ b_star
+ bb
+ bo_tab
+ box_tbl
+ bprime
+ brinopers
+ brintest
+ bt_f8_heap
+ bt_i4_heap
+ bt_name_heap
+ bt_txt_heap
+ btree_tall_tbl
+ c
+ c_star
+ cantcompare
+ char_tbl
+ check2_tbl
+ check_con_tbl
+ check_seq
+ check_tbl
+ circle_tbl
+ city
+ clstr_tst_s
+ clstr_tst_s_rf_a_seq
+ comment_test
+ complex
+ copy_tbl
+ credit_card
+ credit_usage
+ customer
+ d
+ d_star
+ date_tab
+ date_tbl
+ default_seq
+ default_tbl
+ defaultexpr_tbl
+ dept
+ depth0
+ depth1
+ depth2
+ domain_test
+ domcontest
+ domnotnull
+ domtab
+ domview
+ dropcolumn
+ dropcolumnanother
+ dropcolumnchild
+ dropcolumnexists
+ dropped_objects
+ dupindexcols
+ e_star
+ ec0
+ ec1
+ ec2
+ emp
+ equipment_r
+ event_trigger_test
+ f_star
+ fast_emp4000
+ float4_tbl
+ float8_tbl
+ foo
+ foo_f1_seq
+ foo_rescan_t
+ foobar
+ found_test_tbl
+ func_index_heap
+ gin_test_tbl
+ gist_point_tbl
+ hash_f8_heap
+ hash_i4_heap
+ hash_name_heap
+ hash_txt_heap
+ hobbies_r
+ hslot
+ hub
+ i2_tab
+ i4_tab
+ iexit
+ iface
+ ihighway
+ inet_tbl
+ inhf
+ inhx
+ insert_seq
+ insert_tbl
+ int2_tbl
+ int4_tbl
+ int8_tbl
+ interval_tbl
+ iportaltest
+ jbpop
+ jpop
+ jpop2
+ kd_point_tbl
+ line_tbl
+ log_table
+ lseg_tbl
+ main_table
+ money_data
+ my_credit_card_normal
+ my_credit_card_secure
+ my_credit_card_usage_normal
+ my_credit_card_usage_secure
+ my_property_normal
+ my_property_secure
+ my_rr_tab
+ no_oids
+ num_data
+ num_exp_add
+ num_exp_div
+ num_exp_ln
+ num_exp_log10
+ num_exp_mul
+ num_exp_power_10_ln
+ num_exp_sqrt
+ num_exp_sub
+ num_input_test
+ num_result
+ nums
+ nv_child_2009
+ nv_child_2010
+ nv_child_2011
+ nv_parent
+ onek
+ onek2
+ path_tbl
+ person
+ pfield
+ pfield_v1
+ phone
+ pline
+ point_tbl
+ polygon_tbl
+ pslot
+ quad
+ quad_point_tbl
+ query
+ radix_text_tbl
+ ramp
+ random_tbl
+ rc_test
+ real_city
+ record_type
+ reltime_tbl
+ renamecolumn
+ renamecolumnanother
+ renamecolumnchild
+ rewritemetoo1
+ rewritemetoo2
+ rewritemetoo3
+ rewritetype
+ rls_tbl
+ rls_tbl_force
+ road
+ room
+ rtest_admin
+ rtest_comp
+ rtest_emp
+ rtest_emplog
+ rtest_empmass
+ rtest_interface
+ rtest_nothn1
+ rtest_nothn2
+ rtest_nothn3
+ rtest_nothn4
+ rtest_order1
+ rtest_order2
+ rtest_person
+ rtest_seq
+ rtest_system
+ rtest_t1
+ rtest_t2
+ rtest_t3
+ rtest_t4
+ rtest_t5
+ rtest_t6
+ rtest_t7
+ rtest_t8
+ rtest_t9
+ rtest_unitfact
+ rtest_v1
+ rtest_vcomp
+ rtest_view1
+ rtest_view2
+ rtest_view3
+ rtest_view4
+ rtest_vview1
+ rtest_vview2
+ rtest_vview3
+ rtest_vview4
+ rtest_vview5
+ rtim_tab
+ rule_and_refint_t1
+ rule_and_refint_t2
+ rule_and_refint_t3
+ rules_log
+ rules_src
+ ruletest_tbl
+ ruletest_tbl2
+ sequence_test2
+ shighway
+ shoe
+ shoe_data
+ shoe_ready
+ shoelace
+ shoelace_arrive
+ shoelace_candelete
+ shoelace_data
+ shoelace_log
+ shoelace_obsolete
+ shoelace_ok
+ slow_emp4000
+ spgist_point_tbl
+ spgist_text_tbl
+ street
+ stud_emp
+ student
+ subselect_tbl
+ sums_1_100
+ system
+ t
+ tab1
+ tab2
+ tab3_mod
+ tenk1
+ tenk2
+ test1
+ test2
+ test3
+ test_inh_check
+ test_inh_check_child
+ test_range_excl
+ test_range_gist
+ test_range_spgist
+ test_storage
+ test_tablesample
+ test_tablesample_v1
+ test_tablesample_v2
+ test_tbl1
+ test_tbl2
+ test_tbl3
+ test_tsquery
+ test_tsvector
+ test_type1
+ test_type2
+ test_type3
+ testjsonb
+ text_tbl
+ thethings
+ time_tbl
+ timestamp_tbl
+ timestamptz_tbl
+ timetz_tbl
+ tinterval_tbl
+ tm
+ tmm
+ toyemp
+ tstz_tab_h
+ tt
+ tt0
+ tt1
+ tt2
+ tt3
+ tt4
+ tt5
+ tt6
+ tt7
+ tt_f1_seq
+ tt_t0
+ tt_t1
+ tv
+ tvm
+ tvmm
+ tvv
+ tvvm
+ tvvmv
+ undroppable_objs
+ unit
+ varchar_tbl
+ wslot
+ xacttest
+ xl_cons_hash2
+ xl_cons_modulo2
+ xmltest
+ xmlview1
+ xmlview5
+(299 rows)
+
+SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer')));
+ name 
+------
+ guts
+(1 row)
+
+SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer')));
+ name 
+------
+ guts
+(1 row)
+
+SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer')));
+ name 
+------
+ guts
+(1 row)
+
+SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer')));
+ name 
+------
+ guts
+(1 row)
+
+SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer')));
+ name 
+------
+ guts
+(1 row)
+
+SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer')));
+ name 
+------
+ guts
+(1 row)
+
+SELECT name(equipment_named_ambiguous_2a(text 'skywalking'));
+ name 
+------
+ guts
+(1 row)
+
+SELECT name(equipment_named_ambiguous_2b(text 'skywalking')) ORDER BY 1;
+     name      
+---------------
+ advil
+ guts
+ hightops
+ peet's coffee
+(4 rows)
+
+SELECT hobbies_by_name('basketball');
+ hobbies_by_name 
+-----------------
+ joe
+(1 row)
+
+SELECT name, overpaid(emp.*) FROM emp ORDER BY 1,2;
+  name  | overpaid 
+--------+----------
+ bill   | t
+ cim    | f
+ jeff   | f
+ linda  | f
+ sam    | t
+ sharon | t
+(6 rows)
+
+--
+-- Try a few cases with SQL-spec row constructor expressions
+--
+SELECT * FROM equipment(ROW('skywalking', 'mer'));
+ name |   hobby    
+------+------------
+ guts | skywalking
+(1 row)
+
+SELECT name(equipment(ROW('skywalking', 'mer')));
+ name 
+------
+ guts
+(1 row)
+
+SELECT *, name(equipment(h.*)) FROM hobbies_r h ORDER BY 1,2,3;
+ name | person | name 
+------+--------+------
+(0 rows)
+
+SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h ORDER BY 1,2,3;
+ name | person | name 
+------+--------+------
+(0 rows)
+
index cc912ec9a0ceaf6b66de77101b524b27d206bb9a..c46223bedfaefb2dd977f3f6fbd46456b269d34f 100644 (file)
@@ -170,87 +170,87 @@ SELECT class, aa, a FROM a_star* ORDER BY 1,2;
 -- versions
 --
 
---
--- postquel functions
---
---
--- mike does post_hacking,
--- joe and sally play basketball, and
--- everyone else does nothing.
---
-SELECT p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2;
-
---
--- as above, but jeff also does post_hacking.
---
-SELECT p.name, name(p.hobbies) FROM person* p ORDER BY 1,2;
-
---
--- the next two queries demonstrate how functions generate bogus duplicates.
--- this is a "feature" ..
---
-SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r
-  ORDER BY 1,2;
-
-SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r ORDER BY 1,2;
-
---
--- mike needs advil and peet's coffee,
--- joe and sally need hightops, and
--- everyone else is fine.
---
-SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p ORDER BY 1,2,3;
-
---
--- as above, but jeff needs advil and peet's coffee as well.
---
-SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p ORDER BY 1,2,3;
-
---
--- just like the last two, but make sure that the target list fixup and
--- unflattening is being done correctly.
---
-SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2,3;
-
-SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p ORDER BY 1,2,3;
-
-SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p ORDER BY 1,2,3;
-
-SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p ORDER BY 1,2,3;
-
-SELECT user_relns() AS user_relns
-   ORDER BY user_relns;
-
-SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer')));
-
-SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer')));
-
-SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer')));
-
-SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer')));
-
-SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer')));
-
-SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer')));
-
-SELECT name(equipment_named_ambiguous_2a(text 'skywalking'));
-
-SELECT name(equipment_named_ambiguous_2b(text 'skywalking')) ORDER BY 1;
-
-SELECT hobbies_by_name('basketball');
-
-SELECT name, overpaid(emp.*) FROM emp ORDER BY 1,2;
-
---
--- Try a few cases with SQL-spec row constructor expressions
---
-SELECT * FROM equipment(ROW('skywalking', 'mer'));
-
-SELECT name(equipment(ROW('skywalking', 'mer')));
-
-SELECT *, name(equipment(h.*)) FROM hobbies_r h ORDER BY 1,2,3;
-
-SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h ORDER BY 1,2,3;
+-- --
+-- -- postquel functions
+-- --
+-- --
+-- -- mike does post_hacking,
+-- -- joe and sally play basketball, and
+-- -- everyone else does nothing.
+-- --
+-- SELECT p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2;
+-- 
+-- --
+-- -- as above, but jeff also does post_hacking.
+-- --
+-- SELECT p.name, name(p.hobbies) FROM person* p ORDER BY 1,2;
+-- 
+-- --
+-- -- the next two queries demonstrate how functions generate bogus duplicates.
+-- -- this is a "feature" ..
+-- --
+-- SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r
+--   ORDER BY 1,2;
+-- 
+-- SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r ORDER BY 1,2;
+-- 
+-- --
+-- -- mike needs advil and peet's coffee,
+-- -- joe and sally need hightops, and
+-- -- everyone else is fine.
+-- --
+-- SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p ORDER BY 1,2,3;
+-- 
+-- --
+-- -- as above, but jeff needs advil and peet's coffee as well.
+-- --
+-- SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p ORDER BY 1,2,3;
+-- 
+-- --
+-- -- just like the last two, but make sure that the target list fixup and
+-- -- unflattening is being done correctly.
+-- --
+-- SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2,3;
+-- 
+-- SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p ORDER BY 1,2,3;
+-- 
+-- SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p ORDER BY 1,2,3;
+-- 
+-- SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p ORDER BY 1,2,3;
+-- 
+-- SELECT user_relns() AS user_relns
+--    ORDER BY user_relns;
+-- 
+-- SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment_named_ambiguous_2a(text 'skywalking'));
+-- 
+-- SELECT name(equipment_named_ambiguous_2b(text 'skywalking')) ORDER BY 1;
+-- 
+-- SELECT hobbies_by_name('basketball');
+-- 
+-- SELECT name, overpaid(emp.*) FROM emp ORDER BY 1,2;
+-- 
+-- --
+-- -- Try a few cases with SQL-spec row constructor expressions
+-- --
+-- SELECT * FROM equipment(ROW('skywalking', 'mer'));
+-- 
+-- SELECT name(equipment(ROW('skywalking', 'mer')));
+-- 
+-- SELECT *, name(equipment(h.*)) FROM hobbies_r h ORDER BY 1,2,3;
+-- 
+-- SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h ORDER BY 1,2,3;
 
 --
 -- check that old-style C functions work properly with TOASTed values
index 14e20205482342db0cbbef316e887b0b3535056f..da98fa561d499adb5287accf4bf49b6b7ec2be93 100644 (file)
@@ -456,339 +456,87 @@ SELECT class, aa, a FROM a_star* ORDER BY 1,2;
 --
 -- versions
 --
---
--- postquel functions
---
---
--- mike does post_hacking,
--- joe and sally play basketball, and
--- everyone else does nothing.
---
-SELECT p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2;
- name |    name     
-------+-------------
- mike | posthacking
-(1 row)
-
---
--- as above, but jeff also does post_hacking.
---
-SELECT p.name, name(p.hobbies) FROM person* p ORDER BY 1,2;
- name  |    name     
--------+-------------
- jeff  | posthacking
- joe   | basketball
- mike  | posthacking
- sally | basketball
-(4 rows)
-
---
--- the next two queries demonstrate how functions generate bogus duplicates.
--- this is a "feature" ..
---
-SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r
-  ORDER BY 1,2;
- name | name 
-------+------
-(0 rows)
-
-SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r ORDER BY 1,2;
- name | name 
-------+------
-(0 rows)
-
---
--- mike needs advil and peet's coffee,
--- joe and sally need hightops, and
--- everyone else is fine.
---
-SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p ORDER BY 1,2,3;
- name | name | name 
-------+------+------
-(0 rows)
-
---
--- as above, but jeff needs advil and peet's coffee as well.
---
-SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p ORDER BY 1,2,3;
- name  |    name     |     name      
--------+-------------+---------------
- jeff  | posthacking | advil
- jeff  | posthacking | peet's coffee
- joe   | basketball  | hightops
- mike  | posthacking | advil
- mike  | posthacking | peet's coffee
- sally | basketball  | hightops
-(6 rows)
-
---
--- just like the last two, but make sure that the target list fixup and
--- unflattening is being done correctly.
---
-SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2,3;
- name | name | name 
-------+------+------
-(0 rows)
-
-SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p ORDER BY 1,2,3;
-     name      | name  |    name     
----------------+-------+-------------
- advil         | jeff  | posthacking
- advil         | mike  | posthacking
- hightops      | joe   | basketball
- hightops      | sally | basketball
- peet's coffee | jeff  | posthacking
- peet's coffee | mike  | posthacking
-(6 rows)
-
-SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p ORDER BY 1,2,3;
- name | name | name 
-------+------+------
-(0 rows)
-
-SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p ORDER BY 1,2,3;
-     name      |    name     | name  
----------------+-------------+-------
- advil         | posthacking | jeff
- advil         | posthacking | mike
- hightops      | basketball  | joe
- hightops      | basketball  | sally
- peet's coffee | posthacking | jeff
- peet's coffee | posthacking | mike
-(6 rows)
-
-SELECT user_relns() AS user_relns
-   ORDER BY user_relns;
-     user_relns      
----------------------
- a
- a_star
- abstime_tbl
- aggtest
- aggtype
- array_index_op_test
- array_op_test
- arrtest
- b
- b_star
- bb
- box_tbl
- bprime
- brinopers
- brintest
- bt_f8_heap
- bt_i4_heap
- bt_name_heap
- bt_txt_heap
- btree_tall_tbl
- c
- c_star
- char_tbl
- check2_tbl
- check_seq
- check_tbl
- circle_tbl
- city
- copy_tbl
- d
- d_star
- date_tbl
- default_seq
- default_tbl
- defaultexpr_tbl
- dept
- dupindexcols
- e_star
- emp
- equipment_r
- f_star
- fast_emp4000
- float4_tbl
- float8_tbl
- foobar
- func_index_heap
- gin_test_tbl
- gist_point_tbl
- hash_f8_heap
- hash_i4_heap
- hash_name_heap
- hash_txt_heap
- hobbies_r
- iexit
- ihighway
- inet_tbl
- inhf
- inhx
- insert_seq
- insert_tbl
- int2_tbl
- int4_tbl
- int8_tbl
- interval_tbl
- iportaltest
- kd_point_tbl
- line_tbl
- log_table
- lseg_tbl
- main_table
- money_data
- num_data
- num_exp_add
- num_exp_div
- num_exp_ln
- num_exp_log10
- num_exp_mul
- num_exp_power_10_ln
- num_exp_sqrt
- num_exp_sub
- num_input_test
- num_result
- onek
- onek2
- path_tbl
- person
- point_tbl
- polygon_tbl
- quad_point_tbl
- radix_text_tbl
- ramp
- random_tbl
- real_city
- reltime_tbl
- rls_tbl
- rls_tbl_force
- road
- shighway
- slow_emp4000
- spgist_point_tbl
- spgist_text_tbl
- street
- stud_emp
- student
- subselect_tbl
- t
- tenk1
- tenk2
- test_range_excl
- test_range_gist
- test_range_spgist
- test_tablesample
- test_tablesample_v1
- test_tablesample_v2
- test_tsvector
- testjsonb
- text_tbl
- time_tbl
- timestamp_tbl
- timestamptz_tbl
- timetz_tbl
- tinterval_tbl
- tm
- tmm
- toyemp
- tv
- tvm
- tvmm
- tvv
- tvvm
- tvvmv
- varchar_tbl
- xacttest
-(133 rows)
-
-SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer')));
- name 
-------
- guts
-(1 row)
-
-SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer')));
- name 
-------
- guts
-(1 row)
-
-SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer')));
- name 
-------
- guts
-(1 row)
-
-SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer')));
- name 
-------
- guts
-(1 row)
-
-SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer')));
- name 
-------
- guts
-(1 row)
-
-SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer')));
- name 
-------
- guts
-(1 row)
-
-SELECT name(equipment_named_ambiguous_2a(text 'skywalking'));
- name 
-------
- guts
-(1 row)
-
-SELECT name(equipment_named_ambiguous_2b(text 'skywalking')) ORDER BY 1;
-     name      
----------------
- advil
- guts
- hightops
- peet's coffee
-(4 rows)
-
-SELECT hobbies_by_name('basketball');
- hobbies_by_name 
------------------
- joe
-(1 row)
-
-SELECT name, overpaid(emp.*) FROM emp ORDER BY 1,2;
-  name  | overpaid 
---------+----------
- bill   | t
- cim    | f
- jeff   | f
- linda  | f
- sam    | t
- sharon | t
-(6 rows)
-
---
--- Try a few cases with SQL-spec row constructor expressions
---
-SELECT * FROM equipment(ROW('skywalking', 'mer'));
- name |   hobby    
-------+------------
- guts | skywalking
-(1 row)
-
-SELECT name(equipment(ROW('skywalking', 'mer')));
- name 
-------
- guts
-(1 row)
-
-SELECT *, name(equipment(h.*)) FROM hobbies_r h ORDER BY 1,2,3;
- name | person | name 
-------+--------+------
-(0 rows)
-
-SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h ORDER BY 1,2,3;
- name | person | name 
-------+--------+------
-(0 rows)
-
+-- --
+-- -- postquel functions
+-- --
+-- --
+-- -- mike does post_hacking,
+-- -- joe and sally play basketball, and
+-- -- everyone else does nothing.
+-- --
+-- SELECT p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2;
+-- 
+-- --
+-- -- as above, but jeff also does post_hacking.
+-- --
+-- SELECT p.name, name(p.hobbies) FROM person* p ORDER BY 1,2;
+-- 
+-- --
+-- -- the next two queries demonstrate how functions generate bogus duplicates.
+-- -- this is a "feature" ..
+-- --
+-- SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r
+--   ORDER BY 1,2;
+-- 
+-- SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r ORDER BY 1,2;
+-- 
+-- --
+-- -- mike needs advil and peet's coffee,
+-- -- joe and sally need hightops, and
+-- -- everyone else is fine.
+-- --
+-- SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p ORDER BY 1,2,3;
+-- 
+-- --
+-- -- as above, but jeff needs advil and peet's coffee as well.
+-- --
+-- SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p ORDER BY 1,2,3;
+-- 
+-- --
+-- -- just like the last two, but make sure that the target list fixup and
+-- -- unflattening is being done correctly.
+-- --
+-- SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2,3;
+-- 
+-- SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p ORDER BY 1,2,3;
+-- 
+-- SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p ORDER BY 1,2,3;
+-- 
+-- SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p ORDER BY 1,2,3;
+-- 
+-- SELECT user_relns() AS user_relns
+--    ORDER BY user_relns;
+-- 
+-- SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer')));
+-- 
+-- SELECT name(equipment_named_ambiguous_2a(text 'skywalking'));
+-- 
+-- SELECT name(equipment_named_ambiguous_2b(text 'skywalking')) ORDER BY 1;
+-- 
+-- SELECT hobbies_by_name('basketball');
+-- 
+-- SELECT name, overpaid(emp.*) FROM emp ORDER BY 1,2;
+-- 
+-- --
+-- -- Try a few cases with SQL-spec row constructor expressions
+-- --
+-- SELECT * FROM equipment(ROW('skywalking', 'mer'));
+-- 
+-- SELECT name(equipment(ROW('skywalking', 'mer')));
+-- 
+-- SELECT *, name(equipment(h.*)) FROM hobbies_r h ORDER BY 1,2,3;
+-- 
+-- SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h ORDER BY 1,2,3;
 --
 -- check that old-style C functions work properly with TOASTed values
 --
index f57a58717403964e7cee4d4a05ac7b1e9c08feaa..e211237998e55493e1c2a6a050365a32fac9fa69 100644 (file)
@@ -140,4 +140,3 @@ test: xc_notrans_block
 
 # This runs XL specific tests
 test: xl_primary_key xl_foreign_key xl_distribution_column_types xl_alter_table xl_distribution_column_types_modulo xl_plan_pushdown xl_functions xl_limitations xl_user_defined_functions xl_join
-
index 4f0ccfe7401297f6d39a904b30e545f74606dedc..5afcf1272e32c638785a0bf6174c5a416cbeaf73 100644 (file)
@@ -168,3 +168,90 @@ drop function f1();
 drop table my_tab1;
 
 --------------------------------------------------
+-- 
+-- versions
+--
+
+-- Bugs related to pushing down volatile functions to datanodes - copied from
+-- misc.sql
+--
+-- postquel functions
+--
+--
+-- mike does post_hacking,
+-- joe and sally play basketball, and
+-- everyone else does nothing.
+--
+SELECT p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2;
+
+--
+-- as above, but jeff also does post_hacking.
+--
+SELECT p.name, name(p.hobbies) FROM person* p ORDER BY 1,2;
+
+--
+-- the next two queries demonstrate how functions generate bogus duplicates.
+-- this is a "feature" ..
+--
+SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r
+  ORDER BY 1,2;
+
+SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r ORDER BY 1,2;
+
+--
+-- mike needs advil and peet's coffee,
+-- joe and sally need hightops, and
+-- everyone else is fine.
+--
+SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p ORDER BY 1,2,3;
+
+--
+-- as above, but jeff needs advil and peet's coffee as well.
+--
+SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p ORDER BY 1,2,3;
+
+--
+-- just like the last two, but make sure that the target list fixup and
+-- unflattening is being done correctly.
+--
+SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p ORDER BY 1,2,3;
+
+SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p ORDER BY 1,2,3;
+
+SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p ORDER BY 1,2,3;
+
+SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p ORDER BY 1,2,3;
+
+SELECT user_relns() AS user_relns
+   ORDER BY user_relns;
+
+SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer')));
+
+SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer')));
+
+SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer')));
+
+SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer')));
+
+SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer')));
+
+SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer')));
+
+SELECT name(equipment_named_ambiguous_2a(text 'skywalking'));
+
+SELECT name(equipment_named_ambiguous_2b(text 'skywalking')) ORDER BY 1;
+
+SELECT hobbies_by_name('basketball');
+
+SELECT name, overpaid(emp.*) FROM emp ORDER BY 1,2;
+
+--
+-- Try a few cases with SQL-spec row constructor expressions
+--
+SELECT * FROM equipment(ROW('skywalking', 'mer'));
+
+SELECT name(equipment(ROW('skywalking', 'mer')));
+
+SELECT *, name(equipment(h.*)) FROM hobbies_r h ORDER BY 1,2,3;
+
+SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h ORDER BY 1,2,3;