Lists: | pgsql-hackers |
---|
From: | Peter Eisentraut <peter_e(at)gmx(dot)net> |
---|---|
To: | pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | auto_explain produces invalid JSON |
Date: | 2012-02-10 18:14:28 |
Message-ID: | 1328897668.5373.3.camel@vanquo.pezone.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
The auto_explain module appears to create invalid JSON (in all versions
since 9.0). For example, with the settings
auto_explain.log_format = 'json'
auto_explain.log_min_duration = 0
the query
select * from pg_type;
produces this in the log:
LOG: duration: 529.808 ms plan:
[
"Query Text": "select * from pg_type;",
"Plan": {
"Node Type": "Seq Scan",
"Relation Name": "pg_type",
"Alias": "pg_type",
"Startup Cost": 0.00,
"Total Cost": 9.87,
"Plan Rows": 287,
"Plan Width": 611
}
]
Note that at the top level, it uses the array delimiters [ ] for what is
actually an object (key/value). Running this through a JSON parser will
fail.
By contrast, EXPLAIN (FORMAT JSON) on the command line produces:
QUERY PLAN
-----------------------------------
[
{
"Plan": {
"Node Type": "Seq Scan",
"Relation Name": "pg_type",
"Alias": "pg_type",
"Startup Cost": 0.00,
"Total Cost": 9.87,
"Plan Rows": 287,
"Plan Width": 611
}
}
]
(1 row)
So there is evidently something out of sync between what EXPLAIN and
what auto_explain produces.
From: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
---|---|
To: | Peter Eisentraut <peter_e(at)gmx(dot)net> |
Cc: | pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: auto_explain produces invalid JSON |
Date: | 2012-02-11 18:18:59 |
Message-ID: | 4F36B113.5000602@dunslane.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
On 02/10/2012 01:14 PM, Peter Eisentraut wrote:
> The auto_explain module appears to create invalid JSON (in all versions
> since 9.0). For example, with the settings
>
> auto_explain.log_format = 'json'
> auto_explain.log_min_duration = 0
>
> the query
>
> select * from pg_type;
>
> produces this in the log:
>
> LOG: duration: 529.808 ms plan:
> [
> "Query Text": "select * from pg_type;",
> "Plan": {
> "Node Type": "Seq Scan",
> "Relation Name": "pg_type",
> "Alias": "pg_type",
> "Startup Cost": 0.00,
> "Total Cost": 9.87,
> "Plan Rows": 287,
> "Plan Width": 611
> }
> ]
>
> Note that at the top level, it uses the array delimiters [ ] for what is
> actually an object (key/value). Running this through a JSON parser will
> fail.
>
> By contrast, EXPLAIN (FORMAT JSON) on the command line produces:
>
> QUERY PLAN
> -----------------------------------
> [
> {
> "Plan": {
> "Node Type": "Seq Scan",
> "Relation Name": "pg_type",
> "Alias": "pg_type",
> "Startup Cost": 0.00,
> "Total Cost": 9.87,
> "Plan Rows": 287,
> "Plan Width": 611
> }
> }
> ]
> (1 row)
>
Yeah, looks like this dates back to when we first got JSON output.
Auto-explain does this:
ExplainBeginOutput(&es);
ExplainQueryText(&es, queryDesc);
ExplainPrintPlan(&es, queryDesc);
ExplainEndOutput(&es);
But ExplainBeginOutput says:
case EXPLAIN_FORMAT_JSON:
/* top-level structure is an array of plans */
appendStringInfoChar(es->str, '[');
Now that's not true in the auto-explain case, which prints one query +
one plan.
Since this is an exposed API, I don't think we can just change it. We
probably need a new API that does the right thing for beginning and
ending auto_explain output. (ExplainBeginLabeledOutput?)
cheers
andrew
From: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
---|---|
To: | Peter Eisentraut <peter_e(at)gmx(dot)net> |
Cc: | pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: auto_explain produces invalid JSON |
Date: | 2012-02-11 20:12:01 |
Message-ID: | 4F36CB91.3030304@dunslane.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
On 02/11/2012 01:18 PM, Andrew Dunstan wrote:
>
>
> On 02/10/2012 01:14 PM, Peter Eisentraut wrote:
>> [ auto-explain JSON output should be an object instead of an array ]
>
>
>
> Yeah, looks like this dates back to when we first got JSON output.
>
> Auto-explain does this:
>
> ExplainBeginOutput(&es);
> ExplainQueryText(&es, queryDesc);
> ExplainPrintPlan(&es, queryDesc);
> ExplainEndOutput(&es);
>
>
> But ExplainBeginOutput says:
>
> case EXPLAIN_FORMAT_JSON:
> /* top-level structure is an array of plans */
> appendStringInfoChar(es->str, '[');
>
>
> Now that's not true in the auto-explain case, which prints one query +
> one plan.
>
> Since this is an exposed API, I don't think we can just change it. We
> probably need a new API that does the right thing for beginning and
> ending auto_explain output. (ExplainBeginLabeledOutput?)
>
>
PFA a patch along these lines, which seems to do the Right Thing (tm)
cheers
andrew
Attachment | Content-Type | Size |
---|---|---|
explain.patch | text/x-patch | 2.5 KB |
From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
Cc: | Peter Eisentraut <peter_e(at)gmx(dot)net>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: auto_explain produces invalid JSON |
Date: | 2012-02-11 20:22:11 |
Message-ID: | 17663.1328991731@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Andrew Dunstan <andrew(at)dunslane(dot)net> writes:
> But ExplainBeginOutput says:
> case EXPLAIN_FORMAT_JSON:
> /* top-level structure is an array of plans */
> appendStringInfoChar(es->str, '[');
> Now that's not true in the auto-explain case, which prints one query +
> one plan.
What about queries that expand to multiple plans because of rules?
> Since this is an exposed API, I don't think we can just change it. We
> probably need a new API that does the right thing for beginning and
> ending auto_explain output. (ExplainBeginLabeledOutput?)
I'm inclined to think that this is auto_explain's error, not that of
the core code, ie we should be changing the output.
regards, tom lane
From: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | Peter Eisentraut <peter_e(at)gmx(dot)net>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: auto_explain produces invalid JSON |
Date: | 2012-02-11 21:26:55 |
Message-ID: | 4F36DD1F.8010609@dunslane.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
On 02/11/2012 03:22 PM, Tom Lane wrote:
> Andrew Dunstan<andrew(at)dunslane(dot)net> writes:
>> But ExplainBeginOutput says:
>> case EXPLAIN_FORMAT_JSON:
>> /* top-level structure is an array of plans */
>> appendStringInfoChar(es->str, '[');
>> Now that's not true in the auto-explain case, which prints one query +
>> one plan.
> What about queries that expand to multiple plans because of rules?
Oh, hmm, good point.
>
>> Since this is an exposed API, I don't think we can just change it. We
>> probably need a new API that does the right thing for beginning and
>> ending auto_explain output. (ExplainBeginLabeledOutput?)
> I'm inclined to think that this is auto_explain's error, not that of
> the core code, ie we should be changing the output.
>
>
It looks like it will be messy either way. ;-(
cheers
andrew
From: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | Peter Eisentraut <peter_e(at)gmx(dot)net>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: auto_explain produces invalid JSON |
Date: | 2012-02-11 21:56:15 |
Message-ID: | 4F36E3FF.90901@dunslane.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
On 02/11/2012 03:22 PM, Tom Lane wrote:
> Andrew Dunstan<andrew(at)dunslane(dot)net> writes:
>> But ExplainBeginOutput says:
>> case EXPLAIN_FORMAT_JSON:
>> /* top-level structure is an array of plans */
>> appendStringInfoChar(es->str, '[');
>> Now that's not true in the auto-explain case, which prints one query +
>> one plan.
> What about queries that expand to multiple plans because of rules?
... and the answer is it logs them in separate pieces of JSON.
>
>> Since this is an exposed API, I don't think we can just change it. We
>> probably need a new API that does the right thing for beginning and
>> ending auto_explain output. (ExplainBeginLabeledOutput?)
> I'm inclined to think that this is auto_explain's error, not that of
> the core code, ie we should be changing the output.
>
>
Well, maybe this is more to your taste, although it strikes me as more
than something of a kludge. At least it's short :-)
cheers
andrew
Attachment | Content-Type | Size |
---|---|---|
explain2.patch | text/x-patch | 611 bytes |
From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
Cc: | Peter Eisentraut <peter_e(at)gmx(dot)net>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: auto_explain produces invalid JSON |
Date: | 2012-02-13 16:15:10 |
Message-ID: | 11187.1329149710@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
[ sorry for ignoring this over the weekend --- I wasn't feeling very well ]
Andrew Dunstan <andrew(at)dunslane(dot)net> writes:
> On 02/11/2012 03:22 PM, Tom Lane wrote:
>> I'm inclined to think that this is auto_explain's error, not that of
>> the core code, ie we should be changing the output.
> Well, maybe this is more to your taste, although it strikes me as more
> than something of a kludge. At least it's short :-)
I see you've already committed this, but I agree that it's quite a
kluge.
After looking a bit more at the existing explain code, it seems like the
critical issue is that explain.c has ExplainOpenGroup/ExplainCloseGroup
calls around the ExplainPrintPlan call (see ExplainOnePlan), while
auto_explain does not. I did not like your originally proposed patch
because it seemed to introduce yet another formatting concept into code
that has already got a few too many. But couldn't we fix this by
exporting ExplainOpenGroup/ExplainCloseGroup and then calling those from
auto_explain?
regards, tom lane
From: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | Peter Eisentraut <peter_e(at)gmx(dot)net>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: auto_explain produces invalid JSON |
Date: | 2012-02-13 17:42:46 |
Message-ID: | 4F394B96.808@dunslane.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
On 02/13/2012 11:15 AM, Tom Lane wrote:
> [ sorry for ignoring this over the weekend --- I wasn't feeling very well ]
>
> Andrew Dunstan<andrew(at)dunslane(dot)net> writes:
>> On 02/11/2012 03:22 PM, Tom Lane wrote:
>>> I'm inclined to think that this is auto_explain's error, not that of
>>> the core code, ie we should be changing the output.
>> Well, maybe this is more to your taste, although it strikes me as more
>> than something of a kludge. At least it's short :-)
> I see you've already committed this, but I agree that it's quite a
> kluge.
>
> After looking a bit more at the existing explain code, it seems like the
> critical issue is that explain.c has ExplainOpenGroup/ExplainCloseGroup
> calls around the ExplainPrintPlan call (see ExplainOnePlan), while
> auto_explain does not. I did not like your originally proposed patch
> because it seemed to introduce yet another formatting concept into code
> that has already got a few too many. But couldn't we fix this by
> exporting ExplainOpenGroup/ExplainCloseGroup and then calling those from
> auto_explain?
Yeah, maybe. We'd still have to do it conditionally (have to use
ExplainBeginOutput for the XML case), but it would possibly be less kludgy.
cheers
andrew
From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
Cc: | Peter Eisentraut <peter_e(at)gmx(dot)net>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: auto_explain produces invalid JSON |
Date: | 2012-02-13 17:48:52 |
Message-ID: | 12688.1329155332@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Andrew Dunstan <andrew(at)dunslane(dot)net> writes:
> On 02/13/2012 11:15 AM, Tom Lane wrote:
>> After looking a bit more at the existing explain code, it seems like the
>> critical issue is that explain.c has ExplainOpenGroup/ExplainCloseGroup
>> calls around the ExplainPrintPlan call (see ExplainOnePlan), while
>> auto_explain does not.
> Yeah, maybe. We'd still have to do it conditionally (have to use
> ExplainBeginOutput for the XML case), but it would possibly be less kludgy.
Hm? I wasn't suggesting removing the ExplainBeginOutput call, but more
like
ExplainBeginOutput(&es);
+ ExplainOpenGroup(...);
ExplainQueryText(&es, queryDesc);
ExplainPrintPlan(&es, queryDesc);
+ ExplainCloseGroup(...);
ExplainEndOutput(&es);
Details still TBD; the point is just that it's not clear to me why
auto_explain should need a formatting concept that doesn't already exist
within explain.c.
regards, tom lane
From: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | Peter Eisentraut <peter_e(at)gmx(dot)net>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: auto_explain produces invalid JSON |
Date: | 2012-02-13 18:33:58 |
Message-ID: | 4F395796.3010004@dunslane.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
On 02/13/2012 12:48 PM, Tom Lane wrote:
> Andrew Dunstan<andrew(at)dunslane(dot)net> writes:
>> On 02/13/2012 11:15 AM, Tom Lane wrote:
>>> After looking a bit more at the existing explain code, it seems like the
>>> critical issue is that explain.c has ExplainOpenGroup/ExplainCloseGroup
>>> calls around the ExplainPrintPlan call (see ExplainOnePlan), while
>>> auto_explain does not.
>> Yeah, maybe. We'd still have to do it conditionally (have to use
>> ExplainBeginOutput for the XML case), but it would possibly be less kludgy.
> Hm? I wasn't suggesting removing the ExplainBeginOutput call, but more
> like
>
> ExplainBeginOutput(&es);
> + ExplainOpenGroup(...);
> ExplainQueryText(&es, queryDesc);
> ExplainPrintPlan(&es, queryDesc);
> + ExplainCloseGroup(...);
> ExplainEndOutput(&es);
>
> Details still TBD; the point is just that it's not clear to me why
> auto_explain should need a formatting concept that doesn't already exist
> within explain.c.
>
>
This will introduce an extra level of nesting for no good reason.
But this would work:
- ExplainBeginOutput(&es);
+ if (auto_explain_log_format != EXPLAIN_FORMAT_JSON)
+ ExplainBeginOutput(&es);
+ else
+ ExplainOpenGroup(NULL, NULL, true,& es);
ExplainQueryText(&es, queryDesc);
ExplainPrintPlan(&es, queryDesc);
- ExplainEndOutput(&es);
+ if (auto_explain_log_format != EXPLAIN_FORMAT_JSON)
+ ExplainEndOutput(&es);
+ else
+ ExplainCloseGroup(NULL, NULL, true, &es);
cheers
andrew
From: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | Peter Eisentraut <peter_e(at)gmx(dot)net>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: auto_explain produces invalid JSON |
Date: | 2012-02-13 19:11:54 |
Message-ID: | 4F39607A.8040803@dunslane.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
On 02/13/2012 01:33 PM, Andrew Dunstan wrote:
>
>
> On 02/13/2012 12:48 PM, Tom Lane wrote:
>> Andrew Dunstan<andrew(at)dunslane(dot)net> writes:
>>> On 02/13/2012 11:15 AM, Tom Lane wrote:
>>>> After looking a bit more at the existing explain code, it seems
>>>> like the
>>>> critical issue is that explain.c has
>>>> ExplainOpenGroup/ExplainCloseGroup
>>>> calls around the ExplainPrintPlan call (see ExplainOnePlan), while
>>>> auto_explain does not.
>>> Yeah, maybe. We'd still have to do it conditionally (have to use
>>> ExplainBeginOutput for the XML case), but it would possibly be less
>>> kludgy.
>> Hm? I wasn't suggesting removing the ExplainBeginOutput call, but more
>> like
>>
>> ExplainBeginOutput(&es);
>> + ExplainOpenGroup(...);
>> ExplainQueryText(&es, queryDesc);
>> ExplainPrintPlan(&es, queryDesc);
>> + ExplainCloseGroup(...);
>> ExplainEndOutput(&es);
>>
>> Details still TBD; the point is just that it's not clear to me why
>> auto_explain should need a formatting concept that doesn't already exist
>> within explain.c.
>>
>>
>
> This will introduce an extra level of nesting for no good reason.
>
> But this would work:
>
> - ExplainBeginOutput(&es);
> + if (auto_explain_log_format != EXPLAIN_FORMAT_JSON)
> + ExplainBeginOutput(&es);
> + else
> + ExplainOpenGroup(NULL, NULL, true,& es);
> ExplainQueryText(&es, queryDesc);
> ExplainPrintPlan(&es, queryDesc);
> - ExplainEndOutput(&es);
> + if (auto_explain_log_format != EXPLAIN_FORMAT_JSON)
> + ExplainEndOutput(&es);
> + else
> + ExplainCloseGroup(NULL, NULL, true, &es);
>
>
Except that it causes other problems.
I think we'd probably bet sleeping dogs lie.
cheers
andrew