Skip to content

Commit 70d07bf

Browse files
committed
[bugfix] Ensure that XQuery Context is correctly cleaned up when finished with
1 parent e478a71 commit 70d07bf

File tree

10 files changed

+137
-103
lines changed

10 files changed

+137
-103
lines changed

exist-core/src/main/java/org/exist/collections/triggers/XQueryTrigger.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ private void prepare(final TriggerEvent event, final DBBroker broker, final Txn
257257
} catch (final XPathException | PermissionDeniedException e) {
258258
TriggerStatePerThread.clear();
259259
throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
260+
} finally {
261+
context.runCleanupTasks();
260262
}
261263
}
262264

@@ -299,6 +301,8 @@ private void finish(final TriggerEvent event, final DBBroker broker, final Txn t
299301
} catch (final PermissionDeniedException e) {
300302
//Should never be reached
301303
LOG.error(e);
304+
} finally {
305+
context.runCleanupTasks();
302306
}
303307

304308
TriggerStatePerThread.clearIfFinished(TriggerPhase.AFTER);
@@ -455,6 +459,7 @@ private void execute(final TriggerPhase phase, final TriggerEvent event, final D
455459
throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
456460
} finally {
457461
compiledQuery.reset();
462+
context.runCleanupTasks();
458463
}
459464

460465
TriggerStatePerThread.clearIfFinished(phase);

exist-core/src/main/java/org/exist/dom/persistent/SortedNodeSet.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ public IteratorItem(final NodeProxy proxy, final PathExpr expr) {
288288
value = buf.toString();
289289
} catch(final XPathException e) {
290290
LOG.warn(e.getMessage(), e); //TODO : throw exception ! -pb
291+
} finally {
292+
expr.getContext().runCleanupTasks();
293+
expr.getContext().reset();
291294
}
292295
}
293296

exist-core/src/main/java/org/exist/repo/Deployment.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,8 @@ private Sequence runQuery(final DBBroker broker, final XmldbURI targetCollection
697697
return xqs.execute(broker, compiled, null);
698698
} catch (final PermissionDeniedException e) {
699699
throw new PackageException(e.getMessage(), e);
700+
} finally {
701+
ctx.runCleanupTasks();
700702
}
701703
}
702704

exist-core/src/main/java/org/exist/security/internal/SMEvents.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ protected void runScript(Subject subject, String scriptURI, String script, QName
142142
pm.queryCompleted(context.getWatchDog());
143143
}
144144
compiled.reset();
145+
context.runCleanupTasks();
145146
context.reset();
146147
}
147148

