aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/explain.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>1998-11-08 19:38:34 +0000
committerTom Lane <tgl@sss.pgh.pa.us>1998-11-08 19:38:34 +0000
commit39792e5b01b5e500432b2624f764b138fdc3871a (patch)
treece2d86bdb9ec22c64ce3ea698c47cf11777ac107 /src/backend/commands/explain.c
parent8f5ff4cf1c7fac2ab5703a90818524699ad40da3 (diff)
downloadpostgresql-39792e5b01b5e500432b2624f764b138fdc3871a.tar.gz
postgresql-39792e5b01b5e500432b2624f764b138fdc3871a.zip
EXPLAIN VERBOSE had a very high probability of triggering
a backend core dump, because it was concatenating a potentially long string onto another string that didn't necessarily have enough room. Shame, shame.
Diffstat (limited to 'src/backend/commands/explain.c')
-rw-r--r--src/backend/commands/explain.c53
1 files changed, 33 insertions, 20 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 1b861c96204..f7bb3e5ec44 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.25 1998/10/21 16:21:20 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.26 1998/11/08 19:38:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,6 +38,7 @@ typedef struct ExplainState
} ExplainState;
static char *Explain_PlanToString(Plan *plan, ExplainState *es);
+static void printLongNotice(const char * header, const char * message);
static void ExplainOneQuery(Query *query, bool verbose, CommandDest dest);
@@ -87,11 +88,9 @@ ExplainQuery(Query *query, bool verbose, CommandDest dest)
static void
ExplainOneQuery(Query *query, bool verbose, CommandDest dest)
{
- char *s = NULL,
- *s2;
+ char *s;
Plan *plan;
ExplainState *es;
- int len;
/* plan the queries (XXX we've ignored rewrite!!) */
plan = planner(query);
@@ -111,30 +110,25 @@ ExplainOneQuery(Query *query, bool verbose, CommandDest dest)
es->rtable = query->rtable;
if (es->printNodes)
+ {
s = nodeToString(plan);
+ if (s)
+ {
+ printLongNotice("QUERY DUMP:\n\n", s);
+ pfree(s);
+ }
+ }
if (es->printCost)
{
- s2 = Explain_PlanToString(plan, es);
- if (s == NULL)
- s = s2;
- else
+ s = Explain_PlanToString(plan, es);
+ if (s)
{
- strcat(s, "\n\n");
- strcat(s, s2);
+ printLongNotice("QUERY PLAN:\n\n", s);
+ pfree(s);
}
}
- /* output the plan */
- len = strlen(s);
- elog(NOTICE, "QUERY PLAN:\n\n%.*s", ELOG_MAXLEN - 64, s);
- len -= ELOG_MAXLEN - 64;
- while (len > 0)
- {
- s += ELOG_MAXLEN - 64;
- elog(NOTICE, "%.*s", ELOG_MAXLEN - 64, s);
- len -= ELOG_MAXLEN - 64;
- }
if (es->printNodes)
pprint(plan); /* display in postmaster log file */
@@ -361,3 +355,22 @@ Explain_PlanToString(Plan *plan, ExplainState *es)
return s;
}
+
+/*
+ * Print a message that might exceed the size of the elog message buffer.
+ * This is a crock ... there shouldn't be an upper limit to what you can elog().
+ */
+static void
+printLongNotice(const char * header, const char * message)
+{
+ int len = strlen(message);
+
+ elog(NOTICE, "%.20s%.*s", header, ELOG_MAXLEN - 64, message);
+ len -= ELOG_MAXLEN - 64;
+ while (len > 0)
+ {
+ message += ELOG_MAXLEN - 64;
+ elog(NOTICE, "%.*s", ELOG_MAXLEN - 64, message);
+ len -= ELOG_MAXLEN - 64;
+ }
+}