Project

Profile

Help

How to set prepared expression vbl from Java?

Added by Anonymous about 16 years ago

Legacy ID: #5010707 Legacy Poster: Chapman Flack (jcflack)

Hi, In a Java function that receives an Evaluate.PreparedExpression from the caller, given a ValueRepresentation that I would like bound to $p1 while evaluating the expression, what are the next things I need to do? I have been kind of groping through the source for clues. The PreparedExpression has a variables[] array, so I assume that variables[0] is the slot number of $p1. It seemed straightforward to try c.setLocalVariable(slot, vr); exp.expression.effectiveBooleanValue(c); but in setLocalVariable() I got an ArrayIndexOutOfBounds. I suspect I am using the wrong context for c. It's a newCleanCopy of the context my Java function received from its XQuery caller as the first argument. I'm guessing that context doesn't have any slot reserved for the prepared expression's $p1, and that slot is somehow reserved in the expStaticContext that's packaged up in the PreparedExpression itself. But hmm, that's an IndependentContext and I can't set a local variable there. Do I need to somehow synthesize an XPathContext with the right slots reserved? Is there some other step that I am missing? I do have the svn browser in front of me but I seem to have been going in circles for a bit and something isn't sinking in. Any hints greatly appreciated. :) -Chap


Replies (2)

RE: How to set prepared expression vbl from J - Added by Anonymous about 16 years ago

Legacy ID: #5010891 Legacy Poster: Michael Kay (mhkay)

You'll find the relevant code in the evaluateItem() and iterate() methods of net.sf.saxon.functions.Evaluate - that is: XPathContextMajor c2 = c.newCleanContext(); c2.setOrigin(details); c2.openStackFrame(pexpr.stackFrameMap); c2.setCurrentIterator(c.getCurrentIterator()); for (int i=1; i<argument.length; i++) { int slot = pexpr.variables[i-1].getLocalSlotNumber(); c2.setLocalVariable(slot, ExpressionTool.eagerEvaluate(argument[i],c)); } return Value.getIterator( ExpressionTool.lazyEvaluate(pexpr.expression, c2, 1)); Here c is the dynamic context and pexpr is the PreparedExpression. Be warned that this is making a lot of use of internal methods that might change from release to release; also, without checking I can't guarantee that all the required interfaces are public. I suspect you left out the openStackFrame() call.

RE: How to set prepared expression vbl from J - Added by Anonymous about 16 years ago

Legacy ID: #5012257 Legacy Poster: Chapman Flack (jcflack)

> I suspect you left out the openStackFrame() call. Suspicion confirmed. It works now, thanks! > Be warned that this is making a lot of use of internal methods that might > change from release to release Roger. If I may so suggest, though, this seems like a small gap in the API; one knows how to create a PreparedExpression and one knows it can be passed to a Java extension, and is a little surprised to find no quite supported API for the extension to use the expression passed to it. If the 'change' in some subsequent release could be to provide a documented method like PreparedExpression.evaluateItem(XPathContext c, SequenceIterator current, ValueRepresentation[] args) that encapsulated the above steps, I wouldn't grumble at all about updating my code to use it. :) I guess the real concern would be if you have a reason in principle for /not/ exposing such an API (e.g. it would break some optimization or concurrency assumption that you are committed to). In that case I suppose I really would be asking for trouble. -Chap

    (1-2/2)

    Please register to reply