exist-core/src/main/java/org/exist/test/runner/AbstractTestRunner.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ protected static Sequence executeQuery(final BrokerPool brokerPool, final Source
7373
final XQueryPool queryPool = brokerPool.getXQueryPool();
7474
CompiledXQuery compiledQuery = queryPool.borrowCompiledXQuery(broker, query);
7575

76+
XQueryContext context = null;
7677
try {
77-
XQueryContext context;
7878
if (compiledQuery == null) {
7979
context = new XQueryContext(broker.getBrokerPool());
8080
} else {
@@ -112,6 +112,10 @@ protected static Sequence executeQuery(final BrokerPool brokerPool, final Source
112112
return xqueryService.execute(broker, compiledQuery, null);
113113

114114
} finally {
115+
if (context != null) {
116+
context.runCleanupTasks();
117+
}
118+
115119
queryPool.returnCompiledXQuery(query, compiledQuery);
116120
}
117121
}

exist-core/src/main/java/org/exist/test/runner/XQueryTestRunner.java

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -100,65 +100,70 @@ private static XQueryTestInfo extractTestInfo(final Path path) throws Initializa
100100
}
101101

102102
final XQueryContext xqueryContext = new XQueryContext(config);
103-
xqueryContext.setTestRepository(Optional.of(expathRepo));
104-
105-
final Source xquerySource = new FileSource(path, UTF_8, false);
106-
final XQuery xquery = new XQuery();
107-
108-
final CompiledXQuery compiledXQuery = xquery.compile(xqueryContext, xquerySource);
109-
110-
String moduleNsPrefix = null;
111-
String moduleNsUri = null;
112-
final List<XQueryTestInfo.TestFunctionDef> testFunctions = new ArrayList<>();
113-
114-
final Iterator<UserDefinedFunction> localFunctions = compiledXQuery.getContext().localFunctions();
115-
while (localFunctions.hasNext()) {
116-
final UserDefinedFunction localFunction = localFunctions.next();
117-
final FunctionSignature localFunctionSignature = localFunction.getSignature();
118-
119-
String testName = null;
120-
boolean isTest = false;
121-
122-
final Annotation[] annotations = localFunctionSignature.getAnnotations();
123-
if (annotations != null) {
124-
for (final Annotation annotation : annotations) {
125-
final QName annotationName = annotation.getName();
126-
if (annotationName.getNamespaceURI().equals(XQSUITE_NAMESPACE)) {
127-
if (annotationName.getLocalPart().startsWith("assert")) {
128-
isTest = true;
129-
if (testName != null) {
130-
break;
131-
}
132-
} else if (annotationName.getLocalPart().equals("name")) {
133-
final LiteralValue[] annotationValues = annotation.getValue();
134-
if (annotationValues != null && annotationValues.length > 0) {
135-
testName = annotationValues[0].getValue().getStringValue();
136-
if (isTest) {
103+
try {
104+
xqueryContext.setTestRepository(Optional.of(expathRepo));
105+
106+
final Source xquerySource = new FileSource(path, UTF_8, false);
107+
final XQuery xquery = new XQuery();
108+
109+
final CompiledXQuery compiledXQuery = xquery.compile(xqueryContext, xquerySource);
110+
111+
String moduleNsPrefix = null;
112+
String moduleNsUri = null;
113+
final List<XQueryTestInfo.TestFunctionDef> testFunctions = new ArrayList<>();
114+
115+
final Iterator<UserDefinedFunction> localFunctions = compiledXQuery.getContext().localFunctions();
116+
while (localFunctions.hasNext()) {
117+
final UserDefinedFunction localFunction = localFunctions.next();
118+
final FunctionSignature localFunctionSignature = localFunction.getSignature();
119+
120+
String testName = null;
121+
boolean isTest = false;
122+
123+
final Annotation[] annotations = localFunctionSignature.getAnnotations();
124+
if (annotations != null) {
125+
for (final Annotation annotation : annotations) {
126+
final QName annotationName = annotation.getName();
127+
if (annotationName.getNamespaceURI().equals(XQSUITE_NAMESPACE)) {
128+
if (annotationName.getLocalPart().startsWith("assert")) {
129+
isTest = true;
130+
if (testName != null) {
137131
break;
138132
}
133+
} else if (annotationName.getLocalPart().equals("name")) {
134+
final LiteralValue[] annotationValues = annotation.getValue();
135+
if (annotationValues != null && annotationValues.length > 0) {
136+
testName = annotationValues[0].getValue().getStringValue();
137+
if (isTest) {
138+
break;
139+
}
140+
}
139141
}
140142
}
141143
}
142144
}
143-
}
144145

145-
if (isTest) {
146-
if (testName == null) {
147-
testName = localFunctionSignature.getName().getLocalPart();
148-
}
146+
if (isTest) {
147+
if (testName == null) {
148+
testName = localFunctionSignature.getName().getLocalPart();
149+
}
149150

150-
if (moduleNsPrefix == null) {
151-
moduleNsPrefix = localFunctionSignature.getName().getPrefix();
152-
}
153-
if (moduleNsUri == null) {
154-
moduleNsUri = localFunctionSignature.getName().getNamespaceURI();
155-
}
151+
if (moduleNsPrefix == null) {
152+
moduleNsPrefix = localFunctionSignature.getName().getPrefix();
153+
}
154+
if (moduleNsUri == null) {
155+
moduleNsUri = localFunctionSignature.getName().getNamespaceURI();
156+
}
156157

157-
testFunctions.add(new XQueryTestInfo.TestFunctionDef(testName));
158-
}
159-
} // end while
158+
testFunctions.add(new XQueryTestInfo.TestFunctionDef(testName));
159+
}
160+
} // end while
160161

161-
return new XQueryTestInfo(moduleNsPrefix, moduleNsUri, testFunctions);
162+
return new XQueryTestInfo(moduleNsPrefix, moduleNsUri, testFunctions);
163+
} finally {
164+
xqueryContext.runCleanupTasks();
165+
xqueryContext.reset();
166+
}
162167

163168
} catch (final DatabaseConfigurationException | IOException | PermissionDeniedException | XPathException e) {
164169
throw new InitializationError(e);

exist-core/src/main/java/org/exist/validation/internal/DatabaseResources.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,10 @@ public Sequence executeQuery(String queryPath, Map<String,String> params, Subjec
132132
}
133133

134134
Sequence result= null;
135+
final XQueryContext context = new XQueryContext(brokerPool);
135136
try(final DBBroker broker = brokerPool.get(Optional.ofNullable(user))) {
136137

137138
final XQuery xquery = brokerPool.getXQueryService();
138-
final XQueryContext context = new XQueryContext(brokerPool);
139139

140140
if(collection!=null){
141141
context.declareVariable(COLLECTION, collection);
@@ -160,6 +160,7 @@ public Sequence executeQuery(String queryPath, Map<String,String> params, Subjec
160160
} catch (final EXistException | XPathException | IOException | PermissionDeniedException ex) {
161161
logger.error("Problem executing xquery", ex);
162162
result= null;
163+
context.runCleanupTasks();
163164

164165
}
165166
return result;

exist-core/src/main/java/org/exist/xquery/functions/util/Compile.java

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -103,63 +103,69 @@ public Compile(XQueryContext context, FunctionSignature signature) {
103103

104104
public Sequence eval(Sequence[] args, Sequence contextSequence)
105105
throws XPathException {
106-
106+
107107
// get the query expression
108108
final String expr = args[0].getStringValue();
109109
if (expr.trim().isEmpty()) {
110-
return new EmptySequence();
110+
return new EmptySequence();
111111
}
112112
context.pushNamespaceContext();
113113
logger.debug("eval: {}", expr);
114114
// TODO(pkaminsk2): why replicate XQuery.compile here?
115-
115+
116116
String error = null;
117117
ErrorCodes.ErrorCode code = null;
118118
int line = -1;
119119
int column = -1;
120-
121-
final XQueryContext pContext =
122-
new XQueryContext(context.getBroker().getBrokerPool());
123-
if (getArgumentCount() == 2 && args[1].hasOne()) {
124-
pContext.setModuleLoadPath(args[1].getStringValue());
125-
}
126-
final XQueryLexer lexer = new XQueryLexer(pContext, new StringReader(expr));
127-
final XQueryParser parser = new XQueryParser(lexer);
128-
// shares the context of the outer expression
129-
final XQueryTreeParser astParser = new XQueryTreeParser(pContext);
120+
121+
final XQueryContext pContext =
122+
new XQueryContext(context.getBroker().getBrokerPool());
130123
try {
131-
parser.xpath();
132-
if(parser.foundErrors()) {
133-
logger.debug(parser.getErrorMessage());
134-
throw new XPathException(this, "error found while executing expression: " +
135-
parser.getErrorMessage());
124+
if (getArgumentCount() == 2 && args[1].hasOne()) {
125+
pContext.setModuleLoadPath(args[1].getStringValue());
126+
}
127+
final XQueryLexer lexer = new XQueryLexer(pContext, new StringReader(expr));
128+
final XQueryParser parser = new XQueryParser(lexer);
129+
// shares the context of the outer expression
130+
final XQueryTreeParser astParser = new XQueryTreeParser(pContext);
131+
try {
132+
parser.xpath();
133+
if (parser.foundErrors()) {
134+
logger.debug(parser.getErrorMessage());
135+
throw new XPathException(this, "error found while executing expression: " +
136+
parser.getErrorMessage());
137+
}
138+
final AST ast = parser.getAST();
139+
140+
final PathExpr path = new PathExpr(pContext);
141+
astParser.xpath(ast, path);
142+
if (astParser.foundErrors()) {
143+
throw astParser.getLastException();
144+
}
145+
path.analyze(new AnalyzeContextInfo());
146+
} catch (final RecognitionException | TokenStreamException e) {
147+
error = e.toString();
148+
} catch (final XPathException e) {
149+
line = e.getLine();
150+
column = e.getColumn();
151+
code = e.getCode();
152+
error = e.getDetailMessage();
153+
} catch (final Exception e) {
154+
error = e.getMessage();
155+
} finally {
156+
context.popNamespaceContext();
157+
pContext.reset(false);
158+
136159
}
137-
final AST ast = parser.getAST();
138-
139-
final PathExpr path = new PathExpr(pContext);
140-
astParser.xpath(ast, path);
141-
if(astParser.foundErrors()) {
142-
throw astParser.getLastException();
160+
161+
if (isCalledAs("compile")) {
162+
return error == null ? Sequence.EMPTY_SEQUENCE : new StringValue(this, error);
163+
} else {
164+
return response(pContext, error, code, line, column);
143165
}
144-
path.analyze(new AnalyzeContextInfo());
145-
} catch (final RecognitionException | TokenStreamException e) {
146-
error = e.toString();
147-
} catch (final XPathException e) {
148-
line = e.getLine();
149-
column = e.getColumn();
150-
code = e.getCode();
151-
error = e.getDetailMessage();
152-
} catch (final Exception e) {
153-
error = e.getMessage();
166+
154167
} finally {
155-
context.popNamespaceContext();
156-
pContext.reset(false);
157-
}
158-
159-
if (isCalledAs("compile")) {
160-
return error == null ? Sequence.EMPTY_SEQUENCE : new StringValue(this, error);
161-
} else {
162-
return response(pContext, error, code, line, column);
168+
pContext.runCleanupTasks();
163169
}
164170
}
165171

exist-core/src/main/java/org/exist/xquery/functions/util/ModuleInfo.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,19 @@ public Sequence eval(Sequence[] args, Sequence contextSequence)
223223
} else {
224224
final ValueSequence resultSeq = new ValueSequence();
225225
final XQueryContext tempContext = new XQueryContext(context.getBroker().getBrokerPool());
226-
for(final Iterator<Module> i = tempContext.getRootModules(); i.hasNext(); ) {
227-
final Module module = i.next();
228-
resultSeq.add(new StringValue(this, module.getNamespaceURI()));
229-
}
230-
if (tempContext.getRepository().isPresent()) {
231-
for (final URI uri : tempContext.getRepository().get().getJavaModules()) {
232-
resultSeq.add(new StringValue(this, uri.toString()));
233-
}
226+
try {
227+
for (final Iterator<Module> i = tempContext.getRootModules(); i.hasNext(); ) {
228+
final Module module = i.next();
229+
resultSeq.add(new StringValue(this, module.getNamespaceURI()));
230+
}
231+
if (tempContext.getRepository().isPresent()) {
232+
for (final URI uri : tempContext.getRepository().get().getJavaModules()) {
233+
resultSeq.add(new StringValue(this, uri.toString()));
234+
}
235+
}
236+
} finally {
237+
tempContext.reset();
238+
tempContext.runCleanupTasks();
234239
}
235240
return resultSeq;
236241
}

exist-core/src/main/java/org/exist/xupdate/XUpdateProcessor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,8 +786,10 @@ private Sequence processQuery(String select) throws SAXException {
786786
} catch (final XPathException e) {
787787
throw new SAXException(e);
788788
} finally {
789-
if (context != null)
790-
{context.reset(false);}
789+
if (context != null) {
790+
context.reset(false);
791+
context.runCleanupTasks();
792+
}
791793
}
792794
}
793795

0 commit comments

Comments
 (0)