]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Don't use_physical_tlist for an IOS with non-returnable columns.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 11 Feb 2022 20:23:52 +0000 (15:23 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 11 Feb 2022 20:23:52 +0000 (15:23 -0500)
createplan.c tries to save a runtime projection step by specifying
a scan plan node's output as being exactly the table's columns, or
index's columns in the case of an index-only scan, if there is not a
reason to do otherwise.  This logic did not previously pay attention
to whether an index's columns are returnable.  That worked, sort of
accidentally, until commit 9a3ddeb51 taught setrefs.c to reject plans
that try to read a non-returnable column.  I have no desire to loosen
setrefs.c's new check, so instead adjust use_physical_tlist() to not
try to optimize this way when there are non-returnable column(s).

Per report from Ryan Kelly.  Like the previous patch, back-patch
to all supported branches.

Discussion: https://postgr.es/m/CAHUie24ddN+pDNw7fkhNrjrwAX=fXXfGZZEHhRuofV_N_ftaSg@mail.gmail.com

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

index 839f20a7f6f56b0ffd1a393363c8b20e47ceacdd..90661f2b147f4c5a1cb0a4498334347dee8a3e78 100644 (file)
@@ -856,6 +856,22 @@ use_physical_tlist(PlannerInfo *root, Path *path, int flags)
                        return false;
        }
 
+       /*
+        * For an index-only scan, the "physical tlist" is the index's indextlist.
+        * We can only return that without a projection if all the index's columns
+        * are returnable.
+        */
+       if (path->pathtype == T_IndexOnlyScan)
+       {
+               IndexOptInfo *indexinfo = ((IndexPath *) path)->indexinfo;
+
+               for (i = 0; i < indexinfo->ncolumns; i++)
+               {
+                       if (!indexinfo->canreturn[i])
+                               return false;
+               }
+       }
+
        /*
         * Also, can't do it if CP_LABEL_TLIST is specified and path is requested
         * to emit any sort/group columns that are not simple Vars.  (If they are
index 6a9e33eb430aba96c8052e871242b221811b95a2..717bb7f03b9af8f79acfba8b7326cec1335e8c08 100644 (file)
@@ -283,6 +283,22 @@ select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95);
  (0,0)
 (1 row)
 
+-- Also check that use_physical_tlist doesn't trigger in such cases.
+explain (verbose, costs off)
+select count(*) from gist_tbl;
+                             QUERY PLAN                              
+---------------------------------------------------------------------
+ Aggregate
+   Output: count(*)
+   ->  Index Only Scan using gist_tbl_multi_index on public.gist_tbl
+(3 rows)
+
+select count(*) from gist_tbl;
+ count 
+-------
+ 10001
+(1 row)
+
 -- This case isn't supported, but it should at least EXPLAIN correctly.
 explain (verbose, costs off)
 select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1;
index ab77dc2721846a260ad3f61450d4b59cff7e2cbf..b1dc41b91bc13d4f3a94e66997b0a2f70d1873a5 100644 (file)
@@ -145,6 +145,11 @@ explain (verbose, costs off)
 select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95);
 select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95);
 
+-- Also check that use_physical_tlist doesn't trigger in such cases.
+explain (verbose, costs off)
+select count(*) from gist_tbl;
+select count(*) from gist_tbl;
+
 -- This case isn't supported, but it should at least EXPLAIN correctly.
 explain (verbose, costs off)
 select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1;