On 03/16/2012 11:06 AM, Charles Duffy wrote:
On 03/14/2012 07:44 PM, Charles Duffy wrote:
Howdy --
Right now, I'm aware of two ways to set the context item via the native protocol:
(1) Insert a "declare context item" header into the document
- Disadvantage: Should only work when XQUERY3 is true
- Disadvantage: Modifies line/column references for errors received
- Disadvantage: Hard to ensure that user-provided XML document will
evaluate to itself in XQuery (security risk)
Bigger disadvantage: ContextItemDecl is allowed only in the second portion of the prolog, so inserting this unambiguously would require parsing the 3rd-party document. Ugh.
(2) Use the "CS" ["Context Set"] command
- Disadvantage: Requires a database to be open (why?)
- Disadvantage: Hard to ensure that user-provided XML document will
evaluate to itself in XQuery (security risk)
I really should have tested before considering this feasible:
CS <root/>
[BASX0007] Query must yield database nodes.
So:
Context.current() accepts only Nodes, which are database-backed; QueryProcessor.context(), by contrast, can accept the ItemCache returned by a query which doesn't return a database reference.
As such -- it seems to me that what is needed is an extension to the query command protocol (as implemented by ClientListener.query()), since a QueryProcessor is available when query commands are being handled but not otherwise.
Perhaps we could define a constant "name" value, something not legal as a string, used to refer to the context as a target for the existing BIND command? Let me propose the byte \1, as in:
\3 query_id\0 \1\0 <root/>\0 \0
...the "type" field in this case being empty simply because I'm not quite sure what to do with it.
It might also be worthwhile to have an additional query command to the effect of "execute query with id1, bind result to query id2", as follows:
\8 source_query_id\0 dest_query_id\0 bind_variable_name\0
...with the byte \1 remaining a valid bind_variable_name value indicating that the target is the context item.
Allowing this would permit clients to ask the server to do parsing operations remotely and set the results as a context variable for a future operation, without needing to transfer the parse results to the client between operations.
My goal here, by the way, is to have feature-parity between the REST API and the server protocol -- the REST API allows the context item to be set when running an arbitrary, unmodified query; the server protocol, at present, does not. One of my side projects is providing a very-high-level, stateless Python API able to work through both backends (my employer has indicated intent to allow this to be eventually released), and this limitation in the protocol prevents parity between the backends.
Thanks!