nfiltered.patch

text/plain

Filename: nfiltered.patch
Type: text/plain
Part: 0
Message: Re: EXPLAIN and nfiltered

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
File+
src/backend/commands/explain.c 5 0
src/backend/executor/execScan.c 3 0
src/include/executor/instrument.h 1 0
*** a/src/backend/commands/explain.c
--- b/src/backend/commands/explain.c
***************
*** 975,992 **** ExplainNode(PlanState *planstate, List *ancestors,
  		double		startup_sec = 1000.0 * planstate->instrument->startup / nloops;
  		double		total_sec = 1000.0 * planstate->instrument->total / nloops;
  		double		rows = planstate->instrument->ntuples / nloops;
  
  		if (es->format == EXPLAIN_FORMAT_TEXT)
  		{
  			appendStringInfo(es->str,
! 							 " (actual time=%.3f..%.3f rows=%.0f loops=%.0f)",
! 							 startup_sec, total_sec, rows, nloops);
  		}
  		else
  		{
  			ExplainPropertyFloat("Actual Startup Time", startup_sec, 3, es);
  			ExplainPropertyFloat("Actual Total Time", total_sec, 3, es);
  			ExplainPropertyFloat("Actual Rows", rows, 0, es);
  			ExplainPropertyFloat("Actual Loops", nloops, 0, es);
  		}
  	}
--- 975,994 ----
  		double		startup_sec = 1000.0 * planstate->instrument->startup / nloops;
  		double		total_sec = 1000.0 * planstate->instrument->total / nloops;
  		double		rows = planstate->instrument->ntuples / nloops;
+ 		double		filtered = planstate->instrument->nfiltered / nloops;
  
  		if (es->format == EXPLAIN_FORMAT_TEXT)
  		{
  			appendStringInfo(es->str,
! 							 " (actual time=%.3f..%.3f rows=%.0f filtered=%.0f loops=%.0f)",
! 							 startup_sec, total_sec, rows, filtered, nloops);
  		}
  		else
  		{
  			ExplainPropertyFloat("Actual Startup Time", startup_sec, 3, es);
  			ExplainPropertyFloat("Actual Total Time", total_sec, 3, es);
  			ExplainPropertyFloat("Actual Rows", rows, 0, es);
+ 			ExplainPropertyFloat("Rows Filtered", rows, 0, es);
  			ExplainPropertyFloat("Actual Loops", nloops, 0, es);
  		}
  	}
***************
*** 999,1004 **** ExplainNode(PlanState *planstate, List *ancestors,
--- 1001,1007 ----
  			ExplainPropertyFloat("Actual Startup Time", 0.0, 3, es);
  			ExplainPropertyFloat("Actual Total Time", 0.0, 3, es);
  			ExplainPropertyFloat("Actual Rows", 0.0, 0, es);
+ 			ExplainPropertyFloat("Rows Filtered", 0.0, 0, es);
  			ExplainPropertyFloat("Actual Loops", 0.0, 0, es);
  		}
  	}
*** a/src/backend/executor/execScan.c
--- b/src/backend/executor/execScan.c
***************
*** 19,24 ****
--- 19,25 ----
  #include "postgres.h"
  
  #include "executor/executor.h"
+ #include "executor/instrument.h"
  #include "miscadmin.h"
  #include "utils/memutils.h"
  
***************
*** 221,226 **** ExecScan(ScanState *node,
--- 222,229 ----
  		 * Tuple fails qual, so free per-tuple memory and try again.
  		 */
  		ResetExprContext(econtext);
+ 		if (node->ps.instrument)
+ 			node->ps.instrument->nfiltered += 1;
  	}
  }
  
*** a/src/include/executor/instrument.h
--- b/src/include/executor/instrument.h
***************
*** 49,54 **** typedef struct Instrumentation
--- 49,55 ----
  	double		startup;		/* Total startup time (in seconds) */
  	double		total;			/* Total total time (in seconds) */
  	double		ntuples;		/* Total tuples produced */
+ 	double		nfiltered;		/* Total tuples filtered by qual */
  	double		nloops;			/* # of run cycles for this node */
  	BufferUsage bufusage;		/* Total buffer usage */
  } Instrumentation;