]> granicus.if.org Git - postgresql/commitdiff
Don't apply sortgroupref labels to a tlist that might not match.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 28 Jun 2016 14:43:11 +0000 (10:43 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 28 Jun 2016 14:43:11 +0000 (10:43 -0400)
If we need to use a gating Result node for pseudoconstant quals,
create_scan_plan() intentionally suppresses use_physical_tlist's checks
on whether there are matches for sortgroupref labels, on the grounds that
we don't need matches because we can label the Result's projection output
properly.  However, it then called apply_pathtarget_labeling_to_tlist
anyway.  This oversight was harmless when written, but in commit aeb9ae645
I made that function throw an error if there was no match.  Thus, the
combination of a table scan, pseudoconstant quals, and a non-simple-Var
sortgroupref column threw the dreaded "ORDER/GROUP BY expression not found
in targetlist" error.  To fix, just skip applying the labeling in this
case.  Per report from Rushabh Lathia.

Report: <CAGPqQf2iLB8t6t-XrL-zR233DFTXxEsfVZ4WSqaYfLupEoDxXA@mail.gmail.com>

src/backend/optimizer/plan/createplan.c
src/test/regress/expected/aggregates.out
src/test/regress/sql/aggregates.sql

index 58bfd491307bf7e3c29db3802d3eb9c9e2088d35..f98cce49c7edac5e83abfd5923dafa4b4a98f95f 100644 (file)
@@ -544,8 +544,13 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags)
                {
                        /* For index-only scan, the preferred tlist is the index's */
                        tlist = copyObject(((IndexPath *) best_path)->indexinfo->indextlist);
-                       /* Transfer any sortgroupref data to the replacement tlist */
-                       apply_pathtarget_labeling_to_tlist(tlist, best_path->pathtarget);
+
+                       /*
+                        * Transfer any sortgroupref data to the replacement tlist, unless
+                        * we don't care because the gating Result will handle it.
+                        */
+                       if (!gating_clauses)
+                               apply_pathtarget_labeling_to_tlist(tlist, best_path->pathtarget);
                }
                else
                {
@@ -557,8 +562,9 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags)
                        }
                        else
                        {
-                               /* Transfer any sortgroupref data to the replacement tlist */
-                               apply_pathtarget_labeling_to_tlist(tlist, best_path->pathtarget);
+                               /* As above, transfer sortgroupref data to replacement tlist */
+                               if (!gating_clauses)
+                                       apply_pathtarget_labeling_to_tlist(tlist, best_path->pathtarget);
                        }
                }
        }
index 3ff669140ffc1ac8e739f57fc2de74c22b0cf148..fba9bb959cd0a06e94ee722af435a6928f7cfb65 100644 (file)
@@ -751,6 +751,25 @@ select max(unique2), generate_series(1,3) as g from tenk1 order by g desc;
  9999 | 1
 (3 rows)
 
+-- interesting corner case: constant gets optimized into a seqscan
+explain (costs off)
+  select max(100) from tenk1;
+                     QUERY PLAN                     
+----------------------------------------------------
+ Result
+   InitPlan 1 (returns $0)
+     ->  Limit
+           ->  Result
+                 One-Time Filter: (100 IS NOT NULL)
+                 ->  Seq Scan on tenk1
+(6 rows)
+
+select max(100) from tenk1;
+ max 
+-----
+ 100
+(1 row)
+
 -- try it on an inheritance tree
 create table minmaxtest(f1 int);
 create table minmaxtest1() inherits (minmaxtest);
index 80ef14cda22cfda17a7a90e1d2a717da66e52007..d7600faf8fadd2649515341fcf3a031d5545519d 100644 (file)
@@ -270,6 +270,11 @@ explain (costs off)
   select max(unique2), generate_series(1,3) as g from tenk1 order by g desc;
 select max(unique2), generate_series(1,3) as g from tenk1 order by g desc;
 
+-- interesting corner case: constant gets optimized into a seqscan
+explain (costs off)
+  select max(100) from tenk1;
+select max(100) from tenk1;
+
 -- try it on an inheritance tree
 create table minmaxtest(f1 int);
 create table minmaxtest1() inherits (minmaxtest);