use of net.sf.saxon.expr.parser.PathMap in project teiid by teiid.
the class SaxonXQueryExpression method useDocumentProjection.
public void useDocumentProjection(List<XMLTable.XMLColumn> columns, AnalysisRecord record) {
try {
streamingPath = StreamingUtils.getStreamingPath(xQueryString, namespaceMap);
} catch (IllegalArgumentException e) {
if (record.recordAnnotations()) {
// $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
record.addAnnotation(XQUERY_PLANNING, "Invalid streaming path " + xQueryString + " " + e.getMessage(), "Document streaming will not be used", Priority.MEDIUM);
}
}
this.contextRoot = null;
PathMap map = new PathMap(this.xQuery.getExpression());
PathMapRoot parentRoot;
try {
parentRoot = map.getContextDocumentRoot();
} catch (IllegalStateException e) {
if (record.recordAnnotations()) {
// $NON-NLS-1$ //$NON-NLS-2$
record.addAnnotation(XQUERY_PLANNING, "Multiple context items exist " + xQueryString, "Document projection will not be used", Priority.MEDIUM);
}
return;
}
if (parentRoot == null) {
// this.xQuery.usesContextItem() should also be false
if (record.recordAnnotations()) {
// $NON-NLS-1$ //$NON-NLS-2$
record.addAnnotation(XQUERY_PLANNING, "No context item reference was found in the XQuery " + xQueryString, "Document projection will not be used", Priority.MEDIUM);
}
return;
}
HashSet<PathMapNode> finalNodes = new HashSet<PathMapNode>();
getReturnableNodes(parentRoot, finalNodes);
if (!finalNodes.isEmpty()) {
if (columns != null && !columns.isEmpty()) {
if (finalNodes.size() != 1) {
if (record.recordAnnotations()) {
// $NON-NLS-1$ //$NON-NLS-2$
record.addAnnotation(XQUERY_PLANNING, "multiple return items exist " + xQueryString, "Document projection will not be used", Priority.MEDIUM);
}
return;
}
parentRoot = projectColumns(parentRoot, columns, finalNodes.iterator().next(), record);
if (parentRoot == null) {
return;
}
} else {
for (Iterator<PathMapNode> iter = finalNodes.iterator(); iter.hasNext(); ) {
PathMapNode subNode = iter.next();
subNode.createArc(AxisInfo.DESCENDANT_OR_SELF, AnyNodeTest.getInstance());
}
}
}
if (parentRoot.hasUnknownDependencies()) {
if (record.recordAnnotations()) {
// $NON-NLS-1$ //$NON-NLS-2$
record.addAnnotation(XQUERY_PLANNING, "There are unknown dependencies (most likely a user defined function) in " + xQueryString, "Document projection will not be used", Priority.MEDIUM);
}
return;
}
if (record.recordAnnotations()) {
StringBuilder sb = null;
if (record.recordDebug()) {
sb = new StringBuilder();
showArcs(sb, parentRoot, 0);
}
// $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
record.addAnnotation(XQUERY_PLANNING, "Projection conditions met for " + xQueryString, "Document projection will be used" + (sb != null ? "\n" + sb.toString() : ""), Priority.MEDIUM);
}
this.contextRoot = parentRoot;
}
use of net.sf.saxon.expr.parser.PathMap in project teiid by teiid.
the class SaxonXQueryExpression method projectColumns.
private PathMapRoot projectColumns(PathMapRoot parentRoot, List<XMLTable.XMLColumn> columns, PathMapNode finalNode, AnalysisRecord record) {
for (XMLColumn xmlColumn : columns) {
if (xmlColumn.isOrdinal()) {
continue;
}
Expression internalExpression = xmlColumn.getPathExpression().getInternalExpression();
PathMap subMap = new PathMap(internalExpression);
PathMapRoot subContextRoot = null;
for (PathMapRoot root : subMap.getPathMapRoots()) {
if (root.getRootExpression() instanceof ContextItemExpression || root.getRootExpression() instanceof RootExpression) {
if (subContextRoot != null) {
if (record.recordAnnotations()) {
// $NON-NLS-1$ //$NON-NLS-2$
record.addAnnotation(XQUERY_PLANNING, "Multiple context items exist in column path " + xmlColumn.getPath(), "Document projection will not be used", Priority.MEDIUM);
}
return null;
}
subContextRoot = root;
}
}
// special case for handling '.', which the pathmap logic doesn't consider as a root
if (internalExpression instanceof ContextItemExpression) {
addReturnedArcs(xmlColumn, finalNode);
}
if (subContextRoot == null) {
continue;
}
for (PathMapArc arc : subContextRoot.getArcs()) {
if (streamingPath != null && !validateColumnForStreaming(record, xmlColumn, arc)) {
streamingPath = null;
}
finalNode.createArc(arc.getAxis(), arc.getNodeTest(), arc.getTarget());
}
HashSet<PathMapNode> subFinalNodes = new HashSet<PathMapNode>();
getReturnableNodes(subContextRoot, subFinalNodes);
for (PathMapNode subNode : subFinalNodes) {
addReturnedArcs(xmlColumn, subNode);
}
}
// Workaround to rerun the reduction algorithm - by making a copy of the old version
PathMap newMap = new PathMap(DUMMY_EXPRESSION);
PathMapRoot newRoot = newMap.makeNewRoot(parentRoot.getRootExpression());
if (parentRoot.isAtomized()) {
newRoot.setAtomized();
}
if (parentRoot.isReturnable()) {
newRoot.setReturnable(true);
}
if (parentRoot.hasUnknownDependencies()) {
newRoot.setHasUnknownDependencies();
}
for (PathMapArc arc : parentRoot.getArcs()) {
newRoot.createArc(arc.getAxis(), arc.getNodeTest(), arc.getTarget());
}
return newMap.reduceToDownwardsAxes(newRoot);
}
Aggregations