clearDocumentPool and re-execution
Added by Anonymous over 19 years ago
Legacy ID: #3286049 Legacy Poster: marcvc (marcvc)
Michael, I don't think this is new to Saxon 8.5. We see the folowing behaviour with a specific query. - the first iteration returns the expected results - subsequently the document pool is cleared - the second iteration returns no results. Clearly, it could well be that we're overlooking certain aspects and are doing something wrong. I've included the Java main method as reproducable at the end of this message. - it uses items.xml from the use cases - we expct the query to return 4 items - removing the clearDocumentPool(), makes both iterations behave the same - we have also tried not to specify null as parameter of the iterate method, but something like "new XPathContextMajor(null, sqc.getConfiguration())". However it doesn't seem to make a difference. Thanks, Marc JAVA MAIN METHOD: public static void main(String[] args) throws Exception { String query = "declare namespace f='f.ns'; " + "declare variable $Bicycles := " + "doc('items.xml')//DESCRIPTION[fn:contains(.,'Bicycle')]; " + "declare function local:IsBicycle($item) { " + " some $b in $Bicycles satisfies $b is $item " + "}; " + "declare function f:foo() { " + "doc('items.xml')//DESCRIPTION[local:IsBicycle(.)] " + "}; " + "()"; XQueryExpression exp = new StaticQueryContext(new Configuration()).compileQuery(query); StaticQueryContext sqc = exp.getStaticContext(); UserFunction fn1 = sqc.getUserDefinedFunction("f.ns", "foo", 0); Controller controller = exp.getController(); Value v = (Value)fn1.call(new ValueRepresentation[] {}, controller); SequenceIterator i = v.iterate(null); while (i.next() != null) System.out.println("first"); controller.clearDocumentPool(); v = (Value)fn1.call(new ValueRepresentation[] {}, controller); i = v.iterate(null); while (i.next() != null) System.out.println("second"); System.out.println("finished"); }
Replies (7)
Please register to reply
RE: clearDocumentPool and re-execution - Added by Anonymous over 19 years ago
Legacy ID: #3290881 Legacy Poster: Michael Kay (mhkay)
Doing a clearDocumentPool() at this point is going to mean that next time doc('items.xml') is evaluated, it returns a different tree from the one containing the nodes in global variable $Bicycles. I would not recommend using clearDocumentPool() during the course of a query, that is, while there are global variables in existence. The same applies to reset(). I''ll make changes to the documentation to make this clear. Michael Kay
RE: clearDocumentPool and re-execution - Added by Anonymous over 19 years ago
Legacy ID: #3291436 Legacy Poster: marcvc (marcvc)
Michael, Consider the following scenario. Suppose that my fn:doc is accessing a webserver providing stock quotes (or a local file which is updated frequently). I want to prepare my query and reuse the execution plan as my app executes the query over time. But clearly, I want to get up to date information through my fn:doc call, not the old values. Thanks, Marc
RE: clearDocumentPool and re-execution - Added by Anonymous over 19 years ago
Legacy ID: #3292685 Legacy Poster: Michael Kay (mhkay)
I would recommend using saxon:discard-document() in this scenario. This would remove the document from the pool only when there are no remaining references to it: which means that in your example, the document whose nodes are in a global variable will remain loaded. The particular difficulty in your case was that you cleared the document pool while there were nodes present in the value of a global variable, and then expected a further call on doc() to return nodes with the original node identity. Michael Kay
RE: clearDocumentPool and re-execution - Added by Anonymous over 19 years ago
Legacy ID: #3292871 Legacy Poster: marcvc (marcvc)
Michael, can I conclude the following? If my query contains global variables, possibly accessing fn:doc, and I want to make sure that all documents are re-loaded then I have no other option than simply "re-preparing" my query? Thanks, Marc
RE: clearDocumentPool and re-execution - Added by Anonymous over 19 years ago
Legacy ID: #3294137 Legacy Poster: Michael Kay (mhkay)
No, you shouldn't need to recompile the query; you should only need to run it with a new Controller, or possibly a Controller on which you have called reset() and clearDocumentPool(). (Note, the getController() method on XQueryExpression is poorly named: it actually creates a new Controller and returns it)
RE: clearDocumentPool and re-execution - Added by Anonymous over 19 years ago
Legacy ID: #3296412 Legacy Poster: marcvc (marcvc)
Michael, ok, the reset() method, that's the part I overlooked. Thanks for all your help! I modified the example provided in the initial message as added controller.reset(). Unfortunatelly I get a NPE: java.lang.NullPointerException at net.sf.saxon.instruct.Bindery.getGlobalVariableValue(Bindery.java:150) at net.sf.saxon.instruct.GlobalVariable.evaluateVariable(GlobalVariable.java:78) at net.sf.saxon.expr.VariableReference.evaluateVariable(VariableReference.java:242) at net.sf.saxon.expr.VariableReference.iterate(VariableReference.java:215) at net.sf.saxon.expr.QuantifiedExpression.effectiveBooleanValue(QuantifiedExpression.java:141) at net.sf.saxon.expr.QuantifiedExpression.evaluateItem(QuantifiedExpression.java:130) at net.sf.saxon.expr.LetExpression.evaluateItem(LetExpression.java:180) at net.sf.saxon.expr.ExpressionTool.eagerEvaluate(ExpressionTool.java:292) at net.sf.saxon.expr.ExpressionTool.lazyEvaluate(ExpressionTool.java:240) at net.sf.saxon.instruct.UserFunction.call(UserFunction.java:159) at net.sf.saxon.expr.UserFunctionCall.callFunction(UserFunctionCall.java:245) at net.sf.saxon.expr.UserFunctionCall.iterate(UserFunctionCall.java:196) at net.sf.saxon.expr.FilterIterator.matches(FilterIterator.java:82) at net.sf.saxon.expr.FilterIterator.getNextMatchingItem(FilterIterator.java:64) at net.sf.saxon.expr.FilterIterator.next(FilterIterator.java:44) at net.sf.saxon.expr.MappingIterator.next(MappingIterator.java:76) at net.sf.saxon.value.SequenceExtent.<init>(SequenceExtent.java:100) at net.sf.saxon.sort.DocumentOrderIterator.<init>(DocumentOrderIterator.java:30) at net.sf.saxon.sort.DocumentSorter.iterate(DocumentSorter.java:66) at net.sf.saxon.value.Closure.iterate(Closure.java:231) at SaxonReexecute.main(SaxonReexecute.java:41) Exception in thread "main" Thanks! Marc
RE: clearDocumentPool and re-execution - Added by Anonymous about 19 years ago
Legacy ID: #3313146 Legacy Poster: Michael Kay (mhkay)
The problem here is that the reset() method is defined (by JAXP) to give you a Controller (JAXP Transformer) in the same state as you would get from the JAXP Templates.newTransformer() method: the resulting state is that the Controller is bound to an Executable but no values exist for global variables. In JAXP it's then possible to make repeated calls on the transform() method, each of which clears the Bindery. The processing model here is rather different. I'm going to make the initializeController() method public: this is the method called on each transform(). You'll then be able to call reset() followed by initializeController(), and the next function you call will cause global variables to be re-evaluated. However, I don't think this gains you much compared with creating a new Controller from scratch. Michael Kay
Please register to reply