Changes

Jump to navigation Jump to search
5 bytes added ,  17:58, 13 July 2020
no edit summary
Subsequent rewritings might result in query plans that differ a lot from the original query. As this might complicate debugging, you can disable function inling during development by setting {{Option|INLINELIMIT}} to {{Code|0}}.
==Static TypingPaths== Due to the compact syntax of XPath, it can make a big difference if a slash is added or omitted in a path expression. A classical example is the double slash {{Code|//}}, which is a shortcut for {{Code|descendant-or-node()/}}. If the query is evaluated without optimizations, all nodes of a document are gathered, and for each of them, the next step is evaluated. This leads to a potentially huge number of duplicate node tree traversals, most of which are redundant, as all duplicate nodes will be removed at the end anyway. In most cases, paths with a double slash can be rewritten to descendant steps… <syntaxhighlight lang="xquery">(: equivalent queries, with identical syntax trees :)doc('addressbook.xml')//city,doc('addressbook.xml')/descendant-or-node()/child::city (: rewritten to :)doc('addressbook.xml')/descendant::city</syntaxhighlight> …unless the last step does not contain a positional predicate: <syntaxhighlight lang="xquery">doc('addressbook.xml')//city[1]</syntaxhighlight> As the positional test refers to the city child step, a rewritten query would yield different steps. Paths may contain predicates that will be evaluated again by a later axis step. Such predicates are either shifted down or discarded: <syntaxhighlight lang="xquery">(: equivalent query :)a[b]/b[c/d]/c (: rewritten to :)a/b/c[d]</syntaxhighlight>
If the type Names of a value is known at compile time, type checks nodes can be removedspecified via name tests or predicates. In the example belowIf names are e.g. supplied via external variables, the static information that {{Code|$i}} will always reference items of type {{Code|xs:integer}} predicates can often be utilized to simplify the expressiondissolved:
<syntaxhighlight lang="xquery">
for declare variable $i in 1 to 5return typeswitch($i) case xsname external :numeric return = 'numbercity'; default return db:open('stringaddressbook')//*[name() = $name]
(: rewritten to :)
for $i in 1 to 5return db:open('numberaddressbook')//city
</syntaxhighlight>
</syntaxhighlight>
==Static Typing== If the type of a value is known at compile time, type checks can be removed. In the example below, the static information that {{Code|$i}} will always reference items of type {{Code|xs:integer}} can be utilized to simplify the expression: <syntaxhighlight lang="xquery">for $i in 1 to 5return typeswitch($i) case xs:numeric return 'number' default return 'string' (: rewritten to :)for $i in 1 to 5return 'number'</syntaxhighlight> ==Pure Logic==
If expressions can often be simplified:
* <code>xs:double('NaN') * 0</code> yields <code>NaN</code> instead of <code>0</code>
* <code>true#0 and true#0</code> must raise an error; it cannot be simplified to <code>true#0</code>
 
==Paths==
 
Due to the compact syntax of XPath, it can make a big difference if a slash is added or omitted in a path expression. A classical example is the double slash {{Code|//}}, which is a shortcut for {{Code|descendant-or-node()/}}. If the query is evaluated without optimizations, all nodes of a document are gathered, and for each of them, the next step is evaluated. This leads to a potentially huge number of duplicate node tree traversals, most of which are redundant, as all duplicate nodes will be removed at the end anyway.
 
In most cases, paths with a double slash can be rewritten to descendant steps…
 
<syntaxhighlight lang="xquery">
(: equivalent queries, with identical syntax trees :)
doc('addressbook.xml')//city,
doc('addressbook.xml')/descendant-or-node()/child::city
 
(: rewritten to :)
doc('addressbook.xml')/descendant::city
</syntaxhighlight>
 
…unless the last step does not contain a positional predicate:
 
<syntaxhighlight lang="xquery">
doc('addressbook.xml')//city[1]
</syntaxhighlight>
 
As the positional test refers to the city child step, a rewritten query would yield different steps.
 
Paths may contain predicates that will be evaluated again by a later axis step. Such predicates are either shifted down or discarded:
 
<syntaxhighlight lang="xquery">
(: equivalent query :)
a[b]/b[c/d]/c
 
(: rewritten to :)
a/b/c[d]
</syntaxhighlight>
 
Names of nodes can be specified via name tests or predicates. If names are e.g. supplied via external variables, the predicates can often be dissolved:
 
<syntaxhighlight lang="xquery">
declare variable $name external := 'city';
db:open('addressbook')//*[name() = $name]
 
(: rewritten to :)
db:open('addressbook')//city
</syntaxhighlight>
=Physical Optimizations=
Bureaucrats, editor, reviewer, Administrators
13,550

edits

Navigation menu