Hi Christian,

thank you for getting back!


On Sun, Feb 24, 2013 at 8:29 PM, Christian Grün <christian.gruen@gmail.com> wrote:
> I have a question regarding the client protocol:  Can a query that has been
> prepared using the "QUERY" protocol message be executed only once, or
> multiple times?

a query that is created with the client protocol can also be executed
once. After running the query, you should get an exception saying "The
query has already been executed.".

The current approach shouldn’t represent any bottleneck, as query
object are pretty light-weight objects. If your tests should yield
unsatisfactory results, feel free to tell us more.

It is not that I'm really suffering from performance issues and I may well be in premature optimization land, but anyway:  I am writing a web application which will be backed by a thin middleware implemented in Node.JS and BaseX as database.  My performance interest is keeping the latency between the end user and the database at a minimum, and this basically means that I want to reduce the number of request-response interactions between the client, the middle layer and the database.

Most of the queries will be stored in static files and parametrized by the incoming request.  For example, I have a file named 'person.xq' in a special directory which is mapped to requests for /person/:id and looks like this:

declare variable $components := tokenize($path, '/');
declare variable $personId := $components[count($components)];
declare variable $person := /ballhaus/people/person[@id = $personId];

<person> {
  $person/(@*, *),
  <roles> {
    for $role in distinct-values(/ballhaus/events/event/people/person[@ref = $personId]/@role)
    return <role name="{$role}"> {
      for $event in /ballhaus/events/event[people/person/@ref = $personId and people/person/@role = $role]
      return <event ref="{$event/@id}">{$event/name}</event>
    } </role>
  } </roles>
} </person>

The middle layer reads this file, prepares the query using the "QUERY" client message, binds the "path" variable to the path of the request and then executes the query.  The handler is not specific to the person query above, but works for all XQuery files in a designated directory.

I am using a new Node.JS BaseX client that I wrote because I had this urge to pipeline things for minimum latency (https://github.com/hanshuebner/simple-basex), and pipelining the BIND and EXECUTE together works fine (i.e. the middle layer does not need to wait for the confirmation for every BIND, and the protocol messages will be sent out together with the EXECUTE).  Yet, the initial QUERY message needs to be synchronous in order to retrieve the query ID, and the query cannot be reused, so bound queries necessarily have more latency than simple COMMAND invocations.

In other databases, the QUERY/BIND/EXECUTE thing is often referred to as prepared query execution, and prepared queries can usually be executed multiple times, which is why I asked.  In the mean time, I have looked at the Java side of things a bit and found that for one, the behavior is as you describe, and for another, it would not be very hard to add a client interface for bound queries if that would really make sense.  But then, maybe it would be even better to switch to the ReST interface instead.

Anyway, all this is fun and exciting, and it is great to see that BaseX is supported well!  Any thoughts about my approach would be grealy appreciated.

Cheers,
Hans