5858import org .exist .source .DbStoreSource ;
5959import org .exist .source .FileSource ;
6060import org .exist .source .Source ;
61+ import org .exist .source .StringSource ;
6162import org .exist .storage .BrokerPool ;
6263import org .exist .storage .DBBroker ;
6364import org .exist .storage .lock .Lock .LockMode ;
6667import org .exist .storage .txn .Txn ;
6768import org .exist .util .LockException ;
6869import org .exist .xmldb .function .LocalXmldbFunction ;
69- import org .exist .xquery .CompiledXQuery ;
7070import org .exist .xquery .XPathException ;
71- import org .exist .xquery .XQuery ;
7271import org .exist .xquery .XQueryContext ;
7372import org .exist .xquery .XQueryUtil ;
7473import org .exist .xquery .value .AnyURIValue ;
@@ -216,34 +215,27 @@ public EXistResourceSet execute(final XMLResource res, final CompiledExpression
216215 }
217216
218217 private EXistResourceSet execute (final DBBroker broker , final Txn transaction , XmldbURI [] docs , final Sequence contextSet , final CompiledExpression expression , final String sortExpr ) throws XMLDBException {
219- final CompiledXQuery expr = (CompiledXQuery ) expression ;
220- final XQueryContext context = expr .getContext ();
218+ if (!(expression instanceof LocalCompiledExpression )) {
219+ throw new XMLDBException (ErrorCodes .VENDOR_ERROR , "LocalXPathQueryService#execute requires a LocalCompiledExpression" );
220+ }
221+ final LocalCompiledExpression localCompiledExpression = (LocalCompiledExpression ) expression ;
222+ final XQueryUtil .CompilationResult compilationResult = localCompiledExpression .getCompilationResult ();
221223
222- boolean queryResultOwnershipTransferred = false ;
223- @ Nullable XQueryUtil .QueryResult queryResult = null ;
224- try {
225- context .setStaticallyKnownDocuments (docs );
224+ final ConsumerE <XQueryContext , XPathException > preExecutionContext = xqueryContext -> {
225+ xqueryContext .setStaticallyKnownDocuments (docs );
226226 if (lockedDocuments != null ) {
227- context .setProtectedDocs (lockedDocuments );
228- }
229- setupContext (null , context );
230- declareVariables (context );
231-
232- final XQuery xquery = brokerPool .getXQueryService ();
233-
234- final long executionStarted = System .currentTimeMillis ();
235- @ Nullable final Sequence result = xquery .execute (broker , expr , null , contextSet , properties , true );
236- final long executionFinished = System .currentTimeMillis ();
237-
238- if (LOG .isTraceEnabled ()) {
239- LOG .trace ("Query took {} ms." , executionFinished - executionStarted );
240- }
241-
242- if (result == null ) {
243- return null ;
227+ xqueryContext .setProtectedDocs (lockedDocuments );
244228 }
229+ setupContext (compilationResult .source , xqueryContext );
230+ declareVariables (xqueryContext );
231+ };
245232
246- queryResult = new XQueryUtil .QueryResult (expr .getSource (), null , expr , context , -1 , executionFinished - executionStarted , result );
233+ boolean queryResultOwnershipTransferred = false ;
234+ @ Nullable XQueryUtil .QueryResult queryResult = null ;
235+ try {
236+ // TODO(AR) does reset context need to be called on the result? it was previously (note the 'true' param) -> xquery.execute(broker, expr, null, contextSet, properties, true);
237+ // NOTE(AR) queryResult takes ownership of compilationResult
238+ queryResult = XQueryUtil .execute (broker , compilationResult , contextSet , properties , preExecutionContext , null );
247239
248240 final Properties resourceSetProperties = new Properties (properties );
249241 resourceSetProperties .setProperty (EXistOutputKeys .XDM_SERIALIZATION , "yes" );
@@ -259,11 +251,11 @@ private EXistResourceSet execute(final DBBroker broker, final Txn transaction, X
259251
260252 } finally {
261253 if (!queryResultOwnershipTransferred ) {
262- // NOTE(AR) we are returning null or an exception was raised, and so we still own the queryResult and we must therefore close it
254+ // NOTE(AR) we are returning null or an exception was raised, and so we still own the queryResult or compilationResult and we must therefore close it
263255 if (queryResult != null ) {
264256 queryResult .close ();
265257 } else {
266- context . runCleanupTasks ();
258+ compilationResult . close ();
267259 }
268260 }
269261 }
@@ -306,11 +298,7 @@ private EXistResourceSet execute(final DBBroker broker, final Txn transaction, f
306298
307299 final ConsumerE <XQueryContext , XPathException > setupXqueryContextPreCompilation = xqueryContext -> {
308300 xqueryContext .setStaticallyKnownDocuments (docs );
309- try {
310- setupContext (source , xqueryContext );
311- } catch (final XMLDBException e ) {
312- throw new XPathException (e );
313- }
301+ setupContext (source , xqueryContext );
314302 };
315303
316304 final ConsumerE <XQueryContext , XPathException > setupXqueryContextPreExecution = this ::declareVariables ;
@@ -374,20 +362,22 @@ public CompiledExpression compileAndCheck(final String query) throws XMLDBExcept
374362 }
375363
376364 private Either <XPathException , CompiledExpression > compileAndCheck (final DBBroker broker , final Txn transaction , final String query ) throws XMLDBException {
377- final long start = System .currentTimeMillis ();
378- final XQuery xquery = broker .getBrokerPool ().getXQueryService ();
379- final XQueryContext context = new XQueryContext (broker .getBrokerPool ());
365+
366+ final Source source = new StringSource (query );
367+
368+ final ConsumerE <XQueryContext , XPathException > preCompilationContext = xqueryContext -> setupContext (source , xqueryContext );
380369
381370 try {
382- setupContext (null , context );
383- final CompiledExpression expr = xquery .compile (context , query );
384- if (LOG .isDebugEnabled ()) {
385- LOG .debug ("compilation took {}" , System .currentTimeMillis () - start );
371+ final XQueryUtil .CompilationResult compilationResult = XQueryUtil .compile (broker , source , false , true , preCompilationContext );
372+ if (LOG .isDebugEnabled ()) {
373+ LOG .debug ("Compilation took {}ms" , compilationResult .compilationTime );
386374 }
387- return Either .Right (expr );
375+
376+ final CompiledExpression compiledExpression = new LocalCompiledExpression (compilationResult );
377+ return Either .Right (compiledExpression );
388378 } catch (final PermissionDeniedException e ) {
389379 throw new XMLDBException (ErrorCodes .PERMISSION_DENIED , e .getMessage (), e );
390- } catch (final IllegalArgumentException e ) {
380+ } catch (final IOException e ) {
391381 throw new XMLDBException (ErrorCodes .VENDOR_ERROR , e .getMessage (), e );
392382 } catch (final XPathException e ) {
393383 return Either .Left (e );
@@ -406,14 +396,10 @@ public EXistResourceSet queryResource(final String resource, final String query)
406396 });
407397 }
408398
409- protected void setupContext (final Source source , final XQueryContext context ) throws XMLDBException , XPathException {
410- try {
411- context .setBaseURI (new AnyURIValue (properties .getProperty ("base-uri" , collection .getPath ())));
412- } catch (final XPathException e ) {
413- throw new XMLDBException (ErrorCodes .INVALID_URI ,"Invalid base uri" ,e );
414- }
399+ protected void setupContext (final Source source , final XQueryContext context ) throws XPathException {
400+ context .setBaseURI (new AnyURIValue (properties .getProperty ("base-uri" , collection .getPath ())));
415401
416- if (moduleLoadPath != null ) {
402+ if (moduleLoadPath != null ) {
417403 context .setModuleLoadPath (moduleLoadPath );
418404 } else if (source != null ) {
419405 String modulePath = null ;
@@ -561,7 +547,10 @@ public void setModuleLoadPath(final String path) {
561547
562548 @ Override
563549 public void dump (final CompiledExpression expression , final Writer writer ) throws XMLDBException {
564- final CompiledXQuery expr = (CompiledXQuery )expression ;
565- expr .dump (writer );
550+ if (!(expression instanceof LocalCompiledExpression )) {
551+ throw new XMLDBException (ErrorCodes .VENDOR_ERROR , "LocalXPathQueryService#dump requires a LocalCompiledExpression" );
552+ }
553+ final LocalCompiledExpression localCompiledExpression = (LocalCompiledExpression ) expression ;
554+ localCompiledExpression .getCompilationResult ().dump (writer );
566555 }
567556}
0 commit comments