1818#include "commands/defrem.h"
1919#include "commands/prepare.h"
2020#include "executor/hashjoin.h"
21- #include "executor/instrument.h"
2221#include "foreign/fdwapi.h"
2322#include "optimizer/clauses.h"
2423#include "parser/parsetree.h"
@@ -76,6 +75,8 @@ static void show_sort_keys_common(PlanState *planstate,
7675 List * ancestors , ExplainState * es );
7776static void show_sort_info (SortState * sortstate , ExplainState * es );
7877static void show_hash_info (HashState * hashstate , ExplainState * es );
78+ static void show_instrumentation_count (const char * qlabel , int which ,
79+ PlanState * planstate , ExplainState * es );
7980static void show_foreignscan_info (ForeignScanState * fsstate , ExplainState * es );
8081static const char * explain_get_index_name (Oid indexId );
8182static void ExplainScanTarget (Scan * plan , ExplainState * es );
@@ -1000,9 +1001,15 @@ ExplainNode(PlanState *planstate, List *ancestors,
10001001 case T_IndexScan :
10011002 show_scan_qual (((IndexScan * ) plan )-> indexqualorig ,
10021003 "Index Cond" , planstate , ancestors , es );
1004+ if (((IndexScan * ) plan )-> indexqualorig )
1005+ show_instrumentation_count ("Rows Removed by Index Recheck" , 2 ,
1006+ planstate , es );
10031007 show_scan_qual (((IndexScan * ) plan )-> indexorderbyorig ,
10041008 "Order By" , planstate , ancestors , es );
10051009 show_scan_qual (plan -> qual , "Filter" , planstate , ancestors , es );
1010+ if (plan -> qual )
1011+ show_instrumentation_count ("Rows Removed by Filter" , 1 ,
1012+ planstate , es );
10061013 break ;
10071014 case T_BitmapIndexScan :
10081015 show_scan_qual (((BitmapIndexScan * ) plan )-> indexqualorig ,
@@ -1011,20 +1018,29 @@ ExplainNode(PlanState *planstate, List *ancestors,
10111018 case T_BitmapHeapScan :
10121019 show_scan_qual (((BitmapHeapScan * ) plan )-> bitmapqualorig ,
10131020 "Recheck Cond" , planstate , ancestors , es );
1021+ if (((BitmapHeapScan * ) plan )-> bitmapqualorig )
1022+ show_instrumentation_count ("Rows Removed by Index Recheck" , 2 ,
1023+ planstate , es );
10141024 /* FALL THRU */
10151025 case T_SeqScan :
10161026 case T_ValuesScan :
10171027 case T_CteScan :
10181028 case T_WorkTableScan :
10191029 case T_SubqueryScan :
10201030 show_scan_qual (plan -> qual , "Filter" , planstate , ancestors , es );
1031+ if (plan -> qual )
1032+ show_instrumentation_count ("Rows Removed by Filter" , 1 ,
1033+ planstate , es );
10211034 break ;
10221035 case T_FunctionScan :
10231036 if (es -> verbose )
10241037 show_expression (((FunctionScan * ) plan )-> funcexpr ,
10251038 "Function Call" , planstate , ancestors ,
10261039 es -> verbose , es );
10271040 show_scan_qual (plan -> qual , "Filter" , planstate , ancestors , es );
1041+ if (plan -> qual )
1042+ show_instrumentation_count ("Rows Removed by Filter" , 1 ,
1043+ planstate , es );
10281044 break ;
10291045 case T_TidScan :
10301046 {
@@ -1038,34 +1054,61 @@ ExplainNode(PlanState *planstate, List *ancestors,
10381054 tidquals = list_make1 (make_orclause (tidquals ));
10391055 show_scan_qual (tidquals , "TID Cond" , planstate , ancestors , es );
10401056 show_scan_qual (plan -> qual , "Filter" , planstate , ancestors , es );
1057+ if (plan -> qual )
1058+ show_instrumentation_count ("Rows Removed by Filter" , 1 ,
1059+ planstate , es );
10411060 }
10421061 break ;
10431062 case T_ForeignScan :
10441063 show_scan_qual (plan -> qual , "Filter" , planstate , ancestors , es );
1064+ if (plan -> qual )
1065+ show_instrumentation_count ("Rows Removed by Filter" , 1 ,
1066+ planstate , es );
10451067 show_foreignscan_info ((ForeignScanState * ) planstate , es );
10461068 break ;
10471069 case T_NestLoop :
10481070 show_upper_qual (((NestLoop * ) plan )-> join .joinqual ,
10491071 "Join Filter" , planstate , ancestors , es );
1072+ if (((NestLoop * ) plan )-> join .joinqual )
1073+ show_instrumentation_count ("Rows Removed by Join Filter" , 1 ,
1074+ planstate , es );
10501075 show_upper_qual (plan -> qual , "Filter" , planstate , ancestors , es );
1076+ if (plan -> qual )
1077+ show_instrumentation_count ("Rows Removed by Filter" , 2 ,
1078+ planstate , es );
10511079 break ;
10521080 case T_MergeJoin :
10531081 show_upper_qual (((MergeJoin * ) plan )-> mergeclauses ,
10541082 "Merge Cond" , planstate , ancestors , es );
10551083 show_upper_qual (((MergeJoin * ) plan )-> join .joinqual ,
10561084 "Join Filter" , planstate , ancestors , es );
1085+ if (((MergeJoin * ) plan )-> join .joinqual )
1086+ show_instrumentation_count ("Rows Removed by Join Filter" , 1 ,
1087+ planstate , es );
10571088 show_upper_qual (plan -> qual , "Filter" , planstate , ancestors , es );
1089+ if (plan -> qual )
1090+ show_instrumentation_count ("Rows Removed by Filter" , 2 ,
1091+ planstate , es );
10581092 break ;
10591093 case T_HashJoin :
10601094 show_upper_qual (((HashJoin * ) plan )-> hashclauses ,
10611095 "Hash Cond" , planstate , ancestors , es );
10621096 show_upper_qual (((HashJoin * ) plan )-> join .joinqual ,
10631097 "Join Filter" , planstate , ancestors , es );
1098+ if (((HashJoin * ) plan )-> join .joinqual )
1099+ show_instrumentation_count ("Rows Removed by Join Filter" , 1 ,
1100+ planstate , es );
10641101 show_upper_qual (plan -> qual , "Filter" , planstate , ancestors , es );
1102+ if (plan -> qual )
1103+ show_instrumentation_count ("Rows Removed by Filter" , 2 ,
1104+ planstate , es );
10651105 break ;
10661106 case T_Agg :
10671107 case T_Group :
10681108 show_upper_qual (plan -> qual , "Filter" , planstate , ancestors , es );
1109+ if (plan -> qual )
1110+ show_instrumentation_count ("Rows Removed by Filter" , 1 ,
1111+ planstate , es );
10691112 break ;
10701113 case T_Sort :
10711114 show_sort_keys ((SortState * ) planstate , ancestors , es );
@@ -1079,6 +1122,9 @@ ExplainNode(PlanState *planstate, List *ancestors,
10791122 show_upper_qual ((List * ) ((Result * ) plan )-> resconstantqual ,
10801123 "One-Time Filter" , planstate , ancestors , es );
10811124 show_upper_qual (plan -> qual , "Filter" , planstate , ancestors , es );
1125+ if (plan -> qual )
1126+ show_instrumentation_count ("Rows Removed by Filter" , 1 ,
1127+ planstate , es );
10821128 break ;
10831129 case T_Hash :
10841130 show_hash_info ((HashState * ) planstate , es );
@@ -1508,6 +1554,37 @@ show_hash_info(HashState *hashstate, ExplainState *es)
15081554 }
15091555}
15101556
1557+ /*
1558+ * If it's EXPLAIN ANALYZE, show instrumentation information for a plan node
1559+ *
1560+ * "which" identifies which instrumentation counter to print
1561+ */
1562+ static void
1563+ show_instrumentation_count (const char * qlabel , int which ,
1564+ PlanState * planstate , ExplainState * es )
1565+ {
1566+ double nfiltered ;
1567+ double nloops ;
1568+
1569+ if (!es -> analyze || !planstate -> instrument )
1570+ return ;
1571+
1572+ if (which == 2 )
1573+ nfiltered = planstate -> instrument -> nfiltered2 ;
1574+ else
1575+ nfiltered = planstate -> instrument -> nfiltered1 ;
1576+ nloops = planstate -> instrument -> nloops ;
1577+
1578+ /* In text mode, suppress zero counts; they're not interesting enough */
1579+ if (nfiltered > 0 || es -> format != EXPLAIN_FORMAT_TEXT )
1580+ {
1581+ if (nloops > 0 )
1582+ ExplainPropertyFloat (qlabel , nfiltered / nloops , 0 , es );
1583+ else
1584+ ExplainPropertyFloat (qlabel , 0.0 , 0 , es );
1585+ }
1586+ }
1587+
15111588/*
15121589 * Show extra information for a ForeignScan node.
15131590 */
0 commit comments