Thread: explain root element for auto-explain
The attached tiny patch sets the <explain> root element for auto-explain XML output, so it looks something like this: <explain xmlns="http://www.postgresql.org/2009/explain"> <Plan> <Node-Type>Result</Node-Type> <Startup-Cost>0.00</Startup-Cost> <Total-Cost>0.01</Total-Cost> <Plan-Rows>1</Plan-Rows> <Plan-Width>0</Plan-Width> </Plan> </explain> The JSON output looks like this: [ "Plan": { "Node Type": "Result", "Startup Cost": 0.00, "Total Cost": 0.01, "Plan Rows": 1, "Plan Width": 0 } ] This is worth doing in itself in the XML case for reasons previously explained, but it also makes it relatively easy to add a Query-Text node or some such to the structured output, which is very much worth having, and would be my next proposed step. cheers andrew Index: contrib/auto_explain/auto_explain.c =================================================================== RCS file: /cvsroot/pgsql/contrib/auto_explain/auto_explain.c,v retrieving revision 1.7 diff -c -r1.7 auto_explain.c *** contrib/auto_explain/auto_explain.c 10 Aug 2009 05:46:49 -0000 1.7 --- contrib/auto_explain/auto_explain.c 17 Aug 2009 21:19:08 -0000 *************** *** 222,228 **** --- 222,230 ---- es.verbose = auto_explain_log_verbose; es.format = auto_explain_log_format; + ExplainBeginOutput(&es); ExplainPrintPlan(&es, queryDesc); + ExplainEndOutput(&es); /* Remove last line break */ if (es.str->len > 0 && es.str->data[es.str->len - 1] == '\n') Index: src/backend/commands/explain.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/commands/explain.c,v retrieving revision 1.189 diff -c -r1.189 explain.c *** src/backend/commands/explain.c 10 Aug 2009 05:46:50 -0000 1.189 --- src/backend/commands/explain.c 17 Aug 2009 21:19:09 -0000 *************** *** 91,98 **** bool labeled, ExplainState *es); static void ExplainDummyGroup(const char *objtype, const char *labelname, ExplainState *es); - static void ExplainBeginOutput(ExplainState *es); - static void ExplainEndOutput(ExplainState *es); static void ExplainXMLTag(const char *tagname, int flags, ExplainState *es); static void ExplainJSONLineEnding(ExplainState *es); static void escape_json(StringInfo buf, const char *str); --- 91,96 ---- *************** *** 1712,1718 **** * This is just enough different from processing a subgroup that we need * a separate pair of subroutines. */ ! static void ExplainBeginOutput(ExplainState *es) { switch (es->format) --- 1710,1716 ---- * This is just enough different from processing a subgroup that we need * a separate pair of subroutines. */ ! void ExplainBeginOutput(ExplainState *es) { switch (es->format) *************** *** 1739,1745 **** /* * Emit the end-of-output boilerplate. */ ! static void ExplainEndOutput(ExplainState *es) { switch (es->format) --- 1737,1743 ---- /* * Emit the end-of-output boilerplate. */ ! void ExplainEndOutput(ExplainState *es) { switch (es->format) Index: src/include/commands/explain.h =================================================================== RCS file: /cvsroot/pgsql/src/include/commands/explain.h,v retrieving revision 1.41 diff -c -r1.41 explain.h *** src/include/commands/explain.h 10 Aug 2009 05:46:50 -0000 1.41 --- src/include/commands/explain.h 17 Aug 2009 21:19:09 -0000 *************** *** 54,59 **** --- 54,63 ---- extern void ExplainInitState(ExplainState *es); + extern void ExplainBeginOutput(ExplainState *es); + + extern void ExplainEndOutput(ExplainState *es); + extern TupleDesc ExplainResultDesc(ExplainStmt *stmt); extern void ExplainOneUtility(Node *utilityStmt, ExplainState *es,
Andrew Dunstan <andrew.dunstan@pgexperts.com> writes: > The attached tiny patch sets the <explain> root element for auto-explain > XML output, so it looks something like this: This looks reasonable in itself, but it sort of begs the question on two other things: * what's the xmlns URL really going to be? * what's the <Query> element in regular XML output good for? And shouldn't we make both explain and auto-explain either have that or not? > The JSON output looks like this: > [ > "Plan": { > "Node Type": "Result", > "Startup Cost": 0.00, > "Total Cost": 0.01, > "Plan Rows": 1, > "Plan Width": 0 > } > ] <squint> Bearing in mind that I know roughly nothing of JSON ... surely the above is syntactically incorrect? A labeled value should be within {...} not [...]. I think this is closely related to the point about <Query>, ie the same semantic nesting level is missing in both cases. regards, tom lane
Tom Lane wrote: > Andrew Dunstan <andrew.dunstan@pgexperts.com> writes: > >> The attached tiny patch sets the <explain> root element for auto-explain >> XML output, so it looks something like this: >> > > This looks reasonable in itself, but it sort of begs the question on > two other things: > > * what's the xmlns URL really going to be? > By convention it refers to a place where you publish the schema for the document type, but it is in fact completely arbitrary, and can refer to a non-existant resource - as long as it is unique - it's just a namespace designator, and from an XML POV has no more semantic significance that a schema name does in SQL. > * what's the <Query> element in regular XML output good for? And > shouldn't we make both explain and auto-explain either have that or not? > > and also, why isn't it present in the JSON output for either? We seem to have several places when we output an XML tag but not a corresponding named JSON node. Is that really a good idea? >> The JSON output looks like this: >> > > >> [ >> "Plan": { >> "Node Type": "Result", >> "Startup Cost": 0.00, >> "Total Cost": 0.01, >> "Plan Rows": 1, >> "Plan Width": 0 >> } >> ] >> > > <squint> Bearing in mind that I know roughly nothing of JSON ... surely > the above is syntactically incorrect? A labeled value should be within > {...} not [...]. I think this is closely related to the point about > <Query>, ie the same semantic nesting level is missing in both cases. > Looks like it. <http://www.jsonlint.com/> is useful for checking such things. Of course, the current JSON output from auto-explain (i.e. without the enclosing [ ] ) is also illegal, unlike the output from "explain (format json) select 1", which encloses the Plan node in { } inside the [ ], cheers andrew
Andrew Dunstan wrote: > > > Tom Lane wrote: >> >> >> * what's the xmlns URL really going to be? >> > > By convention it refers to a place where you publish the schema for > the document type, but it is in fact completely arbitrary, and can > refer to a non-existant resource - as long as it is unique - it's just > a namespace designator, and from an XML POV has no more semantic > significance that a schema name does in SQL. > > One thing I definitely think we should do is to put the namespace URL in a header file. Think of it as being a bit like the catversion. Hardcoding it in explain.c doesn't seem like a good idea. cheers andrew
Andrew Dunstan <andrew@dunslane.net> writes: > One thing I definitely think we should do is to put the namespace URL in > a header file. Think of it as being a bit like the catversion. > Hardcoding it in explain.c doesn't seem like a good idea. Well, it could at least be a #define, but what's the point of exposing it in a header file --- what other code will use that file? regards, tom lane
Tom Lane wrote: > Andrew Dunstan <andrew@dunslane.net> writes: > >> One thing I definitely think we should do is to put the namespace URL in >> a header file. Think of it as being a bit like the catversion. >> Hardcoding it in explain.c doesn't seem like a good idea. >> > > Well, it could at least be a #define, but what's the point of exposing > it in a header file --- what other code will use that file? > > > Good point. None right now I guess. But certainly a #define. cheers andrew
On Tue, Aug 18, 2009 at 02:11, Andrew Dunstan<andrew@dunslane.net> wrote: > > Tom Lane wrote: >> >> Andrew Dunstan <andrew.dunstan@pgexperts.com> writes: >> >>> >>> The attached tiny patch sets the <explain> root element for auto-explain >>> XML output, so it looks something like this: >>> >> >> This looks reasonable in itself, but it sort of begs the question on >> two other things: >> >> * what's the xmlns URL really going to be? >> > > By convention it refers to a place where you publish the schema for the > document type, but it is in fact completely arbitrary, and can refer to a > non-existant resource - as long as it is unique - it's just a namespace > designator, and from an XML POV has no more semantic significance that a > schema name does in SQL. I'd suggest using a different namespace than www.postgresql.org, just to be sure it won't conflict with some system we use in the future. Perhaps http://schemas.postgresql.org/<whatever>? It doesn't actually need to exist until we want to put anything there, but it mustn't conflict with anything else. -- Magnus HaganderMe: http://www.hagander.net/Work: http://www.redpill-linpro.com/
Are we going to publish an XML DTD for EXPLAIN, or have we already? --------------------------------------------------------------------------- Andrew Dunstan wrote: > > The attached tiny patch sets the <explain> root element for auto-explain > XML output, so it looks something like this: > > <explain xmlns="http://www.postgresql.org/2009/explain"> > <Plan> > <Node-Type>Result</Node-Type> > <Startup-Cost>0.00</Startup-Cost> > <Total-Cost>0.01</Total-Cost> > <Plan-Rows>1</Plan-Rows> > <Plan-Width>0</Plan-Width> > </Plan> > </explain> > > The JSON output looks like this: > > [ > "Plan": { > "Node Type": "Result", > "Startup Cost": 0.00, > "Total Cost": 0.01, > "Plan Rows": 1, > "Plan Width": 0 > } > ] > > This is worth doing in itself in the XML case for reasons previously > explained, but it also makes it relatively easy to add a Query-Text node > or some such to the structured output, which is very much worth having, > and would be my next proposed step. > > cheers > > andrew > > -- > Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-hackers -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + If your life is a hard drive, Christ can be your backup. +
Bruce Momjian wrote: > Are we going to publish an XML DTD for EXPLAIN, or have we already? Not a DTD, but I am working on an XML Schema (DTDs are a bit yesterday). cheers andrew
Andrew Dunstan wrote: > Bruce Momjian wrote: > > Are we going to publish an XML DTD for EXPLAIN, or have we already? > > Not a DTD, but I am working on an XML Schema (DTDs are a bit yesterday). OK, either one would be good. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + If your life is a hard drive, Christ can be your backup. +
Andrew Dunstan <andrew@dunslane.net> writes: > Bruce Momjian wrote: >> Are we going to publish an XML DTD for EXPLAIN, or have we already? > Not a DTD, but I am working on an XML Schema (DTDs are a bit yesterday). +1 ... I asked for a spec for the output format before, and this would do fine. regards, tom lane
Andrew Dunstan wrote: > Bruce Momjian wrote: >> Are we going to publish an XML DTD for EXPLAIN, or have we already? > > Not a DTD, but I am working on an XML Schema (DTDs are a bit yesterday). > > Here is a RelaxNG spec which people might find a bit easier to read. It has been autocreated by a little tool called trang, that I used on a very large body of explain output that I produced by mangling the regression tests (and, incidentally, crashing the server in the result - I still have to chase that up). I have a couple of questions, however. First, in that long list of alternatives for a Plan node, can any of them occur more than once? Second, we are using Item as a child of both Output and Sort-Key nodes. Are they really describing the same thing? And in any case, Item is a wonderfully non-informative name, as is Output, for that matter. BTW - I know this requires tweaking - those xsd:NCName values will probably just become text, for example. cheers andrew default namespace = "http://www.postgresql.org/2009/explain" start = element explain { element Query { Plan, element Triggers { empty }, element Total-Runtime{ xsd:decimal } } } Plan = element Plan { (element Actual-Loops { xsd:integer } | element Actual-Rows { xsd:integer } | element Actual-Startup-Time{ xsd:decimal } | element Actual-Total-Time { xsd:decimal } | element Alias { text } | elementFilter { text } | element Function-Name { xsd:NCName } | element Hash-Cond { text } | element Index-Name{ xsd:NCName } | element Join-Filter { text } | element Join-Type { xsd:NCName } | element Merge-Cond{ text } | element Node-Type { text } | element One-Time-Filter { text } | element Output { Item+ } | element Parent-Relationship { xsd:NCName } | element Plan-Rows { xsd:integer } | element Plan-Width { xsd:integer} | element Plans { Plan* } | element Recheck-Cond { text } | element Relation-Name { xsd:NCName } | element Scan-Direction { xsd:NCName } | element Schema { xsd:NCName } | element Sort-Key { Item+ } | elementSort-Method { text } | element Sort-Space-Type { xsd:NCName } | element Sort-Space-Used { xsd:integer } |element Startup-Cost { xsd:decimal } | element Strategy { xsd:NCName } | element Subplan-Name { text } | elementTotal-Cost { xsd:decimal })*, element Index-Cond { text }? } Item = element Item { text }
On Thu, Aug 20, 2009 at 9:30 AM, Andrew Dunstan<andrew@dunslane.net> wrote: > > > Andrew Dunstan wrote: >> >> Bruce Momjian wrote: >>> >>> Are we going to publish an XML DTD for EXPLAIN, or have we already? >> >> Not a DTD, but I am working on an XML Schema (DTDs are a bit yesterday). >> >> > > Here is a RelaxNG spec which people might find a bit easier to read. It has > been autocreated by a little tool called trang, that I used on a very large > body of explain output that I produced by mangling the regression tests This is definitely easy to read, especially for XML. > (and, incidentally, crashing the server in the result - I still have to > chase that up). Hmm. > I have a couple of questions, however. First, in that long list of > alternatives for a Plan node, can any of them occur more than once? I don't think so. But I also don't think Index-Cond should be treated specially, as you have done here. > Second, > we are using Item as a child of both Output and Sort-Key nodes. Are they > really describing the same thing? And in any case, Item is a wonderfully > non-informative name, as is Output, for that matter. Well, I can't help Output. That's what 8.4-EXPLAIN calls it. I do think maybe it should be ripped out of EXPLAIN (VERBOSE) and made a separate option. Are they really the same thing? Obviously not. I just needed a way to make a list of scalars in XML and I picked that for want of creativity. > BTW - I know this requires tweaking - those xsd:NCName values will probably > just become text, for example. As far as I'm concerned, you're already way ahead producing something that fits on the screen. ...Robert
Andrew Dunstan <andrew@dunslane.net> writes: > I have a couple of questions, however. First, in that long list of > alternatives for a Plan node, can any of them occur more than once? No. > Second, we are using Item as a child of both Output and Sort-Key nodes. > Are they really describing the same thing? And in any case, Item is a > wonderfully non-informative name, as is Output, for that matter. They are both describing expressions. I wanted to rename Item as Expr, if you'll recall. But I think we should have a concrete plan about all the tweaks we want to make to the output schema before doing anything, so I haven't pushed to change it immediately. I don't see anything wrong with Output --- what else would you call the output expressions of a node? regards, tom lane
I wrote: > > > Andrew Dunstan wrote: >> Bruce Momjian wrote: >>> Are we going to publish an XML DTD for EXPLAIN, or have we already? >> >> Not a DTD, but I am working on an XML Schema (DTDs are a bit yesterday). >> >> > > Here is a RelaxNG spec which people might find a bit easier to read. > It has been autocreated by a little tool called trang, that I used on > a very large body of explain output that I produced by mangling the > regression tests (and, incidentally, crashing the server in the result > - I still have to chase that up). Updated version with more complete information (regression crash was due to my bad script). cheers andrew default namespace = "http://www.postgresql.org/2009/explain" start = element explain { element Query { Plan, Triggers, element Total-Runtime { xsd:decimal } }+ } Plan = element Plan { (element Actual-Loops { xsd:integer } | element Actual-Rows { xsd:integer } | element Actual-Startup-Time{ xsd:decimal } | element Actual-Total-Time { xsd:decimal } | element Alias { text } | elementCTE-Name { text } | element Command { text } | element Filter { text } | element Function-Name { text } | element Hash-Cond { text } | element Index-Cond { text } | element Index-Name { text } | element Join-Filter{ text } | element Join-Type { text } | element Merge-Cond { text } | element Node-Type { text } |element One-Time-Filter { text } | element Output { Item* } | element Parent-Relationship { text } | element Plan-Rows{ xsd:integer } | element Plan-Width { xsd:integer } | element Plans { Plan* } | element Recheck-Cond {text } | element Relation-Name { text } | element Scan-Direction { text } | element Schema { text } | elementSort-Key { Item+ } | element Sort-Method { text } | element Sort-Space-Type { text } | element Sort-Space-Used{ xsd:integer } | element Startup-Cost { xsd:decimal } | element Strategy { text } | element Subplan-Name{ text } | element Total-Cost { xsd:decimal }, | element TID-Cond { text } )* } Triggers = element Triggers { element Trigger { element Trigger-Name { text }, element Constraint-Name { text }?, element Relation { text }, element Time { xsd:decimal }, element Calls { xsd:integer } }* } Item = element Item { text }
Andrew Dunstan <andrew@dunslane.net> writes: > Updated version with more complete information (regression crash was due > to my bad script). I took a look through the source code to match it against this. I found that you missed a couple of possibilities: we have <Notify /> and <Utility-Statement /> as alternatives to <Query> just below <explain>. Also, it looks to me like <Item> is simply being used as an element of lists (cf ExplainPropertyList); I was mistaken to equate it with <Expr>. I don't know XML well enough to understand if we really need that syntactic detail, or if there's a more idiomatic way to treat lists. BTW, I wonder why <explain> doesn't have an init-cap like every other node type name ... regards, tom lane
Tom Lane wrote: > Andrew Dunstan <andrew@dunslane.net> writes: > >> Updated version with more complete information (regression crash was due >> to my bad script). >> > > I took a look through the source code to match it against this. I found > that you missed a couple of possibilities: we have <Notify /> and > <Utility-Statement /> as alternatives to <Query> just below <explain>. > What causes those to happen? Here's how I mangled the regression tests to produce the output that this analysis was taken from: perl -spi.bak -e 's/^(insert|update|select|delete|declare|execute|create table .* as) /explain (analyse true, verbose true, format xml) $1 /i;' *.sql cheers andrew
Andrew Dunstan <andrew@dunslane.net> writes: > Tom Lane wrote: >> I took a look through the source code to match it against this. I found >> that you missed a couple of possibilities: we have <Notify /> and >> <Utility-Statement /> as alternatives to <Query> just below <explain>. > What causes those to happen? You can get a <Notify> via explaining a command that's been affected by a rule likeCREATE RULE foo ... DO ALSO NOTIFY foo; I think the <Utility-Statement> case is not actually reachable code at present. NOTIFY is the only utility command that's allowed in CREATE RULE, and auto-explain is hooked in in a place where it can't see utility statements at all. I suppose we could make EXPLAIN throw error there, instead of printing a node type we'd have to document. regards, tom lane
On Thu, Aug 20, 2009 at 12:40 PM, Andrew Dunstan<andrew@dunslane.net> wrote: > > > Tom Lane wrote: >> >> Andrew Dunstan <andrew@dunslane.net> writes: >> >>> >>> Updated version with more complete information (regression crash was due >>> to my bad script). >>> >> >> I took a look through the source code to match it against this. I found >> that you missed a couple of possibilities: we have <Notify /> and >> <Utility-Statement /> as alternatives to <Query> just below <explain>. >> > > > What causes those to happen? Here's how I mangled the regression tests to > produce the output that this analysis was taken from: > > perl -spi.bak -e 's/^(insert|update|select|delete|declare|execute|create > table .* as) /explain (analyse true, verbose true, format xml) $1 /i;' *.sql CREATE RULE foo_notify AS ON UPDATE TO foo DO ALSO NOTIFY bob; I am not sure that there's any way to get any other kind of utility statement in there; I think that's just a safety valve in case someone changes the rule mechanism and forgets to update EXPLAIN. ...Robert