Bug #6553
closedjava.lang.AssertionError when compile Xquery with tracing enabled
0%
Description
Hi Team, We are migrating from Saxon-ee 9 to 12.5. During regression test, some simple xquery is raising java.lang.AssertionError during compile with FeatureKeys.COMPILE_WITH_TRACING is set to true. This issue can be reproduced with the attach xquery compileXQueryWithTraceEnabled_test001.xquery and the java code below:
@Test
public final void testXQueryCompile_01() throws Exception {
// Use a default config different than the xml rule
// to check if that affect the compile result
final EnterpriseConfiguration config = new EnterpriseConfiguration();
SaxonActivator.activate(config);
try {
final InputStream source = new BufferedInputStream(Thread.currentThread().getContextClassLoader().getResourceAsStream("compileXQueryWithTraceEnabled_test001.xquery"));
config.setConfigurationProperty(FeatureKeys.COMPILE_WITH_TRACING, true);
final Processor processor = new Processor(config);
final XQueryCompiler xQueryCompiler = processor.newXQueryCompiler();
final XQueryExecutable exec = xQueryCompiler.compile(source);
if (exec != null) {
System.out.println(exec.toString());
}
} catch (Throwable e) {
e.printStackTrace();
}
}
Files
Updated by Michael Kay about 2 months ago
- Status changed from New to In Progress
Updated by Michael Kay about 2 months ago
Thanks for reporting it. I have reproduced the problem from the command line running with -q:test.xq -T
.
Updated by Michael Kay about 2 months ago
During function inlining, which requires copying a subtree of the expression tree, it's failing on a check that says an expression must either have a retainedStaticContext
property, or must have a parent expression. The FLWOR expression forming the body of the function has no parent, which is correct, but it also has no retained static context, which appears to be incorrect.
During initial parsing, the FLWORExpression comprising the body [@2048] appears to be created correctly, and it does have a retainedStaticContext
property [@2024].
XQueryFunction.compile()
subsequently calls TraceCodeInjector.inject()
and after this process the FLWORExpression
still has a retainedStaticContext
property. Then TraceCodeInjector.process()
wraps the FLWORExpression
[@1936] in a ComponentTracer
[@2036], and after this everything still looks good.
Fasf-forward to the point where we do function inlining, and the FLWORExpression
has been simplified by inlining of the variable $dummy
. The FLWOR expression now consists solely of a trace clause and a return clause; but there's nothing obviously wrong with it. We now get to function.getBody().copy()
, which is where the failure occurs. I suspect the problem is in FLWORExpression.copy()
when the only clause in the FLWOR expression is a trace clause.
Updated by Michael Kay about 2 months ago
Right: although the let
clause has been dropped from the FLWOR expression through variable inlining, the trace
clause that remains still refers to the let
clause in its target
property, which is looking rather questionable. But that doesn't seem to be the core of the problem.
The immediate cause of the failure is that we construct a new FLWOR expression, and then copy each of the clauses individually, and while copying the (first) trace clause, we access the retained static context of the new FLWOR expression, which hasn't yet been initialized.
Trying to initialise the RSC earlier doesn't work, because it propagates to all the operands and these aren't initialised yet. So the real problem is that TraceClause.copy()
shouldn't be trying to access the RSC of its parent expression.
Which raises the question, why does TraceClause
need to initialise a NamespaceResolver
? It's used at run-time to initialise the NamespaceResolver
property of the ClauseInfo
passed to the TraceListener
. But ClauseInfo.getNamespaceResolver()
appears to be used only by unit tests and not by any real code. It isn't used by the XQueryTraceListener
- though we have to be careful, because it could potentially be used by a user-written TraceListener
.
So there are a number of things to explore here:
(a) When we inline the variable in a let clause, we should not only remove the let clause, we should also remove any trace clause that refers to it.
(b) When we copy a trace clause, we should not rely on the static context of the new FLWORExpression that we are attaching it to.
(c) It's not clear whether the NamespaceResolver of a trace clause is actually needed at all.
Updated by Michael Kay about 2 months ago
Started with (b): the TraceClause no longer accesses the retained static context of the containing FLWOR expression at the time it is created, only subsequently when a request for its namespaceResolver arises.
On (c) I think it's safest to leave the namespaceResolver available, just in case there are applications that use it.
On (a) I have changed the code so that when trace code has been injected, variables declared in let clauses are not inlined. I have also made this subject to the setting of OptimizerOptions.INLINE_VARIABLES
Updated by Michael Kay about 2 months ago
- Status changed from In Progress to Resolved
- Priority changed from High to Normal
- Applies to branch trunk added
- Fix Committed on Branch 12, trunk added
- Platforms .NET added
Updated by Joe Che about 2 months ago
Hi Michael, thanks for the quick response. Is the change for OptimizerOptions.INLINE_VARIABLES already in 12.5 or need to wait for a patch?
Updated by Michael Kay about 2 months ago
All of these changes will become available in the next maintenance release on the 12.x branch and in the 13.x release, whenever they happen.
Please register to edit this issue