The MarkLogic profile integration generates results like in https://plugins.jetbrains.com/files/8612/screenshot_19187.png. It could be useful to have something similar in BaseX. I would envision that this would apply the optimization steps first (function call rewriting, constant count evaluation, index access, etc.) and then profile the resulting query. It could even be useful in figuring out what queries to rewrite in the BaseX optimization pass.
Thanks for the example, I’ll take this into consideration.
Something that might be interesting/useful is being able to relate the query plan to the original source. Likewise for the information on applying indices. That would help when working on more advanced integration, such as annotating the types that BaseX evaluates variables, expressions, etc. to.
I have slightly extended the code for generating the query plan. With the latest snapshot, the query…
for $x in 1 to 5 return $x * $x
…will yield the following query plan:
<QueryPlan compiled="true" updating="false"> <GFLWOR type="xs:integer+" size="5" line="1" column="5"> <For type="xs:integer" size="1" line="1" column="5" name="$x" id="0"> <RangeSeq from="1" to="5" type="xs:integer+" size="5"/> </For> <Arith op="*" type="xs:integer" size="1" line="1" column="29"> <VarRef type="xs:integer" size="1" line="1" column="25" name="$x" id="0"/> <VarRef type="xs:integer" size="1" line="1" column="30" name="$x" id="0"/> </Arith> </GFLWOR> </QueryPlan>
Another example (that involves some rewritings):
let $gauss := function($x) { sum(1 to $x) } for $i in 1 to 2 return <x>{ $gauss(100000000) }</x>
The optimized query looks as follows:
for $i_1 in util:replicate("", 2) return element x { (5000000050000000) }
The corresponding query plan (the COMPPLAN option can be turned off to get the plan of the unoptimized AST):
<QueryPlan compiled="true" updating="false"> <GFLWOR type="element()+" size="2" line="2" column="5"> <For type="xs:integer" size="1" line="2" column="5" name="$_" id="1"> <SingletonSeq type="xs:string+" size="2"> <Str type="xs:string" size="1"/> </SingletonSeq> </For> <CElem type="element()" size="1" line="3" column="43"> <QNm type="xs:QName" size="1">x_</QNm> <Int type="xs:integer" size="1">5000000050000000</Int> </CElem> </GFLWOR> </QueryPlan>
I’m still hesitant to include the line and column numbers in the official release, as it would make sense to also include the base URI of the module for each expression if other modules are imported (and this would bloat the plan noticeably). Maybe we could add yet another option for generating a more comprehensive version of the query plan.
Q: Is there any documentation on the format that the query errors can take? Q: How are query errors with function call stacks formatted, including from other modules?
Here you can find the construction of the error message and the stack trace:
https://github.com/BaseXdb/basex/blob/c813a426267b542b4500ecad0ceca84e2824fc...
Hope this helps, Christian