SystemId information not available to TraceListener
When running XQuery with a TraceListener, the method call InstructionInfo.getSystemId() returns null, rather than giving useful location information for the instruction.
#1 Updated by Michael Kay over 5 years ago
- Status changed from New to In Progress
Created a test case (Pisoi3/XQueryDebugger).
First observation: in QueryModule initialization, we call sqc.makeExecutable() twice, which is inefficient and gives the opportunity for inconsistencies.
Second observation: in StaticQueryContext.compileQuery, we create another (third) Executable, rather than using the one already created by the main QueryModule.
After fixing these problems, the InstructionInfo for FLWOR clauses (a ClauseInfo) now contains the correct system ID. But the systemId for a TraceExpression is still null.
ClauseInfo gets the SystemID from getContainer().getPackageData().getLocationMap().getSystemId(locationid), which gives the right answer. But TraceExpression gets it using Expression.getSystemId(), which is null. There is commented-out code in Expression.getSystemId() which attempts to get the location information via the PackageData - it's not clear why it is commented out.
Expression.getSystemId() seems a rather important method, critical to all error reporting, so it's odd that it should be wrong, and we need to take great care if we're going to change it.
#2 Updated by Michael Kay over 5 years ago
Further investigation shows that for dynamic errors in XQuery code, we are getting line numbers but we are not getting the system ID of the module. This is true whether the dynamic error is in the main query expression, in a function in the main module, or in a function in an imported module.
#3 Updated by Michael Kay over 5 years ago
- Status changed from In Progress to Resolved
I think the reason that Expression.getSystemId() doesn't use the location map is because of problems encountered with XSLT packages. The problem here is generating globally-unique location IDs when packages are compiled indepedently. In fact this problem was never quite solved for 9.6, which continues to use globally-unique location IDs because they are needed on the receiver pipeline. But the change was an attempt to reduce reliance on them.
I'm trying to see if I can make it work using the system ID of the container, making sure this is correctly set. First step is to change XQueryExpression.getSystemId() to return mainModule.getSystemId() instead of null.
This now gives me a system ID but unfortunately it is wrong. In my test case, the failure occurs in a function in an imported module, but the function was inlined, and I'm now getting the original line number, but the system ID of the module into which the code was inlined. Because the inlined function code doesn't have a container of its own, this suggests that using the system ID of the container is not safe, so we may have to fall back on location IDs after all.
I have changed Expression.getSystemId() to use the locationId and locationMap. This change gives correct location information both for my dynamic error test case and for the original TraceListener test case. I now need to check that it doesn't cause regression elsewhere.
Checked OK that static errors in XQuery are still reported correctly: both in the main module and library modules. Also ran the "error" test-set for XSLT 3.0 and checked that module and line information is being produced. Also checked -T output with both Transform and Query command line. All seems well, so I will commit the changes for both th 9.6 nad 9.7 branches.
Please register to edit this issue