4

We are refactoring a very large system and looking at many of the xQuery's we have written and wondering if using and including an xQuery that declares many global variables would not help.

But the question is for the architects ... are these loaded on reference or only loaded when used?

Meaning lets say I have some xQuery ... _global.xq like this:

module namespace g="global/variables";
declare variable $g:col.build := '/db/foo/data/Build';
declare variable $g:doc.langmap := doc(concat($g:col.build,'/','langmap.xml'));
declare variable $g:doc.easymap := doc(concat($g:col.build,'/','easymap.xml'));
declare variable $g:doc.foomap := doc(concat($g:col.build,'/','foomap.xml'));

And then I reference this in my xQuery:

import module namespace g='global/variables' at '_global.xq';

Then I use only $g:doc.langmapin my xQuery. Are the other two ($g:doc.easymap and $g:doc.foomap) evaluated and loaded in memory also even though I do not use them?

Is $g:doc.langmap populated on the import or only when I actually use it in the query? Like if I write an xQuery that does not ever reference $g:doc.langmap but imports that module, is it still created in memory and populated or not?

I wonder because if I have dozens of other declare variables in _global.xq to be used in many, many other xQueries. And of course I do not use but only a few of the references in each. The question is then simple ... does the import module command cause them all to be evaluated at the time of import, or do they only have values when they are used?

I suspect this will be a very short answer.

Kevin Brown
  • 8,805
  • 2
  • 20
  • 38

1 Answers1

4

OK, I believe I know the answer to this already with some simple test.

I created an Xquery when run takes about 87sec.

xquery version "3.0";
declare variable $test := collection('/db/foo/data')//*[@docnum='GS01'];
let $foo := 'bar'
return
$test

If I change that to this:

xquery version "3.0";
declare variable $test := collection('/db/foo/data')//*[@docnum='GS01'];
let $foo := 'bar'
return
$foo

It runs is a fraction of a second. This leads me to believe that $test is not actually populated with data unless it is used which would answer my question. If I am wrong please chime in.

Kevin Brown
  • 8,805
  • 2
  • 20
  • 38
  • 4
    The answer may be more subtle, and you'll need an eXist expert for a definitive answer. For example, the answer may not be the same if there is a static reference to the global reference but the code containing the static reference is not executed (for example, it it appears in an un-called function.) It may also depend on configuration settings (with Saxon, for example, it would depend on the optimization level). – Michael Kay Feb 01 '19 at 10:26
  • Thank you @MichaelKay. We are doing some additional testing and so far have not seen any "odd" effects. Although I would say that in the test query above I purposefully selected something that is NOT indexed in a range index to make the query run longer. If what we build in variable is also indexed, we were actually not sure if anything is happening as the query is 0.1 to 0.2 seconds. – Kevin Brown Feb 01 '19 at 21:32