Add new EXPLAIN options "plan" and "rewrite"
authorAndres Freund <andres@anarazel.de>
Wed, 9 Nov 2011 16:52:38 +0000 (17:52 +0100)
committerAndres Freund <andres@anarazel.de>
Fri, 18 Nov 2011 17:52:02 +0000 (18:52 +0100)
Those commands are useful to make it easier to gauge the costs of those
respective steps when introducing new features or optimizing existing code.
Another useful thing would be to be able to separate the parse and
parse-analyze steps, but that is more invasive.

src/backend/commands/explain.c
src/include/commands/explain.h

index e38de5c153485f49b413fbc53892b534a3cf68aa..2987d3b84e1721bfc8907f7e90c50e9d83107758 100644 (file)
@@ -133,6 +133,10 @@ ExplainQuery(ExplainStmt *stmt, const char *queryString,
            es.costs = defGetBoolean(opt);
        else if (strcmp(opt->defname, "buffers") == 0)
            es.buffers = defGetBoolean(opt);
+       else if (strcmp(opt->defname, "plan") == 0)
+           es.plan = defGetBoolean(opt);
+       else if (strcmp(opt->defname, "rewrite") == 0)
+           es.rewrite = defGetBoolean(opt);
        else if (strcmp(opt->defname, "format") == 0)
        {
            char       *p = defGetString(opt);
@@ -158,11 +162,25 @@ ExplainQuery(ExplainStmt *stmt, const char *queryString,
                            opt->defname)));
    }
 
+
    if (es.buffers && !es.analyze)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("EXPLAIN option BUFFERS requires ANALYZE")));
 
+   if ((!es.plan || !es.rewrite) && es.analyze)
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("EXPLAIN option !PLAN contradicts ANALYZE")));
+   /*
+    * XXX: we could check for !plan && rewrite but that would mean !rewrite
+    * would have to explicitly specified when disabling planning...
+    */
+
+   /* emit opening boilerplate */
+   ExplainBeginOutput(&es);
+
+   Assert(IsA(stmt->query, Query));
    /*
     * Parse analysis was done already, but we still have to run the rule
     * rewriter.  We do not do AcquireRewriteLocks: we assume the query either
@@ -175,11 +193,13 @@ ExplainQuery(ExplainStmt *stmt, const char *queryString,
     * executed repeatedly.  (See also the same hack in DECLARE CURSOR and
     * PREPARE.)  XXX FIXME someday.
     */
-   Assert(IsA(stmt->query, Query));
-   rewritten = QueryRewrite((Query *) copyObject(stmt->query));
+   if(!es.rewrite){
+       if (es.format == EXPLAIN_FORMAT_TEXT)
+           appendStringInfoString(es.str, "not rewriting query because auf !rewrite\n");
+       goto out;
+   }
 
-   /* emit opening boilerplate */
-   ExplainBeginOutput(&es);
+   rewritten = QueryRewrite((Query *) copyObject(stmt->query));
 
    if (rewritten == NIL)
    {
@@ -189,22 +209,26 @@ ExplainQuery(ExplainStmt *stmt, const char *queryString,
         */
        if (es.format == EXPLAIN_FORMAT_TEXT)
            appendStringInfoString(es.str, "Query rewrites to nothing\n");
+       goto out;
    }
-   else
-   {
-       ListCell   *l;
 
-       /* Explain every plan */
-       foreach(l, rewritten)
-       {
-           ExplainOneQuery((Query *) lfirst(l), &es, queryString, params);
+   if(!es.plan){
+       if (es.format == EXPLAIN_FORMAT_TEXT)
+           appendStringInfoString(es.str, "not planning or rewriting query because !plan\n");
+       goto out;
+   }
 
-           /* Separate plans with an appropriate separator */
-           if (lnext(l) != NULL)
-               ExplainSeparatePlans(&es);
-       }
+   /* Explain every plan */
+   foreach(lc, rewritten)
+   {
+       ExplainOneQuery((Query *) lfirst(lc), &es, queryString, params);
+
+       /* Separate plans with an appropriate separator */
+       if (lnext(lc) != NULL)
+           ExplainSeparatePlans(&es);
    }
 
+out:
    /* emit closing boilerplate */
    ExplainEndOutput(&es);
    Assert(es.indent == 0);
@@ -229,6 +253,8 @@ ExplainInitState(ExplainState *es)
    /* Set default options. */
    memset(es, 0, sizeof(ExplainState));
    es->costs = true;
+   es->plan = true;
+   es->rewrite = true;
    /* Prepare output buffer. */
    es->str = makeStringInfo();
 }
index d7998c31781588143c2ea9fce76b19a8f1d1a62f..78c4e6d8986eeed9d74178728de8aa6b9df5fcd6 100644 (file)
@@ -31,6 +31,8 @@ typedef struct ExplainState
    bool        analyze;        /* print actual times */
    bool        costs;          /* print costs */
    bool        buffers;        /* print buffer usage */
+   bool        plan;           /* plan the query */
+   bool        rewrite;        /* rewrite the query */
    ExplainFormat format;       /* output format */
    /* other states */
    PlannedStmt *pstmt;         /* top of plan */