Commit 1cc29fe7 authored by Tom Lane's avatar Tom Lane

Teach EXPLAIN to print PARAM_EXEC Params as the referenced expressions,

rather than just $N.  This brings the display of nestloop-inner-indexscan
plans back to where it's been, and incidentally improves the display of
SubPlan parameters as well.  In passing, simplify the EXPLAIN code by
having it deal primarily in the PlanState tree rather than separately
searching Plan and PlanState trees.  This is noticeably cleaner for
subplans, and about a wash elsewhere.

One small difference from previous behavior is that EXPLAIN will no longer
qualify local variable references in inner-indexscan plan nodes, since it
no longer sees such nodes as possibly referencing multiple tables.  Vars
referenced through PARAM_EXEC Params are still forcibly qualified, though,
so I don't think the display is any more confusing than before.  Adjust a
couple of examples in the documentation to match this behavior.
parent 4504a1bc
<!-- $PostgreSQL: pgsql/doc/src/sgml/perform.sgml,v 1.82 2010/06/28 22:46:11 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/perform.sgml,v 1.83 2010/07/13 20:57:19 tgl Exp $ -->
<chapter id="performance-tips"> <chapter id="performance-tips">
<title>Performance Tips</title> <title>Performance Tips</title>
...@@ -316,7 +316,7 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2; ...@@ -316,7 +316,7 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
-&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0) -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0)
Index Cond: (unique1 &lt; 100) Index Cond: (unique1 &lt; 100)
-&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..3.01 rows=1 width=244) -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..3.01 rows=1 width=244)
Index Cond: (t2.unique2 = t1.unique2) Index Cond: (unique2 = t1.unique2)
</programlisting> </programlisting>
</para> </para>
...@@ -329,7 +329,7 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2; ...@@ -329,7 +329,7 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
so it doesn't affect the row count of the outer scan. For the inner (lower) scan, the so it doesn't affect the row count of the outer scan. For the inner (lower) scan, the
<literal>unique2</> value of the current outer-scan row is plugged into <literal>unique2</> value of the current outer-scan row is plugged into
the inner index scan to produce an index condition like the inner index scan to produce an index condition like
<literal>t2.unique2 = <replaceable>constant</replaceable></literal>. <literal>unique2 = <replaceable>constant</replaceable></literal>.
So we get the same inner-scan plan and costs that we'd get from, say, So we get the same inner-scan plan and costs that we'd get from, say,
<literal>EXPLAIN SELECT * FROM tenk2 WHERE unique2 = 42</literal>. The <literal>EXPLAIN SELECT * FROM tenk2 WHERE unique2 = 42</literal>. The
costs of the loop node are then set on the basis of the cost of the outer costs of the loop node are then set on the basis of the cost of the outer
...@@ -405,7 +405,7 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2; ...@@ -405,7 +405,7 @@ WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
-&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0) (actual time=0.546..0.546 rows=100 loops=1) -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..2.37 rows=106 width=0) (actual time=0.546..0.546 rows=100 loops=1)
Index Cond: (unique1 &lt; 100) Index Cond: (unique1 &lt; 100)
-&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..3.01 rows=1 width=244) (actual time=0.067..0.078 rows=1 loops=100) -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..3.01 rows=1 width=244) (actual time=0.067..0.078 rows=1 loops=100)
Index Cond: (t2.unique2 = t1.unique2) Index Cond: (unique2 = t1.unique2)
Total runtime: 14.452 ms Total runtime: 14.452 ms
</screen> </screen>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/planstats.sgml,v 1.9 2007/12/28 21:03:31 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/planstats.sgml,v 1.10 2010/07/13 20:57:19 tgl Exp $ -->
<chapter id="planner-stats-details"> <chapter id="planner-stats-details">
<title>How the Planner Uses Statistics</title> <title>How the Planner Uses Statistics</title>
...@@ -353,7 +353,7 @@ WHERE t1.unique1 &lt; 50 AND t1.unique2 = t2.unique2; ...@@ -353,7 +353,7 @@ WHERE t1.unique1 &lt; 50 AND t1.unique2 = t2.unique2;
-&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.63 rows=50 width=0) -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.63 rows=50 width=0)
Index Cond: (unique1 &lt; 50) Index Cond: (unique1 &lt; 50)
-&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..6.27 rows=1 width=244) -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..6.27 rows=1 width=244)
Index Cond: (t2.unique2 = t1.unique2) Index Cond: (unique2 = t1.unique2)
</programlisting> </programlisting>
The restriction on <structname>tenk1</structname>, The restriction on <structname>tenk1</structname>,
......
This diff is collapsed.
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.350 2010/07/06 19:19:00 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.351 2010/07/13 20:57:19 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -609,8 +609,8 @@ extern Datum pg_get_function_result(PG_FUNCTION_ARGS); ...@@ -609,8 +609,8 @@ extern Datum pg_get_function_result(PG_FUNCTION_ARGS);
extern char *deparse_expression(Node *expr, List *dpcontext, extern char *deparse_expression(Node *expr, List *dpcontext,
bool forceprefix, bool showimplicit); bool forceprefix, bool showimplicit);
extern List *deparse_context_for(const char *aliasname, Oid relid); extern List *deparse_context_for(const char *aliasname, Oid relid);
extern List *deparse_context_for_plan(Node *plan, Node *outer_plan, extern List *deparse_context_for_planstate(Node *planstate, List *ancestors,
List *rtable, List *subplans); List *rtable);
extern const char *quote_identifier(const char *ident); extern const char *quote_identifier(const char *ident);
extern char *quote_qualified_identifier(const char *qualifier, extern char *quote_qualified_identifier(const char *qualifier,
const char *ident); const char *ident);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment