use of org.exist.storage.NodePath in project exist by eXist-db.
the class OptimizeFieldPragma method before.
@Override
public void before(final XQueryContext context, final Expression expression, final Sequence contextSequence) throws XPathException {
final LocationStep locationStep = (LocationStep) expression;
@Nullable final Predicate[] preds = locationStep.getPredicates();
if (preds != null) {
final Expression parentExpr = locationStep.getParentExpression();
if (!(parentExpr instanceof RewritableExpression)) {
return;
}
// get path of path expression before the predicates
final NodePath contextPath = RangeQueryRewriter.toNodePath(RangeQueryRewriter.getPrecedingSteps(locationStep));
rewritten = tryRewriteToFields(locationStep, preds, contextPath, contextSequence);
axis = locationStep.getAxis();
}
}
use of org.exist.storage.NodePath in project exist by eXist-db.
the class RangeQueryRewriter method rewriteLocationStep.
@Override
public Pragma rewriteLocationStep(final LocationStep locationStep) throws XPathException {
int axis = locationStep.getAxis();
if (!(axis == Constants.CHILD_AXIS || axis == Constants.DESCENDANT_AXIS || axis == Constants.DESCENDANT_SELF_AXIS || axis == Constants.ATTRIBUTE_AXIS || axis == Constants.DESCENDANT_ATTRIBUTE_AXIS || axis == Constants.SELF_AXIS)) {
return null;
}
@Nullable final Predicate[] preds = locationStep.getPredicates();
if (preds != null) {
final Expression parentExpr = locationStep.getParentExpression();
if ((parentExpr instanceof RewritableExpression)) {
// Step 1: replace all optimizable expressions within predicates with
// calls to the range functions. If those functions are used or not will
// be decided at run time.
// will become true if optimizable expression is found
boolean canOptimize = false;
// get path of path expression before the predicates
NodePath contextPath = toNodePath(getPrecedingSteps(locationStep));
// process the remaining predicates
for (Predicate pred : preds) {
if (pred.getLength() != 1) {
// can only optimize predicates with one expression
break;
}
Expression innerExpr = pred.getExpression(0);
List<LocationStep> steps = getStepsToOptimize(innerExpr);
if (steps == null || steps.isEmpty()) {
// no optimizable steps found
continue;
}
// check if inner steps are on an axis we can optimize
if (innerExpr instanceof InternalFunctionCall) {
InternalFunctionCall fcall = (InternalFunctionCall) innerExpr;
axis = ((Optimizable) fcall.getFunction()).getOptimizeAxis();
} else {
axis = ((Optimizable) innerExpr).getOptimizeAxis();
}
if (!(axis == Constants.CHILD_AXIS || axis == Constants.DESCENDANT_AXIS || axis == Constants.DESCENDANT_SELF_AXIS || axis == Constants.ATTRIBUTE_AXIS || axis == Constants.DESCENDANT_ATTRIBUTE_AXIS || axis == Constants.SELF_AXIS)) {
continue;
}
// compute left hand path
NodePath innerPath = toNodePath(steps);
if (innerPath == null) {
continue;
}
NodePath path;
if (contextPath == null) {
path = innerPath;
} else {
path = new NodePath(contextPath);
path.append(innerPath);
}
if (path.length() > 0) {
// replace with call to lookup function
// collect arguments
Lookup func = rewrite(innerExpr, path);
// preserve original comparison: may need it for in-memory lookups
func.setFallback(innerExpr, axis);
func.setLocation(innerExpr.getLine(), innerExpr.getColumn());
pred.replace(innerExpr, new InternalFunctionCall(func));
canOptimize = true;
}
}
if (canOptimize) {
// not be called.
return new OptimizeFieldPragma(OptimizeFieldPragma.OPTIMIZE_RANGE_PRAGMA, null, getContext());
}
}
}
return null;
}
use of org.exist.storage.NodePath in project exist by eXist-db.
the class Lookup method findConfiguration.
private RangeIndexConfigElement findConfiguration(Sequence contextSequence) {
NodePath path = contextPath;
if (path == null) {
if (contextQName == null) {
return null;
}
path = new NodePath(contextQName);
}
for (final Iterator<Collection> i = contextSequence.getCollectionIterator(); i.hasNext(); ) {
final Collection collection = i.next();
if (collection.getURI().startsWith(XmldbURI.SYSTEM_COLLECTION_URI)) {
continue;
}
IndexSpec idxConf = collection.getIndexConfiguration(context.getBroker());
if (idxConf != null) {
RangeIndexConfig config = (RangeIndexConfig) idxConf.getCustomIndexSpec(RangeIndex.ID);
if (config != null) {
RangeIndexConfigElement rice = config.find(path);
if (rice != null && !rice.isComplex()) {
return rice;
}
}
}
}
return null;
}
use of org.exist.storage.NodePath in project exist by eXist-db.
the class RangeIndexConfigField method match.
public boolean match(NodePath parentPath, NodePath other) {
if (relPath == null) {
return parentPath.match(other);
} else {
NodePath absPath = new NodePath(parentPath);
absPath.append(relPath);
return absPath.match(other);
}
}
use of org.exist.storage.NodePath in project exist by eXist-db.
the class ContentReceiver method startElement.
@Override
public void startElement(QName qname, AttrList attribs) throws SAXException {
// Calculate path to current element
currentElementPath.addComponent(qname);
// Current path matches wanted path
if (matches(currentElementPath)) {
if (sendDataToCB) {
// Data is already sent to callback, ignore
} else {
// New element match, new data
// Save reference to current path
startElementPath = new NodePath(currentElementPath);
// Store old fragment in stack
context.pushDocumentContext();
// Create new receiver
MemTreeBuilder memBuilder = context.getDocumentBuilder();
docBuilderReceiver = new DocumentBuilderReceiver(memBuilder);
// Switch on retrievel
sendDataToCB = true;
}
}
if (sendDataToCB) {
docBuilderReceiver.startElement(qname, attribs);
}
}
Aggregations