diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-02-02 23:46:38 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-02-02 23:46:38 +0000 |
commit | c7bceca156cc7ffd744b17669b7839b69eb1c9d3 (patch) | |
tree | 58f7d62d3aa61ac3f6228c2c67f3bb96f2c12983 /src/backend/commands/explain.c | |
parent | 6adb475f77c63eee8ba8b85bf00cd841d57037aa (diff) | |
download | postgresql-c7bceca156cc7ffd744b17669b7839b69eb1c9d3.tar.gz postgresql-c7bceca156cc7ffd744b17669b7839b69eb1c9d3.zip |
Implement EXPLAIN EXECUTE. By Neil Conway, with some kibitzing from
Tom Lane.
Diffstat (limited to 'src/backend/commands/explain.c')
-rw-r--r-- | src/backend/commands/explain.c | 65 |
1 files changed, 46 insertions, 19 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 3820dd8b462..6c8b02a156e 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -1,20 +1,23 @@ -/* +/*------------------------------------------------------------------------- + * * explain.c - * Explain the query execution plan + * Explain query execution plans * * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.99 2002/12/15 16:17:38 tgl Exp $ + * IDENTIFICATION + * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.100 2003/02/02 23:46:38 tgl Exp $ * + *------------------------------------------------------------------------- */ - #include "postgres.h" #include "access/genam.h" #include "access/heapam.h" #include "catalog/pg_type.h" #include "commands/explain.h" +#include "commands/prepare.h" #include "executor/executor.h" #include "executor/instrument.h" #include "lib/stringinfo.h" @@ -81,8 +84,11 @@ ExplainQuery(ExplainStmt *stmt, CommandDest dest) if (query->commandType == CMD_UTILITY) { - /* rewriter will not cope with utility statements */ - do_text_output_oneline(tstate, "Utility statements have no plan structure"); + /* Rewriter will not cope with utility statements */ + if (query->utilityStmt && IsA(query->utilityStmt, ExecuteStmt)) + ExplainExecuteQuery(stmt, tstate); + else + do_text_output_oneline(tstate, "Utility statements have no plan structure"); } else { @@ -119,10 +125,6 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate) { Plan *plan; QueryDesc *queryDesc; - ExplainState *es; - StringInfo str; - double totaltime = 0; - struct timeval starttime; /* planner will not cope with utility statements */ if (query->commandType == CMD_UTILITY) @@ -134,6 +136,13 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate) return; } + /* + * We don't support DECLARE CURSOR in EXPLAIN, but parser will take it + * because it's an OptimizableStmt + */ + if (query->isPortal) + elog(ERROR, "EXPLAIN / DECLARE CURSOR is not supported"); + /* plan the query */ plan = planner(query); @@ -141,15 +150,34 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate) if (plan == NULL) return; - /* We don't support DECLARE CURSOR here */ - Assert(!query->isPortal); - - gettimeofday(&starttime, NULL); - /* Create a QueryDesc requesting no output */ queryDesc = CreateQueryDesc(query, plan, None, NULL, NULL, stmt->analyze); + ExplainOnePlan(queryDesc, stmt, tstate); +} + +/* + * ExplainOnePlan - + * given a planned query, execute it if needed, and then print + * EXPLAIN output + * + * This is exported because it's called back from prepare.c in the + * EXPLAIN EXECUTE case + * + * Note: the passed-in QueryDesc is freed when we're done with it + */ +void +ExplainOnePlan(QueryDesc *queryDesc, ExplainStmt *stmt, + TupOutputState *tstate) +{ + struct timeval starttime; + double totaltime = 0; + ExplainState *es; + StringInfo str; + + gettimeofday(&starttime, NULL); + /* call ExecutorStart to prepare the plan for execution */ ExecutorStart(queryDesc); @@ -160,7 +188,6 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate) ExecutorRun(queryDesc, ForwardScanDirection, 0L); /* We can't clean up 'till we're done printing the stats... */ - totaltime += elapsed_time(&starttime); } @@ -169,14 +196,14 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate) es->printCost = true; /* default */ es->printNodes = stmt->verbose; es->printAnalyze = stmt->analyze; - es->rtable = query->rtable; + es->rtable = queryDesc->parsetree->rtable; if (es->printNodes) { char *s; char *f; - s = nodeToString(plan); + s = nodeToString(queryDesc->plantree); if (s) { if (Explain_pretty_print) @@ -195,7 +222,7 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate) if (es->printCost) { - explain_outNode(str, plan, queryDesc->planstate, + explain_outNode(str, queryDesc->plantree, queryDesc->planstate, NULL, 0, es); } |